From 8c0712acf701925fa36ca85a548d56a7851543c5 Mon Sep 17 00:00:00 2001 From: sr Date: Sun, 2 Sep 2012 18:49:16 +0200 Subject: [SERVER] Add list of trusted servers and namespaces (load, display) --- src/config.h | 2 +- src/kernel/net.c | 28 ++++++++-- src/server/ipc.c | 153 +++++++++++++++++++++++++++++++++++++++------------- src/server/job.c | 39 ++++++++++++-- src/server/net.c | 5 ++ src/server/server.c | 9 +--- src/server/server.h | 17 ++++++ src/server/utils.c | 111 +++++++++++++++++++++++++++++++++++--- src/server/utils.h | 4 ++ src/types.h | 13 ++--- 10 files changed, 310 insertions(+), 71 deletions(-) diff --git a/src/config.h b/src/config.h index ff638d2..2f348aa 100644 --- a/src/config.h +++ b/src/config.h @@ -63,7 +63,7 @@ #define KERNEL_SECTOR_SIZE 512 #define DNBD3_BLOCK_SIZE 4096 #define NUMBER_DEVICES 8 -#define DEFAULT_READ_AHEAD_KB 256 +#define DEFAULT_READ_AHEAD_KB 512 // +++++ Misc +++++ #define DEFAULT_SERVER_CONFIG_FILE "/etc/dnbd3/server.conf" diff --git a/src/kernel/net.c b/src/kernel/net.c index 57279d6..b116ad6 100644 --- a/src/kernel/net.c +++ b/src/kernel/net.c @@ -124,6 +124,8 @@ int dnbd3_net_connect(dnbd3_device_t *dev) struct timeval timeout; + char get_servers = 0, set_client = 0; + timeout.tv_sec = SOCKET_TIMEOUT_CLIENT_DATA; timeout.tv_usec = 0; @@ -136,11 +138,21 @@ int dnbd3_net_connect(dnbd3_device_t *dev) memcpy(dev->alt_servers, &dev->initial_server, sizeof(dev->alt_servers[0])); if (!dev->is_server) { - req1 = kmalloc(sizeof(*req1), GFP_ATOMIC); - if (!req1) - error_dev("FATAL: Kmalloc(1) failed."); + get_servers = 1; } } + if (dev->better_sock) + { + set_client = 1; + } + + if (get_servers || set_client) + { + req1 = kmalloc(sizeof(*req1), GFP_ATOMIC); + if (!req1) + error_dev("FATAL: Kmalloc(1) failed."); + } + if (dev->cur_server.port == 0 || dev->cur_server.hostaddrtype == 0 || dev->imgname == NULL) error_dev("FATAL: Host, port or image name not set."); if (dev->sock) @@ -224,6 +236,7 @@ int dnbd3_net_connect(dnbd3_device_t *dev) // store image information set_capacity(dev->disk, dev->reported_size >> 9); /* 512 Byte blocks */ debug_dev_va("INFO: Filesize: %llu.", dev->reported_size); + dev->update_available = 0; } else // Switching server, connection is already established and size request was executed { @@ -236,15 +249,20 @@ int dnbd3_net_connect(dnbd3_device_t *dev) dev->panic = 0; dev->panic_count = 0; - dev->update_available = 0; - if (req1) // This connection is established to the initial server (from the ioctl call) + if (get_servers) // This connection is established to the initial server (from the ioctl call) { // Enqueue request to request_queue_send for a fresh list of alt servers req1->cmd_type = REQ_TYPE_SPECIAL; req1->cmd_flags = CMD_GET_SERVERS; list_add(&req1->queuelist, &dev->request_queue_send); } + else if (set_client) + { + req1->cmd_type = REQ_TYPE_SPECIAL; + req1->cmd_flags = CMD_SET_CLIENT_MODE; + list_add(&req1->queuelist, &dev->request_queue_send); + } // create required threads dev->thread_send = kthread_create(dnbd3_net_send, dev, dev->disk->disk_name); diff --git a/src/server/ipc.c b/src/server/ipc.c index 37ca36f..e988abc 100644 --- a/src/server/ipc.c +++ b/src/server/ipc.c @@ -361,7 +361,7 @@ static int recv_data(int client_sock, void *buffer_out, int len) */ static int ipc_receive(int client_sock) { - GSList *iterator = NULL; + GSList *iterator, *iterator2; struct tm *timeinfo; #define STRBUFLEN 100 @@ -374,7 +374,7 @@ static int ipc_receive(int client_sock) int ret, locked; int return_value = 0; xmlDocPtr docReply = NULL, docRequest = NULL; - xmlNodePtr root_node, images_node, clients_node, tmp_node, log_parent_node, log_node; + xmlNodePtr root_node, parent_node, tmp_node, log_parent_node, log_node, server_node; xmlChar *xmlbuff; int buffersize; @@ -420,10 +420,10 @@ static int ipc_receive(int client_sock) xmlDocSetRootElement(docReply, root_node); // Images - images_node = xmlNewNode(NULL, BAD_CAST "images"); - if (images_node == NULL) + parent_node = xmlNewNode(NULL, BAD_CAST "images"); + if (parent_node == NULL) goto get_info_reply_cleanup; - xmlAddChild(root_node, images_node); + xmlAddChild(root_node, parent_node); locked = 1; pthread_spin_lock(&_spinlock); for (iterator = _dnbd3_images; iterator; iterator = iterator->next) @@ -450,13 +450,18 @@ static int ipc_receive(int client_sock) sprintf(strbuffer, "%d", complete / size); xmlNewProp(tmp_node, BAD_CAST "cachefill", BAD_CAST image->cache_file); } - xmlAddChild(images_node, tmp_node); + xmlAddChild(parent_node, tmp_node); } + pthread_spin_unlock(&_spinlock); + locked = 0; + // Clients - clients_node = xmlNewNode(NULL, BAD_CAST "clients"); - if (clients_node == NULL) + parent_node = xmlNewNode(NULL, BAD_CAST "clients"); + if (parent_node == NULL) goto get_info_reply_cleanup; - xmlAddChild(root_node, clients_node); + xmlAddChild(root_node, parent_node); + locked = 1; + pthread_spin_lock(&_spinlock); for (iterator = _dnbd3_clients; iterator; iterator = iterator->next) { dnbd3_client_t *client = iterator->data; @@ -469,7 +474,48 @@ static int ipc_receive(int client_sock) inet_ntop(client->addrtype, client->ipaddr, strbuffer, STRBUFLEN); xmlNewProp(tmp_node, BAD_CAST "ip", BAD_CAST strbuffer); xmlNewProp(tmp_node, BAD_CAST "file", BAD_CAST client->image->file); - xmlAddChild(clients_node, tmp_node); + xmlAddChild(parent_node, tmp_node); + } + } + pthread_spin_unlock(&_spinlock); + locked = 0; + + // Trusted servers + parent_node = xmlNewNode(NULL, BAD_CAST "trusted"); + if (parent_node == NULL) + goto get_info_reply_cleanup; + xmlAddChild(root_node, parent_node); + locked = 1; + pthread_spin_lock(&_spinlock); + for (iterator = _trusted_servers; iterator; iterator = iterator->next) + { + dnbd3_trusted_server_t *server = iterator->data; + if (server->hostaddrtype != 0) + { + tmp_node = xmlNewNode(NULL, BAD_CAST "server"); + if (tmp_node == NULL) + goto get_info_reply_cleanup; + *strbuffer = '\0'; + inet_ntop(server->hostaddrtype, server->hostaddr, strbuffer, STRBUFLEN); + xmlNewProp(tmp_node, BAD_CAST "ip", BAD_CAST strbuffer); + sprintf(strbuffer, "%d", (int)server->port); + xmlNewProp(tmp_node, BAD_CAST "port", BAD_CAST strbuffer); + if (server->comment) + xmlNewProp(tmp_node, BAD_CAST "comment", BAD_CAST server->comment); + for (iterator2 = server->namespaces; iterator2; iterator2 = iterator2->next) + { + const dnbd3_namespace_t *ns = iterator2->data; + server_node = xmlNewNode(NULL, BAD_CAST "namespace"); + if (server_node == NULL) + goto get_info_reply_cleanup; + xmlAddChild(tmp_node, server_node); + xmlNewProp(server_node, BAD_CAST "name", BAD_CAST ns->name); + if (ns->auto_replicate) + xmlNewProp(server_node, BAD_CAST "replicate", BAD_CAST "1"); + if (ns->recursive) + xmlNewProp(server_node, BAD_CAST "recursive", BAD_CAST "1"); + } + xmlAddChild(parent_node, tmp_node); } } pthread_spin_unlock(&_spinlock); @@ -656,7 +702,7 @@ void dnbd3_ipc_send(int cmd) { int count; int term_width = get_terminal_width(); - xmlNodePtr cur; + xmlNodePtr cur, childit; // Print log xmlChar *log = getTextFromPath(doc, "/data/log"); @@ -668,16 +714,15 @@ void dnbd3_ipc_send(int cmd) int watime = 0, wname = 0, wrid = 5; FOR_EACH_NODE(doc, "/data/images/image", cur) { - if (cur->type == XML_ELEMENT_NODE) - { - xmlChar *atime = xmlGetNoNsProp(cur, BAD_CAST "atime"); - xmlChar *vid = xmlGetNoNsProp(cur, BAD_CAST "name"); - xmlChar *rid = xmlGetNoNsProp(cur, BAD_CAST "rid"); - watime = MAX(watime, xmlStrlen(atime)); - wname = MAX(wname, xmlStrlen(vid)); - wrid = MAX(wrid, xmlStrlen(rid)); - // Too lazy to free vars, client will exit anyways - } + if (cur->type != XML_ELEMENT_NODE) + continue; + xmlChar *atime = xmlGetNoNsProp(cur, BAD_CAST "atime"); + xmlChar *vid = xmlGetNoNsProp(cur, BAD_CAST "name"); + xmlChar *rid = xmlGetNoNsProp(cur, BAD_CAST "rid"); + watime = MAX(watime, xmlStrlen(atime)); + wname = MAX(wname, xmlStrlen(vid)); + wrid = MAX(wrid, xmlStrlen(rid)); + // Too lazy to free vars, client will exit anyways } END_FOR_EACH; char format[100]; @@ -691,16 +736,15 @@ void dnbd3_ipc_send(int cmd) count = 0; FOR_EACH_NODE(doc, "/data/images/image", cur) { - if (cur->type == XML_ELEMENT_NODE) - { - ++count; - xmlChar *atime = xmlGetNoNsProp(cur, BAD_CAST "atime"); - xmlChar *vid = xmlGetNoNsProp(cur, BAD_CAST "name"); - xmlChar *rid = xmlGetNoNsProp(cur, BAD_CAST "rid"); - xmlChar *file = xmlGetNoNsProp(cur, BAD_CAST "file"); - printf(format, atime, vid, rid, file); - // Too lazy to free vars, client will exit anyways - } + if (cur->type != XML_ELEMENT_NODE) + continue; + ++count; + xmlChar *atime = xmlGetNoNsProp(cur, BAD_CAST "atime"); + xmlChar *vid = xmlGetNoNsProp(cur, BAD_CAST "name"); + xmlChar *rid = xmlGetNoNsProp(cur, BAD_CAST "rid"); + xmlChar *file = xmlGetNoNsProp(cur, BAD_CAST "file"); + printf(format, atime, vid, rid, file); + // Too lazy to free vars, client will exit anyways } END_FOR_EACH; char_repeat_br('=', term_width); printf("\nNumber of images: %d\n\n", count); @@ -711,17 +755,50 @@ void dnbd3_ipc_send(int cmd) count = 0; FOR_EACH_NODE(doc, "/data/clients/client", cur) { - if (cur->type == XML_ELEMENT_NODE) + if (cur->type != XML_ELEMENT_NODE) + continue; + ++count; + xmlChar *ip = xmlGetNoNsProp(cur, BAD_CAST "ip"); + xmlChar *file = xmlGetNoNsProp(cur, BAD_CAST "file"); + printf("%-40s %s\n", ip, file); + // Too lazy to free vars, client will exit anyways + } END_FOR_EACH; + char_repeat_br('=', term_width); + printf("\nNumber clients: %d\n\n", count); + + // Print trusted servers + printf("Trusted servers:\n"); + char_repeat_br('=', term_width); + count = 0; + FOR_EACH_NODE(doc, "/data/trusted/server", cur) + { + if (cur->type != XML_ELEMENT_NODE) + continue; + ++count; + xmlChar *ip = xmlGetNoNsProp(cur, BAD_CAST "ip"); + xmlChar *comment = xmlGetNoNsProp(cur, BAD_CAST "comment"); + if (comment) + printf("%-30s (%s)\n", ip, comment); + else + printf("%-30s\n", ip); + for (childit = cur->children; childit; childit = childit->next) { - ++count; - xmlChar *ip = xmlGetNoNsProp(cur, BAD_CAST "ip"); - xmlChar *file = xmlGetNoNsProp(cur, BAD_CAST "file"); - printf("%-40s %s\n", ip, file); - // Too lazy to free vars, client will exit anyways + if (childit->type != XML_ELEMENT_NODE || childit->name == NULL || strcmp(childit->name, "namespace") != 0) + continue; + xmlChar *name = xmlGetNoNsProp(childit, BAD_CAST "name"); + xmlChar *replicate = xmlGetNoNsProp(childit, BAD_CAST "replicate"); + xmlChar *recursive = xmlGetNoNsProp(childit, BAD_CAST "recursive"); + printf(" %-40s ", name); + if (replicate && *replicate != '0') + printf(" replicate"); + if (recursive && *recursive != '0') + printf(" recursive"); + putchar('\n'); } + // Too lazy to free vars, client will exit anyways } END_FOR_EACH; char_repeat_br('=', term_width); - printf("\nNumber clients: %d\n\n", count); + printf("\nNumber servers: %d\n\n", count); // Cleanup xmlFreeDoc(doc); diff --git a/src/server/job.c b/src/server/job.c index 8753c2c..b50a7f3 100644 --- a/src/server/job.c +++ b/src/server/job.c @@ -1,10 +1,13 @@ #include "job.h" +#include "utils.h" #include #include #include #include #include #include +#include +#include #define DEV_STRLEN 12 // INCLUDING NULLCHAR (increase to 13 if you need more than 100 (0-99) devices) #define MAX_NUM_DEVICES_TO_CHECK 100 @@ -26,10 +29,13 @@ typedef struct // "/dev/dnbdXX" == 11 bytes per device + nullchar = 12 static device_t *devices = NULL; static int num_devices = 0; - static char keep_running = TRUE; +// Private functions static char* get_free_device(); +static void query_servers(); + +// void* dnbd3_job_thread(void *data) { @@ -38,7 +44,7 @@ void* dnbd3_job_thread(void *data) char dev[DEV_STRLEN]; for (i = 0; i < MAX_NUM_DEVICES_TO_CHECK; ++i) { - sprintf(dev, "/dev/dnbd%d", i); + snprintf(dev, DEV_STRLEN, "/dev/dnbd%d", i); if (access(dev, W_OK | R_OK)) // Need RW access to device to read and do ioctl continue; ++num_devices; @@ -49,7 +55,7 @@ void* dnbd3_job_thread(void *data) for (i = 0, j = 0; i < MAX_NUM_DEVICES_TO_CHECK; ++i) { memset(dev, 0, DEV_STRLEN); - sprintf(dev, "/dev/dnbd%d", i); + snprintf(dev, DEV_STRLEN, "/dev/dnbd%d", i); if (access(dev, W_OK | R_OK)) continue; if (j >= num_devices) // More available devices during second iteration? :-( @@ -60,14 +66,26 @@ void* dnbd3_job_thread(void *data) } } // + time_t next_delete_invocation = 0; + // // Job/Watchdog mainloop while (keep_running) { + const time_t starttime = time(NULL); + // // TODO: Update image atime - // TODO: Handle image deletion + // Call image deletion function if last call is more than 5 minutes ago + if (starttime < next_delete_invocation) + { + next_delete_invocation = starttime + 300; + dnbd3_exec_delete(TRUE); + } // TODO: Replicate proxied images (limited bandwidth) - // TODO: Query other servers for new images/status/... + // Query other servers for new images/status/... + query_servers(); // TODO: Switch server of dnbd device based on more sophisticated inputs than just rtt + // Calc sleep timeout for next iteration + sleep(30 - (time(NULL) - starttime)); // Sleep 30 seconds, but account for the time it took to execute the loop } // free(devices); @@ -81,6 +99,17 @@ void dnbd3_job_shutdown() keep_running = FALSE; } +static void query_servers() +{ + struct timeval client_timeout; + client_timeout.tv_sec = 0; + client_timeout.tv_usec = 500 * 1000; + int client_sock; + // Apply read/write timeout + setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, &client_timeout, sizeof(client_timeout)); + setsockopt(client_sock, SOL_SOCKET, SO_SNDTIMEO, &client_timeout, sizeof(client_timeout)); +} + /** * Get full name of an available dnbd3 device, eg. /dev/dnbd4 * Returned buffer is owned by this module, do not modify or free! diff --git a/src/server/net.c b/src/server/net.c index b953e13..bcbf056 100644 --- a/src/server/net.c +++ b/src/server/net.c @@ -361,6 +361,7 @@ void *dnbd3_handle_query(void *dnbd3_client) case CMD_GET_SERVERS: + client->is_server = FALSE; // Only clients request list of servers // Build list of known working alt servers num = 0; for (i = 0; i < NUMBER_SERVERS; i++) @@ -379,6 +380,10 @@ void *dnbd3_handle_query(void *dnbd3_client) send_reply(client->sock, &reply, NULL); break; + case CMD_SET_CLIENT_MODE: + client->is_server = FALSE; + break; + default: memlogf("ERROR: Unknown command\n"); break; diff --git a/src/server/server.c b/src/server/server.c index 1ca55fa..feee30b 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -47,6 +47,7 @@ char *_config_file_name = DEFAULT_SERVER_CONFIG_FILE; char *_local_namespace = NULL; char *_ipc_password = NULL; GSList *_dnbd3_images = NULL; // of dnbd3_image_t +GSList *_trusted_servers = NULL; void dnbd3_print_help(char* argv_0) { @@ -211,7 +212,6 @@ int main(int argc, char* argv[]) struct sockaddr_in client; unsigned int len = sizeof(client); int fd; - time_t next_delete_invocation = 0; struct timeval timeout; timeout.tv_sec = SOCKET_TIMEOUT_SERVER; timeout.tv_usec = 0; @@ -267,13 +267,6 @@ int main(int argc, char* argv[]) continue; } pthread_detach(dnbd3_client->thread); - // Call image deletion function if last call is more than 5 minutes ago - const time_t now = time(NULL); - if (now < next_delete_invocation) - { - next_delete_invocation = now + 300; - dnbd3_exec_delete(TRUE); - } } dnbd3_cleanup(); diff --git a/src/server/server.h b/src/server/server.h index 832777e..1e17048 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -64,10 +64,27 @@ typedef struct dnbd3_image_t *image; } dnbd3_client_t; +typedef struct +{ + uint8_t hostaddr[16]; + uint16_t port; + uint8_t hostaddrtype; + gchar *comment; + GSList *namespaces; // List of dnbd3_namespace_t +} dnbd3_trusted_server_t; + +typedef struct +{ + char *name; + uint8_t auto_replicate; + uint8_t recursive; +} dnbd3_namespace_t; + extern GSList *_dnbd3_clients; // of dnbd3_client_t extern pthread_spinlock_t _spinlock; extern char *_config_file_name, *_local_namespace, *_ipc_password; extern GSList *_dnbd3_images; // of dnbd3_image_t +extern GSList *_trusted_servers; #ifdef _DEBUG diff --git a/src/server/utils.c b/src/server/utils.c index 391992d..dc3d6c4 100644 --- a/src/server/utils.c +++ b/src/server/utils.c @@ -120,7 +120,8 @@ static char is_valid_namespace(char *namespace) while (*namespace) { if (*namespace != '/' && *namespace != '-' && (*namespace < 'a' || *namespace > 'z') - && (*namespace < 'A' || *namespace > 'Z')) + && (*namespace < 'A' || *namespace > 'Z') + && (*namespace < '0' || *namespace > '9')) return 0; ++namespace; } @@ -135,8 +136,10 @@ static char is_valid_imagename(char *namespace) return 0; // Invalid: Length = 0 or starting with a space while (*namespace) { // Check for invalid chars - if (*namespace != '.' && *namespace != '-' && *namespace != ' ' && *namespace != '(' && *namespace != ')' - && (*namespace < 'a' || *namespace > 'z') && (*namespace < 'A' || *namespace > 'Z')) + if (*namespace != '.' && *namespace != '-' && *namespace != ' ' + && *namespace != '(' && *namespace != ')' + && (*namespace < 'a' || *namespace > 'z') && (*namespace < 'A' || *namespace > 'Z') + && (*namespace < '0' || *namespace > '9')) return 0; ++namespace; } @@ -145,6 +148,13 @@ static char is_valid_imagename(char *namespace) return 1; } +static inline int is_same_server(const dnbd3_trusted_server_t * const a, const dnbd3_trusted_server_t * const b) +{ + return (a->hostaddrtype == b->hostaddrtype) + && (a->port == b->port) + && (0 == memcmp(a->hostaddr, b->hostaddr, (a->hostaddrtype == AF_INET ? 4 : 16))); +} + static void strtolower(char *string) { while (*string) @@ -157,7 +167,7 @@ static void strtolower(char *string) void dnbd3_load_config() { - gint i; + gint i, j; if (_config_handle != NULL) { @@ -188,9 +198,32 @@ void dnbd3_load_config() for (i = 0; i < section_count; i++) { - // Special group, ignore - if (strcmp(groups[i], "settings") == 0 || strcmp(groups[i], "trusted") == 0) + // Ignore settings section + if (strcmp(groups[i], "settings") == 0) + continue; + + // List of trusted servers/namespaces + if (strncmp(groups[i], "trust:", 6) == 0) { + gchar *addr = g_key_file_get_string(_config_handle, groups[i], "address", NULL); + if (addr == NULL) + continue; + dnbd3_trusted_server_t *server = dnbd3_get_trusted_server(addr, TRUE); + g_free(addr); + if (server == NULL) + continue; + server->comment = strdup(groups[i]+6); + gsize key_count; + gchar **keys = g_key_file_get_keys(_config_handle, groups[i], &key_count, NULL); + for (j = 0; j < key_count; ++j) + { + if (strcmp(keys[j], "address") == 0) + continue; + char *flags = g_key_file_get_string(_config_handle, groups[i], keys[j], NULL); + dnbd3_add_trusted_namespace(server, keys[j], flags); + g_free(flags); + } + g_strfreev(keys); continue; } @@ -216,13 +249,11 @@ void dnbd3_load_config() gsize num_servers; gchar **servers = g_key_file_get_string_list(_config_handle, groups[i], "servers", &num_servers, NULL); - pthread_spin_lock(&_spinlock); dnbd3_image_t *image = prepare_image(groups[i], rid, image_file, cache_file, servers, num_servers); if (image) { _dnbd3_images = g_slist_prepend(_dnbd3_images, image); } - pthread_spin_unlock(&_spinlock); g_free(image_file); g_free(cache_file); @@ -650,6 +681,70 @@ void dnbd3_exec_delete(int save_if_changed) save_config(); } +/** + * Return pointer to trusted_server matching given address. + * If not found and create_if_not_found is TRUE, a new entry will be created, + * added to the list and then returned + * Returns NULL otherwise, or if the address could not be parsed + * !! Lock before calling this function !! + */ +dnbd3_trusted_server_t *dnbd3_get_trusted_server(char *address, char create_if_not_found) +{ + dnbd3_trusted_server_t server; + memset(&server, 0, sizeof(server)); + if (!parse_address(address, &server.hostaddrtype, server.hostaddr, &server.port)) + { + memlogf("[WARNING] Could not parse address '%s' of trusted server", address); + return NULL; + } + GSList *iterator; + for (iterator = _trusted_servers; iterator; iterator = iterator->next) + { + dnbd3_trusted_server_t *comp = iterator->data; + if (is_same_server(comp, &server)) + return comp; + } + if (!create_if_not_found) + return NULL; + dnbd3_trusted_server_t *copy = malloc(sizeof(server)); + memcpy(copy, &server, sizeof(*copy)); + _trusted_servers = g_slist_prepend(_trusted_servers, copy); + return copy; +} + +/** + * Add new trusted namespace to given trusted server, using given flags. + * Overwrites any existing entry for the given server and namespace + * !! Lock before calling this function !! + */ +int dnbd3_add_trusted_namespace(dnbd3_trusted_server_t *server, char *namespace, char *flags) +{ + int nslen = strlen(namespace) + 1; + char nslow[nslen]; + memcpy(nslow, namespace, nslen); + strtolower(nslow); + GSList *iterator; + dnbd3_namespace_t *ns = NULL; + for (iterator = server->namespaces; iterator; iterator = iterator->next) + { + dnbd3_namespace_t *cmp = iterator->data; + if (strcmp(nslow, cmp->name) == 0) + { + ns = cmp; + break; + } + } + if (ns == NULL) + { + ns = calloc(1, sizeof(*ns)); + ns->name = strdup(nslow); + server->namespaces = g_slist_prepend(server->namespaces, ns); + } + ns->auto_replicate = (flags && strstr(flags, "replicate")); + ns->recursive = (flags && strstr(flags, "recursive")); + return TRUE; +} + /** * Return local image name for a global image name * eg. "uni-freiburg/rz/ubuntu 12.04" -> "ubuntu 12.04" diff --git a/src/server/utils.h b/src/server/utils.h index e923f82..53dc076 100644 --- a/src/server/utils.h +++ b/src/server/utils.h @@ -21,6 +21,7 @@ #include #include +#include "server.h" #include "../config.h" #ifndef UTILS_H_ @@ -48,6 +49,9 @@ void dnbd3_exec_delete(int save_if_changed); dnbd3_image_t* dnbd3_get_image(char *name, int rid, const char do_lock); +dnbd3_trusted_server_t *dnbd3_get_trusted_server(char *address, char create_if_not_found); +int dnbd3_add_trusted_namespace(dnbd3_trusted_server_t *server, char *namespace, char *flags); + void dnbd3_handle_sigpipe(int signum); void dnbd3_handle_sigterm(int signum); diff --git a/src/types.h b/src/types.h index ab3a2f0..72449da 100644 --- a/src/types.h +++ b/src/types.h @@ -74,12 +74,13 @@ typedef struct } dnbd3_ioctl_t; // network -#define CMD_GET_BLOCK 1 -#define CMD_GET_SIZE 2 -#define CMD_GET_SERVERS 3 -#define CMD_ERROR 4 -#define CMD_KEEPALIVE 5 -#define CMD_LATEST_RID 6 +#define CMD_GET_BLOCK 1 +#define CMD_GET_SIZE 2 +#define CMD_GET_SERVERS 3 +#define CMD_ERROR 4 +#define CMD_KEEPALIVE 5 +#define CMD_LATEST_RID 6 +#define CMD_SET_CLIENT_MODE 7 #pragma pack(1) typedef struct -- cgit v1.2.3-55-g7522