This patch add a config file to the Sheepdog store directory, and save
Sheepdog cluster info to it instead of extended attributes.  We need
to update a config file atomically, so we use journaling for the write
operations.

Signed-off-by: MORITA Kazutaka <[email protected]>
---
 sheep/store.c |  126 +++++++++++++++++++++++++++-----------------------------
 1 files changed, 61 insertions(+), 65 deletions(-)

diff --git a/sheep/store.c b/sheep/store.c
index 8eb2d5b..3da5713 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -24,13 +24,17 @@
 
 #include "sheep_priv.h"
 
-#define ANAME_CTIME "user.sheepdog.ctime"
-#define ANAME_COPIES "user.sheepdog.copies"
+struct sheepdog_config {
+       uint64_t ctime;
+       uint32_t copies;
+       uint32_t flags;
+};
 
 static char *obj_path;
 static char *epoch_path;
 static char *mnt_path;
 static char *jrnl_path;
+static char *config_path;
 
 static mode_t def_dmode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | 
S_IXGRP;
 static mode_t def_fmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
@@ -538,7 +542,7 @@ int read_object_local(uint64_t oid, char *data, unsigned 
int datalen,
 
 static int store_queue_request_local(struct request *req, uint32_t epoch)
 {
-       int fd = -1, copies;
+       int fd = -1;
        int ret = SD_RES_SUCCESS;
        struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
        struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&req->rp;
@@ -575,14 +579,6 @@ static int store_queue_request_local(struct request *req, 
uint32_t epoch)
                        goto out;
                }
 
-               ret = fsetxattr(fd, ANAME_COPIES, &hdr->copies,
-                               sizeof(hdr->copies), 0);
-               if (ret) {
-                       eprintf("use 'user_xattr' option?\n");
-                       ret = SD_RES_SYSTEM_ERROR;
-                       goto out;
-               }
-
                if (hdr->flags & SD_FLAG_CMD_COW) {
                        dprintf("%" PRIu64 ", %" PRIx64 "\n", oid, 
hdr->cow_oid);
 
@@ -648,17 +644,6 @@ static int store_queue_request_local(struct request *req, 
uint32_t epoch)
                }
                break;
        case SD_OP_READ_OBJ:
-               /*
-                * TODO: should be optional (we can use the flags) for
-                * performance; qemu doesn't always need the copies.
-                */
-               copies = 0;
-               ret = fgetxattr(fd, ANAME_COPIES, &copies, sizeof(copies));
-               if (ret != sizeof(copies)) {
-                       ret = SD_RES_SYSTEM_ERROR;
-                       goto out;
-               }
-
                ret = pread64(fd, req->data, hdr->data_length, hdr->offset);
                if (ret < 0) {
                        ret = SD_RES_EIO;
@@ -666,7 +651,7 @@ static int store_queue_request_local(struct request *req, 
uint32_t epoch)
                }
 
                rsp->data_length = ret;
-               rsp->copies = copies;
+               rsp->copies = sys->nr_sobjs;
 
                ret = SD_RES_SUCCESS;
                break;
@@ -1002,15 +987,18 @@ int set_cluster_ctime(uint64_t ctime)
 {
        int fd, ret;
 
-       fd = open(epoch_path, O_RDONLY);
+       fd = open(config_path, O_SYNC | O_WRONLY);
        if (fd < 0)
                return -1;
 
-       ret = fsetxattr(fd, ANAME_CTIME, &ctime, sizeof(ctime), 0);
+       ret = jrnl_perform(fd, &ctime, sizeof(ctime),
+                          offsetof(struct sheepdog_config, ctime),
+                          config_path, jrnl_path);
        close(fd);
 
        if (ret)
                return -1;
+
        return 0;
 }
 
@@ -1019,11 +1007,12 @@ uint64_t get_cluster_ctime(void)
        int fd, ret;
        uint64_t ctime;
 
-       fd = open(epoch_path, O_RDONLY);
+       fd = open(config_path, O_RDONLY);
        if (fd < 0)
                return 0;
 
-       ret = fgetxattr(fd, ANAME_CTIME, &ctime, sizeof(ctime));
+       ret = pread64(fd, &ctime, sizeof(ctime),
+                     offsetof(struct sheepdog_config, ctime));
        close(fd);
 
        if (ret != sizeof(ctime))
@@ -1319,13 +1308,6 @@ next:
                        goto err;
                }
 
