started moving to a pluggable backend
authorAndrew Tridgell <tridge@samba.org>
Mon, 25 Aug 2008 23:28:31 +0000 (09:28 +1000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 25 Aug 2008 23:28:31 +0000 (09:28 +1000)
Makefile
common.c
hacksm.h
hacksm_ls.c
hacksm_migrate.c
hacksmd.c
store.h [new file with mode: 0644]
store_file.c [new file with mode: 0644]

index 6e06659..777659b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,16 +4,18 @@ LIBS=-ldmapi
 
 all: hacksmd hacksm_migrate hacksm_ls
 
+COMMON=store_file.o common.o
+
 .c.o:
        $(CC) $(CFLAGS) -c $< -o $@
 
-hacksmd: hacksmd.o common.o
+hacksmd: hacksmd.o $(COMMON)
        $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
 
-hacksm_migrate: hacksm_migrate.o common.o
+hacksm_migrate: hacksm_migrate.o $(COMMON)
        $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
 
-hacksm_ls: hacksm_ls.o common.o
+hacksm_ls: hacksm_ls.o $(COMMON)
        $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
 
 clean: 
index fb183ad..11a7228 100644 (file)
--- a/common.c
+++ b/common.c
@@ -106,27 +106,6 @@ new_session:
 }
 
 
