summaryrefslogtreecommitdiffstats
path: root/glfs-operations.c
diff options
context:
space:
mode:
authorPrasanna Kumar Kalever <prasanna.kalever@redhat.com>2017-01-25 16:09:12 +0530
committerPrasanna Kumar Kalever <prasanna.kalever@redhat.com>2017-01-30 19:31:50 +0530
commitd65f7b890a2554c9e3d0cafdb58ac257d4f26ab3 (patch)
tree32fb92ab62279ea56e1ada3d496b950d467b4cbc /glfs-operations.c
parentb58e4765ed7e232f638ceb764b8ef1210bb43ff9 (diff)
gluster-blockd: implement transaction framework
This patch introduce the transaction locking also, start maintaining meta data journaling per block Every request is follows transaction, at the start of any transaction we take blocking lock on "/block-meta/meta.lock" file and at the end we unlock. Meanwhile while, when the transaction is in progress we do journaling, while performing series of operations, used for future purposes and roll backing. A sample journal file looks like: $ cat /mnt/block-meta/LUN1 GBID: xyz-abc SIZE : 5GiB HA: 3 ENTRYCREATE: INPROGRESS ENTRYCREATE: SUCCESS NODE1: INPROGRESS NODE2: INPROGRESS NODE3: INPROGRESS NODE2: SUCCESS NODE3: FAIL NODE1: SUCCESS NODE4: INPROGRESS NODE4: SUCCESS NODE3: CLEANUPSUCCESS <EOF> Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
Diffstat (limited to 'glfs-operations.c')
-rw-r--r--glfs-operations.c189
1 files changed, 163 insertions, 26 deletions
diff --git a/glfs-operations.c b/glfs-operations.c
index 7f76b23..5b99045 100644
--- a/glfs-operations.c
+++ b/glfs-operations.c
@@ -9,28 +9,24 @@
*/
-# include "utils.h"
+# include "common.h"
# include "glfs-operations.h"
-# define LOG_FILE "/var/log/gluster-block/block.log"
-# define LOG_LEVEL 7
-
-int
-glusterBlockCreateEntry(blockCreateCli *blk, char *gbid)
+struct glfs *
+glusterBlockVolumeInit(char *volume, char *volfileserver)
{
struct glfs *glfs;
- struct glfs_fd *fd;
int ret = 0;
- glfs = glfs_new(blk->volume);
+ glfs = glfs_new(volume);
if (!glfs) {
ERROR("%s", "glfs_new: returned NULL");
- return -1;
+ return NULL;
}
- ret = glfs_set_volfile_server(glfs, "tcp", blk->volfileserver, 24007);
+ ret = glfs_set_volfile_server(glfs, "tcp", volfileserver, 24007);
if (ret) {
ERROR("%s", "glfs_set_volfile_server: failed");
goto out;
@@ -48,6 +44,27 @@ glusterBlockCreateEntry(blockCreateCli *blk, char *gbid)
goto out;
}
+ return glfs;
+
+ out:
+ glfs_fini(glfs);
+ return NULL;
+}
+
+
+int
+glusterBlockCreateEntry(blockCreateCli *blk, char *gbid)
+{
+ struct glfs *glfs;
+ struct glfs_fd *fd;
+ int ret = -1;
+
+ glfs = glusterBlockVolumeInit(blk->volume, blk->volfileserver);
+ if (!glfs) {
+ ERROR("%s", "glusterBlockVolumeInit: failed");
+ goto out;
+ }
+
fd = glfs_creat(glfs, gbid,
O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR);
@@ -77,39 +94,159 @@ int
glusterBlockDeleteEntry(blockCreate *blk)
{
struct glfs *glfs;
- int ret = 0;
+ int ret = -1;
- glfs = glfs_new(blk->volume);
+ glfs = glusterBlockVolumeInit(blk->volume, blk->volfileserver);
if (!glfs) {
- ERROR("%s", "glfs_new: returned NULL");
- return -1;
+ ERROR("%s", "glusterBlockVolumeInit: failed");
+ goto out;
}
- ret = glfs_set_volfile_server(glfs, "tcp", blk->volfileserver, 24007);
+ ret = glfs_unlink(glfs, blk->gbid);
if (ret) {
- ERROR("%s", "glfs_set_volfile_server: failed");
+ ERROR("%s", "glfs_unlink: failed");
goto out;
}
- ret = glfs_set_logging(glfs, LOG_FILE, LOG_LEVEL);
- if (ret) {
- ERROR("%s", "glfs_set_logging: failed");
+ out:
+ glfs_fini(glfs);
+ return ret;
+}
+
+
+struct glfs_fd *
+glusterBlockCreateMetaLockFile(struct glfs *glfs)
+{
+ struct glfs_fd *lkfd;
+ int ret;
+
+ ret = glfs_mkdir (glfs, "/block-meta", 0);
+ if (ret && errno != EEXIST) {
+ ERROR("%s", "glfs_mkdir: failed");
goto out;
}
- ret = glfs_init(glfs);
+ ret = glfs_chdir (glfs, "/block-meta");
if (ret) {
- ERROR("%s", "glfs_init: failed");
+ ERROR("%s", "glfs_chdir: failed");
goto out;
}
- ret = glfs_unlink(glfs, blk->gbid);
- if (ret) {
- ERROR("%s", "glfs_unlink: failed");
+ lkfd = glfs_creat(glfs, "meta.lock", O_RDWR, S_IRUSR | S_IWUSR);
+ if (!lkfd) {
+ ERROR("%s", "glfs_creat: failed");
goto out;
}
+ return lkfd;
+
out:
- glfs_fini(glfs);
- return ret;
+ return NULL;
+}
+
+
+static int
+blockEnumParse(const char *opt)
+{
+ int i;
+
+ if (!opt) {
+ return METAKEY__MAX;
+ }
+
+ for (i = 0; i < METAKEY__MAX; i++) {
+ if (!strcmp(opt, MetakeyLookup[i])) {
+ return i;
+ }
+ }
+
+ return i;
+}
+
+void
+blockFreeMetaInfo(MetaInfo *info)
+{
+ int i;
+
+ for (i = 0; i< info->nhosts; i++)
+ GB_FREE(info->list[i]);
+
+ GB_FREE(info->list);
+ GB_FREE(info);
+}
+
+static void
+blockStuffMetaInfo(MetaInfo *info, char *line)
+{
+ char* tmp = strdup(line);
+ char* opt = strtok(tmp,":");
+ int Flag = 0;
+ size_t i;
+
+ switch (blockEnumParse(opt)) {
+ case GBID:
+ strcpy(info->gbid, strchr(line, ' ')+1);
+ break;
+ case SIZE:
+ sscanf(strchr(line, ' ')+1, "%zu", &info->size);
+ break;
+ case HA:
+ sscanf(strchr(line, ' ')+1, "%zu", &info->mpath);
+ break;
+ case ENTRYCREATE:
+ strcpy(info->entry, strchr(line, ' ')+1);
+ break;
+
+ default:
+ if(!info->list) {
+ if(GB_ALLOC(info->list) < 0)
+ return;
+ if(GB_ALLOC(info->list[0]) < 0)
+ return;
+ strcpy(info->list[0]->addr, opt);
+ strcpy(info->list[0]->status, strchr(line, ' ')+1);
+ info->nhosts = 1;
+ } else {
+ for (i = 0; i < info->nhosts; i++) {
+ if(!strcmp(info->list[i]->addr, opt)) {
+ strcpy(info->list[i]->status, strchr(line, ' ')+1);
+ Flag = 1;
+ break;
+ }
+ }
+ if (!Flag) {
+ if(GB_ALLOC(info->list[info->nhosts]) < 0)
+ return;
+ strcpy(info->list[info->nhosts]->addr, opt);
+ strcpy(info->list[info->nhosts]->status, strchr(line, ' ')+1);
+ info->nhosts++;
+ }
+ }
+ break;
+ }
+
+ GB_FREE(tmp);
+}
+
+void
+blockGetMetaInfo(struct glfs* glfs, char* metafile, MetaInfo *info)
+{
+ size_t count = 0;
+ struct glfs_fd *tgfd;
+ char line[48];
+ char *tmp;
+
+ tgfd = glfs_open(glfs, metafile, O_RDWR);
+ if (!tgfd) {
+ ERROR("%s", "glfs_open failed");
+ }
+
+ while (glfs_read (tgfd, line, 48, 0) > 0) {
+ tmp = strtok(line,"\n");
+ count += strlen(tmp) + 1;
+ blockStuffMetaInfo(info, tmp);
+ glfs_lseek(tgfd, count, SEEK_SET);
+ }
+
+ glfs_close(tgfd);
}