summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
authorsr2012-09-01 18:08:27 +0200
committersr2012-09-01 18:08:27 +0200
commit3e992e066c6aeb3972758a2304cccbdba024c31e (patch)
treeb7d31b75002d5b6edd3c18b884eebf08346828ac /src/server
parent[SERVER] Added soft and hard timeouts for image deletion: reject any new clie... (diff)
downloaddnbd3-3e992e066c6aeb3972758a2304cccbdba024c31e.tar.gz
dnbd3-3e992e066c6aeb3972758a2304cccbdba024c31e.tar.xz
dnbd3-3e992e066c6aeb3972758a2304cccbdba024c31e.zip
[KERNEL] Tell server whether we're a client or a server in proxy mode
[KERNEL] SysFS: Return empty string for current_server if not connected [SERVER] Code refactoring
Diffstat (limited to 'src/server')
-rw-r--r--src/server/ipc.c32
-rw-r--r--src/server/net.c8
-rw-r--r--src/server/server.c16
-rw-r--r--src/server/server.h13
-rw-r--r--src/server/utils.c62
5 files changed, 78 insertions, 53 deletions
diff --git a/src/server/ipc.c b/src/server/ipc.c
index ebc907b..37ca36f 100644
--- a/src/server/ipc.c
+++ b/src/server/ipc.c
@@ -364,7 +364,8 @@ static int ipc_receive(int client_sock)
GSList *iterator = NULL;
struct tm *timeinfo;
- char time_buff[64], rid[20], ipaddr[100];
+#define STRBUFLEN 100
+ char strbuffer[STRBUFLEN];
dnbd3_ipc_t header;
@@ -428,18 +429,27 @@ static int ipc_receive(int client_sock)
for (iterator = _dnbd3_images; iterator; iterator = iterator->next)
{
const dnbd3_image_t *image = iterator->data;
- sprintf(rid, "%d", image->rid);
- timeinfo = localtime(&image->atime);
- strftime(time_buff, 64, "%d.%m.%y %H:%M:%S", timeinfo);
tmp_node = xmlNewNode(NULL, BAD_CAST "image");
if (tmp_node == NULL)
goto get_info_reply_cleanup;
xmlNewProp(tmp_node, BAD_CAST "name", BAD_CAST image->config_group);
- xmlNewProp(tmp_node, BAD_CAST "atime", BAD_CAST time_buff);
- xmlNewProp(tmp_node, BAD_CAST "rid", BAD_CAST rid);
+ timeinfo = localtime(&image->atime);
+ strftime(strbuffer, STRBUFLEN, "%d.%m.%y %H:%M:%S", timeinfo);
+ xmlNewProp(tmp_node, BAD_CAST "atime", BAD_CAST strbuffer);
+ sprintf(strbuffer, "%d", image->rid);
+ xmlNewProp(tmp_node, BAD_CAST "rid", BAD_CAST strbuffer);
xmlNewProp(tmp_node, BAD_CAST "file", BAD_CAST image->file);
- xmlNewProp(tmp_node, BAD_CAST "servers", BAD_CAST "???");
- xmlNewProp(tmp_node, BAD_CAST "cache", BAD_CAST image->cache_file);
+ xmlNewProp(tmp_node, BAD_CAST "servers", BAD_CAST "???"); // TODO
+ if (image->cache_file && image->cache_map)
+ {
+ xmlNewProp(tmp_node, BAD_CAST "cachefile", BAD_CAST image->cache_file);
+ int i, complete = 0, size = IMGSIZE_TO_MAPBYTES(image->filesize);
+ for (i = 0; i < size; ++i)
+ if (image->cache_map[i])
+ complete += 100;
+ sprintf(strbuffer, "%d", complete / size);
+ xmlNewProp(tmp_node, BAD_CAST "cachefill", BAD_CAST image->cache_file);
+ }
xmlAddChild(images_node, tmp_node);
}
// Clients
@@ -455,9 +465,9 @@ static int ipc_receive(int client_sock)
tmp_node = xmlNewNode(NULL, BAD_CAST "client");
if (tmp_node == NULL)
goto get_info_reply_cleanup;
- *ipaddr = '\0';
- inet_ntop(client->addrtype, client->ipaddr, ipaddr, 100);
- xmlNewProp(tmp_node, BAD_CAST "ip", BAD_CAST ipaddr);
+ *strbuffer = '\0';
+ inet_ntop(client->addrtype, client->ipaddr, strbuffer, STRBUFLEN);
+ xmlNewProp(tmp_node, BAD_CAST "ip", BAD_CAST strbuffer);
xmlNewProp(tmp_node, BAD_CAST "file", BAD_CAST client->image->file);
xmlAddChild(clients_node, tmp_node);
}
diff --git a/src/server/net.c b/src/server/net.c
index b1a7b20..37ac0b4 100644
--- a/src/server/net.c
+++ b/src/server/net.c
@@ -160,6 +160,7 @@ void *dnbd3_handle_query(void *dnbd3_client)
client_version = serializer_get_uint16(&payload);
image_name = serializer_get_string(&payload);
rid = serializer_get_uint16(&payload);
+ client->is_server = serializer_get_uint8(&payload);
if (request.size < 3 || !image_name || client_version < MIN_SUPPORTED_CLIENT)
{
if (client_version < MIN_SUPPORTED_CLIENT)
@@ -208,7 +209,8 @@ void *dnbd3_handle_query(void *dnbd3_client)
else
{
client->image = image;
- image->atime = time(NULL); // TODO: check if mutex is needed
+ if (!client->is_server)
+ image->atime = time(NULL); // TODO: check if mutex is needed
if (image->cache_map && image->cache_file)
image_cache = open(image->cache_file, O_RDWR);
@@ -288,8 +290,8 @@ void *dnbd3_handle_query(void *dnbd3_client)
// first make sure the whole requested part is in the local cache file
while(cur_offset < last_offset)
{
- map_y = cur_offset >> 15;
- map_x = (cur_offset >> 12) & 7; // mod 256
+ 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;
diff --git a/src/server/server.c b/src/server/server.c
index 28da0ae..1ca55fa 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -52,16 +52,16 @@ void dnbd3_print_help(char* argv_0)
{
printf("Usage: %s [OPTIONS]...\n", argv_0);
printf("Start the DNBD3 server\n");
- printf("-f or --file \t\t Configuration file (default /etc/dnbd3-server.conf)\n");
+ printf("-f or --file Configuration file (default /etc/dnbd3-server.conf)\n");
#ifdef _DEBUG
- printf("-d or --delay \t\t 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 \t Start server in foreground\n");
- printf("-r or --reload \t\t Reload configuration file\n");
- printf("-s or --stop \t\t Stop running dnbd3-server\n");
- printf("-i or --info \t\t Print connected clients and used images\n");
- printf("-H or --help \t\t Show this help text and quit\n");
- printf("-V or --version \t Show version and quit\n");
+ 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);
}
diff --git a/src/server/server.h b/src/server/server.h
index 90aae5c..832777e 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -28,6 +28,15 @@
#include "../config.h"
#include "../types.h"
+// one byte in the map covers 8 4kib blocks, so 32kib per byte
+// "+ (1 << 15) - 1" is required to account for the last bit of
+// the image that is smaller than 32kib
+// this would be the case whenever the image file size is not a
+// multiple of 32kib (= the number of blocks is not divisible by 8)
+// ie: if the image is 49152 bytes and you do 49152 >> 15 you get 1,
+// but you actually need 2 bytes to have a complete cache map
+#define IMGSIZE_TO_MAPBYTES(bytes) ((int)(((bytes) + (1 << 15) - 1) >> 15))
+
typedef struct
{
char *config_group; // exact name of group in config file that represents this image
@@ -42,13 +51,15 @@ typedef struct
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 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;
diff --git a/src/server/utils.c b/src/server/utils.c
index 665d96d..391992d 100644
--- a/src/server/utils.c
+++ b/src/server/utils.c
@@ -438,9 +438,9 @@ static dnbd3_image_t *prepare_image(char *image_name, int rid, char *image_file,
image->config_group = strdup(image_name);
image->rid = rid;
- const char relayed = (image_file == NULL || image_file == '\0');
+ image->relayed = (image_file == NULL || image_file == '\0');
- if (relayed) // Image is relayed (this server acts as proxy)
+ if (image->relayed) // Image is relayed (this server acts as proxy)
{
if (strchr(image_name, '/') == NULL)
{
@@ -508,45 +508,47 @@ static dnbd3_image_t *prepare_image(char *image_name, int rid, char *image_file,
}
else if (image->filesize > 0)
{
- const size_t map_len_bytes = (image->filesize + (1 << 15) - 1) >> 15;
+ const size_t map_len_bytes = IMGSIZE_TO_MAPBYTES(image->filesize);
image->cache_map = calloc(map_len_bytes, sizeof(uint8_t));
// read cache map from file
- // one byte in the map covers 8 4kib blocks, so 32kib per byte
- // "+ (1 << 15) - 1" is required to account for the last bit of
- // the image that is smaller than 32kib
- // this would be the case whenever the image file size is not a
- // multiple of 32kib (= the number of blocks is not divisible by 8)
- // ie: if the image is 49152 bytes and you do 49152 >> 15 you get 1,
- // but you actually need 2 bytes to have a complete cache map
char tmp[strlen(image->cache_file) + 5];
strcpy(tmp, image->cache_file);
strcat(tmp, ".map");
- fd = open(tmp, O_RDONLY); // TODO: Check if map file has expected size
+ fd = open(tmp, O_RDONLY);
if (fd >= 0)
{
- read(fd, image->cache_map, map_len_bytes * sizeof(uint8_t));
- close(fd);
- // If the whole image is cached, mark it as working right away without waiting for an upstream server
- image->working = 1;
- for (j = 0; j < map_len_bytes - 1; ++j)
+ const off_t size = lseek(fd, 0, SEEK_END);
+ if (size != map_len_bytes)
{
- if (image->cache_map[j] != 0xFF)
+ memlogf("[DEBUG] Cache-Map of %s is corrupted (%d != %d)", image_name, (int)size, (int)map_len_bytes);
+ }
+ else
+ {
+ lseek(fd, 0, SEEK_SET);
+ read(fd, image->cache_map, map_len_bytes);
+ // If the whole image is cached, mark it as working right away without waiting for an upstream server
+ image->working = 1;
+ for (j = 0; j < map_len_bytes - 1; ++j)
{
- image->working = 0;
- break;
+ if (image->cache_map[j] != 0xFF)
+ {
+ image->working = 0;
+ break;
+ }
}
+ const int blocks_in_last_byte = (image->filesize >> 12) & 7;
+ uint8_t last_byte = 0;
+ if (blocks_in_last_byte == 0)
+ last_byte = 0xFF;
+ else
+ for (j = 0; j < blocks_in_last_byte; ++j)
+ last_byte |= (1 << j);
+ if ((image->cache_map[map_len_bytes - 1] & last_byte) != last_byte)
+ image->working = 0;
+ else
+ memlogf("[INFO] Instantly publishing relayed image '%s' because the local cache copy is complete", image_name);
}
- const int blocks_in_last_byte = (image->filesize >> 12) & 7;
- uint8_t last_byte = 0;
- if (blocks_in_last_byte == 0)
- last_byte = 0xFF;
- else
- for (j = 0; j < blocks_in_last_byte; ++j)
- last_byte = (last_byte << 1) | 1;
- if ((image->cache_map[map_len_bytes - 1] & last_byte) != last_byte)
- image->working = 0;
- else
- memlogf("[INFO] Instantly publishing relayed image '%s' because the local cache copy is complete", image_name);
+ close(fd);
}
/*