-int hsm_store_open(dev_t device, ino_t inode, int flags)
-{
-       char *fname = NULL;
-       asprintf(&fname, HSM_STORE "/0x%llx:0x%llx",
-                (unsigned long long)device, (unsigned long long)inode);
-       int fd = open(fname, flags, 0600);
-       free(fname);
-       return fd;
-}
-
-int hsm_store_unlink(dev_t device, ino_t inode)
-{
-       char *fname = NULL;
-       int ret;
-       asprintf(&fname, HSM_STORE "/0x%llx:0x%llx",
-                (unsigned long long)device, (unsigned long long)inode);
-       ret = unlink(fname);
-       free(fname);
-       return ret;
-}
-
 void msleep(int t)
 {
        struct timeval tval;  
index 576502d..ad65fb5 100644 (file)
--- a/hacksm.h
+++ b/hacksm.h
@@ -48,4 +48,4 @@ struct hsm_attr {
 #define HSM_MAGIC "HSM1"
 #define HSM_ATTRNAME "hacksm"
 
-#define HSM_STORE "/hacksm_store"
+#include "store.h"
index c28c314..3da5d97 100644 (file)
@@ -21,6 +21,8 @@ static struct {
        .sid = DM_NO_SESSION
 };
 
+static struct hsm_store_context *store_ctx;
+
 /*
   if we exit unexpectedly then we need to cleanup any rights we held
   by reponding to our userevent
@@ -52,6 +54,12 @@ static void hsm_init(void)
        printf("Initialised DMAPI version '%s'\n", dmapi_version);      
 
        hsm_recover_session(SESSION_NAME, &dmapi.sid);
+
+       store_ctx = hsm_store_init(void);
+       if (store_ctx == NULL) {
+               printf("Unable to open HSM store - %s\n", strerror(errno));
+               exit(1);
+       }
 }
 
 
@@ -172,13 +180,14 @@ static void hsm_ls(const char *path)
 
        /* if it is migrated then also check the store file is OK */
        if (h.state == HSM_STATE_MIGRATED) {
-               fd = hsm_store_open(h.device, h.inode, O_RDONLY);
-               if (fd == -1) {
+               struct hsm_store_handle *h;
+               h = hsm_store_open(store_ctx, h.device, h.inode, true);
+               if (h == NULL) {
                        printf("Failed to open store file for %s - %s (0x%llx:0x%llx)\n", 
                               path, strerror(errno), 
                               (unsigned long long)h.device, (unsigned long long)h.inode);
                }
-               close(fd);
+               hsm_store_close(h);
        }
 
        printf("m %7u %d  %s\n", (unsigned)h.size, (int)h.state, path);
index 653b6aa..c594a5d 100644 (file)
@@ -17,6 +17,8 @@ static struct {
 };
 
 
+static struct hsm_store_context *store_ctx;
+
 /*
   if we exit unexpectedly then we need to cleanup any rights we held
   by reponding to our userevent
@@ -49,6 +51,12 @@ static void hsm_init(void)
        printf("Initialised DMAPI version '%s'\n", dmapi_version);      
 
        hsm_recover_session(SESSION_NAME, &dmapi.sid);
+
+       store_ctx = hsm_store_init(void);
+       if (store_ctx == NULL) {
+               printf("Unable to open HSM store - %s\n", strerror(errno));
+               exit(1);
+       }
 }
 
 /*
@@ -67,7 +75,6 @@ static int hsm_migrate(const char *path)
        dm_region_t region;
        dm_boolean_t exactFlag;
        off_t ofs;
-       int fd;
        int retval = 1;
 
        dmapi.token = DM_NO_TOKEN;
@@ -151,8 +158,8 @@ static int hsm_migrate(const char *path)
        }
 
        /* open up the store file */
-       fd = hsm_store_open(st.st_dev, st.st_ino, O_CREAT|O_TRUNC|O_WRONLY);
-       if (fd == -1) {
+       h = hsm_store_open(store_ctx, st.st_dev, st.st_ino, O_CREAT|O_TRUNC|O_WRONLY);
+       if (h == NULL) {
                printf("Failed to open store file for %s - %s\n", path, strerror(errno));
                goto respond;
        }
@@ -160,9 +167,10 @@ static int hsm_migrate(const char *path)
        /* read the file data and store it away */
        ofs = 0;
        while ((ret = dm_read_invis(dmapi.sid, hanp, hlen, dmapi.token, ofs, sizeof(buf), buf)) > 0) {
-               if (write(fd, buf, ret) != ret) {
+               if (hsm_store_write(h, buf, ret) != ret) {
                        printf("Failed to write to store for %s - %s\n", path, strerror(errno));
-                       hsm_store_unlink(st.st_dev, st.st_ino);
+                       hsm_store_close(h);
+                       hsm_store_remove(store_ctx, st.st_dev, st.st_ino);
                        goto respond;
                }
                ofs += ret;
@@ -172,8 +180,7 @@ static int hsm_migrate(const char *path)
                hsm_store_unlink(st.st_dev, st.st_ino);
                goto respond;
        }
-       fsync(fd);
-       close(fd);
+       hsm_store_close(h);
 
        /* now upgrade to a exclusive right on the file before we
           change the dmattr and punch holes in the file. */
index c23522a..b46a906 100644 (file)
--- a/hacksmd.c
+++ b/hacksmd.c
@@ -25,6 +25,8 @@ static struct {
        .sid = DM_NO_SESSION
 };
 
+static struct hsm_store_context *store_ctx;
+
 #define SESSION_NAME "hacksmd"
 
 /* no special handling on terminate in hacksmd, as we want existing
@@ -48,6 +50,16 @@ static void hsm_init(void)
        int ret;
        int errcode = 0;
 
+       if (store_ctx) {
+               hsm_store_shutdown(store_ctx);
+       }
+
+       store_ctx = hsm_store_init(void);
+       if (store_ctx == NULL) {
+               printf("Unable to open HSM store - %s\n", strerror(errno));
+               exit(1);
+       }
+
        while ((ret = dm_init_service(&dmapi_version)) == -1) {
                if (errno != errcode) {
                        errcode = errno;
@@ -132,12 +144,12 @@ static void hsm_handle_recall(dm_eventmsg_t *msg)
        dm_token_t token = msg->ev_token;
        struct hsm_attr h;
        dm_boolean_t exactFlag;
-       int fd;
        char buf[0x10000];
        off_t ofs;
        dm_right_t right;
        dm_response_t response = DM_RESP_CONTINUE;
        int retcode = 0;
+       struct hsm_store_handle *h;
 
         ev = DM_GET_VALUE(msg, ev_data, dm_data_event_t *);
         hanp = DM_GET_VALUE(ev, de_handle, void *);
@@ -212,10 +224,11 @@ static void hsm_handle_recall(dm_eventmsg_t *msg)
 
        /* get the migrated data from the store, and put it in the
           file with invisible writes */
-       fd = hsm_store_open(h.device, h.inode, O_RDONLY);
-       if (fd == -1) {
-               printf("Failed to open store file for file 0x%llx:0x%llx\n",
-                      (unsigned long long)h.device, (unsigned long long)h.inode);
+       h = hsm_store_open(store_ctx, h.device, h.inode, O_RDONLY);
+       if (h == NULL) {
+               printf("Failed to open store file for file 0x%llx:0x%llx - %s\n",
+                      (unsigned long long)h.device, (unsigned long long)h.inode,
+                      strerror(errno));
                retcode = EIO;
                response = DM_RESP_ABORT;
                goto done;
@@ -234,7 +247,7 @@ static void hsm_handle_recall(dm_eventmsg_t *msg)
        }
 
        ofs = 0;
-       while ((ret = read(fd, buf, sizeof(buf))) > 0) {
+       while ((ret = hsm_store_read(h, buf, sizeof(buf))) > 0) {
                int ret2 = dm_write_invis(dmapi.sid, hanp, hlen, token, DM_WRITE_SYNC, ofs, ret, buf);
                if (ret2 != ret) {
                        printf("dm_write_invis failed - %s\n", strerror(errno));
@@ -244,7 +257,7 @@ static void hsm_handle_recall(dm_eventmsg_t *msg)
                }
                ofs += ret;
        }
-       close(fd);
+       hsm_store_close(h);
 
        /* remove the attribute from the file - it is now fully recalled */
        ret = dm_remove_dmattr(dmapi.sid, hanp, hlen, token, 0, &attrname);
@@ -256,7 +269,7 @@ static void hsm_handle_recall(dm_eventmsg_t *msg)
        }
 
        /* remove the store file */
-       ret = hsm_store_unlink(h.device, h.inode);
+       ret = hsm_store_remove(store_ctx, h.device, h.inode);
        if (ret != 0) {
                printf("WARNING: Failed to unlink store file\n");
        }
@@ -359,7 +372,7 @@ static void hsm_handle_destroy(dm_eventmsg_t *msg)
        }
 
        /* remove the store file */
-       ret = hsm_store_unlink(h.device, h.inode);
+       ret = hsm_store_remove(store_ctx, h.device, h.inode);
        if (ret == -1) {
                printf("WARNING: Failed to unlink store file for file 0x%llx:0x%llx\n",
                       (unsigned long long)h.device, (unsigned long long)h.inode);
diff --git a/store.h b/store.h
new file mode 100644 (file)
index 0000000..b3c6926
--- /dev/null
+++ b/store.h
@@ -0,0 +1,34 @@
+/*
+  header for HSM store backends
+ */
+
+/*
+  initialise the link to the HSM store
+ */
+struct hsm_store_context *hsm_store_init(void);
+
+/* 
+   open a file handle in the HSM store
+ */
+struct hsm_store_handle *hsm_store_open(struct hsm_store_context *,
+                                       dev_t device, ino_t inode, bool readonly);
+
+/*
+  read from an open handle
+ */
+size_t hsm_store_read(struct hsm_store_handle *, uint8_t *buf, size_t n);
+
+/* 
+   write to an open handle
+ */
+size_t hsm_store_write(struct hsm_store_handle *, uint8_t *buf, size_t n);
+
+/* 
+   close a handle
+ */
+int hsm_store_close(struct hsm_store_handle *);
+
+/* 
+   shutdown the link to the store
+ */
+void hsm_store_shutdown(struct hsm_store_context *);
diff --git a/store_file.c b/store_file.c
new file mode 100644 (file)
index 0000000..6b84ffc
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+  HSM store backend
+
+  Andrew Tridgell August 2008
+
+ */
+
+#include "hacksm.h"
+
+#define HSM_STORE_PATH "/hacksm_store"
+
+struct hsm_store_context {
+       const char *basepath;
+};
+
+struct hsm_store_handle {
+       struct hsm_store_context *ctx;
+       int fd;
+       bool readonly;
+};
+
+/*
+  initialise the link to the store
+ */
+struct hsm_store_context *hsm_store_init(void)
+{
+       struct hsm_store_context *ctx;
+       struct stat st;
+
+       ctx = malloc(sizeof(struct hsm_store_context));
+       if (ctx == NULL) {
+               errno = ENOMEM;
+               return NULL;
+       }
+
+       ctx->basepath = HSM_STORE;
+       if (stat(ctx->basepath, &st) != 0 ||
+           !S_ISDIR(st.st_mode)) {
+               errno = EINVAL;
+               free(ctx);
+               return NULL;
+       }
+
+       return ctx;
+}
+
+/*
+  shutdown the link to the store
+ */
+void hsm_store_shutdown(struct hsm_store_context *ctx)
+{
+       ctx->basepath = NULL;
+       free(ctx);
+}
+
+/*
+  return a filename in the store
+ */
+static char *store_fname(struct hsm_store_context *ctx, dev_t device, ino_t inode)
+{
+       char *fname = NULL;
+       asprintf(&fname, "%s/0x%llx:0x%llx",
+                ctx->basepath,
+                (unsigned long long)device, (unsigned long long)inode);
+       if (fname == NULL) {
+               errno = ENOMEM;
+               return NULL;
+       }
+       return fname;
+}
+
+/*
+  open a file in the store
+ */
+struct hsm_store_handle *hsm_store_open(struct hsm_store_context *ctx,
+                                       dev_t device, ino_t inode, bool readonly)
+{
+       struct hsm_store_handle *h;
+       char *fname = NULL;
+
+       fname = store_fname(ctx, device, inode);
+       if (fname == NULL) {
+               return NULL;
+       }
+
+       h = malloc(sizeof(struct hsm_store_handle));
+       if (h == NULL) {
+               errno = ENOMEM;
+               free(fname);
+               return NULL;
+       }
+
+       h->ctx = ctx;
+       h->readonly = readonly;
+
+       if (readonly) {
+               h->fd = open(fname, O_RDONLY);
+       } else {
+               h->fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0600);
+       }
+
+       free(fname);
+
+       if (h->fd == -1) {
+               free(h);
+               return NULL;
+       }
+
+       return h;
+}
+
+/*
+  remove a file from the store
+ */
+int hsm_store_remove(struct hsm_store_context *ctx,
+                    dev_t device, ino_t inode)
+{
+       char *fname;
+       int ret;
+
+       fname = store_fname(ctx, device, inode);
+       if (fname == NULL) {
+               return -1;
+       }
+       ret = unlink(fname);
+       free(fname);
+       return ret;
+}
+
+
+/*
+  read from a stored file
+ */
+size_t hsm_store_read(struct hsm_store_handle *h, uint8_t *buf, size_t n)
+{
+       return read(h->fd, buf, n);
+}
+
+/*
+  write to a stored file
+ */
+size_t hsm_store_write(struct hsm_store_handle *h, uint8_t *buf, size_t n)
+{
+       return write(h->fd, buf, n);
+}
+
+/*
+  close a store file
+ */
+int hsm_store_close(struct hsm_store_handle *h)
+{
+       int ret;
+       
+       if (!h->readonly) {
+               fsync(h->fd);
+       }
+       ret = close(h->fd);
+       h->fd = -1;
+       free(h);
+       return ret;
+}