summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohann Latocha2012-07-31 19:32:44 +0200
committerJohann Latocha2012-07-31 19:32:44 +0200
commit3d248eaa0594e352c4ee235c0309ff5a6140d215 (patch)
tree771e0b119db937421c672e24f35f2c3871def741
parent[SERVER] IPC, some protocol refactoring (diff)
downloaddnbd3-jjl-thesis-final.tar.gz
dnbd3-jjl-thesis-final.tar.xz
dnbd3-jjl-thesis-final.zip
[SERVER] IPC, delete imagednbd3-jjl-thesis-final
TODO: unlink file
-rw-r--r--src/server/ipc.c74
-rw-r--r--src/server/ipc.h3
-rw-r--r--src/server/utils.c58
-rw-r--r--src/server/utils.h4
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);