summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
authorsr2012-09-03 15:27:36 +0200
committersr2012-09-03 15:27:36 +0200
commita55be46ec7a281f5c3d41d48edf32e57ef5e4ba1 (patch)
treed375eaf63e03a6e1b5e199712735a68b448c6d97 /src/server
parent[SERVER] Add list of trusted servers and namespaces (load, display) (diff)
downloaddnbd3-a55be46ec7a281f5c3d41d48edf32e57ef5e4ba1.tar.gz
dnbd3-a55be46ec7a281f5c3d41d48edf32e57ef5e4ba1.tar.xz
dnbd3-a55be46ec7a281f5c3d41d48edf32e57ef5e4ba1.zip
[*] Fixed and unified formatting
Diffstat (limited to 'src/server')
-rw-r--r--src/server/ipc.c27
-rw-r--r--src/server/ipc.h8
-rw-r--r--src/server/job.c24
-rw-r--r--src/server/job.h2
-rw-r--r--src/server/memlog.c20
-rw-r--r--src/server/memlog.h2
-rw-r--r--src/server/net.c535
-rw-r--r--src/server/server.c405
-rw-r--r--src/server/server.h34
-rw-r--r--src/server/utils.c121
-rw-r--r--src/server/utils.h2
11 files changed, 599 insertions, 581 deletions
diff --git a/src/server/ipc.c b/src/server/ipc.c
index e988abc..339dcc6 100644
--- a/src/server/ipc.c
+++ b/src/server/ipc.c
@@ -600,7 +600,8 @@ get_info_reply_cleanup:
xmlFree(image.file);
xmlFree(image.cache_file);
}
- } END_FOR_EACH;
+ }
+ END_FOR_EACH;
if (count == 0)
header.error = htonl(ERROR_MISSING_ARGUMENT);
}
@@ -723,11 +724,12 @@ void dnbd3_ipc_send(int cmd)
wname = MAX(wname, xmlStrlen(vid));
wrid = MAX(wrid, xmlStrlen(rid));
// Too lazy to free vars, client will exit anyways
- } END_FOR_EACH;
+ }
+ END_FOR_EACH;
char format[100];
snprintf(format, 100,
- "%%-%ds %%-%ds %%%ds %%s\n", watime, wname, wrid);
+ "%%-%ds %%-%ds %%%ds %%s\n", watime, wname, wrid);
// Print images
printf("Exported images\n");
@@ -745,7 +747,8 @@ void dnbd3_ipc_send(int cmd)
xmlChar *file = xmlGetNoNsProp(cur, BAD_CAST "file");
printf(format, atime, vid, rid, file);
// Too lazy to free vars, client will exit anyways
- } END_FOR_EACH;
+ }
+ END_FOR_EACH;
char_repeat_br('=', term_width);
printf("\nNumber of images: %d\n\n", count);
@@ -762,7 +765,8 @@ void dnbd3_ipc_send(int cmd)
xmlChar *file = xmlGetNoNsProp(cur, BAD_CAST "file");
printf("%-40s %s\n", ip, file);
// Too lazy to free vars, client will exit anyways
- } END_FOR_EACH;
+ }
+ END_FOR_EACH;
char_repeat_br('=', term_width);
printf("\nNumber clients: %d\n\n", count);
@@ -796,7 +800,8 @@ void dnbd3_ipc_send(int cmd)
putchar('\n');
}
// Too lazy to free vars, client will exit anyways
- } END_FOR_EACH;
+ }
+ END_FOR_EACH;
char_repeat_br('=', term_width);
printf("\nNumber servers: %d\n\n", count);
@@ -831,7 +836,7 @@ static int is_password_correct(xmlDocPtr doc)
xmlChar *pass = getTextFromPath(doc, "/data/password");
if (pass == NULL)
return 0;
- if (strcmp((char*)pass, _ipc_password) == 0)
+ if (strcmp((char *)pass, _ipc_password) == 0)
{
xmlFree(pass);
return 1;
@@ -842,8 +847,8 @@ static int is_password_correct(xmlDocPtr doc)
static int get_terminal_width()
{
- struct winsize w;
- if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) < 0)
- return 80;
- return w.ws_col;
+ struct winsize w;
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) < 0)
+ return 80;
+ return w.ws_col;
}
diff --git a/src/server/ipc.h b/src/server/ipc.h
index d4ec7db..36d1f60 100644
--- a/src/server/ipc.h
+++ b/src/server/ipc.h
@@ -27,7 +27,7 @@
#define IPC_ADDIMG 3
#define IPC_DELIMG 4
-void* dnbd3_ipc_mainloop();
+void *dnbd3_ipc_mainloop();
void dnbd3_ipc_shutdown();
@@ -38,9 +38,9 @@ void dnbd3_ipc_send(int cmd);
typedef struct
{
uint32_t handle;// 4byte
- uint32_t cmd; // 4byte
- uint32_t size; // 4byte
- uint32_t error; // 4byte
+ uint32_t cmd; // 4byte
+ uint32_t size; // 4byte
+ uint32_t error; // 4byte
} dnbd3_ipc_t;
#pragma pack(0)
diff --git a/src/server/job.c b/src/server/job.c
index b50a7f3..1f10cb6 100644
--- a/src/server/job.c
+++ b/src/server/job.c
@@ -32,12 +32,12 @@ static int num_devices = 0;
static char keep_running = TRUE;
// Private functions
-static char* get_free_device();
+static char *get_free_device();
static void query_servers();
//
-void* dnbd3_job_thread(void *data)
+void *dnbd3_job_thread(void *data)
{
int i, j;
// Determine number of available dnbd3 devices, which are needed for proxy mode
@@ -74,18 +74,18 @@ void* dnbd3_job_thread(void *data)
const time_t starttime = time(NULL);
//
// TODO: Update image atime
- // Call image deletion function if last call is more than 5 minutes ago
- if (starttime < next_delete_invocation)
- {
- next_delete_invocation = starttime + 300;
- dnbd3_exec_delete(TRUE);
- }
+ // Call image deletion function if last call is more than 5 minutes ago
+ if (starttime < next_delete_invocation)
+ {
+ next_delete_invocation = starttime + 300;
+ dnbd3_exec_delete(TRUE);
+ }
// TODO: Replicate proxied images (limited bandwidth)
// Query other servers for new images/status/...
- query_servers();
+ query_servers();
// TODO: Switch server of dnbd device based on more sophisticated inputs than just rtt
- // Calc sleep timeout for next iteration
- sleep(30 - (time(NULL) - starttime)); // Sleep 30 seconds, but account for the time it took to execute the loop
+ // Calc sleep timeout for next iteration
+ sleep(30 - (time(NULL) - starttime)); // Sleep 30 seconds, but account for the time it took to execute the loop
}
//
free(devices);
@@ -114,7 +114,7 @@ static void query_servers()
* Get full name of an available dnbd3 device, eg. /dev/dnbd4
* Returned buffer is owned by this module, do not modify or free!
*/
-static char* get_free_device()
+static char *get_free_device()
{
if (devices == NULL)
return NULL;
diff --git a/src/server/job.h b/src/server/job.h
index 87be5d5..d8bb090 100644
--- a/src/server/job.h
+++ b/src/server/job.h
@@ -1,6 +1,6 @@
#ifndef JOB_H_
#define JOB_H_
-void* dnbd3_job_thread(void *data);
+void *dnbd3_job_thread(void *data);
#endif
diff --git a/src/server/memlog.c b/src/server/memlog.c
index 9809e64..6d4ec09 100644
--- a/src/server/memlog.c
+++ b/src/server/memlog.c
@@ -58,11 +58,11 @@ void memlogf(const char *fmt, ...)
va_list ap;
int ret;
time_t rawtime;
- struct tm * timeinfo;
+ struct tm *timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
pthread_spin_lock(&logLock);
- LogLine * const line = (LogLine *)&(logBuffer[bufferPos % LINE_COUNT]);
+ LogLine *const line = (LogLine *)&(logBuffer[bufferPos % LINE_COUNT]);
const size_t offset = strftime(line->text, LINE_LEN, "[%d.%m. %H:%M:%S] ", timeinfo);
if (offset == 0) *line->text = '\0';
va_start(ap, fmt);
@@ -79,7 +79,7 @@ void memlogf(const char *fmt, ...)
puts(line->text);
}
-char * fetchlog(int maxlines)
+char *fetchlog(int maxlines)
{
if (!logBuffer) return NULL;
if (maxlines <= 0 || maxlines > LINE_COUNT) maxlines = LINE_COUNT;
@@ -88,8 +88,10 @@ char * fetchlog(int maxlines)
//printf("Outputting log from %d to %d\n", start, bufferPos);
pthread_spin_lock(&logLock);
// Determine required buffer space for all log lines
- for (i = start; i < bufferPos; ++i) {
- if (logBuffer[i % LINE_COUNT].len > 0) {
+ for (i = start; i < bufferPos; ++i)
+ {
+ if (logBuffer[i % LINE_COUNT].len > 0)
+ {
len += logBuffer[i % LINE_COUNT].len + 1;
}
}
@@ -99,9 +101,11 @@ char * fetchlog(int maxlines)
if (retval == NULL) goto endFunction;
// Concatenate all log lines, delimit using '\n'
char *pos = retval;
- for (i = start; i < bufferPos; ++i) {
- LogLine * const line = (LogLine *)&(logBuffer[i % LINE_COUNT]);
- if (line->len > 0) {
+ for (i = start; i < bufferPos; ++i)
+ {
+ LogLine *const line = (LogLine *)&(logBuffer[i % LINE_COUNT]);
+ if (line->len > 0)
+ {
memcpy(pos, (char *)line->text, line->len);
pos += line->len;
*pos++ = '\n';
diff --git a/src/server/memlog.h b/src/server/memlog.h
index 24e3880..38c4349 100644
--- a/src/server/memlog.h
+++ b/src/server/memlog.h
@@ -34,6 +34,6 @@ void memlogf(char *text, ...);
* Returns NULL on error
* maxlines - Limit number of lines returned, 0 = everything
*/
-char * fetchlog(int maxlines);
+char *fetchlog(int maxlines);
#endif /* MEMLOG_H_ */
diff --git a/src/server/net.c b/src/server/net.c
index bcbf056..afb7077 100644
--- a/src/server/net.c
+++ b/src/server/net.c
@@ -43,29 +43,29 @@ static inline char recv_request_header(int sock, dnbd3_request_t *request)
{
int ret;
// Read request header from socket
- if ((ret = recv(sock, request, sizeof(*request), MSG_WAITALL)) != sizeof(*request))
- {
- if (ret == 0) return 0;
- printf("[DEBUG] Error receiving request: Could not read message header (%d/%d)\n", ret, (int)sizeof(*request));
- return 0;
- }
- // Make sure all bytes are in the right order (endianness)
- fixup_request(*request);
- if (request->magic != dnbd3_packet_magic)
- {
- printf("[DEBUG] Magic in client request incorrect (cmd: %d, len: %d)\n", (int)request->cmd, (int)request->size);
- return 0;
- }
- // Payload sanity check
- if (request->cmd != CMD_GET_BLOCK && request->size > MAX_PAYLOAD)
- {
- memlogf("[WARNING] Client tries to send a packet of type %d with %d bytes payload. Dropping client.", (int)request->cmd, (int)request->size);
- return 0;
- }
+ if ((ret = recv(sock, request, sizeof(*request), MSG_WAITALL)) != sizeof(*request))
+ {
+ if (ret == 0) return 0;
+ printf("[DEBUG] Error receiving request: Could not read message header (%d/%d)\n", ret, (int)sizeof(*request));
+ return 0;
+ }
+ // Make sure all bytes are in the right order (endianness)
+ fixup_request(*request);
+ if (request->magic != dnbd3_packet_magic)
+ {
+ printf("[DEBUG] Magic in client request incorrect (cmd: %d, len: %d)\n", (int)request->cmd, (int)request->size);
+ return 0;
+ }
+ // Payload sanity check
+ if (request->cmd != CMD_GET_BLOCK && request->size > MAX_PAYLOAD)
+ {
+ memlogf("[WARNING] Client tries to send a packet of type %d with %d bytes payload. Dropping client.", (int)request->cmd, (int)request->size);
+ return 0;
+ }
#ifdef _DEBUG
- if (_fake_delay) usleep(_fake_delay);
+ if (_fake_delay) usleep(_fake_delay);
#endif
- return 1;
+ return 1;
}
static inline char recv_request_payload(int sock, uint32_t size, serialized_buffer_t *payload)
@@ -120,44 +120,44 @@ static inline char send_reply(int sock, dnbd3_reply_t *reply, void *payload)
void *dnbd3_handle_query(void *dnbd3_client)
{
- dnbd3_client_t *client = (dnbd3_client_t *) (uintptr_t) dnbd3_client;
- dnbd3_request_t request;
- dnbd3_reply_t reply;
-
- dnbd3_image_t *image = NULL;
- int image_file = -1, image_cache = -1;
-
- int i, num;
-
- uint64_t map_y;
- char map_x, bit_mask;
- serialized_buffer_t payload;
- char *image_name;
- uint16_t rid, client_version;
-
- uint64_t todo_size = 0;
- uint64_t todo_offset = 0;
- uint64_t cur_offset = 0;
- uint64_t last_offset = 0;
-
- dnbd3_server_entry_t server_list[NUMBER_SERVERS];
-
- int dirty = 0;
-
- reply.magic = dnbd3_packet_magic;
-
- // Receive first packet. This must be CMD_GET_SIZE by protocol specification
- if (recv_request_header(client->sock, &request))
- {
- if (request.cmd != CMD_GET_SIZE)
- {
- printf("[DEBUG] Client sent invalid handshake (%d). Dropping Client\n", (int)request.cmd);
- }
- else
- {
- if (recv_request_payload(client->sock, request.size, &payload))
- {
- client_version = serializer_get_uint16(&payload);
+ dnbd3_client_t *client = (dnbd3_client_t *) (uintptr_t) dnbd3_client;
+ dnbd3_request_t request;
+ dnbd3_reply_t reply;
+
+ dnbd3_image_t *image = NULL;
+ int image_file = -1, image_cache = -1;
+
+ int i, num;
+
+ uint64_t map_y;
+ char map_x, bit_mask;
+ serialized_buffer_t payload;
+ char *image_name;
+ uint16_t rid, client_version;
+
+ uint64_t todo_size = 0;
+ uint64_t todo_offset = 0;
+ uint64_t cur_offset = 0;
+ uint64_t last_offset = 0;
+
+ dnbd3_server_entry_t server_list[NUMBER_SERVERS];
+
+ int dirty = 0;
+
+ reply.magic = dnbd3_packet_magic;
+
+ // Receive first packet. This must be CMD_GET_SIZE by protocol specification
+ if (recv_request_header(client->sock, &request))
+ {
+ if (request.cmd != CMD_GET_SIZE)
+ {
+ printf("[DEBUG] Client sent invalid handshake (%d). Dropping Client\n", (int)request.cmd);
+ }
+ else
+ {
+ if (recv_request_payload(client->sock, request.size, &payload))
+ {
+ client_version = serializer_get_uint16(&payload);
image_name = serializer_get_string(&payload);
rid = serializer_get_uint16(&payload);
client->is_server = serializer_get_uint8(&payload);
@@ -182,7 +182,7 @@ void *dnbd3_handle_query(void *dnbd3_client)
printf("[DEBUG] Client requested non-existent image '%s' (rid:%d)\n", image_name, (int)rid);
}
else if ((image->delete_soft != 0 && image->delete_soft < now)
- || (image->delete_hard != 0 && image->delete_hard < now))
+ || (image->delete_hard != 0 && image->delete_hard < now))
{
printf("[DEBUG] Client requested end-of-life image '%s' (rid:%d)\n", image_name, (int)rid);
}
@@ -220,221 +220,224 @@ void *dnbd3_handle_query(void *dnbd3_client)
pthread_spin_unlock(&_spinlock);
}
}
- }
+ }
}
- if (image) while (recv_request_header(client->sock, &request))
- {
- switch (request.cmd)
- {
-
- case CMD_GET_BLOCK:
- if (request.offset >= image->filesize)
- { // Sanity check
- memlogf("[WARNING] Client requested non-existent block");
- reply.size = 0;
- reply.cmd = CMD_ERROR;
- send_reply(client->sock, &reply, NULL);
- break;
- }
- if (request.offset + request.size > image->filesize)
- { // Sanity check
- memlogf("[WARNING] Client requested data block that extends beyond image size");
- reply.size = 0;
- reply.cmd = CMD_ERROR;
- send_reply(client->sock, &reply, NULL);
- break;
- }
- if (request.size > image->filesize)
- { // Sanity check
- memlogf("[WARNING] Client requested data block that is bigger than the image size");
- reply.size = 0;
- reply.cmd = CMD_ERROR;
- send_reply(client->sock, &reply, NULL);
- break;
- }
-
- reply.cmd = CMD_GET_BLOCK;
- reply.size = request.size;
- reply.handle = request.handle;
-
- fixup_reply(reply);
- if (send(client->sock, &reply, sizeof(dnbd3_reply_t), MSG_MORE) != sizeof(dnbd3_reply_t))
+ if (image) while (recv_request_header(client->sock, &request))
+ {
+ switch (request.cmd)
{
- printf("[DEBUG] Sending CMD_GET_BLOCK header failed\n");
- return 0;
+
+ case CMD_GET_BLOCK:
+ if (request.offset >= image->filesize)
+ {
+ // Sanity check
+ memlogf("[WARNING] Client requested non-existent block");
+ reply.size = 0;
+ reply.cmd = CMD_ERROR;
+ send_reply(client->sock, &reply, NULL);
+ break;
+ }
+ if (request.offset + request.size > image->filesize)
+ {
+ // Sanity check
+ memlogf("[WARNING] Client requested data block that extends beyond image size");
+ reply.size = 0;
+ reply.cmd = CMD_ERROR;
+ send_reply(client->sock, &reply, NULL);
+ break;
+ }
+ if (request.size > image->filesize)
+ {
+ // Sanity check
+ memlogf("[WARNING] Client requested data block that is bigger than the image size");
+ reply.size = 0;
+ reply.cmd = CMD_ERROR;
+ send_reply(client->sock, &reply, NULL);
+ break;
+ }
+
+ reply.cmd = CMD_GET_BLOCK;
+ reply.size = request.size;
+ reply.handle = request.handle;
+
+ fixup_reply(reply);
+ if (send(client->sock, &reply, sizeof(dnbd3_reply_t), MSG_MORE) != sizeof(dnbd3_reply_t))
+ {
+ printf("[DEBUG] Sending CMD_GET_BLOCK header failed\n");
+ return 0;
+ }
+
+ if (request.size == 0) // Request for 0 bytes, done after sending header
+ break;
+
+ // caching is off
+ if (image_cache == -1)
+ {
+ if (sendfile(client->sock, image_file, (off_t *)&request.offset, request.size) != request.size)
+ {
+ printf("[ERROR] sendfile failed (image to net)\n");
+ close(client->sock);
+ client->sock = -1;
+ }
+ break;
+ }
+
+ // caching is on
+ dirty = 0;
+ todo_size = 0;
+ todo_offset = request.offset;
+ cur_offset = request.offset;
+ last_offset = request.offset + request.size;
+
+ // first make sure the whole requested part is in the local cache file
+ while(cur_offset < last_offset)
+ {
+ map_y = cur_offset >> 15; // div 32768
+ map_x = (cur_offset >> 12) & 7; // (X div 4096) mod 8
+ bit_mask = 0b00000001 << (map_x);
+
+ cur_offset += 4096;
+
+ if ((image->cache_map[map_y] & bit_mask) != 0) // cache hit
+ {
+ if (todo_size != 0) // fetch missing chunks
+ {
+ lseek(image_cache, todo_offset, SEEK_SET);
+ if (sendfile(image_cache, image_file, (off_t *) &todo_offset, todo_size) != todo_size)
+ {
+ printf("[ERROR] sendfile failed (copy to cache 1)\n");
+ close(client->sock);
+ client->sock = -1;
+ // Reset these so we don't update the cache map with false information
+ dirty = 0;
+ todo_size = 0;
+ break;
+ }
+ todo_size = 0;
+ dirty = 1;
+ }
+ todo_offset = cur_offset;
+ }
+ else
+ {
+ todo_size += 4096;
+ }
+ }
+
+ // whole request was missing
+ if (todo_size != 0)
+ {
+ lseek(image_cache, todo_offset, SEEK_SET);
+ if (sendfile(image_cache, image_file, (off_t *) &todo_offset, todo_size) != todo_size)
+ {
+ printf("[ERROR] sendfile failed (copy to cache 2)\n");
+ close(client->sock);
+ client->sock = -1;
+ break;
+ }
+ dirty = 1;
+ }
+
+ if (dirty) // cache map needs to be updated as something was missing locally
+ {
+ // set 1 in cache map for whole request
+ cur_offset = request.offset;
+ while(cur_offset < last_offset)
+ {
+ map_y = cur_offset >> 15;
+ map_x = (cur_offset >> 12) & 7; // mod 8
+ bit_mask = 0b00000001 << (map_x);
+ image->cache_map[map_y] |= bit_mask;
+ cur_offset += 4096;
+ }
+ }
+
+ // send data to client
+ if (sendfile(client->sock, image_cache, (off_t *) &request.offset, request.size) != request.size)
+ {
+ memlogf("[ERROR] sendfile failed (cache to net)\n");
+ close(client->sock);
+ client->sock = -1;
+ }
+ break;
+
+
+ case CMD_GET_SERVERS:
+ client->is_server = FALSE; // Only clients request list of servers
+ // Build list of known working alt servers
+ num = 0;
+ for (i = 0; i < NUMBER_SERVERS; i++)
+ {
+ if (image->servers[i].hostaddrtype == 0 || image->servers[i].failures > 200) continue;
+ memcpy(server_list + num++, image->servers + i, sizeof(dnbd3_server_entry_t));
+ }
+ reply.cmd = CMD_GET_SERVERS;
+ reply.size = num * sizeof(dnbd3_server_entry_t);
+ send_reply(client->sock, &reply, server_list);
+ break;
+
+ case CMD_KEEPALIVE:
+ reply.cmd = CMD_KEEPALIVE;
+ reply.size = 0;
+ send_reply(client->sock, &reply, NULL);
+ break;
+
+ case CMD_SET_CLIENT_MODE:
+ client->is_server = FALSE;
+ break;
+
+ default:
+ memlogf("ERROR: Unknown command\n");
+ break;
+
}
- if (request.size == 0) // Request for 0 bytes, done after sending header
- break;
-
- // caching is off
- if (image_cache == -1)
- {
- if (sendfile(client->sock, image_file, (off_t *)&request.offset, request.size) != request.size)
- {
- printf("[ERROR] sendfile failed (image to net)\n");
- close(client->sock);
- client->sock = -1;
- }
- break;
- }
-
- // caching is on
- dirty = 0;
- todo_size = 0;
- todo_offset = request.offset;
- cur_offset = request.offset;
- last_offset = request.offset + request.size;
-
- // first make sure the whole requested part is in the local cache file
- while(cur_offset < last_offset)
- {
- map_y = cur_offset >> 15; // div 32768
- map_x = (cur_offset >> 12) & 7; // (X div 4096) mod 8
- bit_mask = 0b00000001 << (map_x);
-
- cur_offset += 4096;
-
- if ((image->cache_map[map_y] & bit_mask) != 0) // cache hit
- {
- if (todo_size != 0) // fetch missing chunks
- {
- lseek(image_cache, todo_offset, SEEK_SET);
- if (sendfile(image_cache, image_file, (off_t *) &todo_offset, todo_size) != todo_size)
- {
- printf("[ERROR] sendfile failed (copy to cache 1)\n");
- close(client->sock);
- client->sock = -1;
- // Reset these so we don't update the cache map with false information
- dirty = 0;
- todo_size = 0;
- break;
- }
- todo_size = 0;
- dirty = 1;
- }
- todo_offset = cur_offset;
- }
- else
- {
- todo_size += 4096;
- }
- }
-
- // whole request was missing
- if (todo_size != 0)
- {
- lseek(image_cache, todo_offset, SEEK_SET);
- if (sendfile(image_cache, image_file, (off_t *) &todo_offset, todo_size) != todo_size)
- {
- printf("[ERROR] sendfile failed (copy to cache 2)\n");
- close(client->sock);
- client->sock = -1;
- break;
- }
- dirty = 1;
- }
-
- if (dirty) // cache map needs to be updated as something was missing locally
- {
- // set 1 in cache map for whole request
- cur_offset = request.offset;
- while(cur_offset < last_offset)
- {
- map_y = cur_offset >> 15;
- map_x = (cur_offset >> 12) & 7; // mod 8
- bit_mask = 0b00000001 << (map_x);
- image->cache_map[map_y] |= bit_mask;
- cur_offset += 4096;
- }
- }
-
- // send data to client
- if (sendfile(client->sock, image_cache, (off_t *) &request.offset, request.size) != request.size)
- {
- memlogf("[ERROR] sendfile failed (cache to net)\n");
- close(client->sock);
- client->sock = -1;
- }
- break;
-
-
- case CMD_GET_SERVERS:
- client->is_server = FALSE; // Only clients request list of servers
- // Build list of known working alt servers
- num = 0;
- for (i = 0; i < NUMBER_SERVERS; i++)
- {
- if (image->servers[i].hostaddrtype == 0 || image->servers[i].failures > 200) continue;
- memcpy(server_list + num++, image->servers + i, sizeof(dnbd3_server_entry_t));
- }
- reply.cmd = CMD_GET_SERVERS;
- reply.size = num * sizeof(dnbd3_server_entry_t);
- send_reply(client->sock, &reply, server_list);
- break;
-
- case CMD_KEEPALIVE:
- reply.cmd = CMD_KEEPALIVE;
- reply.size = 0;
- send_reply(client->sock, &reply, NULL);
- break;
-
- case CMD_SET_CLIENT_MODE:
- client->is_server = FALSE;
- break;
-
- default:
- memlogf("ERROR: Unknown command\n");
- break;
-
- }
-
- }
- pthread_spin_lock(&_spinlock);
- _dnbd3_clients = g_slist_remove(_dnbd3_clients, client);
- pthread_spin_unlock(&_spinlock);
- if (client->sock != -1)
- close(client->sock);
- if (image_file != -1) close(image_file);
- if (image_cache != -1) close(image_cache);
- g_free(client);
- pthread_exit((void *) 0);
+ }
+ pthread_spin_lock(&_spinlock);
+ _dnbd3_clients = g_slist_remove(_dnbd3_clients, client);
+ pthread_spin_unlock(&_spinlock);
+ if (client->sock != -1)
+ close(client->sock);
+ if (image_file != -1) close(image_file);
+ if (image_cache != -1) close(image_cache);
+ g_free(client);
+ pthread_exit((void *) 0);
}
int dnbd3_setup_socket()
{
- int sock;
- struct sockaddr_in server;
-
- // Create socket
- sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sock < 0)
- {
- memlogf("ERROR: Socket setup failure\n");
- return -1;
- }
- const int opt = 1;
+ int sock;
+ struct sockaddr_in server;
+
+ // Create socket
+ sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (sock < 0)
+ {
+ memlogf("ERROR: Socket setup failure\n");
+ return -1;
+ }
+ const int opt = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
- memset(&server, 0, sizeof(server));
- server.sin_family = AF_INET; // IPv4
- server.sin_addr.s_addr = htonl(INADDR_ANY); // Take all IPs
- server.sin_port = htons(PORT); // set port number
-
- // Bind to socket
- if (bind(sock, (struct sockaddr*) &server, sizeof(server)) < 0)
- {
- memlogf("ERROR: Bind failure\n");
- return -1;
- }
-
- // Listen on socket
- if (listen(sock, 100) == -1)
- {
- memlogf("ERROR: Listen failure\n");
- return -1;
- }
-
- return sock;
+ memset(&server, 0, sizeof(server));
+ server.sin_family = AF_INET; // IPv4
+ server.sin_addr.s_addr = htonl(INADDR_ANY); // Take all IPs
+ server.sin_port = htons(PORT); // set port number
+
+ // Bind to socket
+ if (bind(sock, (struct sockaddr *) &server, sizeof(server)) < 0)
+ {
+ memlogf("ERROR: Bind failure\n");
+ return -1;
+ }
+
+ // Listen on socket
+ if (listen(sock, 100) == -1)
+ {
+ memlogf("ERROR: Listen failure\n");
+ return -1;
+ }
+
+ return sock;
}
diff --git a/src/server/server.c b/src/server/server.c
index feee30b..9fc5383 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -49,225 +49,226 @@ char *_ipc_password = NULL;
GSList *_dnbd3_images = NULL; // of dnbd3_image_t
GSList *_trusted_servers = NULL;
-void dnbd3_print_help(char* argv_0)
+void dnbd3_print_help(char *argv_0)
{
- printf("Usage: %s [OPTIONS]...\n", argv_0);
- printf("Start the DNBD3 server\n");
- printf("-f or --file Configuration file (default /etc/dnbd3-server.conf)\n");
+ printf("Usage: %s [OPTIONS]...\n", argv_0);
+ printf("Start the DNBD3 server\n");
+ printf("-f or --file Configuration file (default /etc/dnbd3-server.conf)\n");
#ifdef _DEBUG
- printf("-d or --delay Add a fake network delay of X µs\n");
+ printf("-d or --delay Add a fake network delay of X µs\n");
#endif
- printf("-n or --nodaemon Start server in foreground\n");
- printf("-r or --reload Reload configuration file\n");
- printf("-s or --stop Stop running dnbd3-server\n");
- printf("-i or --info Print connected clients and used images\n");
- printf("-H or --help Show this help text and quit\n");
- printf("-V or --version Show version and quit\n");
- exit(0);
+ printf("-n or --nodaemon Start server in foreground\n");
+ printf("-r or --reload Reload configuration file\n");
+ printf("-s or --stop Stop running dnbd3-server\n");
+ printf("-i or --info Print connected clients and used images\n");
+ printf("-H or --help Show this help text and quit\n");
+ printf("-V or --version Show version and quit\n");
+ exit(0);
}
void dnbd3_print_version()
{
- printf("Version: %s\n", VERSION_STRING);
- exit(0);
+ printf("Version: %s\n", VERSION_STRING);
+ exit(0);
}
void dnbd3_cleanup()
{
- int fd;
- memlogf("INFO: Cleanup...\n");
-
- close(sock);
- sock = -1;
-
- dnbd3_ipc_shutdown();
-
- pthread_spin_lock(&_spinlock);
- GSList *iterator = NULL;
- for (iterator = _dnbd3_clients; iterator; iterator = iterator->next)
- {
- dnbd3_client_t *client = iterator->data;
- shutdown(client->sock, SHUT_RDWR);
- pthread_join(client->thread, NULL);
- g_free(client);
- }
- g_slist_free(_dnbd3_clients);
-
-
- for (iterator = _dnbd3_images; iterator; iterator = iterator->next)
- {
- // save cache maps to files
- dnbd3_image_t *image = iterator->data;
- if (image->cache_file)
- {
- char tmp[strlen(image->cache_file)+4];
- strcpy(tmp, image->cache_file);
- strcat(tmp, ".map");
- fd = open(tmp, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
-
- if (fd > 0)
- write(fd, image->cache_map, ((image->filesize + (1 << 15) - 1) >> 15) * sizeof(char));
-
- close(fd);
- }
-
- free(image->cache_map);
- free(image->config_group);
- free(image->low_name);
- free(image->file);
- free(image->cache_file);
- g_free(image);
- }
- g_slist_free(_dnbd3_images);
-
- pthread_spin_unlock(&_spinlock);
+ int fd;
+ memlogf("INFO: Cleanup...\n");
+
+ close(sock);
+ sock = -1;
+
+ dnbd3_ipc_shutdown();
+
+ pthread_spin_lock(&_spinlock);
+ GSList *iterator = NULL;
+ for (iterator = _dnbd3_clients; iterator; iterator = iterator->next)
+ {
+ dnbd3_client_t *client = iterator->data;
+ shutdown(client->sock, SHUT_RDWR);
+ pthread_join(client->thread, NULL);
+ g_free(client);
+ }
+ g_slist_free(_dnbd3_clients);
+
+
+ for (iterator = _dnbd3_images; iterator; iterator = iterator->next)
+ {
+ // save cache maps to files
+ dnbd3_image_t *image = iterator->data;
+ if (image->cache_file)
+ {
+ char tmp[strlen(image->cache_file)+4];
+ strcpy(tmp, image->cache_file);
+ strcat(tmp, ".map");
+ fd = open(tmp, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
+
+ if (fd > 0)
+ write(fd, image->cache_map, ((image->filesize + (1 << 15) - 1) >> 15) * sizeof(char));
+
+ close(fd);
+ }
+
+ free(image->cache_map);
+ free(image->config_group);
+ free(image->low_name);
+ free(image->file);
+ free(image->cache_file);
+ g_free(image);
+ }
+ g_slist_free(_dnbd3_images);
+
+ pthread_spin_unlock(&_spinlock);
#ifndef IPC_TCP
- unlink(UNIX_SOCKET);
+ unlink(UNIX_SOCKET);
#endif
- exit(EXIT_SUCCESS);
+ exit(EXIT_SUCCESS);
}
-int main(int argc, char* argv[])
+int main(int argc, char *argv[])
{
- int demonize = 1;
- int opt = 0;
- int longIndex = 0;
- static const char *optString = "f:d:nrsiHV?";
- static const struct option longOpts[] =
- {
- { "file", required_argument, NULL, 'f' },
- { "delay", required_argument, NULL, 'd' },
- { "nodaemon", no_argument, NULL, 'n' },
- { "reload", no_argument, NULL, 'r' },
- { "stop", no_argument, NULL, 's' },
- { "info", no_argument, NULL, 'i' },
- { "help", no_argument, NULL, 'H' },
- { "version", no_argument, NULL, 'V' } };
-
- opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
-
- while (opt != -1)
- {
- switch (opt)
- {
- case 'f':
- _config_file_name = strdup(optarg);
- break;
- case 'd':
+ int demonize = 1;
+ int opt = 0;
+ int longIndex = 0;
+ static const char *optString = "f:d:nrsiHV?";
+ static const struct option longOpts[] =
+ {
+ { "file", required_argument, NULL, 'f' },
+ { "delay", required_argument, NULL, 'd' },
+ { "nodaemon", no_argument, NULL, 'n' },
+ { "reload", no_argument, NULL, 'r' },
+ { "stop", no_argument, NULL, 's' },
+ { "info", no_argument, NULL, 'i' },
+ { "help", no_argument, NULL, 'H' },
+ { "version", no_argument, NULL, 'V' }
+ };
+
+ opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
+
+ while (opt != -1)
+ {
+ switch (opt)
+ {
+ case 'f':
+ _config_file_name = strdup(optarg);
+ break;
+ case 'd':
#ifdef _DEBUG
- _fake_delay = atoi(optarg);
- break;
+ _fake_delay = atoi(optarg);
+ break;
#else
- printf("This option is only available in debug builds.\n\n");
- return EXIT_FAILURE;
+ printf("This option is only available in debug builds.\n\n");
+ return EXIT_FAILURE;
#endif
- case 'n':
- demonize = 0;
- break;
- case 'r':
- printf("INFO: Reloading configuration file...\n\n");
- dnbd3_ipc_send(IPC_RELOAD);
- return EXIT_SUCCESS;
- case 's':
- printf("INFO: Stopping running server...\n\n");
- dnbd3_ipc_send(IPC_EXIT);
- return EXIT_SUCCESS;
- case 'i':
- printf("INFO: Requesting information...\n\n");
- dnbd3_ipc_send(IPC_INFO);
- return EXIT_SUCCESS;
- case 'H':
- dnbd3_print_help(argv[0]);
- break;
- case 'V':
- dnbd3_print_version();
- break;
- case '?':
- dnbd3_print_help(argv[0]);
- break;
- }
- opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
- }
-
- if (demonize)
- daemon(1, 0);
-
- pthread_spin_init(&_spinlock, PTHREAD_PROCESS_PRIVATE);
-
- initmemlog();
- memlogf("DNBD3 server starting.... Machine type: " ENDIAN_MODE);
-
- // load config file
- dnbd3_load_config();
-
- // setup signal handler
- signal(SIGPIPE, dnbd3_handle_sigpipe);
- signal(SIGTERM, dnbd3_handle_sigterm);
- signal(SIGINT, dnbd3_handle_sigterm);
-
- // setup network
- sock = dnbd3_setup_socket();
- if (sock < 0)
- exit(EXIT_FAILURE);
- struct sockaddr_in client;
- unsigned int len = sizeof(client);
- int fd;
- struct timeval timeout;
- timeout.tv_sec = SOCKET_TIMEOUT_SERVER;
- timeout.tv_usec = 0;
-
- // setup ipc
- pthread_t thread_ipc;
- pthread_create(&(thread_ipc), NULL, &dnbd3_ipc_mainloop, NULL);
-
- memlogf("[INFO] Server is ready...");
-
- // main loop
- while (1)
- {
- fd = accept(sock, (struct sockaddr*) &client, &len);
- if (fd < 0)
- {
- memlogf("[ERROR] Accept failure");
- continue;
- }
- //memlogf("INFO: Client %s connected\n", inet_ntoa(client.sin_addr));
-
- setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof(timeout));
- setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof(timeout));
-
- dnbd3_client_t *dnbd3_client = g_new0(dnbd3_client_t, 1);
- if (dnbd3_client == NULL)
- {
- memlogf("[ERROR] Could not alloc dnbd3_client_t for new client.");
- close(fd);
- continue;
- }
- // TODO: Extend this if you ever want to add IPv6 (something like:)
- // dnbd3_client->addrtype = AF_INET6;
- // memcpy(dnbd3_client->ipaddr, &(client.sin6_addr), 16);
- dnbd3_client->addrtype = AF_INET;
- memcpy(dnbd3_client->ipaddr, &(client.sin_addr), 4);
- dnbd3_client->sock = fd;
- dnbd3_client->image = NULL;
-
- // This has to be done before creating the thread, otherwise a race condition might occur when the new thread dies faster than this thread adds the client to the list after creating the thread
- pthread_spin_lock(&_spinlock);
- _dnbd3_clients = g_slist_prepend(_dnbd3_clients, dnbd3_client);
- pthread_spin_unlock(&_spinlock);
-
- if (0 != pthread_create(&(dnbd3_client->thread), NULL, dnbd3_handle_query, (void *) (uintptr_t) dnbd3_client))
- {
- memlogf("[ERROR] Could not start thread for new client.");
- pthread_spin_lock(&_spinlock);
- _dnbd3_clients = g_slist_remove(_dnbd3_clients, dnbd3_client);
- pthread_spin_unlock(&_spinlock);
- g_free(dnbd3_client);
- close(fd);
- continue;
- }
- pthread_detach(dnbd3_client->thread);
- }
-
- dnbd3_cleanup();
+ case 'n':
+ demonize = 0;
+ break;
+ case 'r':
+ printf("INFO: Reloading configuration file...\n\n");
+ dnbd3_ipc_send(IPC_RELOAD);
+ return EXIT_SUCCESS;
+ case 's':
+ printf("INFO: Stopping running server...\n\n");
+ dnbd3_ipc_send(IPC_EXIT);
+ return EXIT_SUCCESS;
+ case 'i':
+ printf("INFO: Requesting information...\n\n");
+ dnbd3_ipc_send(IPC_INFO);
+ return EXIT_SUCCESS;
+ case 'H':
+ dnbd3_print_help(argv[0]);
+ break;
+ case 'V':
+ dnbd3_print_version();
+ break;
+ case '?':
+ dnbd3_print_help(argv[0]);
+ break;
+ }
+ opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
+ }
+
+ if (demonize)
+ daemon(1, 0);
+
+ pthread_spin_init(&_spinlock, PTHREAD_PROCESS_PRIVATE);
+
+ initmemlog();
+ memlogf("DNBD3 server starting.... Machine type: " ENDIAN_MODE);
+
+ // load config file
+ dnbd3_load_config();
+
+ // setup signal handler
+ signal(SIGPIPE, dnbd3_handle_sigpipe);
+ signal(SIGTERM, dnbd3_handle_sigterm);
+ signal(SIGINT, dnbd3_handle_sigterm);
+
+ // setup network
+ sock = dnbd3_setup_socket();
+ if (sock < 0)
+ exit(EXIT_FAILURE);
+ struct sockaddr_in client;
+ unsigned int len = sizeof(client);
+ int fd;
+ struct timeval timeout;
+ timeout.tv_sec = SOCKET_TIMEOUT_SERVER;
+ timeout.tv_usec = 0;
+
+ // setup ipc
+ pthread_t thread_ipc;
+ pthread_create(&(thread_ipc), NULL, &dnbd3_ipc_mainloop, NULL);
+
+ memlogf("[INFO] Server is ready...");
+
+ // main loop
+ while (1)
+ {
+ fd = accept(sock, (struct sockaddr *) &client, &len);
+ if (fd < 0)
+ {
+ memlogf("[ERROR] Accept failure");
+ continue;
+ }
+ //memlogf("INFO: Client %s connected\n", inet_ntoa(client.sin_addr));
+
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof(timeout));
+ setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof(timeout));
+
+ dnbd3_client_t *dnbd3_client = g_new0(dnbd3_client_t, 1);
+ if (dnbd3_client == NULL)
+ {
+ memlogf("[ERROR] Could not alloc dnbd3_client_t for new client.");
+ close(fd);
+ continue;
+ }
+ // TODO: Extend this if you ever want to add IPv6 (something like:)
+ // dnbd3_client->addrtype = AF_INET6;
+ // memcpy(dnbd3_client->ipaddr, &(client.sin6_addr), 16);
+ dnbd3_client->addrtype = AF_INET;
+ memcpy(dnbd3_client->ipaddr, &(client.sin_addr), 4);
+ dnbd3_client->sock = fd;
+ dnbd3_client->image = NULL;
+
+ // This has to be done before creating the thread, otherwise a race condition might occur when the new thread dies faster than this thread adds the client to the list after creating the thread
+ pthread_spin_lock(&_spinlock);
+ _dnbd3_clients = g_slist_prepend(_dnbd3_clients, dnbd3_client);
+ pthread_spin_unlock(&_spinlock);
+
+ if (0 != pthread_create(&(dnbd3_client->thread), NULL, dnbd3_handle_query, (void *) (uintptr_t) dnbd3_client))
+ {
+ memlogf("[ERROR] Could not start thread for new client.");
+ pthread_spin_lock(&_spinlock);
+ _dnbd3_clients = g_slist_remove(_dnbd3_clients, dnbd3_client);
+ pthread_spin_unlock(&_spinlock);
+ g_free(dnbd3_client);
+ close(fd);
+ continue;
+ }
+ pthread_detach(dnbd3_client->thread);
+ }
+
+ dnbd3_cleanup();
}
diff --git a/src/server/server.h b/src/server/server.h
index 1e17048..c608066 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -41,27 +41,27 @@ typedef struct
{
char *config_group; // exact name of group in config file that represents this image
char *low_name; // full (global) name of image, lowercased for comparison, eg. "uni-freiburg/rz/ubuntu-12.04"
- int rid; // revision of provided image
- char *file; // path to image file or device
- uint64_t filesize; // size of image
- dnbd3_server_entry_t servers[NUMBER_SERVERS]; // known alt servers that also offer that image
- time_t atime; // last access time
- uint8_t *cache_map; // cache map telling which parts are locally cached
- char *cache_file; // path to local cache of image (in case the image is read from a dnbd3 device)
- char working; // whether this image is considered working. local images are "working" if the local file exists, proxied images have to have at least one working upstream server or a complete local cache file
- time_t delete_soft; // unixtime telling when this image should be deleted. if there are still clients using this image it weill be kept, but new clients requesting the image will be rejected. 0 = never
- time_t delete_hard; // unixtime telling when this image should be deleted, no matter if there are still clients connected. 0 = never
- uint8_t relayed; // TRUE if relayed from other server (needs dnbd3 client module loaded)
+ int rid; // revision of provided image
+ char *file; // path to image file or device
+ uint64_t filesize; // size of image
+ dnbd3_server_entry_t servers[NUMBER_SERVERS]; // known alt servers that also offer that image
+ time_t atime; // last access time
+ uint8_t *cache_map; // cache map telling which parts are locally cached
+ char *cache_file; // path to local cache of image (in case the image is read from a dnbd3 device)
+ char working; // whether this image is considered working. local images are "working" if the local file exists, proxied images have to have at least one working upstream server or a complete local cache file
+ time_t delete_soft; // unixtime telling when this image should be deleted. if there are still clients using this image it weill be kept, but new clients requesting the image will be rejected. 0 = never
+ time_t delete_hard; // unixtime telling when this image should be deleted, no matter if there are still clients connected. 0 = never
+ uint8_t relayed; // TRUE if relayed from other server (needs dnbd3 client module loaded)
} dnbd3_image_t;
typedef struct
{
- int sock;
- uint8_t ipaddr[16];
- uint8_t addrtype; // ip version (AF_INET or AF_INET6)
- uint8_t is_server; // TRUE if a server in proxy mode, FALSE if real client
- pthread_t thread;
- dnbd3_image_t *image;
+ int sock;
+ uint8_t ipaddr[16];
+ uint8_t addrtype; // ip version (AF_INET or AF_INET6)
+ uint8_t is_server; // TRUE if a server in proxy mode, FALSE if real client
+ pthread_t thread;
+ dnbd3_image_t *image;
} dnbd3_client_t;
typedef struct
diff --git a/src/server/utils.c b/src/server/utils.c
index dc3d6c4..ad40322 100644
--- a/src/server/utils.c
+++ b/src/server/utils.c
@@ -32,13 +32,13 @@
#include "memlog.h"
// Keep parsed config file in memory so it doesn't need to be parsed again every time it's modified
-static GKeyFile* _config_handle = NULL;
+static GKeyFile *_config_handle = NULL;
static char parse_address(char *string, uint8_t *af, uint8_t *addr, uint16_t *port);
static char is_valid_namespace(char *namespace);
static char is_valid_imagename(char *namespace);
static void strtolower(char *string);
-static dnbd3_image_t* prepare_image(char *image_name, int rid, char *image_file, char *cache_file, gchar **servers, gsize num_servers);
+static dnbd3_image_t *prepare_image(char *image_name, int rid, char *image_file, char *cache_file, gchar **servers, gsize num_servers);
static int save_config();
//static char* get_local_image_name(char *global_name);
@@ -120,8 +120,8 @@ static char is_valid_namespace(char *namespace)
while (*namespace)
{
if (*namespace != '/' && *namespace != '-' && (*namespace < 'a' || *namespace > 'z')
- && (*namespace < 'A' || *namespace > 'Z')
- && (*namespace < '0' || *namespace > '9'))
+ && (*namespace < 'A' || *namespace > 'Z')
+ && (*namespace < '0' || *namespace > '9'))
return 0;
++namespace;
}
@@ -135,11 +135,12 @@ static char is_valid_imagename(char *namespace)
if (*namespace == '\0' || *namespace == ' ')
return 0; // Invalid: Length = 0 or starting with a space
while (*namespace)
- { // Check for invalid chars
+ {
+ // Check for invalid chars
if (*namespace != '.' && *namespace != '-' && *namespace != ' '
- && *namespace != '(' && *namespace != ')'
- && (*namespace < 'a' || *namespace > 'z') && (*namespace < 'A' || *namespace > 'Z')
- && (*namespace < '0' || *namespace > '9'))
+ && *namespace != '(' && *namespace != ')'
+ && (*namespace < 'a' || *namespace > 'z') && (*namespace < 'A' || *namespace > 'Z')
+ && (*namespace < '0' || *namespace > '9'))
return 0;
++namespace;
}
@@ -148,11 +149,11 @@ static char is_valid_imagename(char *namespace)
return 1;
}
-static inline int is_same_server(const dnbd3_trusted_server_t * const a, const dnbd3_trusted_server_t * const b)
+static inline int is_same_server(const dnbd3_trusted_server_t *const a, const dnbd3_trusted_server_t *const b)
{
return (a->hostaddrtype == b->hostaddrtype)
- && (a->port == b->port)
- && (0 == memcmp(a->hostaddr, b->hostaddr, (a->hostaddrtype == AF_INET ? 4 : 16)));
+ && (a->port == b->port)
+ && (0 == memcmp(a->hostaddr, b->hostaddr, (a->hostaddrtype == AF_INET ? 4 : 16)));
}
static void strtolower(char *string)
@@ -220,6 +221,7 @@ void dnbd3_load_config()
if (strcmp(keys[j], "address") == 0)
continue;
char *flags = g_key_file_get_string(_config_handle, groups[i], keys[j], NULL);
+ g_key_file_remove_key(_config_handle, groups[i], keys[j], NULL);
dnbd3_add_trusted_namespace(server, keys[j], flags);
g_free(flags);
}
@@ -290,19 +292,19 @@ int dnbd3_add_image(dnbd3_image_t *image)
}
// Adding image was successful, write config file
- g_key_file_set_integer(_config_handle, image->config_group, "rid", image->rid);
- g_key_file_set_string(_config_handle, image->config_group, "file", image->file);
- //g_key_file_set_string(_config_handle, image->name, "servers", image->serverss); // TODO: Save servers as string
- g_key_file_set_string(_config_handle, image->config_group, "cache", image->cache_file);
-
- pthread_spin_unlock(&_spinlock);
-
- const int ret = save_config();
- if (ret == ERROR_OK)
- memlogf("[INFO] Added new image '%s' (rid %d)", newimage->config_group, newimage->rid);
- else
- memlogf("[INFO] Added new image '%s' (rid %d), but config file could not be written (%s)", newimage->config_group, newimage->rid, _config_file_name);
- return ret;
+ g_key_file_set_integer(_config_handle, image->config_group, "rid", image->rid);
+ g_key_file_set_string(_config_handle, image->config_group, "file", image->file);
+ //g_key_file_set_string(_config_handle, image->name, "servers", image->serverss); // TODO: Save servers as string
+ g_key_file_set_string(_config_handle, image->config_group, "cache", image->cache_file);
+
+ pthread_spin_unlock(&_spinlock);
+
+ const int ret = save_config();
+ if (ret == ERROR_OK)
+ memlogf("[INFO] Added new image '%s' (rid %d)", newimage->config_group, newimage->rid);
+ else
+ memlogf("[INFO] Added new image '%s' (rid %d), but config file could not be written (%s)", newimage->config_group, newimage->rid, _config_file_name);
+ return ret;
}
int dnbd3_del_image(dnbd3_image_t *image)
@@ -326,41 +328,41 @@ int dnbd3_del_image(dnbd3_image_t *image)
dnbd3_exec_delete(FALSE);
existing_image = NULL;
- const int ret = save_config();
- if (ret == ERROR_OK)
- memlogf("[INFO] Marked for deletion: '%s' (rid %d)", image->config_group, image->rid);
- else
- memlogf("[WARNING] Marked for deletion: '%s' (rid %d), but config file could not be written (%s)", image->config_group, image->rid, _config_file_name);
- return ret;
+ const int ret = save_config();
+ if (ret == ERROR_OK)
+ memlogf("[INFO] Marked for deletion: '%s' (rid %d)", image->config_group, image->rid);
+ else
+ memlogf("[WARNING] Marked for deletion: '%s' (rid %d), but config file could not be written (%s)", image->config_group, image->rid, _config_file_name);
+ return ret;
}
static int save_config()
{
pthread_spin_lock(&_spinlock);
- char* data = (char*)g_key_file_to_data(_config_handle, NULL, NULL);
- if (data == NULL)
- {
- pthread_spin_unlock(&_spinlock);
- memlogf("[ERROR] g_key_file_to_data() failed");
- return ERROR_UNSPECIFIED_ERROR;
- }
-
- FILE *f = fopen(_config_file_name, "w");
- if (f < 0)
- {
- pthread_spin_unlock(&_spinlock);
- g_free(data);
- return ERROR_CONFIG_FILE_PERMISSIONS;
- }
- fputs("# Do not edit this file while dnbd3-server is running\n", f);
- fputs(data, f);
- fclose(f);
- pthread_spin_unlock(&_spinlock);
- g_free(data);
- return 0;
+ char *data = (char *)g_key_file_to_data(_config_handle, NULL, NULL);
+ if (data == NULL)
+ {
+ pthread_spin_unlock(&_spinlock);
+ memlogf("[ERROR] g_key_file_to_data() failed");
+ return ERROR_UNSPECIFIED_ERROR;
+ }
+
+ FILE *f = fopen(_config_file_name, "w");
+ if (f < 0)
+ {
+ pthread_spin_unlock(&_spinlock);
+ g_free(data);
+ return ERROR_CONFIG_FILE_PERMISSIONS;
+ }
+ fputs("# Do not edit this file while dnbd3-server is running\n", f);
+ fputs(data, f);
+ fclose(f);
+ pthread_spin_unlock(&_spinlock);
+ g_free(data);
+ return 0;
}
-dnbd3_image_t* dnbd3_get_image(char *name_orig, int rid, const char do_lock)
+dnbd3_image_t *dnbd3_get_image(char *name_orig, int rid, const char do_lock)
{
dnbd3_image_t *result = NULL, *image;
GSList *iterator;
@@ -450,7 +452,8 @@ static dnbd3_image_t *prepare_image(char *image_name, int rid, char *image_file,
}
if (strchr(image_name, '/') == NULL)
- { // Local image, build global name
+ {
+ // Local image, build global name
image->low_name = calloc(strlen(_local_namespace) + strlen(image_name) + 2, sizeof(char));
sprintf(image->low_name, "%s/%s", _local_namespace, image_name);
}
@@ -494,14 +497,14 @@ static dnbd3_image_t *prepare_image(char *image_name, int rid, char *image_file,
if (size <= 0)
{
memlogf("[ERROR] File '%s' of image '%s' has size '%lld'. Image ignored.",
- image->file, image_name, (long long)size);
+ image->file, image_name, (long long)size);
goto error;
}
image->filesize = (uint64_t)size;
if (image->filesize & 4095)
{
memlogf("[WARNING] Size of image '%s' is not a multiple of 4096. Last incomplete block will be ignored!",
- image->file);
+ image->file);
image->filesize &= ~(uint64_t)4095;
}
close(fd);
@@ -513,7 +516,7 @@ static dnbd3_image_t *prepare_image(char *image_name, int rid, char *image_file,
for (k = 0, j = 0; j < MIN(num_servers, NUMBER_SERVERS); ++j)
{
if (parse_address(servers[j], &(image->servers[k].hostaddrtype), image->servers[k].hostaddr,
- &(image->servers[k].port)))
+ &(image->servers[k].port)))
{
++k;
continue;
@@ -533,7 +536,8 @@ static dnbd3_image_t *prepare_image(char *image_name, int rid, char *image_file,
close(fd);
}
if (image->filesize & 4095)
- { // Cache files should always be truncated to 4kib boundaries already
+ {
+ // Cache files should always be truncated to 4kib boundaries already
memlogf("[WARNING] Size of cache file '%s' is not a multiple of 4096. Something's fishy!", image->cache_file);
image->filesize = 0;
}
@@ -649,7 +653,8 @@ void dnbd3_exec_delete(int save_if_changed)
{
const dnbd3_client_t *client = client_iterator->data;
if (client->image == image)
- { // Yep, still in use, keep it
+ {
+ // Yep, still in use, keep it
delete_now = FALSE;
break;
}
diff --git a/src/server/utils.h b/src/server/utils.h
index 53dc076..e254cfd 100644
--- a/src/server/utils.h
+++ b/src/server/utils.h
@@ -47,7 +47,7 @@ int dnbd3_del_image(dnbd3_image_t *image);
void dnbd3_exec_delete(int save_if_changed);
-dnbd3_image_t* dnbd3_get_image(char *name, int rid, const char do_lock);
+dnbd3_image_t *dnbd3_get_image(char *name, int rid, const char do_lock);
dnbd3_trusted_server_t *dnbd3_get_trusted_server(char *address, char create_if_not_found);
int dnbd3_add_trusted_namespace(dnbd3_trusted_server_t *server, char *namespace, char *flags);