From 87986047101826dfda86de42000a3a9f002178fc Mon Sep 17 00:00:00 2001 From: Johann Latocha Date: Thu, 26 Jul 2012 20:49:50 +0200 Subject: [SERVER] IPC add image --- src/server/ipc.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++----- src/server/ipc.h | 1 + src/server/server.c | 10 ++++++- src/server/server.h | 2 ++ src/server/utils.c | 39 +++++++++++++++++++++++- src/server/utils.h | 1 + 6 files changed, 130 insertions(+), 9 deletions(-) diff --git a/src/server/ipc.c b/src/server/ipc.c index 1f462ab..6a322d0 100644 --- a/src/server/ipc.c +++ b/src/server/ipc.c @@ -44,9 +44,14 @@ void* dnbd3_ipc_receive() struct tm * timeinfo; char time_buff[64]; + char buf[64]; int server_sock, client_sock; + struct timeval timeout; + timeout.tv_sec = 2; + timeout.tv_usec = 0; + #ifdef IPC_TCP struct sockaddr_in server, client; unsigned int len = sizeof(client); @@ -63,6 +68,9 @@ void* dnbd3_ipc_receive() server.sin_addr.s_addr = inet_addr("127.0.0.1"); server.sin_port = htons(IPC_PORT); // set port number + int optval = 1; + setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + // Bind to socket if (bind(server_sock, (struct sockaddr*) &server, sizeof(server)) < 0) { @@ -121,7 +129,7 @@ void* dnbd3_ipc_receive() while (1) { - int i = 0; + int i = 0, size = 0; uint32_t cmd; // Accept connection @@ -131,6 +139,9 @@ void* dnbd3_ipc_receive() exit(EXIT_FAILURE); } + setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof(timeout)); + setsockopt(client_sock, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof(timeout)); + recv(client_sock, &cmd, sizeof(cmd), MSG_WAITALL); switch (ntohl(cmd)) @@ -151,14 +162,14 @@ void* dnbd3_ipc_receive() case IPC_INFO: pthread_spin_lock(&_spinlock); - xmlDocPtr doc; + xmlDocPtr doc_info; xmlNodePtr root_node, images_node, clients_node, tmp_node; xmlChar *xmlbuff; int buffersize; - doc = xmlNewDoc(BAD_CAST "1.0"); + doc_info = xmlNewDoc(BAD_CAST "1.0"); root_node = xmlNewNode(NULL, BAD_CAST "dnbd3-server"); - xmlDocSetRootElement(doc, root_node); + xmlDocSetRootElement(doc_info, root_node); // Images images_node = xmlNewNode(NULL, BAD_CAST "images"); @@ -171,10 +182,13 @@ void* dnbd3_ipc_receive() timeinfo = localtime(&_images[i].atime); strftime(time_buff,64,"%d.%m.%y %H:%M:%S",timeinfo); tmp_node = xmlNewNode(NULL, BAD_CAST "image"); + xmlNewProp(tmp_node, BAD_CAST "group", BAD_CAST _images[i].group); xmlNewProp(tmp_node, BAD_CAST "atime", BAD_CAST time_buff); xmlNewProp(tmp_node, BAD_CAST "vid", BAD_CAST vid); xmlNewProp(tmp_node, BAD_CAST "rid", BAD_CAST rid); xmlNewProp(tmp_node, BAD_CAST "file", BAD_CAST _images[i].file); + xmlNewProp(tmp_node, BAD_CAST "servers", BAD_CAST _images[i].serverss); + xmlNewProp(tmp_node, BAD_CAST "cache_file", BAD_CAST _images[i].cache_file); xmlAddChild(images_node, tmp_node); } @@ -194,16 +208,74 @@ void* dnbd3_ipc_receive() } // Dump and send - xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1); + xmlDocDumpFormatMemory(doc_info, &xmlbuff, &buffersize, 1); send(client_sock, (char *) xmlbuff, buffersize, MSG_WAITALL); // Cleanup pthread_spin_unlock(&_spinlock); close(client_sock); xmlFree(xmlbuff); - xmlFreeDoc(doc); + xmlFreeDoc(doc_info); break; + case IPC_CONFIG: + pthread_spin_lock(&_spinlock); + xmlParserCtxtPtr ctxt; + xmlDocPtr doc_config; + + // Parse reply + ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL); + while ( (size=recv(client_sock, &buf, sizeof(buf), MSG_WAITALL)) > 0) + xmlParseChunk(ctxt, buf, size, 0); + + // Indicate the parsing is finished + xmlParseChunk(ctxt, buf, 0, 1); + doc_config = ctxt->myDoc; + + if (ctxt->wellFormed) + { +// xmlDocDump(stdout, doc_config); + + xmlXPathContextPtr xpathCtx; + xmlXPathObjectPtr xpathObj; + xmlChar* xpathExpr; + xmlNodeSetPtr nodes; + xmlNodePtr cur; + + xpathExpr = BAD_CAST "/dnbd3-server/image"; + xpathCtx = xmlXPathNewContext(doc_config); + xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx); + + nodes = xpathObj->nodesetval; + cur = nodes->nodeTab[0]; + if(cur->type == XML_ELEMENT_NODE) + { + dnbd3_image_t image; + image.group = (char *) xmlGetNoNsProp(cur, BAD_CAST "group"); + image.vid = atoi((char *) xmlGetNoNsProp(cur, BAD_CAST "vid")); + image.rid = atoi((char *) xmlGetNoNsProp(cur, BAD_CAST "rid")); + image.file = (char *) xmlGetNoNsProp(cur, BAD_CAST "file"); + image.serverss = (char *) xmlGetNoNsProp(cur, BAD_CAST "servers"); + image.cache_file = (char *) xmlGetNoNsProp(cur, BAD_CAST "cache_file"); + dnbd3_add_image(&image, _config_file_name); + } + + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + } + + // Cleanup + pthread_spin_unlock(&_spinlock); + close(client_sock); + xmlFreeParserCtxt(ctxt); + xmlFreeDoc(doc_config); + xmlCleanupParser(); + + // Reload configuration + printf("INFO: Reloading configuration...\n"); + dnbd3_reload_config(_config_file_name); + break; + default: printf("ERROR: Unknown command: %i\n", cmd); close(client_sock); @@ -334,7 +406,7 @@ void dnbd3_ipc_send(int cmd) printf("\nNumber clients: %d\n\n", n); xmlXPathFreeObject(xpathObj); xmlXPathFreeContext(xpathCtx); - //xmlDocDump(stdout, doc); +// xmlDocDump(stdout, doc); } else { diff --git a/src/server/ipc.h b/src/server/ipc.h index b08ce3c..498c048 100644 --- a/src/server/ipc.h +++ b/src/server/ipc.h @@ -24,6 +24,7 @@ #define IPC_EXIT 0 #define IPC_RELOAD 1 #define IPC_INFO 2 +#define IPC_CONFIG 3 void* dnbd3_ipc_receive(); diff --git a/src/server/server.c b/src/server/server.c index 2171773..371d27a 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -78,9 +78,10 @@ void dnbd3_cleanup() } g_slist_free(_dnbd3_clients); - // save cache maps to files + for (i = 0; i < _num_images; i++) { + // save cache maps to files if (_images[i].cache_file) { char tmp[strlen(_images[i].cache_file)+4]; @@ -93,6 +94,13 @@ void dnbd3_cleanup() close(fd); } + + free(_images[i].group); + free(_images[i].file); + free(_images[i].servers); + free(_images[i].serverss); + free(_images[i].cache_file); + free(_images[i].cache_map); } pthread_spin_unlock(&_spinlock); diff --git a/src/server/server.h b/src/server/server.h index b21b92c..f499acc 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -30,10 +30,12 @@ typedef struct { + char *group; char *file; uint64_t filesize; size_t num_servers; char **servers; + char *serverss; int vid; int rid; time_t atime; diff --git a/src/server/utils.c b/src/server/utils.c index 54ebda9..31d60ad 100644 --- a/src/server/utils.c +++ b/src/server/utils.c @@ -46,8 +46,11 @@ void dnbd3_load_config(char *file) for (i = 0; i < _num_images; i++) { + _images[i].group = malloc(strlen(groups[i])); + strcpy(_images[i].group, groups[i]); _images[i].file = g_key_file_get_string(gkf, groups[i], "file", NULL); _images[i].servers = g_key_file_get_string_list(gkf, groups[i], "servers", &_images[i].num_servers, NULL); + _images[i].serverss = g_key_file_get_string(gkf, groups[i], "servers", NULL); _images[i].vid = g_key_file_get_integer(gkf, groups[i], "vid", NULL); _images[i].rid = g_key_file_get_integer(gkf, groups[i], "rid", NULL); _images[i].cache_file = g_key_file_get_string(gkf, groups[i], "cache", NULL); @@ -105,9 +108,9 @@ void dnbd3_reload_config(char* config_file_name) client->image = NULL; } - // save cache maps for (i = 0; i < _num_images; i++) { + // save cache maps if (_images[i].cache_file) { char tmp[strlen(_images[i].cache_file)+4]; @@ -120,6 +123,13 @@ void dnbd3_reload_config(char* config_file_name) close(fd); } + + free(_images[i].group); + free(_images[i].file); + free(_images[i].servers); + free(_images[i].serverss); + free(_images[i].cache_file); + free(_images[i].cache_map); } _num_images = 0; @@ -133,6 +143,33 @@ void dnbd3_reload_config(char* config_file_name) pthread_spin_unlock(&_spinlock); } +void dnbd3_add_image(dnbd3_image_t *image, char *file) +{ + GKeyFile* gkf; + gkf = g_key_file_new(); + if (!g_key_file_load_from_file(gkf, file, G_KEY_FILE_NONE, NULL)) + { + printf("ERROR: Config file not found: %s\n", file); + exit(EXIT_FAILURE); + } + + g_key_file_set_integer(gkf, image->group, "vid", image->vid); + g_key_file_set_integer(gkf, image->group, "rid", image->rid); + g_key_file_set_string(gkf, image->group, "file", image->file); + g_key_file_set_string(gkf, image->group, "servers", image->serverss); + g_key_file_set_string(gkf, image->group, "cache_file", image->cache_file); + + gchar* data = g_key_file_to_data(gkf, NULL, NULL); + + FILE *f; + f = fopen(file,"w"); + fputs((char*) data, f); + fclose(f); + + g_free(data); + g_key_file_free(gkf); +} + dnbd3_image_t* dnbd3_get_image(int vid, int rid) { int i, max = 0; diff --git a/src/server/utils.h b/src/server/utils.h index e6bd6a9..d71e211 100644 --- a/src/server/utils.h +++ b/src/server/utils.h @@ -28,6 +28,7 @@ void dnbd3_load_config(char *file); void dnbd3_reload_config(char* config_file_name); +void dnbd3_add_image(dnbd3_image_t *image, char *file); dnbd3_image_t* dnbd3_get_image(int vid, int rid); -- cgit v1.2.3-55-g7522