summaryrefslogtreecommitdiffstats
path: root/rpc/block_svc_routines.c
diff options
context:
space:
mode:
Diffstat (limited to 'rpc/block_svc_routines.c')
-rw-r--r--rpc/block_svc_routines.c805
1 files changed, 686 insertions, 119 deletions
diff --git a/rpc/block_svc_routines.c b/rpc/block_svc_routines.c
index b966e05..8b3eaea 100644
--- a/rpc/block_svc_routines.c
+++ b/rpc/block_svc_routines.c
@@ -19,6 +19,7 @@
# define UUID_BUF_SIZE 38
+# define GB_DEFAULT_ERRCODE 255
# define GB_CREATE "create"
# define GB_DELETE "delete"
@@ -42,7 +43,8 @@ pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
typedef enum operations {
CREATE_SRV = 1,
- DELETE_SRV = 2
+ DELETE_SRV = 2,
+ MODIFY_SRV = 3
} operations;
@@ -56,6 +58,14 @@ typedef struct blockRemoteObj {
} blockRemoteObj;
+typedef struct blockRemoteModifyResp {
+ char *attempt;
+ char *success;
+ char *rb_attempt;
+ char *rb_success;
+} blockRemoteModifyResp;
+
+
typedef struct blockRemoteDeleteResp {
char *d_attempt;
char *d_success;
@@ -326,6 +336,14 @@ glusterBlockCallRPC_1(char *host, void *cobj,
goto out;
}
break;
+ case MODIFY_SRV:
+ reply = block_modify_1((blockModify *)cobj, clnt);
+ if (!reply) {
+ LOG("mgmt", GB_LOG_ERROR, "%son host %s",
+ clnt_sperror(clnt, "block remote modify failed"), host);
+ goto out;
+ }
+ break;
}
if (reply) {
@@ -466,7 +484,7 @@ glusterBlockCreateRemote(void *data)
out:
if (!args->reply) {
- if (GB_ASPRINTF(&args->reply, "failed to config on %s %s\n", args->addr,
+ if (GB_ASPRINTF(&args->reply, "failed to configure on %s %s\n", args->addr,
errMsg?errMsg:"") == -1) {
ret = -1;
}
@@ -577,8 +595,8 @@ glusterBlockDeleteRemote(void *data)
out:
if (!args->reply) {
- if (GB_ASPRINTF(&args->reply, "failed to delete config on %s",
- args->addr) == -1) {
+ if (GB_ASPRINTF(&args->reply, "failed to delete config on %s %s",
+ args->addr, errMsg?errMsg:"") == -1) {
ret = -1;
}
}
@@ -589,6 +607,76 @@ glusterBlockDeleteRemote(void *data)
}
+static size_t
+glusterBlockDeleteFillArgs(MetaInfo *info, bool deleteall, blockRemoteObj *args,
+ struct glfs *glfs, blockDelete *dobj)
+{
+ int i = 0;
+ size_t count = 0;
+
+ for (i = 0, count = 0; i < info->nhosts; i++) {
+ switch (blockMetaStatusEnumParse(info->list[i]->status)) {
+ case GB_CONFIG_SUCCESS:
+ case GB_AUTH_ENFORCEING:
+ case GB_AUTH_ENFORCED:
+ case GB_AUTH_ENFORCE_FAIL:
+ case GB_AUTH_CLEAR_ENFORCED:
+ case GB_AUTH_CLEAR_ENFORCEING:
+ case GB_AUTH_CLEAR_ENFORCE_FAIL:
+ if (!deleteall)
+ break;
+ case GB_CLEANUP_INPROGRESS:
+ case GB_CLEANUP_FAIL:
+ case GB_CONFIG_FAIL:
+ if (args) {
+ args[count].glfs = glfs;
+ args[count].obj = (void *)dobj;
+ args[count].volume = info->volume;
+ args[count].addr = info->list[i]->addr;
+ }
+ count++;
+ break;
+ }
+ }
+ return count;
+}
+
+
+static int
+glusterBlockCollectAttemptSuccess (blockRemoteObj *args, size_t count,
+ char **attempt, char **success)
+{
+ char *a_tmp = NULL;
+ char *s_tmp = NULL;
+ int i = 0;
+
+ for (i = 0; i < count; i++) {
+ if (args[i].exit) {
+ if (GB_ASPRINTF(attempt, "%s %s",
+ (a_tmp==NULL?"":a_tmp), args[i].addr) == -1) {
+ goto fail;
+ }
+ GB_FREE(a_tmp);
+ a_tmp = *attempt;
+ } else {
+ if (GB_ASPRINTF(success, "%s %s",
+ (s_tmp==NULL?"":s_tmp), args[i].addr) == -1) {
+ goto fail;
+ }
+ GB_FREE(s_tmp);
+ s_tmp = *success;
+ }
+ }
+ return 0;
+ fail:
+ GB_FREE(a_tmp);
+ GB_FREE(s_tmp);
+ *attempt = NULL;
+ *success = NULL;
+ return -1;
+}
+
+
static int
glusterBlockDeleteRemoteAsync(MetaInfo *info,
struct glfs *glfs,
@@ -599,7 +687,7 @@ glusterBlockDeleteRemoteAsync(MetaInfo *info,
{
pthread_t *tid = NULL;
blockRemoteDeleteResp *local = *savereply;
- static blockRemoteObj *args = NULL;
+ blockRemoteObj *args = NULL;
char *d_attempt = NULL;
char *d_success = NULL;
char *a_tmp = NULL;
@@ -616,27 +704,7 @@ glusterBlockDeleteRemoteAsync(MetaInfo *info,
goto out;
}
- for (i = 0, count = 0; i < info->nhosts; i++) {
- switch (blockMetaStatusEnumParse(info->list[i]->status)) {
- case GB_CLEANUP_INPROGRESS:
- case GB_CLEANUP_FAIL:
- case GB_CONFIG_FAIL:
- args[count].glfs = glfs;
- args[count].obj = (void *)dobj;
- args[count].volume = info->volume;
- args[count].addr = info->list[i]->addr;
- count++;
- break;
- }
- if (deleteall &&
- blockMetaStatusEnumParse(info->list[i]->status) == GB_CONFIG_SUCCESS) {
- args[count].glfs = glfs;
- args[count].obj = (void *)dobj;
- args[count].volume = info->volume;
- args[count].addr = info->list[i]->addr;
- count++;
- }
- }
+ count = glusterBlockDeleteFillArgs(info, deleteall, args, glfs, dobj);
for (i = 0; i < count; i++) {
pthread_create(&tid[i], NULL, glusterBlockDeleteRemote, &args[i]);
@@ -646,23 +714,9 @@ glusterBlockDeleteRemoteAsync(MetaInfo *info,
pthread_join(tid[i], NULL);
}
- /* collect return */
- for (i = 0; i < count; i++) {
- if (args[i].exit) {
- if (GB_ASPRINTF(&d_attempt, "%s %s",
- (a_tmp==NULL?"":a_tmp), args[i].addr) == -1) {
- goto out;
- }
- GB_FREE(a_tmp);
- a_tmp = d_attempt;
- } else {
- if (GB_ASPRINTF(&d_success, "%s %s",
- (s_tmp==NULL?"":s_tmp), args[i].addr) == -1) {
- goto out;
- }
- GB_FREE(s_tmp);
- s_tmp = d_success;
- }
+ ret = glusterBlockCollectAttemptSuccess (args, count, &d_attempt, &d_success);
+ if (ret) {
+ goto out;
}
if (d_attempt) {
@@ -707,6 +761,172 @@ glusterBlockDeleteRemoteAsync(MetaInfo *info,
}
+void *
+glusterBlockModifyRemote(void *data)
+{
+ int ret;
+ blockRemoteObj *args = (blockRemoteObj *)data;
+ blockModify cobj = *(blockModify *)args->obj;
+ char *errMsg = NULL;
+
+ GB_METAUPDATE_OR_GOTO(lock, args->glfs, cobj.block_name, cobj.volume,
+ ret, errMsg, out, "%s: AUTH%sENFORCEING\n", args->addr,
+ cobj.auth_mode?"":"CLEAR");
+
+ ret = glusterBlockCallRPC_1(args->addr, &cobj, MODIFY_SRV, &args->reply);
+ if (ret) {
+ if (errno == ENETUNREACH || errno == ECONNREFUSED || errno == ETIMEDOUT) {
+ LOG("mgmt", GB_LOG_ERROR, "%s hence %s for block %s on"
+ "host %s volume %s", strerror(errno), FAILED_REMOTE_MODIFY,
+ cobj.block_name, args->addr, args->volume);
+ goto out;
+ }
+
+ if (ret == EKEYEXPIRED) {
+ LOG("mgmt", GB_LOG_ERROR, "%s [%s] hence modify block %s on"
+ "host %s volume %s failed", FAILED_DEPENDENCY, strerror(errno),
+ cobj.block_name, args->addr, args->volume);
+ goto out;
+ }
+
+ GB_METAUPDATE_OR_GOTO(lock, args->glfs, cobj.block_name, cobj.volume,
+ ret, errMsg, out, "%s: AUTH%sENFORCEFAIL\n",
+ args->addr, cobj.auth_mode?"":"CLEAR");
+ LOG("mgmt", GB_LOG_ERROR, "%s for block %s on host %s volume %s",
+ FAILED_REMOTE_MODIFY, cobj.block_name, args->addr, args->volume);
+ goto out;
+ }
+
+ GB_METAUPDATE_OR_GOTO(lock, args->glfs, cobj.block_name, cobj.volume,
+ ret, errMsg, out, "%s: AUTH%sENFORCED\n", args->addr,
+ cobj.auth_mode?"":"CLEAR");
+
+ out:
+ if (!args->reply) {
+ if (GB_ASPRINTF(&args->reply, "failed to configure auth on %s %s",
+ args->addr, errMsg?errMsg:"") == -1) {
+ ret = -1;
+ }
+ }
+ GB_FREE(errMsg);
+ args->exit = ret;
+
+ return NULL;
+}
+
+static size_t
+glusterBlockModifyArgsFill(blockModify *mobj, MetaInfo *info,
+ blockRemoteObj *args, struct glfs *glfs)
+{
+ int i = 0;
+ size_t count = 0;
+ bool fill = FALSE;
+
+ for (i = 0, count = 0; i < info->nhosts; i++) {
+ switch (blockMetaStatusEnumParse(info->list[i]->status)) {
+ case GB_CONFIG_SUCCESS:
+ /* case GB_AUTH_ENFORCED: this is not required to be configured */
+ case GB_AUTH_ENFORCE_FAIL:
+ case GB_AUTH_CLEAR_ENFORCED:
+ if (mobj->auth_mode) {
+ fill = TRUE;
+ }
+ break;
+ case GB_AUTH_ENFORCED:
+ if (!mobj->auth_mode) {
+ fill = TRUE;
+ }
+ break;
+ case GB_AUTH_ENFORCEING:
+ case GB_AUTH_CLEAR_ENFORCEING:
+ case GB_AUTH_CLEAR_ENFORCE_FAIL:
+ fill = TRUE;
+ break;
+ }
+ if (fill) {
+ if (args) {
+ args[count].glfs = glfs;
+ args[count].obj = (void *)mobj;
+ args[count].addr = info->list[i]->addr;
+ }
+ count++;
+ }
+ fill = FALSE;
+ }
+ return count;
+}
+
+
+static int
+glusterBlockModifyRemoteAsync(MetaInfo *info,
+ struct glfs *glfs,
+ blockModify *mobj,
+ blockRemoteModifyResp **savereply,
+ bool rollback)
+{
+ pthread_t *tid = NULL;
+ blockRemoteModifyResp *local = *savereply;
+ blockRemoteObj *args = NULL;
+ int ret = -1;
+ size_t i;
+ size_t count = 0;
+
+
+ /* get all (configured - already auth enforced) node count */
+ count = glusterBlockModifyArgsFill(mobj, info, NULL, glfs);
+
+ if (GB_ALLOC_N(tid, count) < 0) {
+ goto out;
+ }
+
+ if (GB_ALLOC_N(args, count) < 0) {
+ goto out;
+ }
+
+ count = glusterBlockModifyArgsFill(mobj, info, args, glfs);
+
+ for (i = 0; i < count; i++) {
+ pthread_create(&tid[i], NULL, glusterBlockModifyRemote, &args[i]);
+ }
+
+ for (i = 0; i < count; i++) {
+ /* collect exit code */
+ pthread_join(tid[i], NULL);
+ }
+
+ if (!rollback) {
+ /* collect return */
+ ret = glusterBlockCollectAttemptSuccess (args, count, &local->attempt,
+ &local->success);
+ if (ret)
+ goto out;
+ } else {
+ /* collect return */
+ ret = glusterBlockCollectAttemptSuccess (args, count,
+ &local->rb_attempt,
+ &local->rb_success);
+ if (ret)
+ goto out;
+ }
+ for (i = 0; i < count; i++) {
+ if (args[i].exit == EKEYEXPIRED) {
+ ret = EKEYEXPIRED;
+ break; /* important to catch */
+ } else if (args[i].exit) {
+ ret = -1;
+ }
+ }
+
+ *savereply = local;
+
+ out:
+ GB_FREE(args);
+ GB_FREE(tid);
+
+ return ret;
+}
+
+
static int
glusterBlockCleanUp(operations opt, struct glfs *glfs, char *blockname,
bool deleteall, void *reply)
@@ -747,20 +967,7 @@ glusterBlockCleanUp(operations opt, struct glfs *glfs, char *blockname,
strcpy(dobj.block_name, blockname);
strcpy(dobj.gbid, info->gbid);
- for (i = 0; i < info->nhosts; i++) {
- switch (blockMetaStatusEnumParse(info->list[i]->status)) {
- case GB_CLEANUP_INPROGRESS:
- case GB_CLEANUP_FAIL:
- case GB_CONFIG_FAIL:
- count++;
- break;
- }
- if (deleteall &&
- blockMetaStatusEnumParse(info->list[i]->status) == GB_CONFIG_SUCCESS) {
- count++;
- }
- }
-
+ count = glusterBlockDeleteFillArgs(info, deleteall, NULL, NULL, NULL);
asyncret = glusterBlockDeleteRemoteAsync(info, glfs, &dobj, count,
deleteall, &drobj);
if (asyncret) {
@@ -873,7 +1080,7 @@ glusterBlockAuditRequest(struct glfs *glfs,
morereq = blk->mpath - successcnt; /* needed nodes to complete req */
if (spare == 0) {
LOG("mgmt", GB_LOG_WARNING,
- "No Spare nodes to create (%s): rewinding creation of target"
+ "No Spare nodes to create (%s): rollingback creation of target"
" on volume %s with given hosts %s",
blk->block_name, blk->volume, blk->block_hosts);
glusterBlockCleanUp(CREATE_SRV, glfs,
@@ -883,7 +1090,7 @@ glusterBlockAuditRequest(struct glfs *glfs,
goto out;
} else if (spare < morereq) {
LOG("mgmt", GB_LOG_WARNING,
- "Not enough Spare nodes for (%s): rewinding creation of target"
+ "Not enough Spare nodes for (%s): rollingback creation of target"
" on volume %s with given hosts %s",
blk->block_name, blk->volume, blk->block_hosts);
glusterBlockCleanUp(CREATE_SRV, glfs,
@@ -927,8 +1134,8 @@ glusterBlockAuditRequest(struct glfs *glfs,
}
void
-block_format_error_response (int json_resp, int errCode, char *errMsg,
- struct blockResponse *reply)
+blockFormatErrorResponse (int json_resp, int errCode, char *errMsg,
+ struct blockResponse *reply)
{
json_object *json_obj = NULL;
reply->exit = errCode;
@@ -946,10 +1153,277 @@ block_format_error_response (int json_resp, int errCode, char *errMsg,
}
}
+static void
+blockStr2arrayAddToJsonObj (json_object *json_obj, char *string, char *label,
+ json_object **json_array)
+{
+ char *tmp = NULL;
+ json_object *json_array1 = NULL;
+
+ if (!string)
+ return;
+
+ json_array1 = json_object_new_array();
+ tmp = strtok (string, " ");
+ while (tmp != NULL)
+ {
+ json_object_array_add(json_array1, json_object_new_string(tmp));
+ tmp = strtok (NULL, " ");
+ }
+ json_object_object_add(json_obj, label, json_array1);
+ *json_array = json_array1;
+}
+
+static void
+blockModifyCliFormatResponse (blockModifyCli *blk, struct blockModify *mobj,
+ int errCode, char *errMsg,
+ blockRemoteModifyResp *savereply,
+ MetaInfo *info, struct blockResponse *reply,
+ bool rollback)
+{
+ json_object *json_obj = NULL;
+ json_object *json_array[4] = {0};
+ char *tmp2 = NULL;
+ char *tmp3 = NULL;
+ char *tmp = NULL;
+ int i = 0;
+
+ if (!reply) {
+ return;
+ }
+
+ if (errCode < 0) {
+ errCode = GB_DEFAULT_ERRCODE;
+ }
+
+ if (errMsg) {
+ blockFormatErrorResponse(blk->json_resp, errCode, errMsg, reply);
+ return;
+ }
+
+ if (blk->json_resp) {
+ json_obj = json_object_new_object();
+
+ blockStr2arrayAddToJsonObj (json_obj, savereply->attempt, "FAILED ON",
+ &json_array[0]);
+
+ if (savereply->success) {
+ blockStr2arrayAddToJsonObj (json_obj, savereply->success,
+ "SUCCESSFUL ON", &json_array[1]);
+ tmp = NULL;
+
+ GB_ASPRINTF(&tmp, "%s%s", GB_TGCLI_IQN_PREFIX, info->gbid);
+ json_object_object_add(json_obj, "IQN",
+ json_object_new_string(tmp?tmp:""));
+ if (mobj->auth_mode) {
+ json_object_object_add(json_obj, "USERNAME",
+ json_object_new_string(info->gbid));
+ json_object_object_add(json_obj, "PASSWORD",
+ json_object_new_string(mobj->passwd));
+ }
+ }
+
+ json_object_object_add(json_obj, "RESULT",
+ errCode?json_object_new_string("FAIL"):json_object_new_string("SUCCESS"));
+
+ if (rollback) {
+ blockStr2arrayAddToJsonObj (json_obj, savereply->rb_attempt,
+ "ROLLBACK FAILED ON", &json_array[2]);
+
+ blockStr2arrayAddToJsonObj (json_obj, savereply->rb_success,
+ "ROLLBACK SUCCESS ON", &json_array[3]);
+ }
+
+ GB_ASPRINTF(&reply->out, "%s\n", json_object_to_json_string_ext(json_obj,
+ mapJsonFlagToJsonCstring(blk->json_resp)));
+
+ for (i = 0; i < 4; i++) {
+ if (json_array[i]) {
+ json_object_put(json_array[i]);
+ }
+ }
+ json_object_put(json_obj);
+ } else {
+ /* save 'failed on'*/
+ if (savereply->attempt)
+ GB_ASPRINTF(&tmp, "FAILED ON: %s\n", savereply->attempt);
+
+ if (savereply->success) {
+ if (mobj->auth_mode) {
+ GB_ASPRINTF(&tmp2, "%s\nIQN: %s%s\nUSERNAME: %s\nPASSWORD: %s",
+ savereply->success, GB_TGCLI_IQN_PREFIX, info->gbid,
+ info->gbid, mobj->passwd);
+ } else {
+ GB_ASPRINTF(&tmp2, "%s\nIQN: %s%s",
+ savereply->success, GB_TGCLI_IQN_PREFIX, info->gbid);
+ }
+ }
+
+ GB_ASPRINTF(&tmp3, "%sSUCCESSFUL ON: %s\n" "RESULT: %s\n", tmp?tmp:"",
+ savereply->success?tmp2:"None", errCode?"FAIL":"SUCCESS");
+
+ GB_FREE(tmp);
+ GB_FREE(tmp2);
+
+ if (rollback) {
+ if (savereply->rb_attempt) {
+ GB_ASPRINTF(&tmp, "ROLLBACK FAILED ON: %s\n", savereply->rb_attempt);
+ }
+ if (savereply->rb_success) {
+ GB_ASPRINTF(&tmp2, "ROLLBACK SUCCESS ON: %s\n", savereply->rb_attempt);
+ }
+ }
+
+ GB_ASPRINTF(&reply->out, "%s%s%s", tmp3, savereply->rb_attempt?tmp:"",
+ savereply->rb_success?tmp2:"");
+ GB_FREE(tmp2);
+ GB_FREE(tmp3);
+ }
+ GB_FREE(tmp);
+}
+
+blockResponse *
+block_modify_cli_1_svc(blockModifyCli *blk, struct svc_req *rqstp)
+{
+ int ret = -1;
+ static blockModify mobj;
+ static blockRemoteModifyResp *savereply = NULL;
+ static blockResponse *reply = NULL;
+ struct glfs *glfs;
+ struct glfs_fd *lkfd = NULL;
+ MetaInfo *info = NULL;
+ uuid_t uuid;
+ char passwd[UUID_BUF_SIZE];
+ int asyncret;
+ bool rollback = false;
+ int errCode = 0;
+ char *errMsg = NULL;
+
+
+ if ((GB_ALLOC(reply) < 0) || (GB_ALLOC(savereply) < 0) ||
+ (GB_ALLOC (info) < 0)) {
+ GB_FREE (reply);
+ GB_FREE (savereply);
+ GB_FREE (info);
+ return NULL;
+ }
+
+ glfs = glusterBlockVolumeInit(blk->volume, &errCode, &errMsg);
+ if (!glfs) {
+ LOG("mgmt", GB_LOG_ERROR,
+ "glusterBlockVolumeInit(%s) for block %s failed [%s]",
+ blk->volume, blk->block_name, strerror(errno));
+ goto initfail;
+ }
+
+ lkfd = glusterBlockCreateMetaLockFile(glfs, blk->volume, &errCode, &errMsg);
+ if (!lkfd) {
+ LOG("mgmt", GB_LOG_ERROR, "%s %s for block %s",
+ FAILED_CREATING_META, blk->volume, blk->block_name);
+ goto nolock;
+ }
+
+ GB_METALOCK_OR_GOTO(lkfd, blk->volume, ret, errMsg, nolock);
+
+ if (glfs_access(glfs, blk->block_name, F_OK)) {
+ LOG("mgmt", GB_LOG_ERROR,
+ "block with name %s doesn't exist in the volume %s",
+ blk->block_name, blk->volume);
+ GB_ASPRINTF(&errMsg, "block %s/%s doesn't exist", blk->volume,
+ blk->block_name);
+ errCode = ENOENT;
+ goto out;
+ }
+
+ ret = blockGetMetaInfo(glfs, blk->block_name, info, NULL);
+ if (ret) {
+ goto out;
+ }
+
+ strcpy(mobj.block_name, blk->block_name);
+ strcpy(mobj.volume, blk->volume);
+ strcpy(mobj.gbid, info->gbid);
+
+ if (blk->auth_mode) {
+ if(info->passwd[0] == '\0') {
+ uuid_generate(uuid);
+ uuid_unparse(uuid, passwd);
+ GB_METAUPDATE_OR_GOTO(lock, glfs, blk->block_name, blk->volume,
+ ret, errMsg, out, "PASSWORD: %s\n", passwd);
+ strcpy(mobj.passwd, passwd);
+ } else {
+ strcpy(mobj.passwd, info->passwd);
+ }
+ mobj.auth_mode = 1;
+ } else {
+ GB_METAUPDATE_OR_GOTO(lock, glfs, blk->block_name, blk->volume,
+ ret, errMsg, out, "PASSWORD: \n");
+ mobj.auth_mode = 0;
+ }
+
+ asyncret = glusterBlockModifyRemoteAsync(info, glfs, &mobj,
+ &savereply, rollback);
+ if (asyncret) {
+ LOG("mgmt", GB_LOG_WARNING,
+ "glusterBlockModifyRemoteAsync(auth=%d): return %d %s for block %s on volume %s",
+ blk->auth_mode, asyncret, FAILED_REMOTE_AYNC_MODIFY, blk->block_name, info->volume);
+ /* Unwind by removing authentication */
+ if (blk->auth_mode) {
+ GB_METAUPDATE_OR_GOTO(lock, glfs, blk->block_name, blk->volume,
+ ret, errMsg, out, "PASSWORD: \n");
+ }
+
+ /* toggle */
+ mobj.auth_mode = !mobj.auth_mode;
+
+ rollback = true;
+ /* undo */
+ asyncret = glusterBlockModifyRemoteAsync(info, glfs, &mobj,
+ &savereply, rollback);
+ if (asyncret) {
+ LOG("mgmt", GB_LOG_WARNING,
+ "glusterBlockModifyRemoteAsync(auth=%d): on rollback return %d %s "
+ "for block %s on volume %s", blk->auth_mode, asyncret, FAILED_REMOTE_AYNC_MODIFY,
+ blk->block_name, info->volume);
+ /* do nothing ? */
+ }
+ }
+
+ out:
+ if (ret == EKEYEXPIRED) {
+ GB_ASPRINTF(&errMsg, "Looks like targetcli and tcmu-runner are not "
+ "installed on " "few nodes.\n");
+ }
+
+ GB_METAUNLOCK(lkfd, blk->volume, ret, errMsg);
+
+ nolock:
+ if (lkfd && glfs_close(lkfd) != 0) {
+ LOG("mgmt", GB_LOG_ERROR,
+ "glfs_close(%s): for block %s on volume %s failed[%s]",
+ GB_TXLOCKFILE, blk->block_name, blk->volume, strerror(errno));
+ }
+
+ initfail:
+ blockModifyCliFormatResponse (blk, &mobj, errCode, errMsg, savereply, info,
+ reply, rollback);
+ glfs_fini(glfs);
+
+ if (savereply) {
+ GB_FREE(savereply->attempt);
+ GB_FREE(savereply->success);
+ GB_FREE(savereply->rb_attempt);
+ GB_FREE(savereply->rb_success);
+ GB_FREE(savereply);
+ }
+
+ return reply;
+}
+
void
-block_create_cli_format_response(blockCreateCli *blk, int errCode,
- char *errMsg, blockRemoteCreateResp *savereply,
- struct blockResponse *reply)
+blockCreateCliFormatResponse(blockCreateCli *blk, int errCode,
+ char *errMsg, blockRemoteCreateResp *savereply,
+ struct blockResponse *reply)
{
json_object *json_obj = NULL;
json_object *json_array = NULL;
@@ -962,11 +1436,11 @@ block_create_cli_format_response(blockCreateCli *blk, int errCode,
}
if (errCode < 0) {
- errCode = 255;
+ errCode = GB_DEFAULT_ERRCODE;
}
if (errMsg) {
- block_format_error_response(blk->json_resp, errCode, errMsg, reply);
+ blockFormatErrorResponse(blk->json_resp, errCode, errMsg, reply);
return;
}
@@ -1006,7 +1480,7 @@ block_create_cli_format_response(blockCreateCli *blk, int errCode,
}
}
tmp = NULL;
- json_object_object_add(json_obj, "REWIND ON", json_array);
+ json_object_object_add(json_obj, "ROLLBACK ON", json_array);
}
json_object_object_add(json_obj, "RESULT",
@@ -1030,7 +1504,7 @@ block_create_cli_format_response(blockCreateCli *blk, int errCode,
/* save 'failed on'*/
tmp = NULL;
if (savereply->obj->d_attempt || savereply->obj->d_success) {
- if (GB_ASPRINTF(&tmp, "REWIND ON: %s %s\n",
+ if (GB_ASPRINTF(&tmp, "ROLLBACK ON: %s %s\n",
savereply->obj->d_attempt?savereply->obj->d_attempt:"",
savereply->obj->d_success?savereply->obj->d_success:"") == -1) {
goto out;
@@ -1062,7 +1536,7 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
if (GB_ALLOC(reply) < 0) {
- goto out;
+ return NULL;
}
list = blockServerParse(blk->block_hosts);
@@ -1141,7 +1615,7 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
if (errCode) {
if (errCode == EKEYEXPIRED) {
LOG("mgmt", GB_LOG_ERROR, "glusterBlockCreateRemoteAsync: return %d"
- " rewinding the create request for block %s on volume %s with hosts %s",
+ " rollingback the create request for block %s on volume %s with hosts %s",
errCode, blk->block_name, blk->volume, blk->block_hosts);
glusterBlockCleanUp(CREATE_SRV, glfs, blk->block_name, TRUE, &savereply);
@@ -1178,7 +1652,7 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
}
optfail:
- block_create_cli_format_response(blk, errCode, errMsg, savereply, reply);
+ blockCreateCliFormatResponse(blk, errCode, errMsg, savereply, reply);
GB_FREE(errMsg);
blockServerDefFree(list);
glfs_fini(glfs);
@@ -1289,9 +1763,9 @@ block_create_1_svc(blockCreate *blk, struct svc_req *rqstp)
}
void
-block_delete_cli_format_response(blockDeleteCli *blk, int errCode, char *errMsg,
- blockRemoteDeleteResp *savereply,
- struct blockResponse *reply)
+blockDeleteCliFormatResponse(blockDeleteCli *blk, int errCode, char *errMsg,
+ blockRemoteDeleteResp *savereply,
+ struct blockResponse *reply)
{
json_object *json_obj = NULL;
json_object *json_array1 = NULL;
@@ -1303,42 +1777,23 @@ block_delete_cli_format_response(blockDeleteCli *blk, int errCode, char *errMsg,
}
if (errCode < 0) {
- errCode = 255;
+ errCode = GB_DEFAULT_ERRCODE;
}
reply->exit = errCode;
if (errMsg) {
- block_format_error_response(blk->json_resp, errCode, errMsg, reply);
+ blockFormatErrorResponse(blk->json_resp, errCode, errMsg, reply);
return;
}
if (blk->json_resp) {
json_obj = json_object_new_object();
- if (savereply->d_attempt) {
- json_array1 = json_object_new_array();
- tmp = strtok (savereply->d_attempt, " ");
- while (tmp!= NULL)
- {
- json_object_array_add(json_array1, json_object_new_string(tmp));
- tmp = strtok (NULL, " ");
- }
- tmp = NULL;
- json_object_object_add(json_obj, "FAILED ON", json_array1);
- }
-
- if (savereply->d_success) {
- json_array2 = json_object_new_array();
- tmp = strtok (savereply->d_success, " ");
- while (tmp!= NULL)
- {
- json_object_array_add(json_array2, json_object_new_string(tmp));
- tmp = strtok (NULL, " ");
- }
- tmp = NULL;
- json_object_object_add(json_obj, "SUCCESSFUL ON", json_array2);
- }
+ blockStr2arrayAddToJsonObj (json_obj, savereply->d_attempt,
+ "FAILED ON", &json_array1);
+ blockStr2arrayAddToJsonObj (json_obj, savereply->d_success,
+ "SUCCESSFUL ON", &json_array2);
json_object_object_add(json_obj, "RESULT",
errCode?json_object_new_string("FAIL"):json_object_new_string("SUCCESS"));
@@ -1347,8 +1802,10 @@ block_delete_cli_format_response(blockDeleteCli *blk, int errCode, char *errMsg,
json_object_to_json_string_ext(json_obj,
mapJsonFlagToJsonCstring(blk->json_resp)));
- json_object_put(json_array1);
- json_object_put(json_array2);
+ if (json_array1)
+ json_object_put(json_array1);
+ if (json_array2)
+ json_object_put(json_array2);
json_object_put(json_obj);
} else {
/* save 'failed on'*/
@@ -1438,7 +1895,7 @@ block_delete_cli_1_svc(blockDeleteCli *blk, struct svc_req *rqstp)
}
- block_delete_cli_format_response(blk, errCode, errMsg, savereply, reply);
+ blockDeleteCliFormatResponse(blk, errCode, errMsg, savereply, reply);
glfs_fini(glfs);
if (savereply) {
@@ -1539,6 +1996,98 @@ block_delete_1_svc(blockDelete *blk, struct svc_req *rqstp)
blockResponse *
+block_modify_1_svc(blockModify *blk, struct svc_req *rqstp)
+{
+ int ret;
+ char *authattr = NULL;
+ char *authcred = NULL;
+ char *exec = NULL;
+ blockResponse *reply = NULL;
+
+
+ if (GB_ALLOC(reply) < 0) {
+ return NULL;
+ }
+ reply->exit = -1;
+
+ /* Check if targetcli and tcmu-runner installed ? */
+ ret = WEXITSTATUS(system(GB_TGCLI_GLFS_CHECK));
+ if (ret == EKEYEXPIRED || ret == 1) {
+ reply->exit = EKEYEXPIRED;
+ if (GB_ASPRINTF(&reply->out,
+ "check if targetcli and tcmu-runner are installed.") == -1) {
+ goto out;
+ }
+ goto out;
+ }
+
+ if (GB_ASPRINTF(&exec, GB_TGCLI_CHECK, blk->block_name) == -1) {
+ goto out;
+ }
+
+ /* Check if block exist on this node ? */
+ if (WEXITSTATUS(system(exec)) == 1) {
+ reply->exit = 0;
+ if (GB_ASPRINTF(&reply->out, "No %s.", blk->block_name) == -1) {
+ goto out;
+ }
+ goto out;
+ }
+ GB_FREE(exec);
+
+ if (blk->auth_mode) {
+ if (GB_ASPRINTF(&authattr, "%s/%s%s/tpg1 set attribute authentication=1",
+ GB_TGCLI_ISCSI, GB_TGCLI_IQN_PREFIX, blk->gbid) == -1) {
+ goto out;
+ }
+
+ if (GB_ASPRINTF(&authcred, "%s/%s%s/tpg1 set auth userid=%s password=%s",
+ GB_TGCLI_ISCSI, GB_TGCLI_IQN_PREFIX, blk->gbid,
+ blk->gbid, blk->passwd) == -1) {
+ goto out;
+ }
+
+ if (GB_ASPRINTF(&exec, "%s && %s && %s", authattr, authcred, GB_TGCLI_SAVE) == -1) {
+ goto out;
+ }
+ } else {
+ if (GB_ASPRINTF(&exec, "%s/%s%s/tpg1 set attribute authentication=0 && %s",
+ GB_TGCLI_ISCSI, GB_TGCLI_IQN_PREFIX, blk->gbid, GB_TGCLI_SAVE) == -1) {
+ goto out;
+ }
+ }
+
+ if (GB_ALLOC_N(reply->out, 4096) < 0) {
+ GB_FREE(reply);
+ goto out;
+ }
+
+ ret = WEXITSTATUS(system(exec));
+ if (ret) {
+ LOG("mgmt", GB_LOG_ERROR,
+ "system(): for block %s executing command %s failed(%s)",
+ blk->block_name, exec, strerror(errno));
+ reply->exit = ret;
+ if (GB_ASPRINTF(&reply->out,
+ "cannot execute auth commands.") == -1) {
+ goto out;
+ }
+ goto out;
+ }
+
+ /* command execution success */
+ reply->exit = 0;
+
+ out:
+ GB_FREE(exec);
+ GB_FREE(authattr);
+ GB_FREE(authcred);
+
+ return reply;
+}
+
+
+blockResponse *
block_list_cli_1_svc(blockListCli *blk, struct svc_req *rqstp)
{
blockResponse *reply;
@@ -1624,7 +2173,7 @@ block_list_cli_1_svc(blockListCli *blk, struct svc_req *rqstp)
}
if (errCode < 0) {
- errCode = 255;
+ errCode = GB_DEFAULT_ERRCODE;
}
reply->exit = errCode;
@@ -1669,10 +2218,27 @@ block_list_cli_1_svc(blockListCli *blk, struct svc_req *rqstp)
return reply;
}
+static bool
+blockhostIsValid (char *status)
+{
+ switch (blockMetaStatusEnumParse(status)) {
+ case GB_CONFIG_SUCCESS:
+ case GB_AUTH_ENFORCEING:
+ case GB_AUTH_ENFORCED:
+ case GB_AUTH_ENFORCE_FAIL:
+ case GB_AUTH_CLEAR_ENFORCED:
+ case GB_AUTH_CLEAR_ENFORCEING:
+ case GB_AUTH_CLEAR_ENFORCE_FAIL:
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
void
-block_info_cli_format_response(blockInfoCli *blk, int errCode,
- char *errMsg, MetaInfo *info,
- struct blockResponse *reply)
+blockInfoCliFormatResponse(blockInfoCli *blk, int errCode,
+ char *errMsg, MetaInfo *info,
+ struct blockResponse *reply)
{
json_object *json_obj = NULL;
json_object *json_array = NULL;
@@ -1685,10 +2251,10 @@ block_info_cli_format_response(blockInfoCli *blk, int errCode,
}
if (errCode < 0) {
- errCode = 255;
+ errCode = GB_DEFAULT_ERRCODE;
}
if (errMsg) {
- block_format_error_response(blk->json_resp, errCode, errMsg, reply);
+ blockFormatErrorResponse(blk->json_resp, errCode, errMsg, reply);
return;
}
@@ -1699,11 +2265,12 @@ block_info_cli_format_response(blockInfoCli *blk, int errCode,
json_object_object_add(json_obj, "GBID", json_object_new_string(info->gbid));
json_object_object_add(json_obj, "SIZE", json_object_new_int64(info->size));
json_object_object_add(json_obj, "HA", json_object_new_int(info->mpath));
+ json_object_object_add(json_obj, "PASSWORD", json_object_new_string(info->passwd));
json_array = json_object_new_array();
for (i = 0; i < info->nhosts; i++) {
- if (blockMetaStatusEnumParse(info->list[i]->status) == GB_CONFIG_SUCCESS) {
+ if (blockhostIsValid (info->list[i]->status)) {
json_object_array_add(json_array, json_object_new_string(info->list[i]->addr));
}
}
@@ -1717,18 +2284,18 @@ block_info_cli_format_response(blockInfoCli *blk, int errCode,
json_object_put(json_obj);
} else {
if (GB_ASPRINTF(&tmp, "NAME: %s\nVOLUME: %s\nGBID: %s\nSIZE: %zu\n"
- "HA: %zu\nBLOCK CONFIG NODE(S):",
- blk->block_name, info->volume, info->gbid,
- info->size, info->mpath) == -1) {
+ "HA: %zu\nPASSWORD: %s\nBLOCK CONFIG NODE(S):",
+ blk->block_name, info->volume, info->gbid, info->size, info->mpath,
+ info->passwd) == -1) {
goto out;
}
for (i = 0; i < info->nhosts; i++) {
- if (blockMetaStatusEnumParse(info->list[i]->status) == GB_CONFIG_SUCCESS) {
- if (GB_ASPRINTF(&out, "%s %s", tmp, info->list[i]->addr) == -1) {
- GB_FREE (tmp);
- goto out;
- }
- tmp = out;
+ if (blockhostIsValid (info->list[i]->status)) {
+ if (GB_ASPRINTF(&out, "%s %s", tmp, info->list[i]->addr) == -1) {
+ GB_FREE (tmp);
+ goto out;
+ }
+ tmp = out;
}
}
if (GB_ASPRINTF(&reply->out, "%s\n", tmp) == -1) {
@@ -1799,7 +2366,7 @@ block_info_cli_1_svc(blockInfoCli *blk, struct svc_req *rqstp)
}
- block_info_cli_format_response(blk, errCode, errMsg, info, reply);
+ blockInfoCliFormatResponse(blk, errCode, errMsg, info, reply);
glfs_fini(glfs);
GB_FREE(errMsg);
blockFreeMetaInfo(info);