diff options
Diffstat (limited to 'cli/src/cli-rpc-ops.c')
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 384 | 
1 files changed, 355 insertions, 29 deletions
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 12f54f61f23..d683457ed25 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -40,6 +40,7 @@  #include "cli-quotad-client.h"  #include "run.h"  #include "quota-common-utils.h" +#include "events.h"  enum gf_task_types {          GF_TASK_TYPE_REBALANCE, @@ -10318,6 +10319,334 @@ out:  }  int +gf_cli_generate_snapshot_event (gf_cli_rsp *rsp, dict_t *dict, +                                int32_t type, char *snap_name, +                                char *volname, char *snap_uuid, +                                char *clone_name) +{ +        int         ret               = -1; +        int         config_command    = 0; +        int32_t     delete_cmd        = -1; +        uint64_t    hard_limit        = 0; +        uint64_t    soft_limit        = 0; +        char       *auto_delete       = NULL; +        char       *snap_activate     = NULL; +        char        msg[PATH_MAX]     = {0, }; +        char        option[PATH_MAX]  = {0, }; + +        GF_VALIDATE_OR_GOTO ("cli", dict, out); +        GF_VALIDATE_OR_GOTO ("cli", rsp, out); + +        switch (type) { +        case GF_SNAP_OPTION_TYPE_CREATE: +                if (!snap_name) { +                        gf_log ("cli", GF_LOG_ERROR, +                                "Failed to get snap name"); +                        goto out; +                } + +                if (!volname) { +                        gf_log ("cli", GF_LOG_ERROR, +                                "Failed to get volume name"); +                        goto out; +                } + +                if (rsp->op_ret != 0) { +                        gf_event (EVENT_SNAPSHOT_CREATE_FAILED, +                                  "snapshot_name=%s;volume_name=%s;error=%s", +                                  snap_name, volname, +                                  rsp->op_errstr ? rsp->op_errstr : +                                  "Please check log file for details"); +                        ret = 0; +                        break; +                } + +                if (!snap_uuid) { +                        gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); +                        goto out; +                } + +                gf_event (EVENT_SNAPSHOT_CREATED, "snapshot_name=%s;" +                          "volume_name=%s;snapshot_uuid=%s", snap_name, +                          volname, snap_uuid); + +                ret = 0; +                break; + +        case GF_SNAP_OPTION_TYPE_ACTIVATE: +                if (!snap_name) { +                        gf_log ("cli", GF_LOG_ERROR, +                                "Failed to get snap name"); +                        goto out; +                } + +                if (rsp->op_ret != 0) { +                        gf_event (EVENT_SNAPSHOT_ACTIVATE_FAILED, +                                  "snapshot_name=%s;error=%s", snap_name, +                                  rsp->op_errstr ? rsp->op_errstr : +                                  "Please check log file for details"); +                        ret = 0; +                        break; +                } + +                if (!snap_uuid) { +                        gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); +                        goto out; +                } + +                gf_event (EVENT_SNAPSHOT_ACTIVATED, "snapshot_name=%s;" +                          "snapshot_uuid=%s", snap_name, snap_uuid); + +                ret = 0; +                break; + +        case GF_SNAP_OPTION_TYPE_DEACTIVATE: +                if (!snap_name) { +                        gf_log ("cli", GF_LOG_ERROR, +                                "Failed to get snap name"); +                        goto out; +                } + +                if (rsp->op_ret != 0) { +                        gf_event (EVENT_SNAPSHOT_DEACTIVATE_FAILED, +                                  "snapshot_name=%s;error=%s", snap_name, +                                  rsp->op_errstr ? rsp->op_errstr : +                                  "Please check log file for details"); +                        ret = 0; +                        break; +                } + +                if (!snap_uuid) { +                        gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); +                        goto out; +                } + +                gf_event (EVENT_SNAPSHOT_DEACTIVATED, "snapshot_name=%s;" +                          "snapshot_uuid=%s", snap_name, snap_uuid); + +                ret = 0; +                break; + +        case GF_SNAP_OPTION_TYPE_RESTORE: +                if (!snap_name) { +                        gf_log ("cli", GF_LOG_ERROR, +                                "Failed to get snap name"); +                        goto out; +                } + +                if (rsp->op_ret != 0) { +                        gf_event (EVENT_SNAPSHOT_RESTORE_FAILED, +                                  "snapshot_name=%s;error=%s", snap_name, +                                  rsp->op_errstr ? rsp->op_errstr : +                                  "Please check log file for details"); +                        ret = 0; +                        break; +                } + +                if (!snap_uuid) { +                        gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); +                        goto out; +                } + +                if (!volname) { +                        gf_log ("cli", GF_LOG_ERROR, "Failed to get volname"); +                        goto out; +                } + +                gf_event (EVENT_SNAPSHOT_RESTORED, "snapshot_name=%s;" +                          "snapshot_uuid=%s;volume_name=%s", +                          snap_name, snap_uuid, volname); + +                ret = 0; +                break; + +        case GF_SNAP_OPTION_TYPE_DELETE: +                ret = dict_get_int32 (dict, "sub-cmd", &delete_cmd); +                if (ret) { +                        gf_log ("cli", GF_LOG_ERROR, "Could not get sub-cmd"); +                        goto out; +                } + +                /* +                 * Need not generate any event (success or failure) for delete * +                 * all, as it will trigger individual delete for all snapshots * +                 */ +                if (delete_cmd == GF_SNAP_DELETE_TYPE_ALL) { +                        ret = 0; +                        break; +                } + +                if (!snap_name) { +                        gf_log ("cli", GF_LOG_ERROR, +                                "Failed to get snap name"); +                        goto out; +                } + +                if (rsp->op_ret != 0) { +                        gf_event (EVENT_SNAPSHOT_DELETE_FAILED, +                                  "snapshot_name=%s;error=%s", snap_name, +                                  rsp->op_errstr ? rsp->op_errstr : +                                  "Please check log file for details"); +                        ret = 0; +                        break; +                } + +                if (!snap_uuid) { +                        gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); +                        goto out; +                } + +                gf_event (EVENT_SNAPSHOT_DELETED, "snapshot_name=%s;" +                          "snapshot_uuid=%s", snap_name, snap_uuid); + +                ret = 0; +                break; + +        case GF_SNAP_OPTION_TYPE_CLONE: +                if (!clone_name) { +                        gf_log ("cli", GF_LOG_ERROR, +                                "Failed to get clone name"); +                        goto out; +                } + +                if (!snap_name) { +                        gf_log ("cli", GF_LOG_ERROR, +                                "Failed to get snapname name"); +                        goto out; +                } + +                if (rsp->op_ret != 0) { +                        gf_event (EVENT_SNAPSHOT_CLONE_FAILED, +                                  "snapshot_name=%s;clone_name=%s;" +                                  "error=%s", snap_name, clone_name, +                                  rsp->op_errstr ? rsp->op_errstr : +                                  "Please check log file for details"); +                        ret = 0; +                        break; +                } + +                if (!snap_uuid) { +                        gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); +                        goto out; +                } + +                gf_event (EVENT_SNAPSHOT_CLONED, "snapshot_name=%s;" +                          "clone_name=%s;clone_uuid=%s", +                          snap_name, clone_name, snap_uuid); + +                ret = 0; +                break; + +        case GF_SNAP_OPTION_TYPE_CONFIG: +                if (rsp->op_ret != 0) { +                        gf_event (EVENT_SNAPSHOT_CONFIG_UPDATE_FAILED, +                                  "error=%s", +                                  rsp->op_errstr ? rsp->op_errstr : +                                  "Please check log file for details"); +                        ret = 0; +                        break; +                } + +                ret = dict_get_int32 (dict, "config-command", &config_command); +                if (ret) { +                        gf_log ("cli", GF_LOG_ERROR, +                                "Could not fetch config type"); +                        goto out; +                } + +                if (config_command == GF_SNAP_CONFIG_DISPLAY) { +                        ret = 0; +                        break; +                } + +                /* These are optional parameters therefore ignore the error */ +                ret = dict_get_uint64 (dict, "snap-max-hard-limit", +                                       &hard_limit); +                ret = dict_get_uint64 (dict, "snap-max-soft-limit", +                                       &soft_limit); +                ret = dict_get_str (dict, "auto-delete", +                                    &auto_delete); +                ret = dict_get_str (dict, "snap-activate-on-create", +                                    &snap_activate); + +                if (!hard_limit && !soft_limit && +                    !auto_delete && !snap_activate) { +                        ret = -1; +                        gf_log ("cli", GF_LOG_ERROR, "At least one option from " +                                "snap-max-hard-limit, snap-max-soft-limit, " +                                "auto-delete and snap-activate-on-create " +                                "should be set"); +                        goto out; +                } + +                volname = NULL; +                ret = dict_get_str (dict, "volname", &volname); + +                if (hard_limit || soft_limit) { +                        snprintf (option, sizeof(option), "%s=%"PRIu64, +                                  hard_limit ? "hard_limit" : "soft_limit", +                                  hard_limit ? hard_limit:soft_limit); +                } else if (auto_delete || snap_activate) { +                        snprintf (option, sizeof(option), "%s=%s", +                                  auto_delete ? "auto-delete" : "snap-activate", +                                  auto_delete ? auto_delete:snap_activate); +                } + +                snprintf (msg, sizeof(msg), "config_type=%s;%s", +                          volname?"volume_config":"system_config", option); + +                gf_event (EVENT_SNAPSHOT_CONFIG_UPDATED, "%s", msg); + +                ret = 0; +                break; + +        default: +                gf_log ("cli", GF_LOG_WARNING, +                        "Cannot generate event for unknown type."); +                ret = 0; +                goto out; +        } + +out: +        return ret; +} + +/* + * Fetch necessary data from dict at one place instead of * + * repeating the same code again and again.               * + */ +int +gf_cli_snapshot_get_data_from_dict (dict_t *dict, char **snap_name, +                                    char **volname, char **snap_uuid, +                                    int8_t *soft_limit_flag, +                                    char **clone_name) +{ +        int     ret = -1; + +        GF_VALIDATE_OR_GOTO ("cli", dict, out); + +        if (snap_name) +                ret = dict_get_str (dict, "snapname", snap_name); + +        if (volname) +                ret = dict_get_str (dict, "volname1", volname); + +        if (snap_uuid) +                ret = dict_get_str (dict, "snapuuid", snap_uuid); + +        if (soft_limit_flag) +                ret = dict_get_int8 (dict, "soft-limit-reach", +                                     soft_limit_flag); + +        if (clone_name) +                ret = dict_get_str (dict, "clonename", clone_name); + +        ret = 0; +out: +        return ret; +} + +int  gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                       int count, void *myframe)  { @@ -10331,6 +10660,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,          gf_boolean_t         snap_driven               = _gf_false;          int8_t               soft_limit_flag           = -1;          char                 *volname                  = NULL; +        char                 *snap_uuid                = NULL;          GF_ASSERT (myframe); @@ -10365,6 +10695,24 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                  goto out;          } +        ret = gf_cli_snapshot_get_data_from_dict (dict, &snap_name, &volname, +                                                  &snap_uuid, &soft_limit_flag, +                                                  &clone_name); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Failed to fetch data from dict."); +                goto out; +        } + +#if (USE_EVENTS) +        ret = gf_cli_generate_snapshot_event (&rsp, dict, type, snap_name, +                                              volname, snap_uuid, clone_name); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, +                        "Failed to generate snapshot event"); +                goto out; +        } +#endif +          /* Snapshot status and delete command is handled separately */          if (global_state->mode & GLUSTER_MODE_XML &&              GF_SNAP_OPTION_TYPE_STATUS != type && @@ -10388,19 +10736,13 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                                   goto out;                  } -                ret = dict_get_str (dict, "snapname", &snap_name); -                if (ret) { +                if (!snap_name) {                          gf_log ("cli", GF_LOG_ERROR,                                  "Failed to get snap name");                          goto out;                  } -                /* TODO : Instead of using volname1 directly use -                 * volname$i in loop once snapshot of multiple -                 * volumes are supported -                 */ -                ret = dict_get_str (dict, "volname1", &volname); -                if (ret) { +                if (!volname) {                          gf_log ("cli", GF_LOG_ERROR,                                  "Failed to get volume name");                          goto out; @@ -10409,8 +10751,6 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                  cli_out ("snapshot create: success: Snap %s created "                                          "successfully", snap_name); -                ret = dict_get_int8 (dict, "soft-limit-reach", -                                    &soft_limit_flag);                  if (soft_limit_flag == 1) {                          cli_out ("Warning: Soft-limit of volume (%s) is "                                  "reached. Snapshot creation is not possible " @@ -10428,15 +10768,13 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                                   goto out;                  } -                ret = dict_get_str (dict, "clonename", &clone_name); -                if (ret) { +                if (!clone_name) {                          gf_log ("cli", GF_LOG_ERROR,                                  "Failed to get clone name");                          goto out;                  } -                ret = dict_get_str (dict, "snapname", &snap_name); -                if (ret) { +                if (!snap_name) {                          gf_log ("cli", GF_LOG_ERROR,                                  "Failed to get snapname name");                          goto out; @@ -10449,9 +10787,6 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                  break;          case GF_SNAP_OPTION_TYPE_RESTORE: -                /* TODO: Check if rsp.op_ret needs to be checked here. Or is -                 * it ok to check this in the start of the function where we -                 * get rsp.*/                  if (rsp.op_ret) {                          cli_err("snapshot restore: failed: %s",                                   rsp.op_errstr ? rsp.op_errstr : @@ -10460,8 +10795,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                                   goto out;                  } -                ret = dict_get_str (dict, "snapname", &snap_name); -                if (ret) { +                if (!snap_name) {                          gf_log ("cli", GF_LOG_ERROR,                                  "Failed to get snap name");                          goto out; @@ -10473,9 +10807,6 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                  ret = 0;                  break;          case GF_SNAP_OPTION_TYPE_ACTIVATE: -                /* TODO: Check if rsp.op_ret needs to be checked here. Or is -                 * it ok to check this in the start of the function where we -                 * get rsp.*/                  if (rsp.op_ret) {                          cli_err("snapshot activate: failed: %s",                                   rsp.op_errstr ? rsp.op_errstr : @@ -10484,8 +10815,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                                   goto out;                  } -                ret = dict_get_str (dict, "snapname", &snap_name); -                if (ret) { +                if (!snap_name) {                          gf_log ("cli", GF_LOG_ERROR,                                  "Failed to get snap name");                          goto out; @@ -10498,9 +10828,6 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                  break;          case GF_SNAP_OPTION_TYPE_DEACTIVATE: -                /* TODO: Check if rsp.op_ret needs to be checked here. Or is -                 * it ok to check this in the start of the function where we -                 * get rsp.*/                  if (rsp.op_ret) {                          cli_err("snapshot deactivate: failed: %s",                                   rsp.op_errstr ? rsp.op_errstr : @@ -10509,8 +10836,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                                   goto out;                  } -                ret = dict_get_str (dict, "snapname", &snap_name); -                if (ret) { +                if (!snap_name) {                          gf_log ("cli", GF_LOG_ERROR,                                  "Failed to get snap name");                          goto out;  | 
