summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsr2012-09-19 18:05:08 +0200
committersr2012-09-19 18:05:08 +0200
commit85cb9c3e7c53ca97907d097d33ce7077cf81be64 (patch)
tree1292b3a1cd419ce092f5131579c9f7211b6996bb
parent[SERVER] Async prealloc of cache file (diff)
downloaddnbd3-85cb9c3e7c53ca97907d097d33ce7077cf81be64.tar.gz
dnbd3-85cb9c3e7c53ca97907d097d33ce7077cf81be64.tar.xz
dnbd3-85cb9c3e7c53ca97907d097d33ce7077cf81be64.zip
[SERVER] Check trust settings before replicating image or adding alt server
[SERVER] Close dnbd3 block deviced of proxy images when shutting down
-rw-r--r--src/server/helper.c7
-rw-r--r--src/server/helper.h1
-rw-r--r--src/server/job.c27
-rw-r--r--src/server/saveload.c45
-rw-r--r--src/server/saveload.h1
-rw-r--r--src/server/server.c11
6 files changed, 86 insertions, 6 deletions
diff --git a/src/server/helper.c b/src/server/helper.c
index 293fa36..c86fcb6 100644
--- a/src/server/helper.c
+++ b/src/server/helper.c
@@ -160,3 +160,10 @@ void strtolower(char *string)
++string;
}
}
+
+void remove_trailing_slash(char *string)
+{
+ char *ptr = string + strlen(string) - 1;
+ while (ptr >= string && *ptr == '/')
+ *ptr-- = '\0';
+}
diff --git a/src/server/helper.h b/src/server/helper.h
index fdcc3b5..8a50f90 100644
--- a/src/server/helper.h
+++ b/src/server/helper.h
@@ -12,6 +12,7 @@ char host_to_string(const dnbd3_host_t *host, char *target, size_t targetlen);
char is_valid_namespace(char *namespace);
char is_valid_imagename(char *namespace);
void strtolower(char *string);
+void remove_trailing_slash(char *string);
static inline int is_same_server(const dnbd3_host_t *const a, const dnbd3_host_t *const b)
{
diff --git a/src/server/job.c b/src/server/job.c
index a71c299..fc3211a 100644
--- a/src/server/job.c
+++ b/src/server/job.c
@@ -512,38 +512,53 @@ static void query_servers()
snprintf(xmlbuffer, MAX_IPC_PAYLOAD, "%s/%s", image, slash);
}
// Image seems legit, check if there's a local copy
+ dnbd3_namespace_t *trust;
pthread_spin_lock(&_spinlock);
+ if (slash == NULL)
+ trust = dnbd3_get_trust_level(&host, ns);
+ else
+ trust = dnbd3_get_trust_level(&host, image);
+ if (trust == NULL)
+ { // Namespace of image is not trusted
+ pthread_spin_unlock(&_spinlock);
+ goto free_current_image;
+ }
dnbd3_image_t *local_image = dnbd3_get_image(xmlbuffer, rid, FALSE);
- if (local_image == NULL)
+ if (local_image == NULL && trust->auto_replicate)
{
pthread_spin_unlock(&_spinlock);
// Image is NEW, add it!
// TODO: Check if replication is requested for this namespace
dnbd3_image_t newimage;
- char cachefile[70];
+ char cachefile[90];
memset(&newimage, 0, sizeof(newimage));
newimage.config_group = xmlbuffer;
newimage.rid = rid;
if (_cache_dir)
{
- newimage.cache_file = create_cache_filename(xmlbuffer, rid, cachefile, 70);
+ newimage.cache_file = create_cache_filename(xmlbuffer, rid, cachefile, 90);
printf("[DEBUG] Cache file is %s\n", newimage.cache_file);
}
dnbd3_add_image(&newimage);
pthread_spin_lock(&_spinlock);
local_image = dnbd3_get_image(xmlbuffer, rid, FALSE);
if (local_image)
- add_alt_server(local_image, &server->host);
+ add_alt_server(local_image, &host);
pthread_spin_unlock(&_spinlock);
}
- else
+ else if (local_image != NULL)
{
// Image is already KNOWN, add alt server if appropriate
// TODO: Check if requested for namespace
if (size != local_image->filesize)
printf("[DEBUG] Ignoring remote image '%s' because it has a different size from the local version!\n", local_image->config_group);
else
- add_alt_server(local_image, &server->host);
+ add_alt_server(local_image, &host);
+ pthread_spin_unlock(&_spinlock);
+ }
+ else
+ {
+ printf("[DEBUG] No NS match: '%s'\n", xmlbuffer);
pthread_spin_unlock(&_spinlock);
}
// Cleanup
diff --git a/src/server/saveload.c b/src/server/saveload.c
index 5f67b28..7dc5455 100644
--- a/src/server/saveload.c
+++ b/src/server/saveload.c
@@ -643,6 +643,7 @@ int dnbd3_add_trusted_namespace(dnbd3_trusted_server_t *server, char *namespace,
int nslen = strlen(namespace) + 1;
char nslow[nslen];
memcpy(nslow, namespace, nslen);
+ remove_trailing_slash(nslow);
strtolower(nslow);
GSList *iterator;
dnbd3_namespace_t *ns = NULL;
@@ -678,6 +679,50 @@ int dnbd3_add_trusted_namespace(dnbd3_trusted_server_t *server, char *namespace,
}
/**
+ * Gives the closest match of a namespace rule that can be applied to
+ * the given namespace
+ * Returns NULL if none
+ * !! Lock before calling this function !!
+ */
+dnbd3_namespace_t *dnbd3_get_trust_level(dnbd3_host_t *host, char *namespace)
+{
+ dnbd3_trusted_server_t *server = NULL;
+ GSList *iterator;
+ for (iterator = _trusted_servers; iterator; iterator = iterator->next)
+ {
+ dnbd3_trusted_server_t *comp = iterator->data;
+ if (!is_same_server(host, &comp->host))
+ continue;
+ server = comp;
+ break;
+ }
+ if (server == NULL)
+ return NULL;
+ dnbd3_namespace_t *best = NULL;
+ int bestlen = 0;
+ char nslow[strlen(namespace)+1];
+ strcpy(nslow, namespace);
+ remove_trailing_slash(nslow);
+ strtolower(nslow);
+ for (iterator = server->namespaces; iterator; iterator = iterator-> next)
+ {
+ dnbd3_namespace_t *comp = iterator->data;
+ const int cmplen = strlen(comp->name);
+ if (strncmp(nslow, comp->name, cmplen) != 0) // names do not match at all
+ continue;
+ if (nslow[cmplen] == '/' && !comp->recursive) // partial match, but recursion is disabled
+ continue;
+ if (nslow[cmplen] != '\0') // in mid-string
+ continue;
+ if (cmplen < bestlen) // Match is not better than one found before
+ continue;
+ bestlen = cmplen;
+ best = comp;
+ }
+ return best;
+}
+
+/**
* Return local image name for a global image name
* eg. "uni-freiburg/rz/ubuntu 12.04" -> "ubuntu 12.04"
* ONLY IF the local name space really is "uni-freiburg/rz"
diff --git a/src/server/saveload.h b/src/server/saveload.h
index 065c0b1..7436cef 100644
--- a/src/server/saveload.h
+++ b/src/server/saveload.h
@@ -53,6 +53,7 @@ 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, char *comment);
int dnbd3_add_trusted_namespace(dnbd3_trusted_server_t *server, char *namespace, char *flags);
+dnbd3_namespace_t *dnbd3_get_trust_level(dnbd3_host_t *host, char *namespace);
void dnbd3_handle_sigpipe(int signum);
void dnbd3_handle_sigterm(int signum);
diff --git a/src/server/server.c b/src/server/server.c
index b0068ce..126ac5e 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -26,6 +26,7 @@
#include <pthread.h>
#include <string.h>
#include <fcntl.h>
+#include <sys/ioctl.h>
#include "../types.h"
#include "../version.h"
@@ -113,6 +114,16 @@ void dnbd3_cleanup()
close(fd);
}
+ // Close bock devices of proxied images
+ if (image->file && strncmp(image->file, "/dev/dnbd", 9) == 0)
+ {
+ int fd = open(image->file, O_RDONLY);
+ dnbd3_ioctl_t msg;
+ memset(&msg, 0, sizeof(msg));
+ msg.len = sizeof(msg);
+ ioctl(fd, IOCTL_CLOSE, &msg);
+ close(fd);
+ }
free(image->cache_map);
free(image->config_group);