From 4075d1520704b1ec60d0737b49a2cfb2703a1326 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Fri, 2 May 2014 18:55:03 +0200 Subject: more re-exec stuff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/mds-server.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/src/mds-server.c b/src/mds-server.c index 7bd49e1..4438397 100644 --- a/src/mds-server.c +++ b/src/mds-server.c @@ -334,6 +334,12 @@ int main(int argc_, char** argv_) char** reexec_args; char** reexec_args_; char reexec_arg[24]; + size_t list_size; + size_t map_size; + size_t list_elements; + size_t msg_size; + ssize_t node; + #if INT_MAX > UINT64_MAX # error It seems int:s are really big, you might need to increase the size of reexec_arg. #endif @@ -348,26 +354,93 @@ int main(int argc_, char** argv_) pthread_cond_wait(&slave_cond, &slave_mutex); pthread_mutex_unlock(&slave_mutex); - /* Marshal the state of the server. */ /* TODO marshal all data. */ - state_n = 2 * sizeof(int) + 1 * sizeof(sig_atomic_t); - state_buf = alloca(state_n); + /* Marshal the state of the server. */ + list_size = linked_list_marshal_size(&client_list); + map_size = fd_table_marshal_size(&client_map); + list_elements = 0; + msg_size = 0; + for (node = client_list.edge;; list_elements++) + { + mds_message_t message; + if ((node = client_list.next[node]) == client_list.edge) + break; + message = ((client_t*)(void*)(client_list.values[node]))->message; + msg_size += mds_message_marshal_size(&message, 1); + } + state_n = sizeof(ssize_t) + 2 * sizeof(int) + 2 * sizeof(size_t); + state_n *= list_elements; + state_n += msg_size; + state_n += 2 * sizeof(int) + 1 * sizeof(sig_atomic_t) + 3 * sizeof(size_t); + state_buf = malloc(state_n); state_buf_ = state_buf; ((int*)state_buf_)[0] = MDS_SERVER_VARS_VERSION; ((int*)state_buf_)[1] = socket_fd; state_buf_ += 2 * sizeof(int) / sizeof(char); ((sig_atomic_t*)state_buf_)[0] = running; state_buf_ += 1 * sizeof(sig_atomic_t) / sizeof(char); + ((size_t*)state_buf_)[0] = list_size; + ((size_t*)state_buf_)[1] = map_size; + ((size_t*)state_buf_)[2] = list_elements; + state_buf_ += 3 * sizeof(size_t) / sizeof(char); + for (node = client_list.edge;;) + { + size_t value_address; + client_t* value; + if ((node = client_list.next[node]) == client_list.edge) + break; + value_address = client_list.values[node]; + value = (client_t*)(void*)value_address; + msg_size = mds_message_marshal_size(&(value->message), 1); + ((size_t*)state_buf_)[0] = value_address; + ((ssize_t*)state_buf_)[1] = value->list_entry; + ((size_t*)state_buf_)[2] = msg_size; + state_buf_ += 3 * sizeof(size_t) / sizeof(char); + ((int*)state_buf_)[0] = value->socket_fd; + ((int*)state_buf_)[1] = value->open; + state_buf_ += 2 * sizeof(int) / sizeof(char); + mds_message_marshal(&(value->message), state_buf_, 1); + state_buf_ += msg_size / sizeof(char); + } if (pipe(pipe_rw) < 0) goto reexec_fail; - errno = 0; while (state_n > 0) { + errno = 0; wrote = write(pipe_rw[1], state_buf, state_n); if (errno && (errno != EINTR)) goto reexec_fail; state_n -= (size_t)(wrote < 0 ? 0 : wrote); state_buf += (size_t)(wrote < 0 ? 0 : wrote); } + free(state_buf); + state_buf = malloc(list_size); + if (state_buf == NULL) + goto reexec_fail; + linked_list_marshal(&client_list, state_buf); + while (list_size > 0) + { + errno = 0; + wrote = write(pipe_rw[1], state_buf, list_size); + if (errno && (errno != EINTR)) + goto reexec_fail; + list_size -= (size_t)(wrote < 0 ? 0 : wrote); + state_buf += (size_t)(wrote < 0 ? 0 : wrote); + } + free(state_buf); + state_buf = malloc(map_size); + if (state_buf == NULL) + goto reexec_fail; + fd_table_marshal(&client_map, state_buf); + while (map_size > 0) + { + errno = 0; + wrote = write(pipe_rw[1], state_buf, map_size); + if (errno && (errno != EINTR)) + goto reexec_fail; + map_size -= (size_t)(wrote < 0 ? 0 : wrote); + state_buf += (size_t)(wrote < 0 ? 0 : wrote); + } + free(state_buf); close(pipe_rw[1]); /* Re-exec the server. */ @@ -389,6 +462,8 @@ int main(int argc_, char** argv_) reexec_fail: perror(*argv); + if (state_buf != NULL) + free(state_buf); close(pipe_rw[0]); close(pipe_rw[1]); /* Returning non-zero is important, otherwise the server cannot -- cgit v1.2.3-70-g09d2