diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-snapshot.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-snapshot.c | 284 |
1 files changed, 222 insertions, 62 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index 327155fee31..e7972bd8674 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -593,10 +593,12 @@ int glusterd_snapshot_restore (dict_t *dict, char **op_errstr, dict_t *rsp_dict) { int ret = -1; + int32_t volcount = -1; char *snapname = NULL; xlator_t *this = NULL; glusterd_volinfo_t *snap_volinfo = NULL; - glusterd_volinfo_t *volinfo = NULL; + glusterd_volinfo_t *tmp = NULL; + glusterd_volinfo_t *parent_volinfo = NULL; glusterd_snap_t *snap = NULL; glusterd_conf_t *priv = NULL; @@ -629,42 +631,43 @@ glusterd_snapshot_restore (dict_t *dict, char **op_errstr, dict_t *rsp_dict) goto out; } - - /* TODO : As of now there is only volume in snapshot. - * Change this when multiple volume snapshot is introduced - */ - snap_volinfo = list_entry (snap->volumes.next, glusterd_volinfo_t, - vol_list); - - ret = glusterd_volinfo_find (snap_volinfo->parent_volname, &volinfo); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Could not get volinfo of " - "%s", snap_volinfo->parent_volname); - goto out; - } - - if (is_origin_glusterd (dict) == _gf_true) { - /* From origin glusterd check if * - * any peers with snap bricks is down */ - ret = glusterd_find_missed_snap (rsp_dict, snap_volinfo, - &priv->peers, - GF_SNAP_OPTION_TYPE_RESTORE); + volcount = 0; + list_for_each_entry_safe (snap_volinfo, tmp, &snap->volumes, vol_list) { + volcount++; + ret = glusterd_volinfo_find (snap_volinfo->parent_volname, + &parent_volinfo); if (ret) { gf_log (this->name, GF_LOG_ERROR, - "Failed to find missed snap restores"); + "Could not get volinfo of %s", + snap_volinfo->parent_volname); goto out; } - } - ret = gd_restore_snap_volume (rsp_dict, volinfo, snap_volinfo); - if (ret) { - /* No need to update op_errstr because it is assumed - * that the called function will do that in case of - * failure. - */ - gf_log (this->name, GF_LOG_ERROR, "Failed to restore " - "snap for %s", snapname); - goto out; + if (is_origin_glusterd (dict) == _gf_true) { + /* From origin glusterd check if * + * any peers with snap bricks is down */ + ret = glusterd_find_missed_snap + (rsp_dict, snap_volinfo, + &priv->peers, + GF_SNAP_OPTION_TYPE_RESTORE); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to find missed snap restores"); + goto out; + } + } + + ret = gd_restore_snap_volume (dict, rsp_dict, parent_volinfo, + snap_volinfo, volcount); + if (ret) { + /* No need to update op_errstr because it is assumed + * that the called function will do that in case of + * failure. + */ + gf_log (this->name, GF_LOG_ERROR, "Failed to restore " + "snap for %s", snapname); + goto out; + } } ret = 0; @@ -693,11 +696,13 @@ glusterd_snapshot_restore_prevalidate (dict_t *dict, char **op_errstr, int ret = -1; int32_t i = 0; int32_t volcount = 0; + int32_t brick_count = 0; gf_boolean_t snap_restored = _gf_false; char key[PATH_MAX] = {0, }; char *volname = NULL; char *snapname = NULL; glusterd_volinfo_t *volinfo = NULL; + glusterd_brickinfo_t *brickinfo = NULL; glusterd_snap_t *snap = NULL; xlator_t *this = NULL; @@ -799,7 +804,64 @@ glusterd_snapshot_restore_prevalidate (dict_t *dict, char **op_errstr, } } - ret = 0; + /* Get brickinfo for snap_volumes */ + volcount = 0; + list_for_each_entry (volinfo, &snap->volumes, vol_list) { + volcount++; + brick_count = 0; + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + brick_count++; + if (uuid_compare (brickinfo->uuid, MY_UUID)) + continue; + + snprintf (key, sizeof (key), "snap%d.brick%d.path", + volcount, brick_count); + ret = dict_set_str (rsp_dict, key, brickinfo->path); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set %s", key); + goto out; + } + + snprintf (key, sizeof (key), + "snap%d.brick%d.snap_status", + volcount, brick_count); + ret = dict_set_int32 (rsp_dict, key, + brickinfo->snap_status); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set %s", key); + goto out; + } + + snprintf (key, sizeof (key), + "snap%d.brick%d.device_path", + volcount, brick_count); + ret = dict_set_str (rsp_dict, key, + brickinfo->device_path); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set %s", key); + goto out; + } + } + + snprintf (key, sizeof (key), "snap%d.brick_count", volcount); + ret = dict_set_int32 (rsp_dict, key, brick_count); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set %s", key); + goto out; + } + } + + ret = dict_set_int32 (rsp_dict, "volcount", volcount); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set %s", key); + goto out; + } + out: return ret; } @@ -1140,6 +1202,101 @@ out: return ret; } +/* Aggregate brickinfo's of the snap volumes to be restored from */ +int32_t +glusterd_snap_restore_use_rsp_dict (dict_t *dst, dict_t *src) +{ + char key[PATH_MAX] = ""; + char *strvalue = NULL; + int32_t value = -1; + int32_t i = -1; + int32_t j = -1; + int32_t vol_count = -1; + int32_t brickcount = -1; + int32_t ret = -1; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); + + if (!dst || !src) { + gf_log (this->name, GF_LOG_ERROR, "Source or Destination " + "dict is empty."); + goto out; + } + + ret = dict_get_int32 (src, "volcount", &vol_count); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, "No volumes"); + ret = 0; + goto out; + } + + for (i = 1; i <= vol_count; i++) { + snprintf (key, sizeof (key), "snap%d.brick_count", i); + ret = dict_get_int32 (src, key, &brickcount); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to get %s", key); + goto out; + } + + for (j = 1; j <= brickcount; j++) { + snprintf (key, sizeof (key), "snap%d.brick%d.path", + i, j); + ret = dict_get_str (src, key, &strvalue); + if (ret) { + /* The brickinfo will be present in + * another rsp_dict */ + gf_log (this->name, GF_LOG_DEBUG, + "%s not present", key); + ret = 0; + continue; + } + ret = dict_set_dynstr_with_alloc (dst, key, strvalue); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, + "Failed to set %s", key); + goto out; + } + + snprintf (key, sizeof (key), + "snap%d.brick%d.snap_status", i, j); + ret = dict_get_int32 (src, key, &value); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to get %s", key); + goto out; + } + ret = dict_set_int32 (dst, key, value); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set %s", key); + goto out; + } + + snprintf (key, sizeof (key), + "snap%d.brick%d.device_path", i, j); + ret = dict_get_str (src, key, &strvalue); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to get %s", key); + goto out; + } + ret = dict_set_dynstr_with_alloc (dst, key, strvalue); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, + "Failed to set %s", key); + goto out; + } + } + } + +out: + gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret); + return ret; +} + int glusterd_snap_pre_validate_use_rsp_dict (dict_t *dst, dict_t *src) { @@ -1172,6 +1329,14 @@ glusterd_snap_pre_validate_use_rsp_dict (dict_t *dst, dict_t *src) goto out; } break; + case GF_SNAP_OPTION_TYPE_RESTORE: + ret = glusterd_snap_restore_use_rsp_dict (dst, src); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Unable to use " + "rsp dict"); + goto out; + } + break; default: break; } @@ -1341,7 +1506,8 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr, goto out; } - device = glusterd_get_brick_mount_details (brickinfo); + device = glusterd_get_brick_mount_details + (brickinfo->path); if (!device) { snprintf (err_str, sizeof (err_str), "getting device name for the brick " @@ -3282,7 +3448,7 @@ out: */ char * glusterd_take_lvm_snapshot (glusterd_volinfo_t *snap_vol, - glusterd_brickinfo_t *brickinfo) + char *brick_path) { char msg[NAME_MAX] = ""; char buf[PATH_MAX] = ""; @@ -3295,17 +3461,13 @@ glusterd_take_lvm_snapshot (glusterd_volinfo_t *snap_vol, xlator_t *this = NULL; this = THIS; + GF_ASSERT (this); + GF_ASSERT (brick_path); - if (!brickinfo) { - gf_log (this->name, GF_LOG_ERROR, "brickinfo NULL"); - goto out; - } - - device = glusterd_get_brick_mount_details (brickinfo); + device = glusterd_get_brick_mount_details (brick_path); if (!device) { gf_log (this->name, GF_LOG_ERROR, "getting device name for " - "the brick %s:%s failed", brickinfo->hostname, - brickinfo->path); + "the brick %s failed", brick_path); goto out; } @@ -3338,8 +3500,8 @@ glusterd_take_lvm_snapshot (glusterd_volinfo_t *snap_vol, /* Takng the actual snapshot */ runinit (&runner); - snprintf (msg, sizeof (msg), "taking snapshot of the brick %s:%s", - brickinfo->hostname, brickinfo->path); + snprintf (msg, sizeof (msg), "taking snapshot of the brick %s", + brick_path); if (match == _gf_true) runner_add_args (&runner, LVM_CREATE, "-s", device, "--setactivationskip", "n", "--name", @@ -3347,12 +3509,12 @@ glusterd_take_lvm_snapshot (glusterd_volinfo_t *snap_vol, else runner_add_args (&runner, LVM_CREATE, "-s", device, "--name", snap_vol->volname, NULL); - runner_log (&runner, "", GF_LOG_DEBUG, msg); + runner_log (&runner, this->name, GF_LOG_DEBUG, msg); ret = runner_start (&runner); if (ret) { gf_log (this->name, GF_LOG_ERROR, "taking snapshot of the " - "brick (%s:%s) of device %s failed", - brickinfo->hostname, brickinfo->path, device); + "brick (%s) of device %s failed", + brick_path, device); runner_end (&runner); goto out; } @@ -3374,7 +3536,6 @@ out: int32_t glusterd_snap_brick_create (char *device, glusterd_volinfo_t *snap_volinfo, - glusterd_brickinfo_t *original_brickinfo, int32_t brick_count, char *snap_brick_dir) { int32_t ret = -1; @@ -3389,12 +3550,11 @@ glusterd_snap_brick_create (char *device, glusterd_volinfo_t *snap_volinfo, GF_ASSERT (device); GF_ASSERT (snap_volinfo); - GF_ASSERT (original_brickinfo); GF_ASSERT (snap_brick_dir); snprintf (snap_brick_mount_path, sizeof (snap_brick_mount_path), "%s/%s/brick%d", snap_mount_folder, snap_volinfo->volname, - brick_count+1); + brick_count); snprintf (snap_brick_path, sizeof (snap_brick_path), "%s%s", snap_brick_mount_path, snap_brick_dir); @@ -3574,7 +3734,6 @@ static int32_t glusterd_take_brick_snapshot (glusterd_volinfo_t *origin_vol, glusterd_volinfo_t *snap_vol, dict_t *rsp_dict, glusterd_brickinfo_t *original_brickinfo, - glusterd_brickinfo_t *snap_brickinfo, char *snap_brick_dir, int32_t brick_count) { char *device = NULL; @@ -3587,10 +3746,10 @@ glusterd_take_brick_snapshot (glusterd_volinfo_t *origin_vol, GF_ASSERT (snap_vol); GF_ASSERT (rsp_dict); GF_ASSERT (original_brickinfo); - GF_ASSERT (snap_brickinfo); GF_ASSERT (snap_brick_dir); - device = glusterd_take_lvm_snapshot (snap_vol, original_brickinfo); + device = glusterd_take_lvm_snapshot (snap_vol, + original_brickinfo->path); /* Fail the snapshot even though snapshot on one of the bricks fails. At the end when we check whether the snapshot volume meets quorum or not, then the @@ -3607,11 +3766,10 @@ glusterd_take_brick_snapshot (glusterd_volinfo_t *origin_vol, /* create the complete brick here */ ret = glusterd_snap_brick_create (device, snap_vol, - original_brickinfo, - brick_count, snap_brick_dir); + brick_count + 1, snap_brick_dir); if (ret) { gf_log (this->name, GF_LOG_ERROR, "not able to" - " create the brickinfo for the snap %s" + " create the brick for the snap %s" ", volume %s", snap_vol->snapshot->snapname, origin_vol->volname); goto out; @@ -3749,7 +3907,6 @@ glusterd_do_snap_vol (glusterd_volinfo_t *origin_vol, glusterd_snap_t *snap, ret = glusterd_take_brick_snapshot (origin_vol, snap_vol, rsp_dict, brickinfo, - snap_brickinfo, snap_brick_dir, brick_count); if (ret) { @@ -4732,7 +4889,7 @@ glusterd_get_brick_lvm_details (dict_t *rsp_dict, priv = this->private; GF_ASSERT (priv); - device = glusterd_get_brick_mount_details (brickinfo); + device = glusterd_get_brick_mount_details (brickinfo->path); if (!device) { gf_log (this->name, GF_LOG_ERROR, "Getting device name for " "the brick %s:%s failed", brickinfo->hostname, @@ -6638,9 +6795,10 @@ out: * @return 0 on success and negative value on error */ int -gd_restore_snap_volume (dict_t *rsp_dict, +gd_restore_snap_volume (dict_t *dict, dict_t *rsp_dict, glusterd_volinfo_t *orig_vol, - glusterd_volinfo_t *snap_vol) + glusterd_volinfo_t *snap_vol, + int32_t volcount) { int ret = -1; glusterd_volinfo_t *new_volinfo = NULL; @@ -6652,6 +6810,7 @@ gd_restore_snap_volume (dict_t *rsp_dict, this = THIS; GF_ASSERT (this); + GF_ASSERT (dict); GF_ASSERT (rsp_dict); conf = this->private; GF_ASSERT (conf); @@ -6713,7 +6872,8 @@ gd_restore_snap_volume (dict_t *rsp_dict, &new_volinfo->snap_volumes); } /* Copy the snap vol info to the new_volinfo.*/ - ret = glusterd_snap_volinfo_restore (rsp_dict, new_volinfo, snap_vol); + ret = glusterd_snap_volinfo_restore (dict, rsp_dict, new_volinfo, + snap_vol, volcount); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to restore snap"); goto out; |