summaryrefslogtreecommitdiffstats
path: root/gluster-blockd.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 /gluster-blockd.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 'gluster-blockd.c')
-rw-r--r--gluster-blockd.c171
1 files changed, 163 insertions, 8 deletions
diff --git a/gluster-blockd.c b/gluster-blockd.c
index 0cef7da..db45b9c 100644
--- a/gluster-blockd.c
+++ b/gluster-blockd.c
@@ -20,7 +20,7 @@
# include "glfs-operations.h"
-# define UUID_BUF_SIZE 256
+# define UUID_BUF_SIZE 38
# define CREATE "create"
# define LIST "list"
@@ -39,6 +39,7 @@
# define MSERVER_DELIMITER ","
+
typedef struct blockServerDef {
size_t nhosts;
char **hosts;
@@ -212,7 +213,7 @@ getCfgstring(char* name, char *blkServer)
blockResponse *
block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
{
- int ret;
+ int ret = -1;
size_t i = 0;
char *out = NULL;
char savereply[8096] = {0,};
@@ -221,10 +222,49 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
static blockResponse *reply = NULL;
blockServerDefPtr list = NULL;
char *gbid = CALLOC(UUID_BUF_SIZE);
+ struct glfs *glfs = NULL;
+ struct glfs_fd *lkfd;
+ struct glfs_fd *tgfd = NULL;
+ struct flock lock = {0, };
+ char *write = NULL;
+
+ glfs = glusterBlockVolumeInit(blk->volume, blk->volfileserver);
+ if (!glfs) {
+ ERROR("%s", "glusterBlockVolumeInit failed");
+ goto out;
+ }
+
+ lkfd = glusterBlockCreateMetaLockFile(glfs);
+ if (!lkfd) {
+ ERROR("%s", "glusterBlockCreateMetaLockFile failed");
+ goto out;
+ }
+
+ METALOCK(lock, lkfd);
uuid_generate(uuid);
uuid_unparse(uuid, gbid);
+ if(GB_ALLOC(reply) < 0)
+ goto out;
+
+
+ if (!glfs_access(glfs, blk->block_name, F_OK)) {
+ GB_STRDUP(reply->out, "BLOCK Already EXIST");
+ reply->exit = EEXIST;
+ goto out;
+ }
+
+ tgfd = glfs_creat(glfs, blk->block_name, O_RDWR, S_IRUSR | S_IWUSR);
+ if (!tgfd) {
+ ERROR("%s", "glfs_creat: failed");
+ goto out;
+ }
+
+ METAUPDATE(tgfd, write,
+ "GBID: %s\nSIZE: %zu\nHA: %d\nENTRYCREATE: INPROGRESS\n",
+ gbid, blk->size, 1);
+
ret = glusterBlockCreateEntry(blk, gbid);
if (ret) {
ERROR("%s volume: %s host: %s",
@@ -232,6 +272,8 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
goto out;
}
+ METAUPDATE(tgfd, write, "ENTRYCREATE: SUCCESS\n");
+
if(GB_ALLOC(cobj) < 0)
goto out;
@@ -244,24 +286,35 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
list = blockServerParse(blk->block_hosts);
for (i = 0; i < list->nhosts; i++) {
+ METAUPDATE(tgfd, write, "%s: INPROGRESS\n", list->hosts[i]);
+
ret = gluster_block_1(list->hosts[i], cobj, CREATE_SRV, &out);
if (ret) {
+ METAUPDATE(tgfd, write, "%s: FAIL\n", list->hosts[i]);
ERROR("%s on host: %s",
FAILED_CREATE, list->hosts[i]);
- goto out;
}
+
+ METAUPDATE(tgfd, write, "%s: SUCCESS\n", list->hosts[i]);
+
strcpy(savereply, out);
GB_FREE(out);
}
- if(GB_ALLOC(reply) < 0)
- goto out;
-
if (GB_STRDUP(reply->out, savereply) < 0)
goto out;
reply->exit = ret;
out:
+ if (glfs_close(tgfd) != 0)
+ ERROR("%s", "glfs_close: failed");
+
+ METAUNLOCK(lock, lkfd);
+
+ if (glfs_close(lkfd) != 0)
+ ERROR("%s", "glfs_close: failed");
+
+ glfs_fini(glfs);
blockServerDefFree(list);
GB_FREE(cobj);
@@ -400,11 +453,38 @@ block_delete_cli_1_svc(blockDeleteCli *blk, struct svc_req *rqstp)
static blockCreate *blkcfg;
static blockDelete *cobj;
static blockResponse *reply = NULL;
+ struct glfs *glfs = NULL;
+ struct glfs_fd *lkfd;
+ struct glfs_fd *tgfd;
+ struct flock lock = {0, };
+ char *write;
+
+ glfs = glusterBlockVolumeInit(blk->volume, "localhost");
+ if (!glfs) {
+ ERROR("%s", "glusterBlockVolumeInit failed");
+ goto out;
+ }
- if(GB_ALLOC(cobj) < 0)
+ lkfd = glusterBlockCreateMetaLockFile(glfs);
+ if (!lkfd) {
+ ERROR("%s", "glusterBlockCreateMetaLockFile failed");
goto out;
+ }
- strcpy(cobj->block_name, blk->block_name);
+ METALOCK(lock, lkfd);
+
+ if (glfs_access(glfs, blk->block_name, F_OK)) {
+ GB_STRDUP(reply->out, "BLOCK Doesn't EXIST");
+ reply->exit = ENOENT;
+ goto out;
+ }
+
+ tgfd = glfs_open(glfs, blk->block_name, O_RDWR);
+ if (!tgfd) {
+ ERROR("%s", "glfs_open: failed");
+ goto out;
+ }
+ glfs_lseek (tgfd, 0, SEEK_END);
//for
cfgstring = getCfgstring(blk->block_name, blk->block_hosts);
@@ -421,16 +501,25 @@ block_delete_cli_1_svc(blockDeleteCli *blk, struct svc_req *rqstp)
goto out;
}
+ if(GB_ALLOC(cobj) < 0)
+ goto out;
+
+ strcpy(cobj->block_name, blk->block_name);
+
+
strcpy(cobj->gbid, blkcfg->gbid);
list = blockServerParse(blk->block_hosts);
for (i = 0; i < list->nhosts; i++) {
+ METAUPDATE(tgfd, write, "%s: CLEANUPINPROGRES\n", list->hosts[i]);
ret = gluster_block_1(list->hosts[i], cobj, DELETE_SRV, &out);
if (ret) {
+ METAUPDATE(tgfd, write, "%s: CLEANUPFAIL\n", list->hosts[i]);
ERROR("%s on host: %s",
FAILED_GATHERING_INFO, list->hosts[i]);
goto out;
}
+ METAUPDATE(tgfd, write, "%s: CLEANUPSUCCESS\n", list->hosts[i]);
/* TODO: aggrigate the result */
strcpy(savereply, out);
GB_FREE(out);
@@ -449,6 +538,22 @@ block_delete_cli_1_svc(blockDeleteCli *blk, struct svc_req *rqstp)
}
out:
+ if (glfs_close(tgfd) != 0)
+ ERROR("%s", "glfs_close: failed");
+
+ ret = glfs_unlink(glfs, blk->block_name);
+ if (ret && errno != ENOENT) {
+ ERROR("%s", "glfs_unlink: failed");
+ goto out;
+ }
+
+ METAUNLOCK(lock, lkfd);
+
+ if (glfs_close(lkfd) != 0)
+ ERROR("%s", "glfs_close: failed");
+
+ glfs_fini(glfs);
+
blockServerDefFree(list);
GB_FREE(cfgstring);
GB_FREE(blkcfg);
@@ -541,6 +646,23 @@ block_list_cli_1_svc(blockListCli *blk, struct svc_req *rqstp)
int ret = -1;
char savereply[8096] = {0,};
blockServerDefPtr list = NULL;
+ struct glfs *glfs;
+ struct glfs_fd *lkfd;
+ struct flock lock = {0, };
+
+ glfs = glusterBlockVolumeInit(blk->volume, "localhost");
+ if (!glfs) {
+ ERROR("%s", "glusterBlockVolumeInit failed");
+ goto out;
+ }
+
+ lkfd = glusterBlockCreateMetaLockFile(glfs);
+ if (!lkfd) {
+ ERROR("%s", "glusterBlockCreateMetaLockFile failed");
+ goto out;
+ }
+
+ METALOCK(lock, lkfd);
asprintf(&cmd, "%s %s", TARGETCLI_GLFS, LUNS_LIST);
@@ -566,6 +688,14 @@ block_list_cli_1_svc(blockListCli *blk, struct svc_req *rqstp)
reply->exit = ret;
out:
+
+ METAUNLOCK(lock, lkfd);
+
+ if (glfs_close(lkfd) != 0)
+ ERROR("%s", "glfs_close: failed");
+
+ glfs_fini(glfs);
+
blockServerDefFree(list);
GB_FREE(cmd);
@@ -584,6 +714,24 @@ block_info_cli_1_svc(blockInfoCli *blk, struct svc_req *rqstp)
char savereply[8096] = {0,};
blockServerDefPtr list = NULL;
+ struct glfs *glfs;
+ struct glfs_fd *lkfd;
+ struct flock lock = {0, };
+
+ glfs = glusterBlockVolumeInit(blk->volume, "localhost");
+ if (!glfs) {
+ ERROR("%s", "glusterBlockVolumeInit failed");
+ goto out;
+ }
+
+ lkfd = glusterBlockCreateMetaLockFile(glfs);
+ if (!lkfd) {
+ ERROR("%s", "glusterBlockCreateMetaLockFile failed");
+ goto out;
+ }
+
+ METALOCK(lock, lkfd);
+
asprintf(&cmd, "%s/%s %s", TARGETCLI_GLFS, blk->block_name, INFO);
//for
@@ -609,6 +757,13 @@ block_info_cli_1_svc(blockInfoCli *blk, struct svc_req *rqstp)
reply->exit = ret;
out:
+ METAUNLOCK(lock, lkfd);
+
+ if (glfs_close(lkfd) != 0)
+ ERROR("%s", "glfs_close: failed");
+
+ glfs_fini(glfs);
+
blockServerDefFree(list);
return reply;