-               ret = fsetxattr(fd, ANAME_COPIES, &rsp->copies,
-                               sizeof(rsp->copies), 0);
-               if (ret) {
-                       eprintf("couldn't set xattr\n");
-                       goto err;
-               }
-
                close(fd);
 
                dprintf("rename %s to %s\n", tmp_path, path);
@@ -1849,35 +1831,6 @@ again:
        return 0;
 }
 
-
-static int attr(char *path, const char *name, void *var, int len, int set)
-{
-       int ret, fd;
-
-       fd = open(path, O_RDONLY);
-       if (fd < 0)
-               return SD_RES_EIO;
-
-       if (set)
-               ret = fsetxattr(fd, name, var, len, 0);
-       else
-               ret = fgetxattr(fd, name, var, len);
-
-       close(fd);
-
-       if (set) {
-               if (ret) {
-                       eprintf("use 'user_xattr' option?, %s\n", name);
-                       return SD_RES_SYSTEM_ERROR;
-               }
-       } else {
-               if (ret != len)
-                       return SD_RES_SYSTEM_ERROR;
-       }
-
-       return SD_RES_SUCCESS;
-}
-
 int init_base_path(const char *d)
 {
        int new = 0;
@@ -2006,6 +1959,18 @@ static int init_jrnl_path(const char *base_path)
        return 0;
 }
 
+#define CONFIG_PATH "/config"
+
+static int init_config_path(const char *base_path)
+{
+       config_path = zalloc(strlen(base_path) + strlen(CONFIG_PATH) + 1);
+       sprintf(config_path, "%s" CONFIG_PATH, base_path);
+
+       mknod(config_path, def_fmode, S_IFREG);
+
+       return 0;
+}
+
 int init_store(const char *d)
 {
        int ret;
@@ -2026,6 +1991,10 @@ int init_store(const char *d)
        if (ret)
                return ret;
 
+       ret = init_config_path(d);
+       if (ret)
+               return ret;
+
        return ret;
 }
 
@@ -2051,10 +2020,37 @@ int read_epoch(uint32_t *epoch, uint64_t *ctime,
 
 int set_global_nr_copies(uint32_t copies)
 {
-       return attr(epoch_path, ANAME_COPIES, &copies, sizeof(copies), 1);
+       int fd, ret;
+
+       fd = open(config_path, O_SYNC | O_WRONLY);
+       if (fd < 0)
+               return SD_RES_EIO;
+
+       ret = jrnl_perform(fd, &copies, sizeof(copies),
+                          offsetof(struct sheepdog_config, copies),
+                          config_path, jrnl_path);
+       close(fd);
+
+       if (ret != 0)
+               return SD_RES_EIO;
+
+       return SD_RES_SUCCESS;
 }
 
 int get_global_nr_copies(uint32_t *copies)
 {
-       return attr(epoch_path, ANAME_COPIES, copies, sizeof(*copies), 0);
+       int fd, ret;
+
+       fd = open(config_path, O_RDONLY);
+       if (fd < 0)
+               return SD_RES_EIO;
+
+       ret = pread64(fd, copies, sizeof(*copies),
+                     offsetof(struct sheepdog_config, copies));
+       close(fd);
+
+       if (ret != sizeof(*copies))
+               return SD_RES_EIO;
+
+       return SD_RES_SUCCESS;
 }
-- 
1.7.2.5

-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to