diff options
author | Prasanna Kumar Kalever <prasanna.kalever@redhat.com> | 2017-01-25 16:09:12 +0530 |
---|---|---|
committer | Prasanna Kumar Kalever <prasanna.kalever@redhat.com> | 2017-01-30 19:31:50 +0530 |
commit | d65f7b890a2554c9e3d0cafdb58ac257d4f26ab3 (patch) | |
tree | 32fb92ab62279ea56e1ada3d496b950d467b4cbc /gluster-blockd.c | |
parent | b58e4765ed7e232f638ceb764b8ef1210bb43ff9 (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.c | 171 |
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; |