aboutsummaryrefslogtreecommitdiffstats
path: root/src/mds-server/mds-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mds-server/mds-server.c')
-rw-r--r--src/mds-server/mds-server.c359
1 files changed, 172 insertions, 187 deletions
diff --git a/src/mds-server/mds-server.c b/src/mds-server/mds-server.c
index 8bb7b83..039a478 100644
--- a/src/mds-server/mds-server.c
+++ b/src/mds-server/mds-server.c
@@ -159,17 +159,12 @@ int main(int argc_, char** argv_)
#endif
-#define exit_if(CONDITION, INSTRUCTION) if (CONDITION) { INSTRUCTION return 1; }
-
-
argc = argc_;
argv = argv_;
/* Drop privileges like it's hot. */
- if (drop_privileges())
- goto pfail;
-
+ fail_if (drop_privileges());
/* Sanity check the number of command line arguments. */
exit_if (argc > ARGC_LIMIT + LIBEXEC_ARGC_EXTRA_LIMIT,
@@ -218,15 +213,12 @@ int main(int argc_, char** argv_)
eprint("missing socket file descriptor argument."););
-#undef exit_if
-
-
/* Run mdsinitrc. */
if (is_respawn == 0)
{
pid_t pid = fork();
- if (pid == (pid_t)-1)
- goto pfail;
+ fail_if (pid == (pid_t)-1);
+
if (pid == 0) /* Child process exec:s, the parent continues without waiting for it. */
{
/* Close all files except stdin, stdout and stderr. */
@@ -247,36 +239,34 @@ int main(int argc_, char** argv_)
if (I >= 5) pthread_cond_destroy(&modify_cond); \
if (I >= 6) hash_table_destroy(&modify_map, NULL, NULL)
-#define __error(I) perror(*argv); __free(I); return 1
-
+#define error_if(I, CONDITION) if (CONDITION) { perror(*argv); __free(I); return 1; }
/* Create list and table of clients. */
if (reexec == 0)
{
- if (fd_table_create(&client_map)) { __error(0); }
- if (linked_list_create(&client_list, 32)) { __error(1); }
+ error_if (0, fd_table_create(&client_map));
+ error_if (1, linked_list_create(&client_list, 32));
}
-
/* Store the current thread so it can be killed from elsewhere. */
master_thread = pthread_self();
/* Make the server update without all slaves dying on SIGUSR1. */
- if (xsigaction(SIGUSR1, sigusr1_trap) < 0) { __error(1); }
+ error_if (1, xsigaction(SIGUSR1, sigusr1_trap) < 0);
/* Implement clean exit on SIGTERM. */
- if (xsigaction(SIGTERM, sigterm_trap) < 0) { __error(1); }
+ error_if (1, xsigaction(SIGTERM, sigterm_trap) < 0);
/* Create mutex and condition for slave counter. */
- if ((errno = pthread_mutex_init(&slave_mutex, NULL))) { __error(1); }
- if ((errno = pthread_cond_init(&slave_cond, NULL))) { __error(2); }
+ error_if (1, (errno = pthread_mutex_init(&slave_mutex, NULL)));
+ error_if (2, (errno = pthread_cond_init(&slave_cond, NULL)));
/* Create mutex, condition and map for message modification. */
- if ((errno = pthread_mutex_init(&modify_mutex, NULL))) { __error(3); }
- if ((errno = pthread_cond_init(&modify_cond, NULL))) { __error(4); }
- if (hash_table_create(&modify_map)) { __error(5); }
-
-#undef __error
+ error_if (3, (errno = pthread_mutex_init(&modify_mutex, NULL)));
+ error_if (4, (errno = pthread_cond_init(&modify_cond, NULL)));
+ error_if (5, hash_table_create(&modify_map));
+
+#undef error_if
/* Unmarshal the state of the server. */
@@ -289,11 +279,7 @@ int main(int argc_, char** argv_)
/* Acquire access to marshalled data. */
xsnprintf(shm_path, SHM_PATH_PATTERN, (unsigned long int)pid);
reexec_fd = shm_open(shm_path, O_RDONLY, S_IRWXU);
- if (reexec_fd < 0)
- {
- perror(*argv);
- abort(); /* Critical. */
- }
+ fail_if (reexec_fd < 0); /* Critical. */
/* Unmarshal state. */
r = unmarshal_server(reexec_fd);
close(reexec_fd);
@@ -337,7 +323,7 @@ int main(int argc_, char** argv_)
}
/* Increase number of running slaves. */
- with_mutex(slave_mutex, running_slaves++;);
+ with_mutex (slave_mutex, running_slaves++;);
/* Start slave thread. */
create_slave(&slave_thread, client_fd);
@@ -349,9 +335,9 @@ int main(int argc_, char** argv_)
goto reexec;
/* Join with all slaves threads. */
- with_mutex(slave_mutex,
- while (running_slaves > 0)
- pthread_cond_wait(&slave_cond, &slave_mutex););
+ with_mutex (slave_mutex,
+ while (running_slaves > 0)
+ pthread_cond_wait(&slave_cond, &slave_mutex););
/* Release resources. */
__free(9999);
@@ -369,9 +355,9 @@ int main(int argc_, char** argv_)
ssize_t node;
/* Join with all slaves threads. */
- with_mutex(slave_mutex,
- while (running_slaves > 0)
- pthread_cond_wait(&slave_cond, &slave_mutex););
+ with_mutex (slave_mutex,
+ while (running_slaves > 0)
+ pthread_cond_wait(&slave_cond, &slave_mutex););
/* Release resources. */
pthread_mutex_destroy(&slave_mutex);
@@ -383,8 +369,7 @@ int main(int argc_, char** argv_)
/* Marshal the state of the server. */
xsnprintf(shm_path, SHM_PATH_PATTERN, (unsigned long int)pid);
reexec_fd = shm_open(shm_path, O_RDWR | O_CREAT | O_EXCL, S_IRWXU);
- if (reexec_fd < 0)
- goto pfail;
+ fail_if (reexec_fd < 0);
if (marshal_server(reexec_fd) < 0)
goto reexec_fail;
close(reexec_fd);
@@ -439,8 +424,7 @@ void* slave_loop(void* data)
if (information == NULL)
{
/* Create information table. */
- if (xmalloc(information, 1, client_t))
- goto pfail;
+ fail_if (xmalloc(information, 1, client_t));
/* NULL-out pointers and initialisation markers. */
information->interception_conditions = NULL;
@@ -479,8 +463,7 @@ void* slave_loop(void* data)
information->interception_conditions_count = 0;
information->send_pending_size = 0;
information->multicasts_count = 0;
- if (mds_message_initialise(&(information->message)))
- goto pfail;
+ fail_if (mds_message_initialise(&(information->message)));
}
@@ -488,21 +471,21 @@ void* slave_loop(void* data)
information->thread = pthread_self();
/* Create mutex to make sure two thread to not try to send
messages concurrently, and other slave local actions. */
- if ((errno = pthread_mutex_init(&(information->mutex), NULL))) goto pfail;
+ fail_if ((errno = pthread_mutex_init(&(information->mutex), NULL)));
information->mutex_created = 1;
/* Create mutex and codition for multicast interception replies. */
- if ((errno = pthread_mutex_init(&(information->modify_mutex), NULL))) goto pfail;
+ fail_if ((errno = pthread_mutex_init(&(information->modify_mutex), NULL)));
information->modify_mutex_created = 1;
- if ((errno = pthread_cond_init(&(information->modify_cond), NULL))) goto pfail;
+ fail_if ((errno = pthread_cond_init(&(information->modify_cond), NULL)));
information->modify_cond_created = 1;
/* Make the server update without all slaves dying on SIGUSR1. */
- if (xsigaction(SIGUSR1, sigusr1_trap) < 0) goto pfail;
+ fail_if (xsigaction(SIGUSR1, sigusr1_trap) < 0);
/* Implement clean exit on SIGTERM. */
- if (xsigaction(SIGTERM, sigterm_trap) < 0) goto pfail;
+ fail_if (xsigaction(SIGTERM, sigterm_trap) < 0);
/* Fetch messages from the slave. */
@@ -512,19 +495,19 @@ void* slave_loop(void* data)
if (information->multicasts_count > 0)
{
multicast_t multicast;
- with_mutex(information->mutex,
- if (information->multicasts_count > 0)
- {
- size_t c = (information->multicasts_count -= 1) * sizeof(multicast_t);
- multicast = information->multicasts[0];
- memmove(information->multicasts, information->multicasts + 1, c);
- if (c == 0)
- {
- free(information->multicasts);
- information->multicasts = NULL;
- }
- }
- );
+ with_mutex (information->mutex,
+ if (information->multicasts_count > 0)
+ {
+ size_t c = (information->multicasts_count -= 1) * sizeof(multicast_t);
+ multicast = information->multicasts[0];
+ memmove(information->multicasts, information->multicasts + 1, c);
+ if (c == 0)
+ {
+ free(information->multicasts);
+ information->multicasts = NULL;
+ }
+ }
+ );
multicast_message(&multicast);
multicast_destroy(&multicast);
}
@@ -538,20 +521,20 @@ void* slave_loop(void* data)
n = information->send_pending_size;
information->send_pending_size = 0;
information->send_pending = NULL;
- with_mutex(information->mutex,
- while (n > 0)
- {
- sent = send_message(information->socket_fd, sendbuf_, n);
- if ((sent < n) && (errno != EINTR)) /* Ignore EINTR */
- {
- perror(*argv);
- break;
- }
- n -= sent;
- sendbuf_ += sent / sizeof(char);
- }
- free(sendbuf);
- );
+ with_mutex (information->mutex,
+ while (n > 0)
+ {
+ sent = send_message(information->socket_fd, sendbuf_, n);
+ if ((sent < n) && (errno != EINTR)) /* Ignore EINTR */
+ {
+ perror(*argv);
+ break;
+ }
+ n -= sent;
+ sendbuf_ += sent / sizeof(char);
+ }
+ free(sendbuf);
+ );
}
/* Fetch message. */
@@ -615,12 +598,12 @@ void* slave_loop(void* data)
client_destroy(information);
/* Unlist client and decrease the slave count. */
- with_mutex(slave_mutex,
- fd_table_remove(&client_map, socket_fd);
- if (entry != LINKED_LIST_UNUSED)
- linked_list_remove(&client_list, entry);
- running_slaves--;
- pthread_cond_signal(&slave_cond););
+ with_mutex (slave_mutex,
+ fd_table_remove(&client_map, socket_fd);
+ if (entry != LINKED_LIST_UNUSED)
+ linked_list_remove(&client_list, entry);
+ running_slaves--;
+ pthread_cond_signal(&slave_cond););
return NULL;
@@ -635,9 +618,9 @@ void* slave_loop(void* data)
this is done because re-exec causes a race-condition
between the acception of a slave and the execution
of the the slave thread. */
- with_mutex(slave_mutex,
- running_slaves--;
- pthread_cond_signal(&slave_cond););
+ with_mutex (slave_mutex,
+ running_slaves--;
+ pthread_cond_signal(&slave_cond););
return NULL;
}
@@ -736,7 +719,7 @@ int message_received(client_t* client)
}
done:
pthread_mutex_unlock(&(modify_mutex));
- with_mutex(client->modify_mutex, pthread_cond_signal(&(client->modify_cond)););
+ with_mutex (client->modify_mutex, pthread_cond_signal(&(client->modify_cond)););
/* Do nothing more, not not even multicast this message. */
return 0;
@@ -753,10 +736,10 @@ int message_received(client_t* client)
if (assign_id && (client->id == 0))
{
intercept |= 2;
- with_mutex(slave_mutex,
- client->id = next_id++;
- if (next_id == 0)
- {
+ with_mutex (slave_mutex,
+ client->id = next_id++;
+ if (next_id == 0)
+ {
eprint("this is impossible, ID counter has overflowed.");
/* If the program ran for a millennium it would
take c:a 585 assignments per nanosecond. This
@@ -764,8 +747,8 @@ int message_received(client_t* client)
dedication by generations of ponies (or just an alicorn)
to maintain the process and transfer it new hardware.) */
abort();
- }
- );
+ }
+ );
}
/* Make the client listen for messages addressed to it. */
@@ -879,29 +862,29 @@ int message_received(client_t* client)
/* Queue message to be sent when this function returns.
This done to simplify `multicast_message` for re-exec. */
- with_mutex(client->mutex,
- if (client->send_pending_size == 0)
- {
- /* Set the pending message. */
- client->send_pending = msgbuf;
- client->send_pending_size = n;
- }
- else
- {
- /* Concatenate message to already pending messages. */
- size_t new_len = client->send_pending_size + n;
- char* msg_new = realloc(client->send_pending, new_len * sizeof(char));
- if (msg_new != NULL)
- {
- memcpy(msg_new + client->send_pending_size, msgbuf, n * sizeof(char));
- client->send_pending = msg_new;
- client->send_pending_size = new_len;
- }
- else
- perror(*argv);
- free(msgbuf);
- }
- );
+ with_mutex (client->mutex,
+ if (client->send_pending_size == 0)
+ {
+ /* Set the pending message. */
+ client->send_pending = msgbuf;
+ client->send_pending_size = n;
+ }
+ else
+ {
+ /* Concatenate message to already pending messages. */
+ size_t new_len = client->send_pending_size + n;
+ char* msg_new = realloc(client->send_pending, new_len * sizeof(char));
+ if (msg_new != NULL)
+ {
+ memcpy(msg_new + client->send_pending_size, msgbuf, n * sizeof(char));
+ client->send_pending = msg_new;
+ client->send_pending_size = new_len;
+ }
+ else
+ perror(*argv);
+ free(msgbuf);
+ }
+ );
}
return 0;
@@ -1188,11 +1171,11 @@ void queue_message_multicast(char* message, size_t length, client_t* sender)
qsort(interceptions, interceptions_count, sizeof(queued_interception_t), cmp_queued_interception);
/* Add prefix to message with ‘Modify ID’ header. */
- with_mutex(slave_mutex,
- modify_id = next_modify_id++;
- if (next_modify_id == 0)
- next_modify_id = 1;
- );
+ with_mutex (slave_mutex,
+ modify_id = next_modify_id++;
+ if (next_modify_id == 0)
+ next_modify_id = 1;
+ );
xsnprintf(modify_id_header, "Modify ID: %" PRIu64 "\n", modify_id);
n = strlen(modify_id_header);
old_buf = message;
@@ -1213,24 +1196,24 @@ void queue_message_multicast(char* message, size_t length, client_t* sender)
message = NULL;
/* Queue message multicasting. */
- with_mutex(sender->mutex,
- if (sender->multicasts == NULL)
- {
- if (xmalloc(sender->multicasts, 1, multicast_t))
- goto fail_queue;
- }
- else
- {
- multicast_t* new_buf;
- new_buf = realloc(sender->multicasts, (sender->multicasts_count + 1) * sizeof(multicast_t));
- if (new_buf == NULL)
- goto fail_queue;
- sender->multicasts = new_buf;
- }
- sender->multicasts[sender->multicasts_count++] = *multicast;
- multicast = NULL;
- fail_queue:
- );
+ with_mutex (sender->mutex,
+ if (sender->multicasts == NULL)
+ {
+ if (xmalloc(sender->multicasts, 1, multicast_t))
+ goto fail_queue;
+ }
+ else
+ {
+ multicast_t* new_buf;
+ new_buf = realloc(sender->multicasts, (sender->multicasts_count + 1) * sizeof(multicast_t));
+ if (new_buf == NULL)
+ goto fail_queue;
+ sender->multicasts = new_buf;
+ }
+ sender->multicasts[sender->multicasts_count++] = *multicast;
+ multicast = NULL;
+ fail_queue:
+ );
errno = 0;
fail: /* This is done before this function returns even if there was no error. */
@@ -1277,7 +1260,7 @@ void multicast_message(multicast_t* multicast)
if (client == NULL)
{
size_t address;
- with_mutex(slave_mutex, address = fd_table_get(&client_map, client_.socket_fd););
+ with_mutex (slave_mutex, address = fd_table_get(&client_map, client_.socket_fd););
client_.client = client = (client_t*)(void*)address;
}
@@ -1289,23 +1272,23 @@ void multicast_message(multicast_t* multicast)
}
/* Send the message. */
- with_mutex(client->mutex,
- errno = 0;
- n *= sizeof(char);
- if (client->open)
- while (n > 0)
- {
- sent = send_message(client->socket_fd, msg + multicast->message_ptr, n);
- if (sent < n)
- {
- if (errno != EINTR)
- perror(*argv);
- break;
- }
- n -= sent;
- multicast->message_ptr += sent / sizeof(char);
- }
- );
+ with_mutex (client->mutex,
+ errno = 0;
+ n *= sizeof(char);
+ if (client->open)
+ while (n > 0)
+ {
+ sent = send_message(client->socket_fd, msg + multicast->message_ptr, n);
+ if (sent < n)
+ {
+ if (errno != EINTR)
+ perror(*argv);
+ break;
+ }
+ n -= sent;
+ multicast->message_ptr += sent / sizeof(char);
+ }
+ );
/* Stop if we are re-exec:ing, or continue to next recipient on error. */
if (n > 0)
@@ -1339,25 +1322,25 @@ void multicast_message(multicast_t* multicast)
mds_message_t* mod;
/* Wait for a reply. */
- with_mutex(modify_mutex,
- if (client->modify_message == NULL)
- {
- if (hash_table_contains_key(&modify_map, (size_t)modify_id) == 0)
- {
- hash_table_put(&modify_map, (size_t)modify_id, (size_t)(void*)client);
- pthread_cond_signal(&slave_cond);
- }
- }
- );
- with_mutex(client->modify_mutex,
- if (client->modify_message == NULL)
- {
- while ((client->modify_message == NULL) && (terminating == 0))
- pthread_cond_timedwait(&slave_cond, &slave_mutex, &timeout);
- if (terminating == 0)
- hash_table_remove(&modify_map, (size_t)modify_id);
- }
- );
+ with_mutex (modify_mutex,
+ if (client->modify_message == NULL)
+ {
+ if (hash_table_contains_key(&modify_map, (size_t)modify_id) == 0)
+ {
+ hash_table_put(&modify_map, (size_t)modify_id, (size_t)(void*)client);
+ pthread_cond_signal(&slave_cond);
+ }
+ }
+ );
+ with_mutex (client->modify_mutex,
+ if (client->modify_message == NULL)
+ {
+ while ((client->modify_message == NULL) && (terminating == 0))
+ pthread_cond_timedwait(&slave_cond, &slave_mutex, &timeout);
+ if (terminating == 0)
+ hash_table_remove(&modify_map, (size_t)modify_id);
+ }
+ );
if (terminating)
return;
@@ -1457,7 +1440,7 @@ void run_initrc(char** args)
/* Test /etc. */
__exec("%s/%s", SYSCONFDIR, INITRC_FILE);
-#undef __exec
+#undef __exec
/* Everything failed. */
eprintf("unable to run %s file, you might as well kill me.", INITRC_FILE);
@@ -1513,13 +1496,13 @@ void signal_all(int signo)
if (pthread_equal(current_thread, master_thread) == 0)
pthread_kill(master_thread, signo);
- with_mutex(slave_mutex,
- foreach_linked_list_node (client_list, node)
- {
- client_t* value = (client_t*)(void*)(client_list.values[node]);
- if (pthread_equal(current_thread, value->thread) == 0)
- pthread_kill(value->thread, signo);
- });
+ with_mutex (slave_mutex,
+ foreach_linked_list_node (client_list, node)
+ {
+ client_t* value = (client_t*)(void*)(client_list.values[node]);
+ if (pthread_equal(current_thread, value->thread) == 0)
+ pthread_kill(value->thread, signo);
+ });
}
@@ -1691,6 +1674,7 @@ int unmarshal_server(int fd)
if (errno)
goto clients_fail;
+ /* Delayed seeking. */
state_buf_ += n / sizeof(char);
@@ -1725,12 +1709,13 @@ int unmarshal_server(int fd)
free(state_buf);
/* Remove non-found elements from the fd table. */
+#define __bit(I, _OP_) client_map.used[I / 64] _OP_ ((uint64_t)1 << (I % 64))
if (with_error)
for (i = 0; i < client_map.capacity; i++)
- if (client_map.used[i / 64] & ((uint64_t)1 << (i % 64)))
+ if ((__bit(i, &)) && (client_map.values[i] == 0))
/* Lets not presume that fd-table actually initialise its allocations. */
- if (client_map.values[i] == 0)
- client_map.used[i / 64] &= ~((uint64_t)1 << (i % 64));
+ __bit(i, &= ~);
+#undef __bit
/* Remap the linked list and remove non-found elements, and start the clients. */
foreach_linked_list_node (client_list, node)
@@ -1747,7 +1732,7 @@ int unmarshal_server(int fd)
int socket_fd = client->socket_fd;
/* Increase number of running slaves. */
- with_mutex(slave_mutex, running_slaves++;);
+ with_mutex (slave_mutex, running_slaves++;);
/* Start slave thread. */
create_slave(&slave_thread, socket_fd);
@@ -1777,7 +1762,7 @@ int create_slave(pthread_t* thread_slot, int socket_fd)
if ((errno = pthread_create(thread_slot, NULL, slave_loop, (void*)(intptr_t)socket_fd)))
{
perror(*argv);
- with_mutex(slave_mutex, running_slaves--;);
+ with_mutex (slave_mutex, running_slaves--;);
return -1;
}
if ((errno = pthread_detach(*thread_slot)))