From fbd127113629a1eed72d32ffb84572b0d40d8154 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Thu, 8 May 2014 03:58:00 +0200 Subject: use the data structure marshallers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 7 +- src/mds-server/client.c | 34 ++++- src/mds-server/client.h | 12 +- src/mds-server/interception_condition.c | 17 +++ src/mds-server/interception_condition.h | 8 ++ src/mds-server/mds-server.c | 213 ++++++-------------------------- 6 files changed, 109 insertions(+), 182 deletions(-) diff --git a/Makefile b/Makefile index 1ea639c..acea291 100644 --- a/Makefile +++ b/Makefile @@ -69,11 +69,10 @@ LIBOBJ = linked-list hash-table fd-table mds-message util all: bin/mds bin/mds-server/mds-server bin/libmdsserver.so -bin/mds-server/mds-server: obj/mds-server/mds-server.o bin/libmdsserver.so \ - obj/mds-server/interception_condition.o \ - obj/mds-server/client.o +MDS_SERVER_OBJ = mds-server/mds-server mds-server/interception_condition mds-server/client +bin/mds-server/mds-server: $(foreach O,$(MDS_SERVER_OBJ),obj/$(O).o) bin/libmdsserver.so mkdir -p $(shell dirname $@) - gcc $(C_FLAGS) -o $@ -Lbin -lmdsserver -lrt obj/mds-server/mds-server.o + gcc $(C_FLAGS) -o $@ -Lbin -lmdsserver -lrt $(foreach O,$(MDS_SERVER_OBJ),obj/$(O).o) bin/%: obj/%.o bin/libmdsserver.so mkdir -p $(shell dirname $@) diff --git a/src/mds-server/client.c b/src/mds-server/client.c index 13b291c..f48a1b0 100644 --- a/src/mds-server/client.c +++ b/src/mds-server/client.c @@ -45,7 +45,7 @@ size_t client_marshal_size(const client_t* restrict this) /** - * Marshals an client information + * Marshals client information * * @param this The client information * @param data Output buffer for the marshalled data @@ -73,7 +73,7 @@ size_t client_marshal(const client_t* restrict this, char* restrict data) /** - * Unmarshals an client information + * Unmarshals client information * * @param this Memory slot in which to store the new client information * @param data In buffer with the marshalled data @@ -94,6 +94,8 @@ size_t client_unmarshal(client_t* restrict this, char* restrict data) data += n / sizeof(char); rc += n; buf_get_next(data, size_t, this->interception_conditions_count); + if (xmalloc(this->interception_conditions, this->interception_conditions_count, interception_condition_t)) + goto fail; for (i = 0; i < this->interception_conditions_count; i++) { n = interception_condition_unmarshal(this->interception_conditions + i, data); @@ -115,6 +117,7 @@ size_t client_unmarshal(client_t* restrict this, char* restrict data) return rc; fail: + mds_message_destroy(&(this->message)); for (i = 0; i < this->interception_conditions_count; i++) free(this->interception_conditions[i].condition); free(this->interception_conditions); @@ -122,3 +125,30 @@ size_t client_unmarshal(client_t* restrict this, char* restrict data) return 0; } +/** + * Pretend to unmarshal client information + * + * @param data In buffer with the marshalled data + * @return The number of read bytes + */ +size_t client_unmarshal_skip(char* restrict data) +{ + size_t n, c, rc = sizeof(ssize_t) + 2 * sizeof(int) + sizeof(uint64_t) + 3 * sizeof(size_t); + buf_next(data, ssize_t, 1); + buf_next(data, int, 2); + buf_next(data, uint64_t, 1); + buf_get_next(data, size_t, n); + data += n / sizeof(char); + rc += n; + buf_get_next(data, size_t, c); + while (c--) + { + n = interception_condition_unmarshal_skip(data); + data += n / sizeof(char); + rc += n; + } + buf_get_next(data, size_t, n); + rc += n * sizeof(char); + return rc; +} + diff --git a/src/mds-server/client.h b/src/mds-server/client.h index a63f2b6..a795c84 100644 --- a/src/mds-server/client.h +++ b/src/mds-server/client.h @@ -103,7 +103,7 @@ typedef struct client size_t client_marshal_size(const client_t* restrict this) __attribute__((pure)); /** - * Marshals an client information + * Marshals client information * * @param this The client information * @param data Output buffer for the marshalled data @@ -112,7 +112,7 @@ size_t client_marshal_size(const client_t* restrict this) __attribute__((pure)); size_t client_marshal(const client_t* restrict this, char* restrict data); /** - * Unmarshals an client information + * Unmarshals client information * * @param this Memory slot in which to store the new client information * @param data In buffer with the marshalled data @@ -121,6 +121,14 @@ size_t client_marshal(const client_t* restrict this, char* restrict data); */ size_t client_unmarshal(client_t* restrict this, char* restrict data); +/** + * Pretend to unmarshal client information + * + * @param data In buffer with the marshalled data + * @return The number of read bytes + */ +size_t client_unmarshal_skip(char* restrict data) __attribute__((pure)); + #endif diff --git a/src/mds-server/interception_condition.c b/src/mds-server/interception_condition.c index 076bc19..47a082a 100644 --- a/src/mds-server/interception_condition.c +++ b/src/mds-server/interception_condition.c @@ -74,3 +74,20 @@ size_t interception_condition_unmarshal(interception_condition_t* restrict this, return sizeof(size_t) + sizeof(int64_t) + sizeof(int) + n; } + +/** + * Pretend to an interception condition + * + * @param data In buffer with the marshalled data + * @return The number of read bytes + */ +size_t interception_condition_unmarshal_skip(char* restrict data) +{ + size_t n = sizeof(size_t) + sizeof(int64_t) + sizeof(int); + buf_next(data, size_t, 1); + buf_next(data, int64_t, 1); + buf_next(data, int, 1); + n += (strlen(data) + 1) * sizeof(char); + return n; +} + diff --git a/src/mds-server/interception_condition.h b/src/mds-server/interception_condition.h index c80fab0..63b9f1c 100644 --- a/src/mds-server/interception_condition.h +++ b/src/mds-server/interception_condition.h @@ -81,6 +81,14 @@ size_t interception_condition_marshal(const interception_condition_t* restrict t */ size_t interception_condition_unmarshal(interception_condition_t* restrict this, char* restrict data); +/** + * Pretend to an interception condition + * + * @param data In buffer with the marshalled data + * @return The number of read bytes + */ +size_t interception_condition_unmarshal_skip(char* restrict data) __attribute__((pure)); + #endif diff --git a/src/mds-server/mds-server.c b/src/mds-server/mds-server.c index f0fa701..bb4f52e 100644 --- a/src/mds-server/mds-server.c +++ b/src/mds-server/mds-server.c @@ -1189,41 +1189,24 @@ int marshal_server(int fd) size_t list_size = linked_list_marshal_size(&client_list); size_t map_size = fd_table_marshal_size(&client_map); size_t list_elements = 0; - size_t msg_size = 0; + size_t state_n = 0; char* state_buf = NULL; char* state_buf_; - size_t state_n; ssize_t wrote; ssize_t node; - size_t j, n; - /* Calculate the grand size of all messages and their buffers. */ + /* Calculate the grand size of all client information. */ for (node = client_list.edge;; list_elements++) { - mds_message_t message; - client_t* value; if ((node = client_list.next[node]) == client_list.edge) break; - - value = (client_t*)(void*)(client_list.values[node]); - n = value->interception_conditions_count; - message = value->message; - msg_size += mds_message_marshal_size(&message, 1); - msg_size += n * (sizeof(size_t) + sizeof(int64_t) + sizeof(int)); - msg_size += value->send_pending_size * sizeof(char); - - for (j = 0; j < n; j++) - msg_size += (strlen(value->interception_conditions[j].condition) + 1) * sizeof(char); + state_n += client_marshal_size((client_t*)(void*)(client_list.values[node])); } - /* Calculate the grand size of all client information. */ - state_n = 6 + sizeof(size_t) + 2 * sizeof(int) + 1 * sizeof(uint64_t); - state_n *= list_elements; - state_n += msg_size; - /* Add the size of the rest of the program's state. */ - state_n += 2 * sizeof(int) + 1 * sizeof(sig_atomic_t) + 2 * sizeof(size_t); + state_n += sizeof(int) + sizeof(sig_atomic_t) + sizeof(uint64_t) + 2 * sizeof(size_t); + state_n += list_elements * sizeof(size_t) + list_size + map_size; /* Allocate a buffer for all data except the client list and the client map. */ state_buf = state_buf_ = malloc(state_n); @@ -1250,41 +1233,17 @@ int marshal_server(int fd) /* Get the client's information. */ client_t* value = (client_t*)(void*)value_address; - /* Get the marshalled size of the message. */ - msg_size = mds_message_marshal_size(&(value->message), 1); - /* Marshal the address, it is used the the client list and the client map, that will be marshalled. */ buf_set_next(state_buf_, size_t, value_address); - /* Tell the program how large the marshalled message is. */ - buf_set_next(state_buf_, size_t, msg_size); - /* Marshal the client info. */ - buf_set_next(state_buf_, ssize_t, value->list_entry); - buf_set_next(state_buf_, int, value->socket_fd); - buf_set_next(state_buf_, int, value->open); - buf_set_next(state_buf_, uint64_t, value->id); - /* Marshal the pending messages. */ - buf_set_next(state_buf_, size_t, value->send_pending_size); - if (value->send_pending_size > 0) - { - memcpy(state_buf_, value->send_pending, value->send_pending_size * sizeof(char)); - state_buf_ += value->send_pending_size; - } - /* Marshal interception conditions. */ - buf_set_next(state_buf_, size_t, n = value->interception_conditions_count); - for (j = 0; j < n; j++) - { - interception_condition_t cond = value->interception_conditions[j]; - memcpy(state_buf_, cond.condition, strlen(cond.condition) + 1); - buf_next(state_buf_, char, strlen(cond.condition) + 1); - buf_set_next(state_buf_, size_t, cond.header_hash); - buf_set_next(state_buf_, int64_t, cond.priority); - buf_set_next(state_buf_, int, cond.modifying); - } - /* Marshal the message. */ - mds_message_marshal(&(value->message), state_buf_, 1); - state_buf_ += msg_size / sizeof(char); + /* Marshal the client informationation. */ + state_buf_ += client_marshal(value, state_buf_) / sizeof(char); } + /* Marshal the client list. */ + linked_list_marshal(&client_list, state_buf_); + state_buf_ += list_size / sizeof(char); + /* Marshal the client map. */ + fd_table_marshal(&client_map, state_buf_); /* Send the marshalled data into the file. */ while (state_n > 0) @@ -1298,38 +1257,6 @@ int marshal_server(int fd) } free(state_buf); - /* Marshal, and send into the file, the client list. */ - state_buf = malloc(list_size); - if (state_buf == NULL) - goto fail; - linked_list_marshal(&client_list, state_buf); - while (list_size > 0) - { - errno = 0; - wrote = write(fd, state_buf, list_size); - if (errno && (errno != EINTR)) - goto fail; - list_size -= (size_t)max(wrote, 0); - state_buf += (size_t)max(wrote, 0); - } - free(state_buf); - - /* Marshal, and send into the file, the client map. */ - state_buf = malloc(map_size); - if (state_buf == NULL) - goto fail; - fd_table_marshal(&client_map, state_buf); - while (map_size > 0) - { - errno = 0; - wrote = write(fd, state_buf, map_size); - if (errno && (errno != EINTR)) - goto fail; - map_size -= (size_t)max(wrote, 0); - state_buf += (size_t)max(wrote, 0); - } - free(state_buf); - return 0; fail: @@ -1437,123 +1364,61 @@ int unmarshal_server(int fd) /* Unmarshal the clients. */ for (i = 0; i < list_elements; i++) { - size_t seek = 0; - size_t j = 0, n = 0; + size_t n; size_t value_address; - size_t msg_size; client_t* value; /* Allocate the client's information. */ if (xmalloc(value, 1, client_t)) - { - perror(*argv); - goto clients_fail; - } + goto clients_fail; /* Unmarshal the address, it is used the the client list and the client map, that are also marshalled. */ buf_get_next(state_buf_, size_t, value_address); - /* Get the marshalled size of the message. */ - buf_get_next(state_buf_, size_t, msg_size); - /* Unmarshal the client info. */ - buf_get_next(state_buf_, ssize_t, value->list_entry); - buf_get_next(state_buf_, int, value->socket_fd); - buf_get_next(state_buf_, int, value->open); - buf_get_next(state_buf_, uint64_t, value->id); - /* Unmarshal the pending messages. */ - buf_get_next(state_buf_, size_t, value->send_pending_size); - if (value->send_pending_size > 0) - { - if (xmalloc(value->send_pending, value->send_pending_size, char)) - { - perror(*argv); - goto clients_fail; - } - memcpy(value->send_pending, state_buf_, value->send_pending_size * sizeof(char)); - state_buf_ += value->send_pending_size; - } - else - value->send_pending = NULL; - /* Unmarshal interception conditions. */ - buf_get_next(state_buf_, size_t, value->interception_conditions_count = n); - seek = 6 * sizeof(size_t) + 2 * sizeof(int) + 1 * sizeof(uint64_t); - if (xmalloc(value->interception_conditions, n, interception_condition_t)) - { - perror(*argv); - goto clients_fail; - } - for (j = 0; j < n; j++) - { - interception_condition_t* cond = value->interception_conditions + j; - size_t m = strlen(state_buf_) + 1; - if (xmalloc(cond->condition, m, char)) - { - perror(*argv); - goto clients_fail; - } - memcpy(cond->condition, state_buf_, m); - buf_next(state_buf_, char, m); - buf_get_next(state_buf_, size_t, cond->header_hash); - buf_get_next(state_buf_, int64_t, cond->priority); - buf_get_next(state_buf_, int, cond->modifying); - seek += m * sizeof(char) + sizeof(size_t) + sizeof(int64_t) + sizeof(int); - } - /* Unmarshal the message. */ - if (mds_message_unmarshal(&(value->message), state_buf_)) - { - perror(*argv); - mds_message_destroy(&(value->message)); - goto clients_fail; - } - state_buf_ += msg_size / sizeof(char); + /* Unmarshal the client information. */ + n = client_unmarshal(value, state_buf_); + if (n == 0) + goto clients_fail; /* Populate the remapping table. */ - hash_table_put(&unmarshal_remap_map, value_address, (size_t)(void*)value); + if (hash_table_put(&unmarshal_remap_map, value_address, (size_t)(void*)value) == 0) + if (errno) + goto clients_fail; + + state_buf_ += n / sizeof(char); /* On error, seek past all clients. */ continue; clients_fail: + perror(*argv); with_error = 1; if (value != NULL) { - if (value->interception_conditions != NULL) - { - for (j = 0; j < n; j++) - free(value->interception_conditions[j].condition); - free(value->interception_conditions); - } - free(value->send_pending); + buf_prev(state_buf_, size_t, 1); free(value); } - state_buf_ -= seek / sizeof(char); for (; i < list_elements; i++) - { - /* There is not need to close the sockets, it is done by - the caller because there are conditions where we cannot - get here anyway. */ - msg_size = ((size_t*)state_buf_)[1]; - buf_next(state_buf_, size_t, 4); - buf_next(state_buf_, int, 2); - buf_next(state_buf_, uint64_t, 1); - buf_get_next(state_buf_, size_t, n); - for (j = 0; j < n; j++) - { - buf_next(state_buf_, char, strlen(state_buf_) + 1); - buf_next(state_buf_, size_t, 1); - buf_next(state_buf_, int64_t, 1); - buf_next(state_buf_, int, 1); - } - state_buf_ += msg_size / sizeof(char); - } + /* There is not need to close the sockets, it is done by + the caller because there are conditions where we cannot + get here anyway. */ + state_buf_ += client_unmarshal_skip(state_buf_) / sizeof(char); break; } /* Unmarshal the client list. */ - linked_list_unmarshal(&client_list, state_buf_); + if (linked_list_unmarshal(&client_list, state_buf_)) + { + perror(*argv); + /* TODO */ + } state_buf_ += list_size / sizeof(char); /* Unmarshal the client map. */ - fd_table_unmarshal(&client_map, state_buf_, unmarshal_remapper); + if (fd_table_unmarshal(&client_map, state_buf_, unmarshal_remapper)) + { + perror(*argv); + /* TODO */ + } /* Release the raw data. */ free(state_buf); -- cgit v1.2.3-70-g09d2