From 3d248eaa0594e352c4ee235c0309ff5a6140d215 Mon Sep 17 00:00:00 2001 From: Johann Latocha Date: Tue, 31 Jul 2012 19:32:44 +0200 Subject: [SERVER] IPC, delete image TODO: unlink file --- src/server/ipc.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++-------- src/server/ipc.h | 3 ++- src/server/utils.c | 58 +++++++++++++++++++++++++++++++++++++++++- src/server/utils.h | 4 +++ 4 files changed, 126 insertions(+), 13 deletions(-) diff --git a/src/server/ipc.c b/src/server/ipc.c index 3398615..917d6e5 100644 --- a/src/server/ipc.c +++ b/src/server/ipc.c @@ -130,6 +130,8 @@ void* dnbd3_ipc_receive() while (1) { int i = 0, size = 0; + char* buf; + xmlDocPtr doc; // Accept connection if ((client_sock = accept(server_sock, &client, &len)) < 0) @@ -170,14 +172,13 @@ void* dnbd3_ipc_receive() case IPC_INFO: pthread_spin_lock(&_spinlock); - xmlDocPtr doc_info; xmlNodePtr root_node, images_node, clients_node, tmp_node; xmlChar *xmlbuff; int buffersize; - doc_info = xmlNewDoc(BAD_CAST "1.0"); + doc = xmlNewDoc(BAD_CAST "1.0"); root_node = xmlNewNode(NULL, BAD_CAST "info"); - xmlDocSetRootElement(doc_info, root_node); + xmlDocSetRootElement(doc, root_node); // Images images_node = xmlNewNode(NULL, BAD_CAST "images"); @@ -216,7 +217,7 @@ void* dnbd3_ipc_receive() } // Dump and send - xmlDocDumpFormatMemory(doc_info, &xmlbuff, &buffersize, 1); + xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1); header.size = htonl(buffersize); header.error = htonl(0); send(client_sock, (char *) &header, sizeof(header), MSG_WAITALL); @@ -226,18 +227,18 @@ void* dnbd3_ipc_receive() pthread_spin_unlock(&_spinlock); close(client_sock); xmlFree(xmlbuff); - xmlFreeDoc(doc_info); + xmlFreeDoc(doc); break; - case IPC_CONFIG: + case IPC_ADDIMG: pthread_spin_lock(&_spinlock); // Parse reply - char* buf = malloc(header.size); + buf = malloc(header.size); size = recv(client_sock, buf, header.size, MSG_WAITALL); - xmlDocPtr doc_config = xmlReadMemory(buf, size, "noname.xml", NULL, 0); + doc = xmlReadMemory(buf, size, "noname.xml", NULL, 0); - if (doc_config) + if (doc) { // xmlDocDump(stdout, doc_config); @@ -248,7 +249,7 @@ void* dnbd3_ipc_receive() xmlNodePtr cur; xpathExpr = BAD_CAST "/info/images/image"; - xpathCtx = xmlXPathNewContext(doc_config); + xpathCtx = xmlXPathNewContext(doc); xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx); nodes = xpathObj->nodesetval; @@ -275,7 +276,58 @@ void* dnbd3_ipc_receive() // Cleanup pthread_spin_unlock(&_spinlock); close(client_sock); - xmlFreeDoc(doc_config); + xmlFreeDoc(doc); + xmlCleanupParser(); + free(buf); + break; + + case IPC_DELIMG: + pthread_spin_lock(&_spinlock); + + // Parse reply + buf = malloc(header.size); + size = recv(client_sock, buf, header.size, MSG_WAITALL); + doc = xmlReadMemory(buf, size, "noname.xml", NULL, 0); + + if (doc) + { +// xmlDocDump(stdout, doc_config); + + xmlXPathContextPtr xpathCtx; + xmlXPathObjectPtr xpathObj; + xmlChar* xpathExpr; + xmlNodeSetPtr nodes; + xmlNodePtr cur; + + xpathExpr = BAD_CAST "/info/images/image"; + xpathCtx = xmlXPathNewContext(doc); + 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"); + header.error = htonl(dnbd3_del_image(&image, _config_file_name)); + } + + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + } + + header.size = htonl(0); + send(client_sock, (char *) &header, sizeof(header), MSG_WAITALL); + + // Cleanup + pthread_spin_unlock(&_spinlock); + close(client_sock); + xmlFreeDoc(doc); xmlCleanupParser(); free(buf); break; diff --git a/src/server/ipc.h b/src/server/ipc.h index e1d9997..4a405ee 100644 --- a/src/server/ipc.h +++ b/src/server/ipc.h @@ -24,7 +24,8 @@ #define IPC_EXIT 0 #define IPC_RELOAD 1 #define IPC_INFO 2 -#define IPC_CONFIG 3 +#define IPC_ADDIMG 3 +#define IPC_DELIMG 4 void* dnbd3_ipc_receive(); diff --git a/src/server/utils.c b/src/server/utils.c index c91142e..0be1569 100644 --- a/src/server/utils.c +++ b/src/server/utils.c @@ -178,7 +178,7 @@ int dnbd3_add_image(dnbd3_image_t *image, char *file) 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); + g_key_file_set_string(gkf, image->group, "cache", image->cache_file); gchar* data = g_key_file_to_data(gkf, NULL, NULL); @@ -200,6 +200,62 @@ int dnbd3_add_image(dnbd3_image_t *image, char *file) } } +int dnbd3_del_image(dnbd3_image_t *image, char *file) +{ + if (image->rid == 0) + { + printf("ERROR: Delete with rid=0 is not allowed\n"); + return ERROR_RID; + } + + dnbd3_image_t* tmp = dnbd3_get_image(image->vid, image->rid); + if (!tmp) + { + printf("ERROR: Image not found: (%d,%d)\n", image->vid, image->rid); + return ERROR_IMAGE_NOT_FOUND; + } + + GSList *iterator = NULL; + for (iterator = _dnbd3_clients; iterator; iterator = iterator->next) + { + dnbd3_client_t *client = iterator->data; + if (tmp == client->image) + { + printf("ERROR: Delete is not allowed, image is in use (%d,%d)\n", tmp->vid, tmp->rid); + return ERROR_IMAGE_IN_USE; + } + } + + 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_remove_group(gkf, tmp->group, NULL); + gchar* data = g_key_file_to_data(gkf, NULL, NULL); + + FILE* f = fopen(file,"w"); + if (f) + { + fputs((char*) data, f); + fclose(f); + g_free(data); + g_key_file_free(gkf); + // TODO: unlink image file + return 0; + } + else + { + g_free(data); + g_key_file_free(gkf); + printf("ERROR: Config file is not writable: %s\n", file); + return ERROR_CONFIG_FILE_PERMISSIONS; + } +} + 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 3975111..d9d3ebc 100644 --- a/src/server/utils.h +++ b/src/server/utils.h @@ -29,11 +29,15 @@ #define ERROR_FILE_NOT_FOUND 1 #define ERROR_IMAGE_ALREADY_EXISTS 2 #define ERROR_CONFIG_FILE_PERMISSIONS 3 +#define ERROR_IMAGE_NOT_FOUND 4 +#define ERROR_RID 5 +#define ERROR_IMAGE_IN_USE 6 #define ERROR_UNKNOWN 10 void dnbd3_load_config(char *file); void dnbd3_reload_config(char* config_file_name); int dnbd3_add_image(dnbd3_image_t *image, char *file); +int dnbd3_del_image(dnbd3_image_t *image, char *file); dnbd3_image_t* dnbd3_get_image(int vid, int rid); -- cgit v1.2.3-55-g7522