summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/server/ipc.c86
-rw-r--r--src/server/ipc.h1
-rw-r--r--src/server/server.c10
-rw-r--r--src/server/server.h2
-rw-r--r--src/server/utils.c39
-rw-r--r--src/server/utils.h1
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);