From e365295caefa910fbd8e3be57515145de4c122ae Mon Sep 17 00:00:00 2001 From: Johann Latocha Date: Mon, 30 Jul 2012 19:05:44 +0200 Subject: [SERVER] Add IPCHeader --- src/server/ipc.c | 172 +++++++++++++++++++++++++++-------------------------- src/server/ipc.h | 10 ++++ src/server/utils.c | 35 ++++++++--- src/server/utils.h | 7 ++- 4 files changed, 129 insertions(+), 95 deletions(-) diff --git a/src/server/ipc.c b/src/server/ipc.c index 6a322d0..9fabd1a 100644 --- a/src/server/ipc.c +++ b/src/server/ipc.c @@ -44,8 +44,8 @@ void* dnbd3_ipc_receive() struct tm * timeinfo; char time_buff[64]; - char buf[64]; + dnbd3_ipc_t header; int server_sock, client_sock; struct timeval timeout; @@ -130,7 +130,6 @@ void* dnbd3_ipc_receive() while (1) { int i = 0, size = 0; - uint32_t cmd; // Accept connection if ((client_sock = accept(server_sock, &client, &len)) < 0) @@ -142,12 +141,18 @@ void* dnbd3_ipc_receive() 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); + recv(client_sock, &header, sizeof(header), MSG_WAITALL); + header.cmd = ntohl(header.cmd); + header.size = ntohl(header.size); + header.error = ntohl(header.error); - switch (ntohl(cmd)) + switch (header.cmd) { case IPC_EXIT: printf("INFO: Server shutdown...\n"); + header.size = ntohl(0); + header.error = ntohl(0); + send(client_sock, (char *) &header, sizeof(header), MSG_WAITALL); close(client_sock); close(server_sock); dnbd3_cleanup(); @@ -156,6 +161,9 @@ void* dnbd3_ipc_receive() case IPC_RELOAD: printf("INFO: Reloading configuration...\n"); dnbd3_reload_config(_config_file_name); + header.size = ntohl(0); + header.error = ntohl(0); + send(client_sock, (char *) &header, sizeof(header), MSG_WAITALL); close(client_sock); break; @@ -209,6 +217,9 @@ void* dnbd3_ipc_receive() // Dump and send xmlDocDumpFormatMemory(doc_info, &xmlbuff, &buffersize, 1); + header.size = htonl(buffersize); + header.error = htonl(0); + send(client_sock, (char *) &header, sizeof(header), MSG_WAITALL); send(client_sock, (char *) xmlbuff, buffersize, MSG_WAITALL); // Cleanup @@ -220,21 +231,15 @@ void* dnbd3_ipc_receive() 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); + // Parse reply + char* buf = malloc(header.size); + size = recv(client_sock, buf, header.size, MSG_WAITALL); + xmlDocPtr doc_config = xmlReadMemory(buf, size, "noname.xml", NULL, 0); - // Indicate the parsing is finished - xmlParseChunk(ctxt, buf, 0, 1); - doc_config = ctxt->myDoc; - - if (ctxt->wellFormed) + if (doc_config) { -// xmlDocDump(stdout, doc_config); + // xmlDocDump(stdout, doc_config); xmlXPathContextPtr xpathCtx; xmlXPathObjectPtr xpathObj; @@ -257,27 +262,29 @@ void* dnbd3_ipc_receive() 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); + header.error = htonl(dnbd3_add_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); - xmlFreeParserCtxt(ctxt); xmlFreeDoc(doc_config); xmlCleanupParser(); - - // Reload configuration - printf("INFO: Reloading configuration...\n"); - dnbd3_reload_config(_config_file_name); + free(buf); break; default: - printf("ERROR: Unknown command: %i\n", cmd); + printf("ERROR: Unknown command: %i\n", header.cmd); + header.size = htonl(0); + header.error = htonl(ERROR_UNKNOWN); + send(client_sock, (char *) &header, sizeof(header), MSG_WAITALL); close(client_sock); break; @@ -288,12 +295,7 @@ void* dnbd3_ipc_receive() void dnbd3_ipc_send(int cmd) { - uint32_t cmd_net = htonl(cmd); int client_sock, size; - char buf[64]; - - xmlParserCtxtPtr ctxt; - xmlDocPtr doc; #ifdef IPC_TCP struct sockaddr_in server; @@ -337,40 +339,39 @@ void dnbd3_ipc_send(int cmd) #endif // Send message - send(client_sock, &cmd_net, sizeof(cmd_net), MSG_WAITALL); - - if (cmd == IPC_INFO) + dnbd3_ipc_t header; + header.cmd = htonl(cmd); + header.size = 0; + header.error = 0; + send(client_sock, (char *) &header, sizeof(header), MSG_WAITALL); + recv(client_sock, &header, sizeof(header), MSG_WAITALL); + + if (cmd == IPC_INFO && header.size > 0) { - // 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 = ctxt->myDoc; + char* buf = malloc(header.size); + size = recv(client_sock, buf, header.size, MSG_WAITALL); + xmlDocPtr doc = xmlReadMemory(buf, size, "noname.xml", NULL, 0); - // Print reply to stdout - if (ctxt->wellFormed) + if (doc) { - int n, i; - - xmlXPathContextPtr xpathCtx; - xmlXPathObjectPtr xpathObj; - xmlChar* xpathExpr; - xmlNodeSetPtr nodes; - xmlNodePtr cur; - - // Print images - xpathExpr = BAD_CAST "/dnbd3-server/images/image"; - xpathCtx = xmlXPathNewContext(doc); - xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx); - printf("Exported images (atime, vid, rid, file):\n"); - printf("========================================\n"); - nodes = xpathObj->nodesetval; - n = (nodes) ? nodes->nodeNr : 0; - for(i = 0; i < n; ++i) - { + int n, i; + + xmlXPathContextPtr xpathCtx; + xmlXPathObjectPtr xpathObj; + xmlChar* xpathExpr; + xmlNodeSetPtr nodes; + xmlNodePtr cur; + + // Print images + xpathExpr = BAD_CAST "/dnbd3-server/images/image"; + xpathCtx = xmlXPathNewContext(doc); + xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx); + printf("Exported images (atime, vid, rid, file):\n"); + printf("========================================\n"); + nodes = xpathObj->nodesetval; + n = (nodes) ? nodes->nodeNr : 0; + for(i = 0; i < n; ++i) + { if(nodes->nodeTab[i]->type == XML_ELEMENT_NODE) { cur = nodes->nodeTab[i]; @@ -380,21 +381,21 @@ void dnbd3_ipc_send(int cmd) xmlChar *file = xmlGetNoNsProp(cur, BAD_CAST "file"); printf("%s\t%s\t%s\t%s\n", atime, vid, rid, file); } - } - printf("\nNumber images: %d\n\n", n); - xmlXPathFreeObject(xpathObj); - xmlXPathFreeContext(xpathCtx); - - // Print clients - xpathExpr = BAD_CAST "/dnbd3-server/clients/client"; - xpathCtx = xmlXPathNewContext(doc); - xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx); - printf("Connected clients (ip, file):\n"); - printf("=============================\n"); - nodes = xpathObj->nodesetval; - n = (nodes) ? nodes->nodeNr : 0; - for(i = 0; i < n; ++i) - { + } + printf("\nNumber images: %d\n\n", n); + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + + // Print clients + xpathExpr = BAD_CAST "/dnbd3-server/clients/client"; + xpathCtx = xmlXPathNewContext(doc); + xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx); + printf("Connected clients (ip, file):\n"); + printf("=============================\n"); + nodes = xpathObj->nodesetval; + n = (nodes) ? nodes->nodeNr : 0; + for(i = 0; i < n; ++i) + { if(nodes->nodeTab[i]->type == XML_ELEMENT_NODE) { cur = nodes->nodeTab[i]; @@ -402,21 +403,22 @@ void dnbd3_ipc_send(int cmd) xmlChar *file = xmlGetNoNsProp(cur, BAD_CAST "file"); printf("%s\t%s\n", ip, file); } - } - printf("\nNumber clients: %d\n\n", n); - xmlXPathFreeObject(xpathObj); - xmlXPathFreeContext(xpathCtx); -// xmlDocDump(stdout, doc); - } - else + } + printf("\nNumber clients: %d\n\n", n); + + // Cleanup + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); + xmlCleanupParser(); + + // xmlDocDump(stdout, doc); + + } else { printf("ERROR: Failed to parse reply\n"); } - // Cleanup - xmlFreeParserCtxt(ctxt); - xmlFreeDoc(doc); - xmlCleanupParser(); } close(client_sock); diff --git a/src/server/ipc.h b/src/server/ipc.h index 498c048..e1d9997 100644 --- a/src/server/ipc.h +++ b/src/server/ipc.h @@ -30,4 +30,14 @@ void* dnbd3_ipc_receive(); void dnbd3_ipc_send(int cmd); + +#pragma pack(1) +typedef struct +{ + uint32_t cmd; // 4byte + uint32_t size; // 4byte + uint32_t error; // 4byte +} dnbd3_ipc_t; +#pragma pack(0) + #endif /* IPC_H_ */ diff --git a/src/server/utils.c b/src/server/utils.c index 8700e6d..8acb8cc 100644 --- a/src/server/utils.c +++ b/src/server/utils.c @@ -63,7 +63,7 @@ void dnbd3_load_config(char *file) if (fd > 0) _images[i].filesize = lseek(fd, 0, SEEK_END); else - printf("ERROR: Image not found: %s\n", _images[i].file); + printf("ERROR: Image file not found: %s\n", _images[i].file); close(fd); @@ -143,13 +143,21 @@ void dnbd3_reload_config(char* config_file_name) pthread_spin_unlock(&_spinlock); } -void dnbd3_add_image(dnbd3_image_t *image, char *file) +int dnbd3_add_image(dnbd3_image_t *image, char *file) { + FILE* f = fopen(image->file,"r"); + if (f == NULL) + { + printf("ERROR: Image file not found: %s\n", image->file); + return ERROR_FILE_NOT_FOUND; + } + fclose (f); + dnbd3_image_t* tmp = dnbd3_get_image(image->vid, image->rid); if (tmp && image->rid != 0) { printf("ERROR: Image already exists (%d,%d)\n", image->vid, image->rid); - return; + return ERROR_IMAGE_ALREADY_EXISTS; } if (tmp && image->rid == 0) @@ -171,13 +179,22 @@ void dnbd3_add_image(dnbd3_image_t *image, char *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); + if (f) + { + fputs((char*) data, f); + fclose(f); + g_free(data); + g_key_file_free(gkf); + 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) diff --git a/src/server/utils.h b/src/server/utils.h index d71e211..3975111 100644 --- a/src/server/utils.h +++ b/src/server/utils.h @@ -26,9 +26,14 @@ #ifndef UTILS_H_ #define UTILS_H_ +#define ERROR_FILE_NOT_FOUND 1 +#define ERROR_IMAGE_ALREADY_EXISTS 2 +#define ERROR_CONFIG_FILE_PERMISSIONS 3 +#define ERROR_UNKNOWN 10 + void dnbd3_load_config(char *file); void dnbd3_reload_config(char* config_file_name); -void dnbd3_add_image(dnbd3_image_t *image, char *file); +int 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