From fe5927b6bd1ed795c9e85996e7c54c3abe36ceba Mon Sep 17 00:00:00 2001 From: Vijaikumar M Date: Fri, 14 Feb 2014 20:01:38 +0530 Subject: glusterd/snapshot: store location for snap driven changes Currently snapshot volfiles are stored at: /vols//snaps/ With snap driven approach we need to store the volfiles at: /snaps// Change-Id: I8efdd5db29833b2b06b64a900cbb4c9b9a5d36b6 Signed-off-by: Vijaikumar M Signed-off-by: Sachin Pandit Reviewed-on: http://review.gluster.org/7006 Reviewed-by: Avra Sengupta Reviewed-by: Rajesh Joseph Tested-by: Rajesh Joseph --- libglusterfs/src/list.h | 28 +- tests/basic/volume-snapshot.t | 4 +- tests/bugs/bug-1040934.t | 2 +- tests/bugs/bug-1045333.t | 6 +- xlators/mgmt/glusterd/src/glusterd-handshake.c | 110 +- xlators/mgmt/glusterd/src/glusterd-op-sm.c | 32 +- xlators/mgmt/glusterd/src/glusterd-snapshot.c | 393 +++---- xlators/mgmt/glusterd/src/glusterd-store.c | 1407 +++++++++-------------- xlators/mgmt/glusterd/src/glusterd-store.h | 25 +- xlators/mgmt/glusterd/src/glusterd-utils.c | 614 ++-------- xlators/mgmt/glusterd/src/glusterd-utils.h | 12 +- xlators/mgmt/glusterd/src/glusterd-volgen.c | 49 +- xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 2 +- xlators/mgmt/glusterd/src/glusterd.c | 2 +- xlators/mgmt/glusterd/src/glusterd.h | 87 +- 15 files changed, 954 insertions(+), 1819 deletions(-) diff --git a/libglusterfs/src/list.h b/libglusterfs/src/list.h index 7f3712b51..392c22ceb 100644 --- a/libglusterfs/src/list.h +++ b/libglusterfs/src/list.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2008-2012 Red Hat, Inc. + Copyright (c) 2008-2014 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser @@ -11,7 +11,6 @@ #ifndef _LLIST_H #define _LLIST_H - struct list_head { struct list_head *next; struct list_head *prev; @@ -45,6 +44,31 @@ list_add_tail (struct list_head *new, struct list_head *head) } +/* This function will insert the element to the list in a order. + Order will be based on the compare function provided as a input. + If element to be inserted in ascending order compare should return: + 0: if both the arguments are equal + >0: if first argument is greater than second argument + <0: if first argument is less than second argument */ +static inline void +list_add_order (struct list_head *new, struct list_head *head, + int (*compare)(struct list_head *, struct list_head *)) +{ + struct list_head *pos = head->prev; + + while ( pos != head ) { + if (compare(new, pos) >= 0) + break; + + /* Iterate the list in the reverse order. This will have + better efficiency if the elements are inserted in the + ascending order */ + pos = pos->prev; + } + + list_add (new, pos); +} + static inline void list_del (struct list_head *old) { diff --git a/tests/basic/volume-snapshot.t b/tests/basic/volume-snapshot.t index bb7dcb458..f6b88068e 100755 --- a/tests/basic/volume-snapshot.t +++ b/tests/basic/volume-snapshot.t @@ -62,9 +62,9 @@ TEST snapshot_exists ${V1}_snap TEST $CLI_1 snapshot config $V0 snap-max-hard-limit 100 TEST $CLI_1 snapshot config $V1 snap-max-hard-limit 100 -TEST mount -t glusterfs $H1:/$V0/snaps/${V0}_snap $M0 +TEST mount -t glusterfs $H1:/snaps/${V0}_snap/${V0} $M0 TEST umount -f $M0 -TEST mount -t glusterfs $H2:/$V1/snaps/${V1}_snap $M0 +TEST mount -t glusterfs $H2:/snaps/${V1}_snap/${V1} $M0 TEST umount -f $M0 #Clean up diff --git a/tests/bugs/bug-1040934.t b/tests/bugs/bug-1040934.t index 38ccc1120..547f6c3bc 100644 --- a/tests/bugs/bug-1040934.t +++ b/tests/bugs/bug-1040934.t @@ -24,7 +24,7 @@ PID_1=$! wait $PID_1 TEST snapshot_exists ${V0}_snap -TEST mount -t glusterfs $H1:$V0/snaps/${V0}_snap $M0 +TEST mount -t glusterfs $H1:/snaps/${V0}_snap/$V0 $M0 cd $M0 TEST ! touch a diff --git a/tests/bugs/bug-1045333.t b/tests/bugs/bug-1045333.t index 5abdd5558..c1fd71beb 100644 --- a/tests/bugs/bug-1045333.t +++ b/tests/bugs/bug-1045333.t @@ -28,13 +28,13 @@ TEST $CLI snapshot create $V0 -n $S3 TEST snapshot_exists $S3 -TEST mount -t glusterfs $H0:/$V0/snaps/$S1 $M0 +TEST mount -t glusterfs $H0:/snaps/$S1/$V0 $M0 TEST umount -f $M0 -TEST mount -t glusterfs $H0:/$V0/snaps/$S2 $M0 +TEST mount -t glusterfs $H0:/snaps/$S2/$V0 $M0 TEST umount -f $M0 -TEST mount -t glusterfs $H0:/$V0/snaps/$S3 $M0 +TEST mount -t glusterfs $H0:/snaps/$S3/$V0 $M0 TEST umount -f $M0 #Clean up diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c index a1368e211..2fe0d0ee8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handshake.c +++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c @@ -48,15 +48,15 @@ build_volfile_path (const char *volname, char *path, char *vol = NULL; char *dup_volname = NULL; char *free_ptr = NULL; - char *tmp = NULL; - glusterd_volinfo_t *volinfo = NULL; + char *save_ptr = NULL; + char *str_token = NULL; + char *snapname = NULL; + char *snap_volname = NULL; glusterd_volinfo_t *parent_volinfo = NULL; + glusterd_volinfo_t *volinfo = NULL; glusterd_snap_t *snap = NULL; char *server = NULL; gf_boolean_t snap_volume = _gf_false; - char *str = NULL; - char *parent_volname = NULL; - char *input_vol = NULL; priv = THIS->private; @@ -66,53 +66,41 @@ build_volfile_path (const char *volname, char *path, path, path_len); ret = 1; goto out; - } else if ((tmp = strstr (volname, "/snaps/"))) { + } else if ((str_token = strstr (volname, "/snaps/"))) { /* Input volname will have below formats: - /snaps// - or - /snaps/snapname - - We need to extract snap uuid from the input volname */ + /snaps//. + or + /snaps// + We need to extract snapname and parent_volname */ snap_volume = _gf_true; - input_vol = gf_strdup (volname); - if (!input_vol) - goto out; - parent_volname = strtok_r (input_vol, "/", &str); - if (!parent_volname) - goto out; - - str = strrchr (volname, '/'); - if (str) - str++; - tmp = strstr (tmp+1, "/"); - while(*tmp && *tmp == '/') - tmp++; + /*split string by "/" */ + str_token = strtok_r(str_token, "/", &save_ptr); + snapname = strtok_r(NULL, "/", &save_ptr); + snap_volname = strtok_r(NULL, "/", &save_ptr); - /* User has provided snapname from the mountpoint. - Map the snapname to uuid to find the volfile */ - if (tmp == str) { - ret = glusterd_volinfo_find (parent_volname, - &parent_volinfo); + snap = glusterd_find_snap_by_name (snapname); + if (!snap) { + gf_log(THIS->name, GF_LOG_ERROR, "Failed to " + "fetch snap %s", snapname); + ret = -1; + goto out; + } + ret = glusterd_volinfo_find (snap_volname, + &parent_volinfo); + if (ret) { + dup_volname = gf_strdup (snap_volname); + } else { + ret = glusterd_snap_volinfo_find_from_parent_volname + (snap_volname, snap, &volinfo); if (ret) { gf_log(THIS->name, GF_LOG_ERROR, "Failed to " - "find parent volinfo for snap %s", str); - goto out; - } - snap = glusterd_find_snap_by_name (parent_volinfo, str); - if (!snap) { - gf_log(THIS->name, GF_LOG_ERROR, "Failed to " - "fetch snap %s", str); - ret = -1; + "fetch snap volume from parent volname"); goto out; } - dup_volname = gf_strdup (snap->snap_volume->volname); - } else { - dup_volname = gf_strdup (str); + dup_volname = gf_strdup (volinfo->volname); } - str = NULL; - } else if (volname[0] != '/') { /* Normal behavior */ dup_volname = gf_strdup (volname); @@ -132,24 +120,26 @@ build_volfile_path (const char *volname, char *path, if (!snap_volume) { ret = glusterd_volinfo_find (dup_volname, &volinfo); - } else { + } else { ret = 0; - if (snap) - volinfo = snap->snap_volume; - else - ret = glusterd_snap_volinfo_find (dup_volname,&volinfo); + if (!volinfo) + ret = glusterd_snap_volinfo_find (dup_volname, snap, + &volinfo); } if (ret) { /* Split the volume name */ - vol = strtok_r (dup_volname, ".", &tmp); + vol = strtok_r (dup_volname, ".", &save_ptr); if (!vol) goto out; - if (!snap_volume) + + if (!snap_volume) { ret = glusterd_volinfo_find (vol, &volinfo); - else - ret = glusterd_snap_volinfo_find (vol, - &volinfo); + } else { + ret = glusterd_snap_volinfo_find (dup_volname, snap, + &volinfo); + } + if (ret) goto out; } @@ -161,8 +151,9 @@ build_volfile_path (const char *volname, char *path, ret = snprintf (path, path_len, "%s/vols/%s/%s.vol", priv->workdir, volinfo->volname, volname); else - ret = snprintf (path, path_len, "%s/vols/%s.vol", - priv->workdir, volname); + ret = snprintf (path, path_len, "%s/snaps/%s/%s/%s.vol", + priv->workdir, volinfo->snapshot->snapname, + volinfo->volname, snap_volname); if (ret == -1) goto out; @@ -177,8 +168,8 @@ build_volfile_path (const char *volname, char *path, dup_volname); else snprintf (path, path_len, - "%s/vols/%s/snaps/%s/%s%s-fuse.vol", - priv->workdir, parent_volname, volinfo->volname, + "%s/snaps/%s/%s/%s%s-fuse.vol", priv->workdir, + volinfo->snapshot->snapname, volinfo->volname, (trusted_str ? trusted_str:""), dup_volname); ret = stat (path, &stbuf); @@ -190,15 +181,14 @@ build_volfile_path (const char *volname, char *path, priv->workdir, volinfo->volname, volname); else snprintf (path, path_len, - "%s/vols/%s/snaps/%s/%s-tcp.vol", - priv->workdir, parent_volname, - volinfo->volname, volname); + "%s/snaps/%s/%s/%s-tcp.vol", + priv->workdir, volinfo->snapshot->snapname, + volinfo->volname, snap_volname); } ret = 1; out: GF_FREE (free_ptr); - GF_FREE (input_vol); return ret; } diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index c0c72445b..625434bc8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -1544,40 +1544,18 @@ glusterd_start_bricks (glusterd_volinfo_t *volinfo) { int ret = -1; glusterd_brickinfo_t *brickinfo = NULL; - glusterd_volinfo_t *parent_volinfo = NULL; GF_ASSERT (volinfo); - if (volinfo->is_snap_volume == _gf_true) { - ret = glusterd_volinfo_find (volinfo->parent_volname, &parent_volinfo); + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + ret = glusterd_brick_start (volinfo, brickinfo, _gf_false); if (ret) { gf_log (THIS->name, GF_LOG_ERROR, - "Unable to find parent volume %s for snap %s", - volinfo->parent_volname, volinfo->volname); + "Failed to start %s:%s for %s", + brickinfo->hostname, brickinfo->path, + volinfo->volname); goto out; } - list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { - ret = glusterd_snap_brick_start (parent_volinfo, volinfo, - brickinfo, _gf_false); - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, - "Failed to start %s:%s for %s", - brickinfo->hostname, brickinfo->path, - volinfo->volname); - goto out; - } - } - } else { - list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { - ret = glusterd_brick_start (volinfo, brickinfo, _gf_false); - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, - "Failed to start %s:%s for %s", - brickinfo->hostname, brickinfo->path, - volinfo->volname); - goto out; - } - } } ret = 0; diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index 4093cda1c..ee077e7bc 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -114,7 +114,7 @@ glusterd_snapshot_restore (dict_t *dict, char **op_errstr) goto out; } - snap = glusterd_find_snap_by_name (volinfo, snapname); + snap = glusterd_find_snap_by_name (snapname); if (NULL == snap) { ret = gf_asprintf (op_errstr, "Snap (%s) not found", snapname); @@ -257,7 +257,7 @@ glusterd_snapshot_restore_prevalidate (dict_t *dict, char **op_errstr, goto out; } - snap = glusterd_find_snap_by_name (volinfo, snapname); + snap = glusterd_find_snap_by_name (snapname); if (NULL == snap) { ret = gf_asprintf (op_errstr, "Snap (%s) not found", snapname); @@ -844,6 +844,7 @@ glusterd_new_snap_object() if (snap) { LOCK_INIT (&snap->lock); INIT_LIST_HEAD (&snap->snap_list); + INIT_LIST_HEAD (&snap->volumes); snap->snap_status = GD_SNAP_STATUS_INIT; } @@ -876,178 +877,124 @@ glusterd_new_snap_cg_object(int64_t volume_count) return cg; } +/* Function glusterd_list_add_snapvol adds the volinfo object (snapshot volume) + to the snapshot object list and to the parent volume list */ int32_t -glusterd_add_snap (glusterd_volinfo_t *volinfo, glusterd_snap_t *snap) +glusterd_list_add_snapvol (glusterd_volinfo_t *origin_vol, + glusterd_volinfo_t *snap_vol) { - int ret = -1; - uint64_t count = -1; - glusterd_snap_t *entry = NULL; - glusterd_snap_t *last = NULL; - glusterd_snap_t *tmp = NULL; + int ret = -1; + glusterd_snap_t *snap = NULL; - GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out); - GF_VALIDATE_OR_GOTO ("glusterd", snap, out); + GF_VALIDATE_OR_GOTO ("glusterd", origin_vol, out); + GF_VALIDATE_OR_GOTO ("glusterd", snap_vol, out); - LOCK (&volinfo->lock); - { - list_for_each_entry_safe (entry, tmp, &volinfo->snaps, - snap_list) { - count++; - if (!strcmp (entry->snap_name, snap->snap_name) || - !uuid_compare (entry->snap_id, snap->snap_id)) { - gf_log (THIS->name, GF_LOG_ERROR, "Found " - "duplicate snap %s (%s)", - entry->snap_name, - uuid_utoa (entry->snap_id)); - goto unlock; - } - last = entry; - } - list_add_tail (&snap->snap_list, &volinfo->snaps); - volinfo->snap_count++; - gf_log (THIS->name, GF_LOG_DEBUG, "Snap %s added @ %"PRIu64, - snap->snap_name, count); - ret = 0; - } -unlock: - UNLOCK (&volinfo->lock); -out: - gf_log ("", GF_LOG_TRACE, "Returning %d", ret); - return ret; -} - -glusterd_snap_t* -glusterd_find_snap_by_index (glusterd_volinfo_t *volinfo, uint64_t index) -{ - uint64_t count = 0; - glusterd_snap_t *entry = NULL; - glusterd_snap_t *tmp = NULL; + snap = snap_vol->snapshot; + GF_ASSERT (snap); - GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out); + list_add_tail (&snap_vol->vol_list, &snap->volumes); + /* TODO: As of now there is only one volume per snapshot. + Below line should be removed once multiple volumes for + snap driven structucture is implemented */ + snap->snap_volume = snap_vol; - LOCK (&volinfo->lock); + LOCK (&origin_vol->lock); { - list_for_each_entry_safe (entry, tmp, &volinfo->snaps, - snap_list) { - if (index == count) { - gf_log (THIS->name, GF_LOG_DEBUG, "Found " - "snap %s (%s)", entry->snap_name, - uuid_utoa (entry->snap_id)); - break; - } - ++count; - } + list_add_tail (&snap_vol->snapvol_list, + &origin_vol->snap_volumes); + origin_vol->snap_count++; } - UNLOCK (&volinfo->lock); + UNLOCK (&origin_vol->lock); + + gf_log (THIS->name, GF_LOG_DEBUG, "Snap %s added to the list", + snap->snapname); + ret = 0; out: - return entry; + return ret; } glusterd_snap_t* -glusterd_find_snap_by_name (glusterd_volinfo_t *volinfo, char *snap_name) +glusterd_find_snap_by_name (char *snapname) { - uint64_t count = -1; - glusterd_snap_t *entry = NULL; - glusterd_snap_t *dup = NULL; - glusterd_snap_t *tmp = NULL; + glusterd_snap_t *snap = NULL; + glusterd_conf_t *priv = NULL; - GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out); - GF_VALIDATE_OR_GOTO ("glusterd", snap_name, out); + priv = THIS->private; + GF_ASSERT (priv); + GF_ASSERT (snapname); - LOCK (&volinfo->lock); - { - list_for_each_entry_safe (entry, tmp, &volinfo->snaps, - snap_list) { - count++; - if (!strcmp (entry->snap_name, snap_name)) { - gf_log (THIS->name, GF_LOG_DEBUG, "Found " - "snap %s (%s)", entry->snap_name, - uuid_utoa (entry->snap_id)); - dup = entry; - break; - } + + list_for_each_entry (snap, &priv->snapshots, snap_list) { + if (!strcmp (snap->snapname, snapname)) { + gf_log (THIS->name, GF_LOG_DEBUG, "Found " + "snap %s (%s)", snap->snapname, + uuid_utoa (snap->snap_id)); + goto out; } } - UNLOCK (&volinfo->lock); + snap = NULL; out: - return dup; + return snap; } glusterd_snap_t* -glusterd_find_snap_by_id (glusterd_volinfo_t *volinfo, uuid_t snap_id) +glusterd_find_snap_by_id (uuid_t snap_id) { - uint64_t count = -1; - glusterd_snap_t *entry = NULL; - glusterd_snap_t *dup = NULL; - glusterd_snap_t *tmp = NULL; + glusterd_snap_t *snap = NULL; + glusterd_conf_t *priv = NULL; + + priv = THIS->private; + GF_ASSERT (priv); - GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out); if (uuid_is_null(snap_id)) goto out; - LOCK (&volinfo->lock); - { - list_for_each_entry_safe (entry, tmp, &volinfo->snaps, - snap_list) { - count++; - if (!uuid_compare (entry->snap_id, snap_id)) { - gf_log (THIS->name, GF_LOG_DEBUG, "Found " - "snap %s (%s)", entry->snap_name, - uuid_utoa (entry->snap_id)); - dup = entry; - break; - } + list_for_each_entry (snap, &priv->snapshots, snap_list) { + if (!uuid_compare (snap->snap_id, snap_id)) { + gf_log (THIS->name, GF_LOG_DEBUG, "Found " + "snap %s (%s)", snap->snapname, + uuid_utoa (snap->snap_id)); + goto out; } } - UNLOCK (&volinfo->lock); + snap = NULL; out: - return dup; + return snap; } glusterd_snap_t* -glusterd_remove_snap_by_id (glusterd_volinfo_t *volinfo, uuid_t snap_id) +glusterd_remove_snap_by_id (uuid_t snap_id) { - glusterd_snap_t *entry = NULL; + glusterd_snap_t *snap = NULL; - GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out); if (uuid_is_null(snap_id)) goto out; - entry = glusterd_find_snap_by_id (volinfo, snap_id); + snap = glusterd_find_snap_by_id (snap_id); - if (entry) { - LOCK (&volinfo->lock); - { - entry->snap_status = GD_SNAP_STATUS_DECOMMISSION; - list_del_init (&entry->snap_list); - } - UNLOCK (&volinfo->lock); + if (snap) { + snap->snap_status = GD_SNAP_STATUS_DECOMMISSION; + list_del_init (&snap->snap_list); } out: - return entry; + return snap; } glusterd_snap_t* -glusterd_remove_snap_by_name (glusterd_volinfo_t *volinfo, char *snap_name) +glusterd_remove_snap_by_name (char *snapname) { - glusterd_snap_t *entry = NULL; + glusterd_snap_t *snap = NULL; - GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out); - GF_VALIDATE_OR_GOTO ("glusterd", snap_name, out); + GF_VALIDATE_OR_GOTO ("glusterd", snapname, out); - entry = glusterd_find_snap_by_name (volinfo, snap_name); + snap = glusterd_find_snap_by_name (snapname); - if (entry) { - LOCK (&volinfo->lock); - { - entry->snap_status = GD_SNAP_STATUS_DECOMMISSION; - list_del_init (&entry->snap_list); - volinfo->snap_count--; - } - UNLOCK (&volinfo->lock); + if (snap) { + snap->snap_status = GD_SNAP_STATUS_DECOMMISSION; + list_del_init (&snap->snap_list); } out: - return entry; + return snap; } // Big lock should already acquired before this is called @@ -1165,13 +1112,12 @@ out: } int32_t -glusterd_delete_snap_volume (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snapinfo) +glusterd_delete_snap_volume (glusterd_volinfo_t *snapinfo) { int ret = -1; - GF_ASSERT (volinfo); + GF_ASSERT (snapinfo); - ret = glusterd_store_delete_volume (volinfo, snapinfo); + ret = glusterd_store_delete_volume (snapinfo); if (ret) goto out; @@ -1215,7 +1161,7 @@ glusterd_snapshot_get_snapdetail_lk (dict_t *dict, char *keyprefix, GF_ASSERT (entry); /* Snap Name */ - value = gf_strdup (entry->snap_name); + value = gf_strdup (entry->snapname); if (NULL == value) { goto out; } @@ -1560,7 +1506,7 @@ glusterd_snapshot_vol_get_snaplist_lk (dict_t *dict, char *keyprefix, value = NULL; /* snapshot taken first should be displayed first */ - list_for_each_entry_safe (entry, tmp, &volinfo->snaps, + list_for_each_entry_safe (entry, tmp, &conf->snapshots, snap_list) { ret = snprintf (key, sizeof (key), "%s.snap-%ld", keyprefix, index); @@ -1584,8 +1530,8 @@ glusterd_snapshot_vol_get_snaplist_lk (dict_t *dict, char *keyprefix, /* If snapname is provided then get snap detail * for only that snap */ - if (strncmp (entry->snap_name, snapname, - sizeof (entry->snap_name))) { + if (strncmp (entry->snapname, snapname, + sizeof (entry->snapname))) { /* Entry not yet found.*/ ret = -1; continue; /* Check the next entry */ @@ -2294,7 +2240,7 @@ glusterd_get_cg_snap_name_lk (dict_t *dict, glusterd_snap_cg_t *cg) goto out; } - snap = glusterd_find_snap_by_index (volinfo, 0); + //snap = glusterd_find_snap_by_index (volinfo, 0); if (NULL == snap) { gf_log (this->name, GF_LOG_ERROR, "Failed to get snap for " "%s CG", cg->cg_name); @@ -2302,7 +2248,7 @@ glusterd_get_cg_snap_name_lk (dict_t *dict, glusterd_snap_cg_t *cg) goto out; } - snapname = gf_strdup (snap->snap_name); + snapname = gf_strdup (snap->snapname); if (NULL == snapname) { ret = -1; goto out; @@ -2652,11 +2598,11 @@ glusterd_snap_delete (glusterd_snap_t *snap) goto out; } - GF_FREE (snap->description); - ret = glusterd_volinfo_delete (snap->snap_volume); + ret = glusterd_store_delete_snap (snap); if (ret) - gf_log (this->name, GF_LOG_WARNING, "deleting the snap volume" - "failed for the snap %s", snap->snap_name); + goto out; + + GF_FREE (snap->description); GF_FREE (snap); ret = 0; @@ -2693,21 +2639,21 @@ out: 3. Then do this and take the snapshot OR take the snapshot and build the snap object (Can be decided later) */ -int32_t +glusterd_snap_t* glusterd_snap_create (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo, char *snapname, + char *snapname, uuid_t *snap_id, char *description, uuid_t *cg_id, glusterd_snap_cg_t *cg, char *cg_name) { glusterd_snap_t *snap = NULL; xlator_t *this = NULL; glusterd_conf_t *priv = NULL; - int ret = -1; + int ret = -1; this = THIS; priv = this->private; - GF_ASSERT (snap_volinfo); + GF_ASSERT (snap_id); GF_ASSERT (snapname); if (cg_id) GF_ASSERT (cg_name); @@ -2748,37 +2694,30 @@ glusterd_snap_create (glusterd_volinfo_t *volinfo, } } snap->time_stamp = time (NULL); - uuid_copy (snap->snap_id, snap_volinfo->volume_id); + uuid_copy (snap->snap_id, *snap_id); if (cg_id){ uuid_copy (snap->cg_id, *cg_id); strncpy (snap->cg_name, cg_name, sizeof (snap->cg_name) - 1); } - snap->snap_volume = snap_volinfo; - strcpy (snap->snap_name, snapname); - - ret = glusterd_add_snap (volinfo, snap); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "could not add the snap " - "object %s to the snap list of the volume %s", - snap_volinfo->volname, volinfo->volname); - goto out; - } + strcpy (snap->snapname, snapname); snap->snap_status = GD_SNAP_STATUS_IN_USE; + ret = 0; out: if (ret) { if (snap) { list_del_init (&snap->snap_list); + list_del_init (&snap->volumes); LOCK_DESTROY (&snap->lock); GF_FREE (snap->description); GF_FREE (snap->snap_volume); GF_FREE (snap); } + snap = NULL; } - gf_log ("", GF_LOG_TRACE, "Returning %d", ret); - return ret; + return snap; } /* This function is called to get the device path of the snap lvm. Usually @@ -3104,7 +3043,7 @@ out: int32_t glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict, glusterd_snap_cg_t *cg, uuid_t *cg_id, int volcount, - uuid_t snap_volid, char *cg_name) + uuid_t *snap_volid, char *cg_name) { char *snap_brick_mount_path = ""; char snapmntname[PATH_MAX] = ""; @@ -3117,6 +3056,7 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict, glusterd_brickinfo_t *brickinfo = NULL; glusterd_conf_t *priv = NULL; glusterd_volinfo_t *snap_volume = NULL; + glusterd_snap_t *snap = NULL; int32_t ret = -1; int32_t brick_count = 0; xlator_t *this = NULL; @@ -3132,6 +3072,16 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict, if (cg_id) GF_ASSERT (cg_name); + snap = glusterd_snap_create (volinfo, snapname, snap_volid, + description, cg_id, cg, cg_name); + if (!snap) { + gf_log (this->name, GF_LOG_ERROR, "creating the " + "snap object failed for the volume %s", + volinfo->volname); + ret = -1; + goto out; + } + ret = glusterd_volinfo_dup (volinfo, &snap_volume); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to duplicate volinfo " @@ -3141,12 +3091,13 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict, /* snap uuid is used as lvm snapshot name. This will avoid restrictions on snapshot names provided by user */ - GLUSTERD_GET_UUID_NOHYPHEN (snap_volume->volname, snap_volid); - + GLUSTERD_GET_UUID_NOHYPHEN (snap_volume->volname, *snap_volid); + snap_volume->snapshot = snap; snap_volume->is_snap_volume = _gf_true; strncpy (snap_volume->parent_volname, volinfo->volname, sizeof(snap_volume->parent_volname) - 1); - uuid_copy (snap_volume->volume_id, snap_volid); + uuid_copy (snap_volume->volume_id, *snap_volid); + snap->snap_volume = snap_volume; /* fetch internal username and password for the snap*/ @@ -3251,22 +3202,19 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict, //TODO: the quorum check of the snap volume here - ret = dict_get_str (dict, "snap-description", &description); - // for now continue the snap, if getting description fails. - - ret = glusterd_snap_create (volinfo, snap_volume, snapname, - description, cg_id, cg, cg_name); + ret = glusterd_store_snap (snap); if (ret) { - gf_log (this->name, GF_LOG_ERROR, "creating the" - "snap object failed for the volume %s", + gf_log (this->name, GF_LOG_WARNING, "Could not store snap" + "object after taking the snapshot (volume: %s)", volinfo->volname); goto out; } - ret = glusterd_store_perform_snap_store (volinfo, snapname); + ret = glusterd_store_volinfo (snap_volume, + GLUSTERD_VOLINFO_VER_AC_INCREMENT); if (ret) { - gf_log (this->name, GF_LOG_WARNING, "could not do volume store" - " after taking the snapshot (volume: %s)", + gf_log (this->name, GF_LOG_ERROR, "Failed to store snapshot " + "volinfo (%s) for volume %s", snap_volume->volname, volinfo->volname); goto out; } @@ -3297,15 +3245,21 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict, goto out; } - //check whether this is needed or not - list_add_tail (&snap_volume->vol_list, &priv->snap_list); + list_add_tail (&snap->snap_list, &priv->snapshots); + ret = glusterd_list_add_snapvol (volinfo, snap_volume); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "could not add the snap " + "volume %s to the list", + snap_volume->volname); + goto out; + } list_for_each_entry (brickinfo, &snap_volume->bricks, brick_list) { if (uuid_compare (brickinfo->uuid, MY_UUID)) continue; - ret = glusterd_snap_brick_start (volinfo, snap_volume, brickinfo, - _gf_true); + ret = glusterd_brick_start (snap_volume, brickinfo, + _gf_true); if (ret) { gf_log (this->name, GF_LOG_WARNING, "starting the " "brick %s:%s for the snap %s (volume: %s) " @@ -3317,23 +3271,20 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict, snap_volume->status = GLUSTERD_STATUS_STARTED; - ret = glusterd_store_perform_snap_volume_store (volinfo, snap_volume); +out: if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to store snapshot volinfo (%s) for volume " - "%s", snap_volume->volname, volinfo->volname); - goto out; - } + if (snap_volume) { + list_del_init (&snap_volume->vol_list); + list_del_init (&snap_volume->snapvol_list); + glusterd_delete_snap_volume (snap_volume); + } - ret = glusterd_volume_compute_cksum (volinfo, snap_volume); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to compute cksum for %s", snap_volume->volname); - goto out; + if (snap) { + glusterd_remove_snap_by_name (snap->snapname); + glusterd_snap_delete (snap); + } } -out: - if (ret) - glusterd_volinfo_delete (snap_volume); - gf_log ("", GF_LOG_TRACE, "Returning %d", ret); return ret; } @@ -3603,7 +3554,7 @@ glusterd_snapshot_remove_prevalidate (dict_t *dict, char **op_errstr, "failed (volume: %s)", volname); goto out; } - snap = glusterd_find_snap_by_name (volinfo, name); + snap = glusterd_find_snap_by_name (name); if (!snap) { ret = -1; snprintf (err_str, sizeof (err_str), "snap %s does " @@ -3621,17 +3572,17 @@ out: } int -glusterd_remove_snap (glusterd_brickinfo_t *brickinfo, const char *mount_pt, - const char *volname, const char *snapname, +glusterd_remove_snap (glusterd_volinfo_t *snap_vol, + glusterd_brickinfo_t *brickinfo, const char *mount_pt, const char *snap_device) { - int ret = -1; - xlator_t *this = NULL; - glusterd_conf_t *priv = NULL; - runner_t runner = {0,}; - char msg[1024] = {0, }; + int ret = -1; + xlator_t *this = NULL; + glusterd_conf_t *priv = NULL; + runner_t runner = {0,}; + char msg[1024] = {0, }; char pidfile[PATH_MAX] = {0, }; - pid_t pid = -1; + pid_t pid = -1; this = THIS; GF_ASSERT (this); @@ -3643,9 +3594,8 @@ glusterd_remove_snap (glusterd_brickinfo_t *brickinfo, const char *mount_pt, goto out; } + GF_ASSERT (snap_vol); GF_ASSERT (mount_pt); - GF_ASSERT (volname); - GF_ASSERT (snapname); GF_ASSERT (snap_device); /* sleep for some time so that the glusterfsd process associated @@ -3657,8 +3607,7 @@ glusterd_remove_snap (glusterd_brickinfo_t *brickinfo, const char *mount_pt, //ret = umount2 (mount_pt, MNT_FORCE); - GLUSTERD_GET_SNAP_BRICK_PIDFILE (pidfile, volname, snapname, brickinfo, - priv); + GLUSTERD_GET_BRICK_PIDFILE (pidfile, snap_vol, brickinfo, priv); if (glusterd_is_service_running (pidfile, &pid)) { ret = kill (pid, SIGKILL); if (ret && errno != ESRCH) { @@ -3761,9 +3710,8 @@ glusterd_brick_snapshot_remove (glusterd_volinfo_t *snap_volinfo, ret = -1; goto out; } - ret = glusterd_remove_snap (brickinfo, mnt_pt, - actual_volinfo->volname, - name, entry->mnt_fsname); + ret = glusterd_remove_snap (snap_volinfo, brickinfo, mnt_pt, + entry->mnt_fsname); if (mtab) endmntent (mtab); if (ret) { @@ -3806,7 +3754,7 @@ glusterd_do_snap_remove (glusterd_volinfo_t *volinfo, char *name) goto out; } - snap = glusterd_find_snap_by_name (volinfo, name); + snap = glusterd_find_snap_by_name (name); if (!snap) { gf_log (this->name, GF_LOG_ERROR, "could not find " "the snap object by the name %s", @@ -3831,9 +3779,7 @@ glusterd_do_snap_remove (glusterd_volinfo_t *volinfo, char *name) (May be a force option to delete forcefully even when the snap volume is in use.) */ - ret = glusterd_snap_brick_stop (volinfo, snap_volinfo, - brickinfo, - _gf_false); + ret = glusterd_brick_stop (snap_volinfo, brickinfo, _gf_false); if (ret) { gf_log (this->name, GF_LOG_WARNING, "stopping " "the brick %s:%s for the snap %s " @@ -3853,26 +3799,20 @@ glusterd_do_snap_remove (glusterd_volinfo_t *volinfo, char *name) goto out; } - ret = glusterd_store_delete_volume (volinfo, snap->snap_volume); + list_del_init (&snap->snap_volume->vol_list); + list_del_init (&snap->snap_volume->snapvol_list); + ret = glusterd_delete_snap_volume (snap->snap_volume); if (ret) { gf_log (this->name, GF_LOG_ERROR, "removing the snap " "store for the snap %s (volume %s) failed", - snap->snap_name, volinfo->volname); + snap->snapname, volinfo->volname); goto out; } - snap = glusterd_remove_snap_by_name (volinfo, snap->snap_name); + snap = glusterd_remove_snap_by_name (snap->snapname); GF_ASSERT (snap); //snap cannot be NULL; glusterd_snap_delete (snap); //deletes in memory snap object - ret = glusterd_store_perform_snap_list_store (volinfo); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "doing the snap " - "store for the volume %s failed", - volinfo->volname); - goto out; - } - ret = 0; out: return ret; @@ -3884,10 +3824,12 @@ glusterd_get_snap_from_cg (glusterd_volinfo_t *volinfo, glusterd_snap_cg_t *cg) char *snap_name = NULL; glusterd_snap_t *tmp_snap = NULL; glusterd_snap_t *snap = NULL; + glusterd_conf_t *priv = NULL; xlator_t *this = NULL; this = THIS; - GF_ASSERT (this); + priv = this->private; + GF_ASSERT (priv); if (!volinfo) { gf_log (this->name, GF_LOG_WARNING, "volinfo NULL"); @@ -3899,7 +3841,7 @@ glusterd_get_snap_from_cg (glusterd_volinfo_t *volinfo, glusterd_snap_cg_t *cg) goto out; } - list_for_each_entry (tmp_snap, &volinfo->snaps, snap_list) { + list_for_each_entry (tmp_snap, &priv->snapshots, snap_list) { if ((!uuid_is_null (tmp_snap->cg_id)) && (uuid_compare (tmp_snap->cg_id, cg->cg_id) == 0)) { snap = tmp_snap; @@ -3908,7 +3850,7 @@ glusterd_get_snap_from_cg (glusterd_volinfo_t *volinfo, glusterd_snap_cg_t *cg) } if (snap) - snap_name = gf_strdup (snap->snap_name); + snap_name = gf_strdup (snap->snapname); out: return snap_name; @@ -4003,6 +3945,7 @@ glusterd_snapshot_remove_commit (dict_t *dict, char **op_errstr, (volinfo)?"snap":"cg", name); goto out; } + volinfo->snap_count--; if (free_name) GF_FREE (name); name = NULL; @@ -4162,8 +4105,8 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr, goto out; } - list_for_each_entry (snap, &volinfo->snaps, snap_list) { - if (!strcmp (snap->snap_name, tmp_name)) { + list_for_each_entry (snap, &priv->snapshots, snap_list) { + if (!strcmp (snap->snapname, tmp_name)) { snprintf (err_str, sizeof (err_str), "snap with" " name %s already exists", tmp_name); gf_log (this->name, GF_LOG_ERROR, "%s", @@ -4188,11 +4131,11 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr, */ if (is_cg) { ret = glusterd_do_snap (volinfo, tmp_name, dict, - cg, cg_id, i, *snap_volid, name); + cg, cg_id, i, snap_volid, name); } else { ret = glusterd_do_snap (volinfo, tmp_name, dict, - cg, cg_id, i, *snap_volid, NULL); + cg, cg_id, i, snap_volid, NULL); } if (ret) { gf_log (this->name, GF_LOG_WARNING, "taking the " diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index c02c2c690..7b45da00f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -76,26 +76,6 @@ glusterd_store_create_brick_dir (glusterd_volinfo_t *volinfo) return ret; } -int32_t -glusterd_store_create_snap_brick_dir (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snapinfo) -{ - int32_t ret = -1; - char brickdirpath[PATH_MAX] = {0,}; - glusterd_conf_t *priv = NULL; - - GF_ASSERT (volinfo); - GF_ASSERT (snapinfo); - - priv = THIS->private; - GF_ASSERT (priv); - - GLUSTERD_GET_SNAP_BRICK_DIR (brickdirpath, volinfo, snapinfo->volname, - priv); - ret = gf_store_mkdir (brickdirpath); - - return ret; -} static void glusterd_store_key_vol_brick_set (glusterd_brickinfo_t *brickinfo, char *key_vol_brick, size_t len) @@ -145,32 +125,6 @@ glusterd_store_brickinfopath_set (glusterd_volinfo_t *volinfo, snprintf (brickpath, len, "%s/%s", brickdirpath, brickfname); } -static void -glusterd_store_snap_brickinfopath_set (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snapinfo, - glusterd_brickinfo_t *brickinfo, - char *brickpath, size_t len) -{ - char brickfname[PATH_MAX] = {0}; - char brickdirpath[PATH_MAX] = {0,}; - glusterd_conf_t *priv = NULL; - - GF_ASSERT (volinfo); - GF_ASSERT (snapinfo); - GF_ASSERT (brickpath); - GF_ASSERT (brickinfo); - GF_ASSERT (len >= PATH_MAX); - - priv = THIS->private; - GF_ASSERT (priv); - - GLUSTERD_GET_SNAP_BRICK_DIR (brickdirpath, volinfo, - snapinfo->volname, priv); - glusterd_store_brickinfofname_set (brickinfo, brickfname, - sizeof (brickfname)); - snprintf (brickpath, len, "%s/%s", brickdirpath, brickfname); -} - gf_boolean_t glusterd_store_is_valid_brickpath (char *volname, char *brick) { @@ -255,24 +209,6 @@ glusterd_store_create_brick_shandle_on_absence (glusterd_volinfo_t *volinfo, return ret; } -int32_t -glusterd_store_create_snap_brick_shandle_on_absence(glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snapinfo, - glusterd_brickinfo_t *brickinfo) -{ - char brickpath[PATH_MAX] = {0,}; - int32_t ret = 0; - - GF_ASSERT (volinfo); - GF_ASSERT (snapinfo); - GF_ASSERT (brickinfo); - - glusterd_store_snap_brickinfopath_set (volinfo, snapinfo, brickinfo, - brickpath, sizeof (brickpath)); - ret = gf_store_handle_create_on_absence (&brickinfo->shandle, - brickpath); - return ret; -} int32_t glusterd_store_brickinfo_write (int fd, glusterd_brickinfo_t *brickinfo) { @@ -366,48 +302,12 @@ glusterd_store_brickinfo (glusterd_volinfo_t *volinfo, goto out; ret = glusterd_store_perform_brick_store (brickinfo); -out: - gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret); - return ret; -} - -int32_t -glusterd_store_snap_brickinfo (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snapinfo, - glusterd_brickinfo_t *brickinfo, - int32_t brick_count, - int vol_fd) -{ - int32_t ret = -1; - - GF_ASSERT (volinfo); - GF_ASSERT (snapinfo); - GF_ASSERT (brickinfo); - - ret = glusterd_store_volinfo_brick_fname_write (vol_fd, brickinfo, - brick_count); - if (ret) - goto out; - - ret = glusterd_store_create_snap_brick_dir (volinfo, snapinfo); - if (ret) - goto out; - - ret = glusterd_store_create_snap_brick_shandle_on_absence (volinfo, - snapinfo, - brickinfo); - if (ret) - goto out; - - ret = glusterd_store_perform_brick_store (brickinfo); - if (ret) - goto out; - ret = gf_store_rename_tmppath (brickinfo->shandle); out: gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret); return ret; } + int32_t glusterd_store_delete_brick (glusterd_brickinfo_t *brickinfo, char *delete_path) { @@ -736,8 +636,7 @@ glusterd_store_voldirpath_set (glusterd_volinfo_t *volinfo, char *voldirpath, priv = THIS->private; GF_ASSERT (priv); - snprintf (voldirpath, len, "%s/%s/%s", priv->workdir, - GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname); + GLUSTERD_GET_VOLUME_DIR (voldirpath, volinfo, priv); } static int32_t @@ -751,67 +650,43 @@ glusterd_store_create_volume_dir (glusterd_volinfo_t *volinfo) glusterd_store_voldirpath_set (volinfo, voldirpath, sizeof (voldirpath)); ret = gf_store_mkdir (voldirpath); + gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret); return ret; } -static void -glusterd_store_vol_snaps_cg_dirpath_set (char *cgdirpath, size_t len) +static int32_t +glusterd_store_create_snap_dir (glusterd_snap_t *snap) { - glusterd_conf_t *priv = NULL; + int32_t ret = -1; + char snapdirpath[PATH_MAX] = {0,}; + glusterd_conf_t *priv = NULL; priv = THIS->private; GF_ASSERT (priv); + GF_ASSERT (snap); - snprintf (cgdirpath, len, "%s/%s", priv->workdir, - GLUSTERD_VOL_SNAP_CG_DIR_PREFIX); -} -static void -glusterd_store_vol_snaps_dirpath_set (glusterd_volinfo_t *volinfo, - char *snapdirpath, size_t len) -{ - glusterd_conf_t *priv = NULL; - - GF_ASSERT (volinfo); - priv = THIS->private; - GF_ASSERT (priv); + snprintf (snapdirpath, PATH_MAX, "%s/snaps/%s", priv->workdir, + snap->snapname); - snprintf (snapdirpath, len, "%s/%s/%s/%s", priv->workdir, - GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname, - GLUSTERD_VOL_SNAP_DIR_PREFIX); + ret = mkdir_p (snapdirpath, 0755, _gf_true); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "Failed to create snaps dir " + "%s", snapdirpath); + } + return ret; } static void -glusterd_store_snap_vol_dirpath_set (glusterd_volinfo_t *volinfo, - char *snapdirpath, size_t len, - char *snap_name) +glusterd_store_vol_snaps_cg_dirpath_set (char *cgdirpath, size_t len) { glusterd_conf_t *priv = NULL; - size_t strlen = 0; - char path[PATH_MAX] = {0,}; - GF_ASSERT (volinfo); priv = THIS->private; GF_ASSERT (priv); - glusterd_store_vol_snaps_dirpath_set (volinfo, path, sizeof (path)); - strlen = sizeof (path) + sizeof (*snap_name); - snprintf (snapdirpath, strlen, "%s/%s", path, snap_name); -} -/* creates GLUSTERD_VOLUME_DIR_PREFIX//snaps directory */ -static int32_t -glusterd_store_create_snaps_dir (glusterd_volinfo_t *volinfo) -{ - int32_t ret = -1; - char snapdirpath[PATH_MAX] = {0,}; - - GF_ASSERT (volinfo); - - glusterd_store_vol_snaps_dirpath_set (volinfo, snapdirpath, - sizeof (snapdirpath)); - ret = gf_store_mkdir (snapdirpath); - gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret); - return ret; + snprintf (cgdirpath, len, "%s/%s", priv->workdir, + GLUSTERD_VOL_SNAP_CG_DIR_PREFIX); } /* creates GLUSTERD_VOLUME_DIR_PREFIX/cg directory */ @@ -827,24 +702,6 @@ glusterd_store_create_snaps_cg_dir () gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret); return ret; } -/* creates GLUSTERD_VOLUME_DIR_PREFIX//snaps/ directory */ -static int32_t -glusterd_store_create_snap_vol_dir (glusterd_volinfo_t *volinfo, char *snap_name) -{ - int32_t ret = -1; - char snapdirpath[PATH_MAX] = {0,}; - - GF_ASSERT (volinfo); - GF_ASSERT (snap_name); - - glusterd_store_snap_vol_dirpath_set (volinfo, snapdirpath, - sizeof (snapdirpath), - snap_name); - - ret = gf_store_mkdir (snapdirpath); - gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret); - return ret; -} int32_t glusterd_store_volinfo_write (int fd, glusterd_volinfo_t *volinfo) @@ -870,6 +727,49 @@ out: return ret; } +int32_t +glusterd_store_snapinfo_write (glusterd_snap_t *snap) +{ + int32_t ret = -1; + int fd = 0; + char buf[PATH_MAX] = ""; + + GF_ASSERT (snap); + + fd = gf_store_mkstemp (snap->shandle); + if (fd <= 0) + goto out; + + ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_ID, + uuid_utoa (snap->snap_id)); + if (ret) + goto out; + + snprintf (buf, sizeof (buf), "%d", snap->snap_status); + ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_STATUS, buf); + if (ret) + goto out; + + snprintf (buf, sizeof (buf), "%d", snap->snap_restored); + ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_RESTORED, buf); + if (ret) + goto out; + + if (snap->description) { + ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_DESC, + snap->description); + if (ret) + goto out; + } + + snprintf (buf, sizeof (buf), "%ld", snap->time_stamp); + ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_TIMESTAMP, buf); + +out: + gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + static void glusterd_store_rbstatepath_set (glusterd_volinfo_t *volinfo, char *rbstatepath, size_t len) @@ -915,49 +815,19 @@ glusterd_store_node_state_path_set (glusterd_volinfo_t *volinfo, } static void -glusterd_store_snap_list_path_set (glusterd_volinfo_t *volinfo, - char *snap_list_path, size_t len) +glusterd_store_snapfpath_set (glusterd_snap_t *snap, char *snap_fpath, + size_t len) { - char voldirpath[PATH_MAX] = {0,}; - GF_ASSERT (volinfo); - GF_ASSERT (snap_list_path); - GF_ASSERT (len <= PATH_MAX); - - glusterd_store_voldirpath_set (volinfo, voldirpath, - sizeof (voldirpath)); - snprintf (snap_list_path, len, "%s/%s", voldirpath, - GLUSTERD_VOL_SNAP_FILE); -} + glusterd_conf_t *priv = NULL; -static void -glusterd_store_snap_volfpath_set (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snapinfo, - char *volfpath, size_t len) -{ - char voldirpath[PATH_MAX] = {0,}; - GF_ASSERT (volinfo); - GF_ASSERT (volfpath); + priv = THIS->private; + GF_ASSERT (priv); + GF_ASSERT (snap); + GF_ASSERT (snap_fpath); GF_ASSERT (len <= PATH_MAX); - glusterd_store_snap_vol_dirpath_set (volinfo, voldirpath, - sizeof (voldirpath), - snapinfo->volname); - snprintf (volfpath, len, "%s/%s", voldirpath, GLUSTERD_VOLUME_INFO_FILE); -} - -int32_t -glusterd_store_create_snap_vol_shandle_on_absence (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snapinfo) -{ - char volfpath[PATH_MAX] = {0}; - int32_t ret = 0; - - GF_ASSERT (volinfo); - - glusterd_store_snap_volfpath_set (volinfo, snapinfo, - volfpath, sizeof (volfpath)); - ret = gf_store_handle_create_on_absence (&snapinfo->shandle, volfpath); - return ret; + snprintf (snap_fpath, len, "%s/snaps/%s/%s", priv->workdir, + snap->snapname, GLUSTERD_SNAP_INFO_FILE); } static void @@ -1032,19 +902,15 @@ glusterd_store_create_nodestate_sh_on_absence (glusterd_volinfo_t *volinfo) } int32_t -glusterd_store_create_snap_list_sh_on_absence (glusterd_volinfo_t *volinfo) +glusterd_store_create_snap_shandle_on_absence (glusterd_snap_t *snap) { - char snap_list_path[PATH_MAX] = {0}; - int32_t ret = 0; - - GF_ASSERT (volinfo); + char snapfpath[PATH_MAX] = {0}; + int32_t ret = 0; - glusterd_store_snap_list_path_set (volinfo, snap_list_path, - sizeof (snap_list_path)); - ret = - gf_store_handle_create_on_absence (&volinfo->snap_list_shandle, - snap_list_path); + GF_ASSERT (snap); + glusterd_store_snapfpath_set (snap, snapfpath, sizeof (snapfpath)); + ret = gf_store_handle_create_on_absence (&snap->shandle, snapfpath); return ret; } @@ -1069,28 +935,6 @@ out: return ret; } -int32_t -glusterd_store_snap_brickinfos (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snapinfo, int vol_fd) -{ - int32_t ret = 0; - glusterd_brickinfo_t *brickinfo = NULL; - int32_t brick_count = 0; - - GF_ASSERT (volinfo); - - list_for_each_entry (brickinfo, &snapinfo->bricks, brick_list) { - ret = glusterd_store_snap_brickinfo (volinfo, snapinfo, - brickinfo, brick_count, - vol_fd); - if (ret) - goto out; - brick_count++; - } -out: - gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); - return ret; -} int32_t glusterd_store_rbstate_write (int fd, glusterd_volinfo_t *volinfo) { @@ -1213,90 +1057,6 @@ out: return ret; } -int32_t -glusterd_store_snap_list_write (int fd, glusterd_snap_t *snap, uint64_t count) -{ - int ret = -1; - char key[256] = {0, }; - char buf[PATH_MAX] = {0, }; - - GF_ASSERT (fd > 0); - GF_ASSERT (snap); - - snprintf (key, sizeof (key), "%s-%"PRIu64, GLUSTERD_STORE_KEY_SNAP_NAME, - count); - ret = gf_store_save_value (fd, key, snap->snap_name); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to store snap-name of " - "snap %s", snap->snap_name); - goto out; - } - - if ( strlen(snap->cg_name) > 0 ) { - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_CG_NAME, count); - ret = gf_store_save_value (fd, key, snap->cg_name); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to store cg_name " - "of snap %s", snap->snap_name); - goto out; - } - } - - snprintf (key, sizeof (key), "%s-%"PRIu64, GLUSTERD_STORE_KEY_SNAP_ID, - count); - ret = gf_store_save_value (fd, key, uuid_utoa(snap->snap_id)); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to store snap-ID of " - "snap %s", snap->snap_name); - goto out; - } - - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_CG_ID, count); - ret = gf_store_save_value (fd, key, uuid_utoa(snap->cg_id)); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to store CG-ID of snap %s", - snap->snap_name); - goto out; - } - snprintf (buf, sizeof (buf), "%d", snap->snap_status); - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_STATUS, count); - ret = gf_store_save_value (fd, key, buf); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to store snap-status of " - "snap %s", snap->snap_name); - goto out; - } - - if (snap->description) { - snprintf (buf, sizeof (buf), "%s", snap->description); - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_DESC, count); - ret = gf_store_save_value (fd, key, buf); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to store snap-description " - "of snap %s", snap->snap_name); - goto out; - } - } - - snprintf (buf, sizeof (buf), "%ld", snap->time_stamp); - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_TIMESTAMP, count); - ret = gf_store_save_value (fd, key, buf); - if (ret){ - gf_log ("", GF_LOG_ERROR, "Failed to store snap-time of %s", - snap->snap_name); - goto out; - } - -out: - gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); - return ret; -} - int32_t glusterd_store_snap_cg_write (int fd, glusterd_snap_cg_t *cg) { @@ -1385,79 +1145,28 @@ out: } int32_t -glusterd_store_perform_snap_volume_store (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo) +glusterd_store_snap_volume (glusterd_volinfo_t *volinfo, glusterd_snap_t *snap) { - int fd = -1; - int32_t ret = -1; + int32_t ret = -1; GF_ASSERT (volinfo); - GF_ASSERT (snap_volinfo); - - ret = glusterd_store_create_snap_vol_shandle_on_absence (volinfo, - snap_volinfo); - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, "Failed to create " - " shandle for snap %s of volume %s", volinfo->volname, - snap_volinfo->volname); - goto out; - } - fd = gf_store_mkstemp (snap_volinfo->shandle); - if (fd <= 0) { - ret = -1; - goto out; - } - - ret = glusterd_store_volinfo_write (fd, snap_volinfo); - if (ret) - goto out; - - ret = glusterd_store_snap_brickinfos (volinfo, snap_volinfo, fd); - if (ret) - goto out; - - ret = gf_store_rename_tmppath (snap_volinfo->shandle); - if (ret) - goto out; -out: - if (ret && (fd > 0)) - gf_store_unlink_tmppath (volinfo->shandle); - if (fd > 0) - close (fd); - gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); - return ret; -} -int32_t -glusterd_store_snap_volume (glusterd_volinfo_t *volinfo, glusterd_snap_t *snap) -{ - int32_t ret = -1; - glusterd_volinfo_t *snap_volinfo = NULL; - - GF_ASSERT (volinfo); - GF_ASSERT (snap); + GF_ASSERT (snap); LOCK (&snap->lock); { - snap_volinfo = snap->snap_volume; - - if (!snap_volinfo) - goto unlock; - - ret = glusterd_store_create_snap_vol_dir (volinfo, - snap_volinfo->volname); + ret = glusterd_store_create_volume_dir (volinfo); if (ret) { gf_log (THIS->name, GF_LOG_ERROR, "Failed create snapshot dir (%s) for volume " - "%s", snap->snap_name, volinfo->volname); + "%s", snap->snapname, volinfo->volname); goto unlock; } - ret = glusterd_store_perform_snap_volume_store (volinfo, - snap_volinfo); + ret = glusterd_store_perform_volume_store (volinfo); if (ret) { gf_log (THIS->name, GF_LOG_ERROR, "Failed store snapshot volinfo (%s) for volume " - "%s", snap->snap_name, volinfo->volname); + "%s", snap->snapname, volinfo->volname); goto unlock; } } @@ -1468,213 +1177,6 @@ unlock: } -int32_t -glusterd_store_perform_snap_list_store (glusterd_volinfo_t *volinfo) -{ - int fd = -1; - int32_t ret = -1; - glusterd_snap_t *entry = NULL; - glusterd_snap_t *tmp = NULL; - uint64_t count = 0; - char buf[PATH_MAX] = {0,}; - - GF_ASSERT (volinfo); - - ret = glusterd_store_create_snap_list_sh_on_absence (volinfo); - if (ret) - goto out; - fd = gf_store_mkstemp (volinfo->snap_list_shandle); - if (fd <= 0) { - ret = -1; - goto out; - } - - LOCK (&volinfo->lock); - { - list_for_each_entry_safe (entry, tmp, &volinfo->snaps, - snap_list) { - ret = glusterd_store_snap_list_write (fd, entry, count); - if (ret) - goto unlock; - count++; - } - snprintf (buf, sizeof(buf), "%"PRIu64, count); - ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_COUNT, - buf); - if (ret) - goto unlock; - } -unlock: - UNLOCK (&volinfo->lock); - - ret = gf_store_rename_tmppath (volinfo->snap_list_shandle); - if (ret) - goto out; - -out: - if (ret && (fd > 0)) - gf_store_unlink_tmppath (volinfo->snap_list_shandle); - if (fd > 0) - close (fd); - - gf_log (THIS->name, GF_LOG_TRACE, "Returning %d", ret); - return ret; -} - -int32_t -glusterd_store_perform_snap_store (glusterd_volinfo_t *volinfo, char *snapname) -{ - int fd = -1; - int32_t ret = -1; - glusterd_snap_t *entry = NULL; - glusterd_snap_t *tmp = NULL; - uint64_t count = 0; - char buf[PATH_MAX] = {0,}; - xlator_t *this = NULL; - - GF_ASSERT (volinfo); - GF_ASSERT (snapname); - - this = THIS; - GF_ASSERT (this); - - ret = glusterd_store_create_snaps_dir (volinfo); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "failed to create the snaps " - "directory for the volume %s (snap: %s)", - volinfo->volname, snapname); - goto out; - } - - ret = glusterd_store_create_snap_list_sh_on_absence (volinfo); - if (ret) - goto out; - fd = gf_store_mkstemp (volinfo->snap_list_shandle); - if (fd <= 0) { - ret = -1; - goto out; - } - - LOCK (&volinfo->lock); - { - list_for_each_entry_safe (entry, tmp, &volinfo->snaps, - snap_list) { - if (!strcmp (entry->snap_name, snapname)) { - ret = glusterd_store_snap_list_write (fd, entry, - count); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Failed to write snap list to" - " store"); - goto unlock; - } - ret = glusterd_store_snap_volume (volinfo, - entry); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Failed to store snap volume"); - goto unlock; - } - } - count++; - } - GF_ASSERT (count == volinfo->snap_count); - snprintf (buf, sizeof(buf), "%"PRIu64, count); - ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_COUNT, - buf); - if (ret) - goto unlock; - } -unlock: - UNLOCK (&volinfo->lock); - - ret = gf_store_rename_tmppath (volinfo->snap_list_shandle); - if (ret) - goto out; - -out: - if (ret && (fd > 0)) - gf_store_unlink_tmppath (volinfo->snap_list_shandle); - if (fd > 0) - close (fd); - - gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret); - return ret; -} - -int32_t -glusterd_store_perform_all_snap_store (glusterd_volinfo_t *volinfo) -{ - int fd = -1; - int32_t ret = -1; - glusterd_snap_t *entry = NULL; - glusterd_snap_t *tmp = NULL; - uint64_t count = 0; - char buf[PATH_MAX] = {0,}; - xlator_t *this = NULL; - - GF_ASSERT (volinfo); - - this = THIS; - GF_ASSERT (this); - - ret = glusterd_store_create_snaps_dir (volinfo); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "failed to create the snaps " - "directory for the volume %s", volinfo->volname); - goto out; - } - - ret = glusterd_store_create_snap_list_sh_on_absence (volinfo); - if (ret) - goto out; - fd = gf_store_mkstemp (volinfo->snap_list_shandle); - if (fd <= 0) { - ret = -1; - goto out; - } - - LOCK (&volinfo->lock); - { - list_for_each_entry_safe (entry, tmp, &volinfo->snaps, - snap_list) { - ret = glusterd_store_snap_list_write (fd, entry, count); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Failed to " - "write snap list to store"); - goto unlock; - } - ret = glusterd_store_snap_volume (volinfo, entry); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Failed to " - "store snap volume"); - goto unlock; - } - count++; - } - snprintf (buf, sizeof(buf), "%"PRIu64, count); - ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_COUNT, - buf); - if (ret) - goto unlock; - } -unlock: - UNLOCK (&volinfo->lock); - - ret = gf_store_rename_tmppath (volinfo->snap_list_shandle); - if (ret) - goto out; - -out: - if (ret && (fd > 0)) - gf_store_unlink_tmppath (volinfo->snap_list_shandle); - if (fd > 0) - close (fd); - - gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret); - return ret; -} - int32_t glusterd_store_snap_cg (glusterd_snap_cg_t *cg) { @@ -1831,8 +1333,14 @@ glusterd_store_volume_cleanup_tmp (glusterd_volinfo_t *volinfo) gf_store_unlink_tmppath (volinfo->rb_shandle); gf_store_unlink_tmppath (volinfo->node_state_shandle); +} - gf_store_unlink_tmppath (volinfo->snap_list_shandle); +void +glusterd_store_snap_cleanup_tmp (glusterd_snap_t *snap) +{ + GF_ASSERT (snap); + + gf_store_unlink_tmppath (snap->shandle); } int32_t @@ -1885,6 +1393,60 @@ out: return ret; } +int32_t +glusterd_store_snap_atomic_update (glusterd_snap_t *snap) +{ + int ret = -1; + GF_ASSERT (snap); + + ret = gf_store_rename_tmppath (snap->shandle); + if (ret) + gf_log (THIS->name, GF_LOG_ERROR, "Couldn't rename " + "temporary file(s): Reason %s", strerror (errno)); + + return ret; +} + +int32_t +glusterd_store_snap (glusterd_snap_t *snap) +{ + int32_t ret = -1; + + GF_ASSERT (snap); + + ret = glusterd_store_create_snap_dir (snap); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "Failed to create snap dir"); + goto out; + } + + ret = glusterd_store_create_snap_shandle_on_absence (snap); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "Failed to create snap info " + "file"); + goto out; + } + + ret = glusterd_store_snapinfo_write (snap); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "Failed to write snap info"); + goto out; + } + + ret = glusterd_store_snap_atomic_update (snap); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR,"Failed to do automic update"); + goto out; + } + +out: + if (ret) + glusterd_store_snap_cleanup_tmp (snap); + + gf_log (THIS->name, GF_LOG_TRACE, "Returning %d", ret); + return ret; +} + int32_t glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t ac) { @@ -1909,9 +1471,6 @@ glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t a if (ret) goto out; - ret = glusterd_store_create_snap_list_sh_on_absence (volinfo); - if (ret) - goto out; ret = glusterd_store_perform_volume_store (volinfo); if (ret) goto out; @@ -1931,12 +1490,8 @@ glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t a if (ret) goto out; - ret = glusterd_store_perform_all_snap_store (volinfo); - if (ret) - goto out; - //checksum should be computed at the end - ret = glusterd_volume_compute_cksum (volinfo, NULL); + ret = glusterd_volume_compute_cksum (volinfo); if (ret) goto out; @@ -2018,8 +1573,7 @@ out: } int32_t -glusterd_store_delete_volume (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snapinfo) +glusterd_store_delete_volume (glusterd_volinfo_t *volinfo) { char pathname[PATH_MAX] = {0,}; int32_t ret = 0; @@ -2041,22 +1595,11 @@ glusterd_store_delete_volume (glusterd_volinfo_t *volinfo, GF_ASSERT (priv); - if (snapinfo) { - GLUSTERD_GET_SNAP_DIR (pathname, volinfo, snapinfo->volname, - priv); - } else { - GLUSTERD_GET_VOLUME_DIR (pathname, volinfo, priv); - } + GLUSTERD_GET_VOLUME_DIR (pathname, volinfo, priv); - if (snapinfo == NULL ) { - snprintf (delete_path, sizeof (delete_path), - "%s/"GLUSTERD_TRASH"/%s.deleted", priv->workdir, - uuid_utoa (volinfo->volume_id)); - } else { - snprintf (delete_path, sizeof (delete_path), - "%s/"GLUSTERD_TRASH"/%s.deleted", priv->workdir, - uuid_utoa (snapinfo->volume_id)); - } + snprintf (delete_path, sizeof (delete_path), + "%s/"GLUSTERD_TRASH"/%s.deleted", priv->workdir, + uuid_utoa (volinfo->volume_id)); snprintf (trashdir, sizeof (trashdir), "%s/"GLUSTERD_TRASH, priv->workdir); @@ -2148,6 +1691,115 @@ out: return ret; } +int32_t +glusterd_store_delete_snap (glusterd_snap_t *snap) +{ + char pathname[PATH_MAX] = {0,}; + int32_t ret = 0; + glusterd_conf_t *priv = NULL; + DIR *dir = NULL; + struct dirent *entry = NULL; + char path[PATH_MAX] = {0,}; + char delete_path[PATH_MAX] = {0,}; + char trashdir[PATH_MAX] = {0,}; + struct stat st = {0, }; + xlator_t *this = NULL; + gf_boolean_t rename_fail = _gf_false; + + this = THIS; + priv = this->private; + GF_ASSERT (priv); + + GF_ASSERT (snap); + GLUSTERD_GET_SNAP_DIR (pathname, snap, priv); + + snprintf (delete_path, sizeof (delete_path), + "%s/"GLUSTERD_TRASH"/snap-%s.deleted", priv->workdir, + uuid_utoa (snap->snap_id)); + + snprintf (trashdir, sizeof (trashdir), "%s/"GLUSTERD_TRASH, + priv->workdir); + + ret = mkdir (trashdir, 0777); + if (ret && errno != EEXIST) { + gf_log (this->name, GF_LOG_ERROR, "Failed to create trash " + "directory, reason : %s", strerror (errno)); + ret = -1; + goto out; + } + + ret = rename (pathname, delete_path); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to rename snap " + "directory %s to %s", snap->snapname, delete_path); + rename_fail = _gf_true; + goto out; + } + + dir = opendir (delete_path); + if (!dir) { + gf_log (this->name, GF_LOG_DEBUG, "Failed to open directory %s." + " Reason : %s", delete_path, strerror (errno)); + ret = 0; + goto out; + } + + glusterd_for_each_entry (entry, dir); + while (entry) { + snprintf (path, PATH_MAX, "%s/%s", delete_path, entry->d_name); + ret = stat (path, &st); + if (ret == -1) { + gf_log (this->name, GF_LOG_DEBUG, "Failed to stat " + "entry %s : %s", path, strerror (errno)); + goto stat_failed; + } + + if (S_ISDIR (st.st_mode)) + ret = rmdir (path); + else + ret = unlink (path); + + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, " Failed to remove " + "%s. Reason : %s", path, strerror (errno)); + } + + gf_log (this->name, GF_LOG_DEBUG, "%s %s", + ret ? "Failed to remove":"Removed", + entry->d_name); +stat_failed: + memset (path, 0, sizeof(path)); + glusterd_for_each_entry (entry, dir); + } + + ret = closedir (dir); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, "Failed to close dir %s. " + "Reason : %s",delete_path, strerror (errno)); + } + + ret = rmdir (delete_path); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, "Failed to rmdir: %s,err: %s", + delete_path, strerror (errno)); + } + ret = rmdir (trashdir); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, "Failed to rmdir: %s, Reason:" + " %s", trashdir, strerror (errno)); + } + +out: + if (snap->shandle) { + gf_store_handle_destroy (snap->shandle); + snap->shandle = NULL; + } + ret = (rename_fail == _gf_true) ? -1: 0; + + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + int glusterd_store_global_info (xlator_t *this) { @@ -2472,10 +2124,8 @@ out: int32_t -glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo) +glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo) { - int32_t ret = 0; glusterd_brickinfo_t *brickinfo = NULL; gf_store_iter_t *iter = NULL; @@ -2490,34 +2140,19 @@ glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo, char *tmpvalue = NULL; struct pmap_registry *pmap = NULL; gf_store_op_errno_t op_errno = GD_STORE_SUCCESS; - glusterd_volinfo_t *tmp_volinfo = NULL; GF_ASSERT (volinfo); GF_ASSERT (volinfo->volname); priv = THIS->private; - if (snap_volinfo) { - GLUSTERD_GET_SNAP_BRICK_DIR (brickdir, volinfo, - snap_volinfo->volname, priv); - } else { - GLUSTERD_GET_BRICK_DIR (brickdir, volinfo, priv); - } - - if (snap_volinfo) - ret = gf_store_iter_new (snap_volinfo->shandle, &tmpiter); - else - ret = gf_store_iter_new (volinfo->shandle, &tmpiter); + GLUSTERD_GET_BRICK_DIR (brickdir, volinfo, priv); + ret = gf_store_iter_new (volinfo->shandle, &tmpiter); if (ret) goto out; - if (snap_volinfo) - tmp_volinfo = snap_volinfo; - else - tmp_volinfo = volinfo; - - while (brick_count < tmp_volinfo->brick_count) { + while (brick_count < volinfo->brick_count) { ret = glusterd_brickinfo_new (&brickinfo); if (ret) @@ -2619,7 +2254,7 @@ glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo, if (ret) goto out; - list_add_tail (&brickinfo->brick_list, &tmp_volinfo->bricks); + list_add_tail (&brickinfo->brick_list, &volinfo->bricks); brick_count++; } @@ -2634,7 +2269,7 @@ out: int32_t -glusterd_store_retrieve_rbstate (char *volname) +glusterd_store_retrieve_rbstate (char *volname, glusterd_snap_t *snap) { int32_t ret = -1; glusterd_volinfo_t *volinfo = NULL; @@ -2648,11 +2283,15 @@ glusterd_store_retrieve_rbstate (char *volname) priv = THIS->private; - ret = glusterd_volinfo_find (volname, &volinfo); - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get" - "volinfo for %s.", volname); - goto out; + if (snap) { + volinfo = snap->snap_volume; + } else { + ret = glusterd_volinfo_find (volname, &volinfo); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get" + "volinfo for %s.", volname); + goto out; + } } GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, priv); @@ -2736,7 +2375,7 @@ out: } int32_t -glusterd_store_retrieve_node_state (char *volname) +glusterd_store_retrieve_node_state (char *volname, glusterd_snap_t *snap) { int32_t ret = -1; glusterd_volinfo_t *volinfo = NULL; @@ -2750,11 +2389,15 @@ glusterd_store_retrieve_node_state (char *volname) priv = THIS->private; - ret = glusterd_volinfo_find (volname, &volinfo); - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get" - "volinfo for %s.", volname); - goto out; + if (snap) { + volinfo = snap->snap_volume; + } else { + ret = glusterd_volinfo_find (volname, &volinfo); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get" + "volinfo for %s.", volname); + goto out; + } } GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, priv); @@ -2827,27 +2470,13 @@ glusterd_store_update_volinfo (glusterd_volinfo_t *volinfo, glusterd_conf_t *conf = NULL; gf_store_iter_t *iter = NULL; gf_store_op_errno_t op_errno = GD_STORE_SUCCESS; - glusterd_volinfo_t *parent_vol = NULL; this = THIS; GF_ASSERT (this); conf = THIS->private; GF_ASSERT (volinfo); - if (snap) { - ret = glusterd_volinfo_find (volinfo->parent_volname, - &parent_vol); - if (ret) { - gf_log (this->name, GF_LOG_DEBUG, "Failed to get parent" - " volume for %s snap volume", volinfo->volname); - goto out; - } - - GLUSTERD_GET_SNAP_DIR (volpath, parent_vol, volinfo->volname, - conf); - } else { - GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, conf); - } + GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, conf); snprintf (path, sizeof (path), "%s/%s", volpath, GLUSTERD_VOLUME_INFO_FILE); @@ -3052,11 +2681,10 @@ out: int32_t glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap) { - int32_t ret = -1; - char volpath[PATH_MAX] = {0,}; + int32_t ret = -1; glusterd_volinfo_t *volinfo = NULL; + glusterd_volinfo_t *origin_volinfo = NULL; glusterd_conf_t *priv = NULL; - glusterd_volinfo_t *parent_vol = NULL; xlator_t *this = NULL; this = THIS; @@ -3071,19 +2699,10 @@ glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap) priv = THIS->private; - if (snap) { - ret = glusterd_volinfo_find (volname, &parent_vol); - if (ret) - goto out; - GLUSTERD_GET_UUID_NOHYPHEN(volinfo->volname, - snap->snap_id); - GLUSTERD_GET_SNAP_DIR (volpath, parent_vol, volinfo->volname, - priv); - strncpy (volinfo->parent_volname, volname, GLUSTERD_MAX_VOLUME_NAME); - } else { - strncpy (volinfo->volname, volname, GLUSTERD_MAX_VOLUME_NAME); - GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, priv); - } + strncpy (volinfo->volname, volname, GLUSTERD_MAX_VOLUME_NAME); + volinfo->snapshot = snap; + if (snap) + volinfo->is_snap_volume = _gf_true; ret = glusterd_store_update_volinfo (volinfo, snap); if (ret) { @@ -3092,32 +2711,29 @@ glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap) goto out; } - if (snap) - ret = glusterd_store_retrieve_bricks (parent_vol, volinfo); - else - ret = glusterd_store_retrieve_bricks (volinfo, NULL); + ret = glusterd_store_retrieve_bricks (volinfo); if (ret) goto out; - if (snap) - ret = glusterd_volume_compute_cksum (parent_vol, volinfo); - else - ret = glusterd_volume_compute_cksum (volinfo, NULL); + ret = glusterd_volume_compute_cksum (volinfo); if (ret) goto out; - if (!snap) { list_add_tail (&volinfo->vol_list, &priv->volumes); } else { - // as of now snap volume are also added to the list of volume - volinfo->is_snap_volume = _gf_true; - snap->snap_volume = volinfo; - list_add_tail (&volinfo->vol_list, &priv->snap_list); + ret = glusterd_volinfo_find (volinfo->parent_volname, + &origin_volinfo); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Parent volinfo " + "not found for %s volume", volname); + goto out; + } + glusterd_list_add_snapvol (origin_volinfo, volinfo); } - - out: + /*TODO: cleanup volinfo pointer on failure */ + gf_log ("", GF_LOG_TRACE, "Returning with %d", ret); return ret; @@ -3325,183 +2941,6 @@ out: return ret; } -int32_t -glusterd_store_retrieve_snap_list (char *volname) -{ - int32_t ret = -1; - glusterd_volinfo_t *volinfo = NULL; - gf_store_iter_t *iter = NULL; - char key[256] = {0, }; - char *value = NULL; - char volpath[PATH_MAX] = {0,}; - glusterd_conf_t *priv = NULL; - char path[PATH_MAX] = {0,}; - gf_store_op_errno_t op_errno = GD_STORE_SUCCESS; - glusterd_snap_t *snap = NULL; - uint64_t count = 0; - uint64_t snap_count = 0; - gf_store_handle_t *shandle = NULL; - - priv = THIS->private; - ret = glusterd_volinfo_find (volname, &volinfo); - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get" - "volinfo for %s.", volname); - goto out; - } - - GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, priv); - snprintf (path, sizeof (path), "%s/%s", volpath, - GLUSTERD_VOL_SNAP_FILE); - - ret = gf_store_handle_retrieve (path, &volinfo->snap_list_shandle); - if (ret) - goto out; - - ret = gf_store_iter_new (volinfo->snap_list_shandle, &iter); - if (ret) - goto out; - - ret = gf_store_iter_get_matching (iter, GLUSTERD_STORE_KEY_SNAP_COUNT, - &value); - if(ret) - goto out; - - snap_count = atol(value); - GF_FREE (value); - value = NULL; - - shandle = volinfo->snap_list_shandle; - while (count <= snap_count) { - snap = glusterd_new_snap_object (); - if (!snap) { - gf_log (THIS->name, GF_LOG_ERROR, - "Failed to create snap object"); - goto out; - } - - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_NAME, count); - ret = gf_store_retrieve_value (shandle, key, &value); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to retrieve " - "snap name"); - goto out; - } - - strncpy (snap->snap_name, value, strlen(value)); - GF_FREE (value); - value = NULL; - - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_STATUS, count); - ret = gf_store_retrieve_value (shandle, key, - &value); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to retrieve " - "snap-status of snap %s", snap->snap_name); - goto out; - } - - snap->snap_status = atoi (value); - GF_FREE (value); - value = NULL; - - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_ID, count); - ret = gf_store_retrieve_value (shandle, key, &value); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to retrieve " - "snap-ID of snap %s", snap->snap_name); - goto out; - } - - uuid_parse (value, snap->snap_id); - GF_FREE (value); - value = NULL; - - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_TIMESTAMP, count); - ret = gf_store_retrieve_value (shandle, key, &value); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to retrieve" - " Time-stamp of snap %s", snap->snap_name); - goto out; - } - - snap->time_stamp = atoi (value); - GF_FREE (value); - value = NULL; - - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_CG_ID, count); - ret = gf_store_retrieve_value (shandle, key, &value); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to retrieve" - " snap CG-ID of snap %s", snap->snap_name); - goto out; - } - - uuid_parse (value, snap->cg_id); - GF_FREE (value); - value = NULL; - - if (!uuid_is_null(snap -> cg_id)) { - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_CG_NAME, count); - ret = gf_store_retrieve_value (shandle, key, &value); - if (ret){ - gf_log ("", GF_LOG_ERROR,"Failed to retreive " - "CG name"); - goto out; - } - strcpy (snap->cg_name, value); - GF_FREE (value); - value = NULL; - } - - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_DESC, count); - ret = gf_store_retrieve_value (shandle, key, &value); - if (!ret) { - if (uuid_is_null (snap -> cg_id)) - snap->description = value; - value = NULL; - } else { - ret = 0; - gf_log (THIS->name, GF_LOG_TRACE, "No desc for %s", - snap->snap_name); - } - - ret = glusterd_add_snap (volinfo, snap); - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, "Failed to add %s to" - " snap_list", value); - goto out; - } - ret = glusterd_store_retrieve_volume (volname, snap); - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, "Failed to retrieve " - "snap %s for volume %s", snap->snap_name, volname); - goto out; - } - count++; - } - - if (op_errno != GD_STORE_EOF) - goto out; - - ret = gf_store_iter_destroy (iter); - - if (ret) - goto out; - -out: - gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); - - return ret; -} - int32_t glusterd_store_retrieve_snap_cgs (xlator_t *this) { @@ -3540,9 +2979,9 @@ out: } int32_t -glusterd_store_retrieve_volumes (xlator_t *this) +glusterd_store_retrieve_volumes (xlator_t *this, glusterd_snap_t *snap) { - int32_t ret = 0; + int32_t ret = -1; char path[PATH_MAX] = {0,}; glusterd_conf_t *priv = NULL; DIR *dir = NULL; @@ -3554,60 +2993,248 @@ glusterd_store_retrieve_volumes (xlator_t *this) GF_ASSERT (priv); - snprintf (path, PATH_MAX, "%s/%s", priv->workdir, - GLUSTERD_VOLUME_DIR_PREFIX); + if (snap) + snprintf (path, PATH_MAX, "%s/snaps/%s", priv->workdir, + snap->snapname); + else + snprintf (path, PATH_MAX, "%s/%s", priv->workdir, + GLUSTERD_VOLUME_DIR_PREFIX); dir = opendir (path); if (!dir) { gf_log ("", GF_LOG_ERROR, "Unable to open dir %s", path); - ret = -1; goto out; } glusterd_for_each_entry (entry, dir); while (entry) { - ret = glusterd_store_retrieve_volume (entry->d_name, NULL); + if ( entry->d_type != DT_DIR ) + goto next; + + ret = glusterd_store_retrieve_volume (entry->d_name, snap); if (ret) { gf_log ("", GF_LOG_ERROR, "Unable to restore " "volume: %s", entry->d_name); goto out; } - ret = glusterd_store_retrieve_rbstate (entry->d_name); + ret = glusterd_store_retrieve_rbstate (entry->d_name, snap); if (ret) { /* Backward compatibility */ gf_log ("", GF_LOG_INFO, "Creating a new rbstate " "for volume: %s.", entry->d_name); - ret = glusterd_volinfo_find (entry->d_name, &volinfo); + if (snap) { + volinfo = snap->snap_volume; + } else { + ret = glusterd_volinfo_find (entry->d_name, + &volinfo); + } ret = glusterd_store_create_rbstate_shandle_on_absence (volinfo); ret = glusterd_store_perform_rbstate_store (volinfo); } - ret = glusterd_store_retrieve_node_state (entry->d_name); + ret = glusterd_store_retrieve_node_state (entry->d_name, snap); if (ret) { /* Backward compatibility */ gf_log ("", GF_LOG_INFO, "Creating a new node_state " "for volume: %s.", entry->d_name); - ret = glusterd_volinfo_find (entry->d_name, &volinfo); - ret = + if (snap) { + volinfo = snap->snap_volume; + } else { + ret = glusterd_volinfo_find (entry->d_name, &volinfo); + } glusterd_store_create_nodestate_sh_on_absence (volinfo); ret = glusterd_store_perform_node_state_store (volinfo); } - ret = glusterd_store_retrieve_snap_list (entry->d_name); - if (ret) { - /* Backward compatibility */ - gf_log ("", GF_LOG_INFO, "Creating a new snap_list " - "for volume: %s.", entry->d_name); - ret = glusterd_volinfo_find (entry->d_name, &volinfo); - ret = - glusterd_store_create_snap_list_sh_on_absence (volinfo); - ret = glusterd_store_perform_all_snap_store (volinfo); - //ret = glusterd_store_perform_snap_list_store (volinfo); TODO: Fix this +next: + glusterd_for_each_entry (entry, dir); + } + + ret = 0; +out: + if (dir) + closedir (dir); + gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); + + return ret; +} + +int +glusterd_store_update_snap (glusterd_snap_t *snap) +{ + int ret = -1; + char *key = NULL; + char *value = NULL; + char snappath[PATH_MAX] = {0,}; + char path[PATH_MAX] = {0,}; + xlator_t *this = NULL; + glusterd_conf_t *conf = NULL; + gf_store_iter_t *iter = NULL; + gf_store_op_errno_t op_errno = GD_STORE_SUCCESS; + + this = THIS; + conf = this->private; + GF_ASSERT (snap); + + GLUSTERD_GET_SNAP_DIR (snappath, snap, conf); + + snprintf (path, sizeof (path), "%s/%s", snappath, + GLUSTERD_SNAP_INFO_FILE); + + ret = gf_store_handle_retrieve (path, &snap->shandle); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "snap handle is NULL"); + goto out; + } + + ret = gf_store_iter_new (snap->shandle, &iter); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get new store " + "iter"); + goto out; + } + + ret = gf_store_iter_get_next (iter, &key, &value, &op_errno); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get next store " + "iter"); + goto out; + } + + while (!ret) { + gf_log (this->name, GF_LOG_DEBUG, "key = %s value = %s", + key, value); + + if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_ID, + strlen (GLUSTERD_STORE_KEY_SNAP_ID))) { + ret = uuid_parse (value, snap->snap_id); + if (ret) + gf_log (this->name, GF_LOG_WARNING, + "Failed to parse uuid"); + } else if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_RESTORED, + strlen (GLUSTERD_STORE_KEY_SNAP_RESTORED))) { + snap->snap_restored = atoi (value); + } else if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_STATUS, + strlen (GLUSTERD_STORE_KEY_SNAP_STATUS))) { + snap->snap_status = atoi (value); + } else if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_DESC, + strlen (GLUSTERD_STORE_KEY_SNAP_DESC))) { + snap->description = gf_strdup (value); + } else if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_TIMESTAMP, + strlen (GLUSTERD_STORE_KEY_SNAP_TIMESTAMP))) { + snap->time_stamp = atoi (value); + } + + GF_FREE (key); + GF_FREE (value); + key = NULL; + value = NULL; + + ret = gf_store_iter_get_next (iter, &key, &value, &op_errno); + } + + if (op_errno != GD_STORE_EOF) + goto out; + + ret = gf_store_iter_destroy (iter); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to destroy store " + "iter"); + } + +out: + return ret; +} + +int32_t +glusterd_store_retrieve_snap (char *snapname) +{ + int32_t ret = -1; + glusterd_snap_t *snap = NULL; + glusterd_conf_t *priv = NULL; + xlator_t *this = NULL; + + this = THIS; + priv = this->private; + GF_ASSERT (priv); + GF_ASSERT (snapname); + + snap = glusterd_new_snap_object (); + if (!snap) { + gf_log (this->name, GF_LOG_ERROR, "Failed to create " + " snap object"); + goto out; + } + + strncpy (snap->snapname, snapname, strlen(snapname)); + ret = glusterd_store_update_snap (snap); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to update snapshot " + "for %s snap", snapname); + goto out; + } + + ret = glusterd_store_retrieve_volumes (this, snap); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to retrieve " + "snap volumes for snap %s", snapname); + goto out; + } + + /* TODO: list_add_order can do 'N-square' comparisions and + is not efficient. Find a better solution to store the snap + in order */ + list_add_order (&snap->snap_list, &priv->snapshots, + glusterd_compare_snap_time); + +out: + gf_log ("", GF_LOG_TRACE, "Returning with %d", ret); + + return ret; +} + +int32_t +glusterd_store_retrieve_snaps (xlator_t *this) +{ + int32_t ret = 0; + char path[PATH_MAX] = {0,}; + glusterd_conf_t *priv = NULL; + DIR *dir = NULL; + struct dirent *entry = NULL; + + GF_ASSERT (this); + priv = this->private; + + GF_ASSERT (priv); + + snprintf (path, PATH_MAX, "%s/snaps", priv->workdir); + + dir = opendir (path); + + if (!dir) { + /* If snaps dir doesn't exists ignore the error for + backward compatibility */ + if (errno != ENOENT) { + ret = -1; + gf_log ("", GF_LOG_ERROR, "Unable to open dir %s", path); + } + goto out; + } + + glusterd_for_each_entry (entry, dir); + + while (entry) { + ret = glusterd_store_retrieve_snap (entry->d_name); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to restore " + "snapshot: %s", entry->d_name); + goto out; } + glusterd_for_each_entry (entry, dir); } @@ -4020,7 +3647,11 @@ glusterd_restore () goto out; } - ret = glusterd_store_retrieve_volumes (this); + ret = glusterd_store_retrieve_volumes (this, NULL); + if (ret) + goto out; + + ret = glusterd_store_retrieve_snaps (this); if (ret) goto out; diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h index 8ddd3e6bd..46f5ffb7f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.h +++ b/xlators/mgmt/glusterd/src/glusterd-store.h @@ -68,7 +68,7 @@ typedef enum glusterd_store_ver_ac_{ #define GLUSTERD_STORE_KEY_SNAP_DESC "desc" #define GLUSTERD_STORE_KEY_SNAP_TIMESTAMP "time-stamp" #define GLUSTERD_STORE_KEY_SNAP_STATUS "status" -#define GLUSTERD_STORE_KEY_SNAP_COUNT "count" +#define GLUSTERD_STORE_KEY_SNAP_RESTORED "snap-restored" #define GLUSTERD_STORE_KEY_CG_VOL_COUNT "count" #define GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT "snap-max-hard-limit" #define GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT "snap-max-soft-limit" @@ -104,8 +104,10 @@ int32_t glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t ac); int32_t -glusterd_store_delete_volume (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snapinfo); +glusterd_store_delete_volume (glusterd_volinfo_t *volinfo); + +int32_t +glusterd_store_delete_snap (glusterd_snap_t *snap); int32_t glusterd_retrieve_uuid (); @@ -145,27 +147,24 @@ int glusterd_store_update_volinfo (glusterd_volinfo_t *volinfo, glusterd_snap_t *snap); int32_t -glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo); +glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo); int32_t glusterd_store_options (xlator_t *this, dict_t *opts); void glusterd_replace_slash_with_hyphen (char *str); + int32_t glusterd_store_perform_volume_store (glusterd_volinfo_t *volinfo); + int32_t -glusterd_store_perform_snap_store (glusterd_volinfo_t *volinfo, char *snapname); -int32_t -glusterd_store_perform_all_snap_store (glusterd_volinfo_t *volinfo); -int32_t -glusterd_store_perform_snap_list_store (glusterd_volinfo_t *volinfo); +glusterd_store_snap (glusterd_snap_t *snap); + int32_t glusterd_store_snap_cg (glusterd_snap_cg_t *cg); + int32_t glusterd_store_delete_snap_cg (glusterd_snap_cg_t *cg); -int32_t -glusterd_store_perform_snap_volume_store (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo); + #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index e7cad0b4d..63adbb75f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -444,8 +444,9 @@ glusterd_volinfo_new (glusterd_volinfo_t **volinfo) LOCK_INIT (&new_volinfo->lock); INIT_LIST_HEAD (&new_volinfo->vol_list); + INIT_LIST_HEAD (&new_volinfo->snapvol_list); INIT_LIST_HEAD (&new_volinfo->bricks); - INIT_LIST_HEAD (&new_volinfo->snaps); + INIT_LIST_HEAD (&new_volinfo->snap_volumes); new_volinfo->dict = dict_new (); if (!new_volinfo->dict) { @@ -1176,32 +1177,64 @@ glusterd_volinfo_find (char *volname, glusterd_volinfo_t **volinfo) } int32_t -glusterd_snap_volinfo_find (char *volname, glusterd_volinfo_t **volinfo) +glusterd_snap_volinfo_find (char *snap_volname, glusterd_snap_t *snap, + glusterd_volinfo_t **volinfo) { - glusterd_volinfo_t *tmp_volinfo = NULL; - int32_t ret = -1; - xlator_t *this = NULL; - glusterd_conf_t *priv = NULL; + int32_t ret = -1; + xlator_t *this = NULL; + glusterd_volinfo_t *snap_vol = NULL; + glusterd_conf_t *priv = NULL; - GF_ASSERT (volname); - gf_log ("", GF_LOG_DEBUG, "Snap Volname = %s", volname); this = THIS; - GF_ASSERT (this); + priv = this->private; + GF_ASSERT (priv); + GF_ASSERT (snap); + GF_ASSERT (snap_volname); + + list_for_each_entry (snap_vol, &snap->volumes, vol_list) { + if (!strcmp (snap_vol->volname, snap_volname)) { + ret = 0; + *volinfo = snap_vol; + goto out; + } + } + gf_log (this->name, GF_LOG_WARNING, "Snap volume %s not found", + snap_volname); +out: + gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret); + return ret; +} + +int32_t +glusterd_snap_volinfo_find_from_parent_volname (char *origin_volname, + glusterd_snap_t *snap, + glusterd_volinfo_t **volinfo) +{ + int32_t ret = -1; + xlator_t *this = NULL; + glusterd_volinfo_t *snap_vol = NULL; + glusterd_conf_t *priv = NULL; + + this = THIS; priv = this->private; GF_ASSERT (priv); + GF_ASSERT (snap); + GF_ASSERT (origin_volname); - list_for_each_entry (tmp_volinfo, &priv->snap_list, vol_list) { - if (!strcmp (tmp_volinfo->volname, volname)) { - gf_log (this->name, GF_LOG_DEBUG, "Snap Volume %s found", - volname); + list_for_each_entry (snap_vol, &snap->volumes, vol_list) { + if (!strcmp (snap_vol->parent_volname, origin_volname)) { ret = 0; - *volinfo = tmp_volinfo; - break; + *volinfo = snap_vol; + goto out; } } - gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); + gf_log (this->name, GF_LOG_DEBUG, "Snap volume not found(snap: %s, " + "origin-volume: %s", snap->snapname, origin_volname); + +out: + gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret); return ret; } @@ -1358,29 +1391,7 @@ _mk_rundir_p (glusterd_volinfo_t *volinfo) return ret; } -static int -_mk_snap_rundir_p (glusterd_volinfo_t *volinfo, glusterd_volinfo_t *snap_volinfo) -{ - char voldir[PATH_MAX] = {0,}; - char rundir[PATH_MAX] = {0,}; - glusterd_conf_t *priv = NULL; - xlator_t *this = NULL; - int ret = -1; - - GF_ASSERT (volinfo); - GF_ASSERT (snap_volinfo); - - this = THIS; - priv = this->private; - GLUSTERD_GET_SNAP_DIR (voldir, volinfo, snap_volinfo->volname, priv); - snprintf (rundir, sizeof (rundir)-1, "%s/run", voldir); - ret = mkdir_p (rundir, 0777, _gf_true); - if (ret) - gf_log (this->name, GF_LOG_ERROR, "Failed to create rundir"); - return ret; -} - - int32_t +int32_t glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo, gf_boolean_t wait) @@ -1452,8 +1463,14 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo, runner_argprintf (&runner, "--log-file=%s", valgrind_logfile); } - snprintf (volfile, PATH_MAX, "%s.%s.%s", volinfo->volname, - brickinfo->hostname, exp_path); + if (volinfo->is_snap_volume) { + snprintf (volfile, PATH_MAX, "/snaps/%s/%s.%s.%s", + volinfo->snapshot->snapname, volinfo->volname, + brickinfo->hostname, exp_path); + } else { + snprintf (volfile, PATH_MAX, "%s.%s.%s", volinfo->volname, + brickinfo->hostname, exp_path); + } if (volinfo->logdir) { snprintf (logfile, PATH_MAX, "%s/%s.log", @@ -1523,166 +1540,6 @@ out: return ret; } -int32_t -glusterd_snap_volume_start_glusterfs (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo, - glusterd_brickinfo_t *brickinfo, - gf_boolean_t wait) -{ - int32_t ret = -1; - xlator_t *this = NULL; - glusterd_conf_t *priv = NULL; - char pidfile[PATH_MAX+1] = {0,}; - char volfile[PATH_MAX] = {0,}; - runner_t runner = {0,}; - char exp_path[PATH_MAX] = {0,}; - char logfile[PATH_MAX] = {0,}; - int port = 0; - int rdma_port = 0; - char socketpath[PATH_MAX] = {0}; - char glusterd_uuid[1024] = {0,}; - char valgrind_logfile[PATH_MAX] = {0}; - char export_path[PATH_MAX] = {0,}; - char sock_filepath[PATH_MAX] = {0,}; - char snap_dir[PATH_MAX] = {0,}; - int expected_file_len = 0; - char snap_volfile[PATH_MAX] = {0, }; - - GF_ASSERT (volinfo); - GF_ASSERT (brickinfo); - - this = THIS; - GF_ASSERT (this); - - priv = this->private; - GF_ASSERT (priv); - - ret = _mk_snap_rundir_p (volinfo, snap_volinfo); - if (ret) - goto out; - - expected_file_len = strlen (GLUSTERD_SOCK_DIR) + strlen ("/") + - MD5_DIGEST_LENGTH*2 + strlen (".socket") + 1; - GF_ASSERT (sizeof (socketpath) >= expected_file_len); - - GLUSTERD_GET_SNAP_DIR (snap_dir, volinfo, snap_volinfo->volname, priv); - GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, export_path); - snprintf (sock_filepath, PATH_MAX, "%s/run/%s-%s", - snap_dir, brickinfo->hostname, export_path); - - glusterd_set_socket_filepath (sock_filepath, socketpath, sizeof (socketpath)); - - GLUSTERD_GET_SNAP_BRICK_PIDFILE (pidfile, volinfo->volname, - snap_volinfo->volname, - brickinfo, priv); - if (glusterd_is_service_running (pidfile, NULL)) - goto connect; - - _reap_brick_process (pidfile, brickinfo->path); - - port = brickinfo->port; - if (!port) - port = pmap_registry_alloc (THIS); - - /* Build the exp_path, before starting the glusterfsd even in - valgrind mode. Otherwise all the glusterfsd processes start - writing the valgrind log to the same file. - */ - GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, exp_path); - runinit (&runner); - - if (priv->valgrind) { - /* Run bricks with valgrind */ - if (snap_volinfo->logdir) { - snprintf (valgrind_logfile, PATH_MAX, - "%s/valgrind-%s-%s.log", - snap_volinfo->logdir, - snap_volinfo->volname, exp_path); - } else { - snprintf (valgrind_logfile, PATH_MAX, - "%s/bricks/valgrind-%s-%s.log", - DEFAULT_LOG_FILE_DIRECTORY, - snap_volinfo->volname, exp_path); - } - - runner_add_args (&runner, "valgrind", "--leak-check=full", - "--trace-children=yes", "--track-origins=yes", - NULL); - runner_argprintf (&runner, "--log-file=%s", valgrind_logfile); - } - - snprintf (volfile, PATH_MAX, "%s/snaps/%s/%s.%s.%s", - volinfo->volname, snap_volinfo->volname, - snap_volinfo->volname, brickinfo->hostname, exp_path); - - if (snap_volinfo->logdir) { - snprintf (logfile, PATH_MAX, "%s/%s.log", - snap_volinfo->logdir, exp_path); - } else { - snprintf (logfile, PATH_MAX, "%s/bricks/%s.log", - DEFAULT_LOG_FILE_DIRECTORY, exp_path); - } - if (!brickinfo->logfile) - brickinfo->logfile = gf_strdup (logfile); - - snprintf (snap_volfile, sizeof (snap_volfile), "%s/vols/%s/snaps/%s/%s", - priv->workdir, volinfo->volname, snap_volinfo->volname, - volfile); - - (void) snprintf (glusterd_uuid, 1024, "*-posix.glusterd-uuid=%s", - uuid_utoa (MY_UUID)); - runner_add_args (&runner, SBIN_DIR"/glusterfsd", - "-s", brickinfo->hostname, "--volfile-id", volfile, - "-p", pidfile, "-S", socketpath, - "--brick-name", brickinfo->path, - "-l", brickinfo->logfile, - "--xlator-option", glusterd_uuid, - NULL); - - runner_add_arg (&runner, "--brick-port"); - if (snap_volinfo->transport_type != GF_TRANSPORT_BOTH_TCP_RDMA) { - runner_argprintf (&runner, "%d", port); - } else { - rdma_port = brickinfo->rdma_port; - if (!rdma_port) - rdma_port = pmap_registry_alloc (THIS); - runner_argprintf (&runner, "%d,%d", port, rdma_port); - runner_add_arg (&runner, "--xlator-option"); - runner_argprintf (&runner, "%s-server.transport.rdma.listen-port=%d", - snap_volinfo->volname, rdma_port); - } - - runner_add_arg (&runner, "--xlator-option"); - runner_argprintf (&runner, "%s-server.listen-port=%d", - snap_volinfo->volname, port); - - if (snap_volinfo->memory_accounting) - runner_add_arg (&runner, "--mem-accounting"); - - runner_log (&runner, "", GF_LOG_DEBUG, "Starting GlusterFS"); - if (wait) { - synclock_unlock (&priv->big_lock); - ret = runner_run (&runner); - synclock_lock (&priv->big_lock); - - } else { - ret = runner_run_nowait (&runner); - } - - if (ret) - goto out; - - brickinfo->port = port; - brickinfo->rdma_port = rdma_port; - -connect: - ret = glusterd_brick_connect (snap_volinfo, brickinfo, socketpath); - if (ret) - goto out; -out: - return ret; -} - int32_t glusterd_brick_unlink_socket_file (glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo) @@ -1714,52 +1571,6 @@ glusterd_brick_unlink_socket_file (glusterd_volinfo_t *volinfo, return ret; } -int32_t -glusterd_snap_brick_unlink_socket_file (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo, - glusterd_brickinfo_t *brickinfo) -{ - char path[PATH_MAX] = {0,}; - char socketpath[PATH_MAX] = {0}; - xlator_t *this = NULL; - glusterd_conf_t *priv = NULL; - int ret = 0; - char sock_filepath[PATH_MAX] = {0, }; - int expected_file_len = 0; - char export_path[PATH_MAX] = {0,}; - - GF_ASSERT (volinfo); - GF_ASSERT (snap_volinfo); - GF_ASSERT (brickinfo); - - this = THIS; - GF_ASSERT (this); - priv = this->private; - GF_ASSERT (priv); - - GLUSTERD_GET_SNAP_DIR (path, volinfo, snap_volinfo->volname, priv); - - glusterd_set_socket_filepath (sock_filepath, socketpath, sizeof (socketpath)); - - expected_file_len = strlen (GLUSTERD_SOCK_DIR) + strlen ("/") + - MD5_DIGEST_LENGTH*2 + strlen (".socket") + 1; - GF_ASSERT (sizeof (socketpath) >= expected_file_len); - - GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, export_path); - snprintf (sock_filepath, PATH_MAX, "%s/run/%s-%s", - path, brickinfo->hostname, export_path); - - ret = unlink (socketpath); - if (ret && (ENOENT == errno)) { - ret = 0; - } else { - gf_log (this->name, GF_LOG_ERROR, "Failed to remove %s" - " error: %s", socketpath, strerror (errno)); - } - - return ret; -} - int32_t glusterd_brick_disconnect (glusterd_brickinfo_t *brickinfo) { @@ -1821,49 +1632,6 @@ glusterd_volume_stop_glusterfs (glusterd_volinfo_t *volinfo, return ret; } -int32_t -glusterd_snap_volume_stop_glusterfs (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo, - glusterd_brickinfo_t *brickinfo, - gf_boolean_t del_brick) -{ - xlator_t *this = NULL; - glusterd_conf_t *priv = NULL; - char pidfile[PATH_MAX] = {0,}; - int ret = 0; - - GF_ASSERT (volinfo); - GF_ASSERT (brickinfo); - GF_ASSERT (snap_volinfo); - - this = THIS; - GF_ASSERT (this); - priv = this->private; - GF_ASSERT (priv); - - if (del_brick) - list_del_init (&brickinfo->brick_list); - - if (GLUSTERD_STATUS_STARTED == snap_volinfo->status) { - (void) glusterd_brick_disconnect (brickinfo); - GLUSTERD_GET_SNAP_BRICK_PIDFILE (pidfile, volinfo->volname, - snap_volinfo->volname, - brickinfo, priv); - ret = glusterd_service_stop ("brick", pidfile, SIGTERM, _gf_false); - if (ret == 0) { - glusterd_set_brick_status (brickinfo, GF_BRICK_STOPPED); - (void) glusterd_snap_brick_unlink_socket_file (volinfo, - snap_volinfo, - brickinfo); - } - } - - if (del_brick) - glusterd_delete_snap_brick (volinfo, snap_volinfo, brickinfo); - - return ret; -} - int32_t glusterd_peer_hostname_new (char *hostname, glusterd_peer_hostname_t **name) { @@ -1999,8 +1767,7 @@ glusterd_sort_and_redirect (const char *src_filepath, int dest_fd) } int -glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo) +glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo) { int32_t ret = -1; glusterd_conf_t *priv = NULL; @@ -2020,12 +1787,7 @@ glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo, priv = THIS->private; GF_ASSERT (priv); - if (snap_volinfo) { - GLUSTERD_GET_SNAP_DIR (path, volinfo, snap_volinfo->volname, - priv); - } else { - GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv); - } + GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv); snprintf (cksum_path, sizeof (cksum_path), "%s/%s", path, GLUSTERD_CKSUM_FILE); @@ -2041,19 +1803,15 @@ glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo, snprintf (filepath, sizeof (filepath), "%s/%s", path, GLUSTERD_VOLUME_INFO_FILE); - if (snap_volinfo) - snprintf (sort_filepath, sizeof (sort_filepath), - "/tmp/%s.XXXXXX", snap_volinfo->volname); - else - snprintf (sort_filepath, sizeof (sort_filepath), - "/tmp/%s.XXXXXX", volinfo->volname); + snprintf (sort_filepath, sizeof (sort_filepath), + "/tmp/%s.XXXXXX", volinfo->volname); sort_fd = mkstemp (sort_filepath); if (sort_fd < 0) { gf_log (this->name, GF_LOG_ERROR, "Could not generate temp " "file, reason: %s for %s: %s", strerror (errno), - (snap_volinfo)?"snap":"volume", - (snap_volinfo)?snap_volinfo->volname:volinfo->volname); + (volinfo->is_snap_volume)?"snap":"volume", + volinfo->volname); goto out; } else { unlink_sortfile = _gf_true; @@ -2092,10 +1850,7 @@ glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo, if (ret) goto out; - if (snap_volinfo) - snap_volinfo->cksum = cksum; - else - volinfo->cksum = cksum; + volinfo->cksum = cksum; out: if (fd > 0) close (fd); @@ -2811,10 +2566,8 @@ void glusterd_do_volume_quorum_action (xlator_t *this, glusterd_volinfo_t *volinfo, gf_boolean_t meets_quorum) { - int ret = -1; glusterd_brickinfo_t *brickinfo = NULL; - glusterd_conf_t *conf = NULL; - glusterd_volinfo_t *parent_volinfo = NULL; + glusterd_conf_t *conf = NULL; conf = this->private; if (volinfo->status != GLUSTERD_STATUS_STARTED) @@ -2823,33 +2576,13 @@ glusterd_do_volume_quorum_action (xlator_t *this, glusterd_volinfo_t *volinfo, if (!glusterd_is_volume_in_server_quorum (volinfo)) meets_quorum = _gf_true; - if (volinfo->is_snap_volume == _gf_true) { - ret = glusterd_volinfo_find (volinfo->parent_volname, &parent_volinfo); - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, - "Unable to find parent volume %s for snap %s", - volinfo->parent_volname, volinfo->volname); - goto out; - } - list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { - if (!glusterd_is_local_brick (this, volinfo, brickinfo)) - continue; - if (meets_quorum) - glusterd_snap_brick_start (parent_volinfo, volinfo, - brickinfo, _gf_false); - else - glusterd_snap_brick_stop (parent_volinfo, volinfo, - brickinfo, _gf_false); - } - } else { - list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { - if (!glusterd_is_local_brick (this, volinfo, brickinfo)) - continue; - if (meets_quorum) - glusterd_brick_start (volinfo, brickinfo, _gf_false); - else - glusterd_brick_stop (volinfo, brickinfo, _gf_false); - } + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + if (!glusterd_is_local_brick (this, volinfo, brickinfo)) + continue; + if (meets_quorum) + glusterd_brick_start (volinfo, brickinfo, _gf_false); + else + glusterd_brick_stop (volinfo, brickinfo, _gf_false); } out: return; @@ -4580,59 +4313,14 @@ out: return ret; } -int -glusterd_snap_brick_start (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo, - glusterd_brickinfo_t *brickinfo, - gf_boolean_t wait) -{ - int ret = -1; - xlator_t *this = NULL; - glusterd_conf_t *conf = NULL; - - if ((!brickinfo) || (!volinfo)) - goto out; - - this = THIS; - GF_ASSERT (this); - conf = this->private; - GF_ASSERT (conf); - - if (uuid_is_null (brickinfo->uuid)) { - ret = glusterd_resolve_brick (brickinfo); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, FMTSTR_RESOLVE_BRICK, - brickinfo->hostname, brickinfo->path); - goto out; - } - } - - if (uuid_compare (brickinfo->uuid, MY_UUID)) { - ret = 0; - goto out; - } - ret = glusterd_snap_volume_start_glusterfs (volinfo, snap_volinfo, - brickinfo, wait); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Unable to start brick %s:%s", - brickinfo->hostname, brickinfo->path); - goto out; - } - -out: - gf_log (this->name, GF_LOG_DEBUG, "returning %d ", ret); - return ret; -} - int glusterd_restart_bricks (glusterd_conf_t *conf) { + int ret = 0; glusterd_volinfo_t *volinfo = NULL; glusterd_brickinfo_t *brickinfo = NULL; - gf_boolean_t start_nodesvcs = _gf_false; - int ret = 0; glusterd_snap_t *snap = NULL; - glusterd_volinfo_t *snap_volume = NULL; + gf_boolean_t start_nodesvcs = _gf_false; xlator_t *this = NULL; this = THIS; @@ -4651,28 +4339,19 @@ glusterd_restart_bricks (glusterd_conf_t *conf) } } - list_for_each_entry (volinfo, &conf->volumes, vol_list) { - if (volinfo->is_snap_volume) + list_for_each_entry (snap, &conf->snapshots, snap_list) { + volinfo = snap->snap_volume; + if (!volinfo) { + gf_log (this->name, GF_LOG_WARNING, "volinfo " + "for the snap %s is NULL", + snap->snapname); continue; - list_for_each_entry (snap, &volinfo->snaps, snap_list) { - snap_volume = snap->snap_volume; - //GF_ASSERT (snap_volume); - if (!snap_volume) { - gf_log (this->name, GF_LOG_WARNING, "volinfo " - "for the snap %s is NULL", - snap->snap_name); - continue; - } - list_for_each_entry (brickinfo, &snap_volume->bricks, - brick_list) { - glusterd_snap_brick_start (volinfo, snap_volume, - brickinfo, _gf_false); - } + } + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + glusterd_brick_start (volinfo, brickinfo, _gf_false); } } - //TODO: start consistency groups also - if (start_nodesvcs) glusterd_nodesvcs_handle_graph_change (NULL); @@ -5262,14 +4941,7 @@ glusterd_add_brick_to_dict (glusterd_volinfo_t *volinfo, if (ret) goto out; - if (volinfo->is_snap_volume == _gf_true) { - /* Fetching the snap pidfile using parent volname */ - GLUSTERD_GET_SNAP_BRICK_PIDFILE (pidfile, - volinfo->parent_volname, - volinfo->volname, - brickinfo, priv); - } else - GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo, brickinfo, priv); + GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo, brickinfo, priv); brick_online = glusterd_is_service_running (pidfile, &pid); @@ -5557,60 +5229,6 @@ out: return ret; } -int -glusterd_snap_brick_stop (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo, - glusterd_brickinfo_t *brickinfo, - gf_boolean_t del_brick) -{ - int ret = -1; - xlator_t *this = NULL; - glusterd_conf_t *conf = NULL; - - this = THIS; - GF_ASSERT (this); - conf = this->private; - GF_ASSERT (conf); - - if ((!brickinfo) || (!volinfo) || !snap_volinfo) { - gf_log (this->name, GF_LOG_ERROR, "input parameters NULL"); - goto out; - } - - if (uuid_is_null (brickinfo->uuid)) { - ret = glusterd_resolve_brick (brickinfo); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, FMTSTR_RESOLVE_BRICK, - brickinfo->hostname, brickinfo->path); - goto out; - } - } - - if (uuid_compare (brickinfo->uuid, MY_UUID)) { - ret = 0; - if (del_brick) - glusterd_delete_snap_brick (volinfo, snap_volinfo, - brickinfo); - goto out; - } - - gf_log (this->name, GF_LOG_DEBUG, "About to stop glusterfs" - " for brick %s:%s", brickinfo->hostname, - brickinfo->path); - ret = glusterd_snap_volume_stop_glusterfs (volinfo, snap_volinfo, - brickinfo, del_brick); - if (ret) { - gf_log (this->name, GF_LOG_CRITICAL, "Unable to stop" - " brick: %s:%s", brickinfo->hostname, - brickinfo->path); - goto out; - } - -out: - gf_log (this->name, GF_LOG_TRACE, "returning %d ", ret); - return ret; -} - int glusterd_is_defrag_on (glusterd_volinfo_t *volinfo) { @@ -6229,7 +5847,7 @@ glusterd_delete_volume (glusterd_volinfo_t *volinfo) int ret = -1; GF_ASSERT (volinfo); - ret = glusterd_store_delete_volume (volinfo, NULL); + ret = glusterd_store_delete_volume (volinfo); if (ret) goto out; @@ -6259,49 +5877,6 @@ glusterd_delete_brick (glusterd_volinfo_t* volinfo, return ret; } -int32_t -glusterd_delete_snap_brick (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo, - glusterd_brickinfo_t *brickinfo) -{ - int ret = 0; - char voldir[PATH_MAX] = {0,}; - xlator_t *this = NULL; - glusterd_conf_t *priv = NULL; - - this = THIS; - GF_ASSERT (this); - priv = this->private; - GF_ASSERT (priv); - - GF_ASSERT (volinfo); - GF_ASSERT (snap_volinfo); - GF_ASSERT (brickinfo); - - GLUSTERD_GET_SNAP_DIR(voldir, volinfo, snap_volinfo->volname, priv); - - ret = glusterd_delete_snap_volfile (volinfo, snap_volinfo, brickinfo); - if (ret) - gf_log (this->name, GF_LOG_WARNING, "failed to delete the " - "volfile for the brick (%s:%s), snap: %s volume: %s", - brickinfo->hostname, brickinfo->path, - snap_volinfo->volname, volinfo->volname); - ret = glusterd_store_delete_brick (brickinfo, voldir); - if (ret) - gf_log (this->name, GF_LOG_WARNING, "failed to delete the " - "store handle of brick (%s:%s), snap: %s volume: %s", - brickinfo->hostname, brickinfo->path, - snap_volinfo->volname, volinfo->volname); - ret = glusterd_brickinfo_delete (brickinfo); - if (ret) - gf_log (this->name, GF_LOG_WARNING, "failed to delete the " - "brickinfo (%s:%s), snap: %s volume: %s", - brickinfo->hostname, brickinfo->path, - snap_volinfo->volname, volinfo->volname); - snap_volinfo->brick_count--; - return ret; -} - int32_t glusterd_delete_all_bricks (glusterd_volinfo_t* volinfo) { @@ -8873,3 +8448,20 @@ glusterd_is_status_tasks_op (glusterd_op_t op, dict_t *dict) out: return is_status_tasks; } + +int +glusterd_compare_snap_time(struct list_head *list1, struct list_head *list2) +{ + glusterd_snap_t *snap1 = NULL; + glusterd_snap_t *snap2 = NULL; + double diff_time = 0; + + GF_ASSERT (list1); + GF_ASSERT (list2); + + snap1 = list_entry(list1, glusterd_snap_t, snap_list); + snap2 = list_entry(list2, glusterd_snap_t, snap_list); + diff_time = difftime(snap1->time_stamp, snap2->time_stamp); + + return ((int)diff_time); +} diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index e1e595669..e2654e6f8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -119,7 +119,12 @@ int32_t glusterd_peer_hostname_new (char *hostname, glusterd_peer_hostname_t **name); int32_t -glusterd_snap_volinfo_find (char *volname, glusterd_volinfo_t **volinfo); +glusterd_snap_volinfo_find (char *volname, glusterd_snap_t *snap, + glusterd_volinfo_t **volinfo); +int32_t +glusterd_snap_volinfo_find_from_parent_volname (char *origin_volname, + glusterd_snap_t *snap, + glusterd_volinfo_t **volinfo); int32_t glusterd_volinfo_find (char *volname, glusterd_volinfo_t **volinfo); @@ -170,8 +175,7 @@ int32_t glusterd_compare_friend_data (dict_t *vols, int32_t *status, char *hostname); int -glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo); +glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo); void glusterd_get_nodesvc_volfile (char *server, char *workdir, @@ -611,4 +615,6 @@ int glusterd_get_brick_root (char *path, char **mount_point); #endif //LINUX_HOST +int +glusterd_compare_snap_time(struct list_head *, struct list_head *); #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index 2565544a6..90886dcf3 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -3200,8 +3200,7 @@ glusterd_generate_snap_brick_volfile (glusterd_volinfo_t *volinfo, if (vol_restore) { GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv); } else { - GLUSTERD_GET_SNAP_DIR (path, volinfo, - snap_volinfo->volname, priv); + GLUSTERD_GET_VOLUME_DIR (path, snap_volinfo, priv); } snprintf (filename, PATH_MAX, "%s/%s.%s.%s.vol", @@ -3440,8 +3439,7 @@ generate_snap_client_volfiles (glusterd_volinfo_t *actual_volinfo, if (vol_restore) { GLUSTERD_GET_VOLUME_DIR (path, actual_volinfo, conf); } else { - GLUSTERD_GET_SNAP_DIR (path, actual_volinfo, - snap_volinfo->volname, conf); + GLUSTERD_GET_VOLUME_DIR (path, snap_volinfo, conf); } for (i = 0; types[i]; i++) { @@ -3729,39 +3727,6 @@ glusterd_delete_volfile (glusterd_volinfo_t *volinfo, return ret; } -int -glusterd_delete_snap_volfile (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo, - glusterd_brickinfo_t *brickinfo) -{ - int ret = 0; - char filename[PATH_MAX] = {0,}; - char brick[PATH_MAX] = {0, }; - char path[PATH_MAX] = {0, }; - glusterd_conf_t *priv = NULL; - - GF_ASSERT (volinfo); - GF_ASSERT (brickinfo); - GF_ASSERT (snap_volinfo); - - priv = THIS->private; - GF_ASSERT (priv); - - GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, brick); - GLUSTERD_GET_SNAP_DIR (path, volinfo, snap_volinfo->volname, priv); - - snprintf (filename, PATH_MAX, "%s/%s.%s.%s.vol", - path, snap_volinfo->volname, - brickinfo->hostname, - brick); - - ret = unlink (filename); - if (ret) - gf_log ("glusterd", GF_LOG_ERROR, "failed to delete file: %s, " - "reason: %s", filename, strerror (errno)); - return ret; -} - int validate_shdopts (glusterd_volinfo_t *volinfo, dict_t *val_dict, @@ -4392,8 +4357,7 @@ gd_update_origin_volume (glusterd_volinfo_t *orig_vol, /* Stop the snap volume */ list_for_each_entry (brickinfo, &snap_vol->bricks, brick_list) { - ret = glusterd_snap_brick_stop (orig_vol, snap_vol, - brickinfo, _gf_false); + ret = glusterd_brick_stop (snap_vol, brickinfo, _gf_false); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to stop " " %s brick", brickinfo->path); @@ -4420,7 +4384,7 @@ gd_update_origin_volume (glusterd_volinfo_t *orig_vol, } /* Retrieve brick list */ - ret = glusterd_store_retrieve_bricks (orig_vol, NULL); + ret = glusterd_store_retrieve_bricks (orig_vol); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to retrieve " "bricks info from store for %s volume", @@ -4465,7 +4429,7 @@ gd_restore_snap_volume (glusterd_volinfo_t *orig_vol, GF_VALIDATE_OR_GOTO (this->name, orig_vol, out); GF_VALIDATE_OR_GOTO (this->name, snap_vol, out); - GLUSTERD_GET_SNAP_DIR (snappath, orig_vol, snap_vol->volname, conf); + GLUSTERD_GET_VOLUME_DIR (snappath, snap_vol, conf); GLUSTERD_GET_VOLUME_DIR (volpath, orig_vol, conf); /* As mentioned earlier the snapshot restore is done by replacing @@ -4489,8 +4453,7 @@ gd_restore_snap_volume (glusterd_volinfo_t *orig_vol, } GLUSTERD_GET_BRICK_DIR (oldfilename, orig_vol, conf); - GLUSTERD_GET_SNAP_BRICK_DIR (newfilename, orig_vol, - snap_vol->volname, conf); + GLUSTERD_GET_BRICK_DIR (newfilename, snap_vol, conf); /* Backup and restore bricks folder and it's contents */ ret = gd_backup_and_restore_snap_files (orig_vol, oldfilename, diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index ac2684de8..bbe0c8d96 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -1649,7 +1649,7 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT); if (ret) { - glusterd_store_delete_volume (volinfo, NULL); + glusterd_store_delete_volume (volinfo); *op_errstr = gf_strdup ("Failed to store the Volume information"); goto out; } diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index c2806bdfa..edb36b7d8 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -1315,7 +1315,7 @@ init (xlator_t *this) INIT_LIST_HEAD (&conf->peers); INIT_LIST_HEAD (&conf->volumes); INIT_LIST_HEAD (&conf->snap_cg); - INIT_LIST_HEAD (&conf->snap_list); + INIT_LIST_HEAD (&conf->snapshots); pthread_mutex_init (&conf->mutex, NULL); conf->rpc = rpc; diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 27ebbbb6c..bd765349a 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -40,6 +40,7 @@ #include "store.h" #define GLUSTERD_MAX_VOLUME_NAME 1000 +#define GLUSTERD_MAX_SNAP_NAME 128 #define GLUSTERD_TR_LOG_SIZE 50 #define GLUSTERD_NAME "glusterd" #define GLUSTERD_SOCKET_LISTEN_BACKLOG 128 @@ -75,6 +76,9 @@ struct glusterd_volinfo_; typedef struct glusterd_volinfo_ glusterd_volinfo_t; +struct glusterd_snap_; +typedef struct glusterd_snap_ glusterd_snap_t; + typedef enum glusterd_op_ { GD_OP_NONE = 0, GD_OP_CREATE_VOLUME, @@ -139,7 +143,7 @@ typedef struct { nodesrv_t *nfs; struct pmap_registry *pmap; struct list_head volumes; - struct list_head snap_list; /*List of snap volumes */ + struct list_head snapshots; /*List of snap volumes */ pthread_mutex_t xprt_lock; struct list_head xprt_list; gf_store_handle_t *handle; @@ -279,6 +283,7 @@ struct glusterd_volinfo_ { gf_lock_t lock; char volname[GLUSTERD_MAX_VOLUME_NAME]; gf_boolean_t is_snap_volume; + glusterd_snap_t *snapshot; gf_boolean_t is_volume_restored; char parent_volname[GLUSTERD_MAX_VOLUME_NAME]; /* In case of a snap volume @@ -292,8 +297,16 @@ struct glusterd_volinfo_ { uint64_t snap_count; uint64_t snap_max_hard_limit; struct list_head vol_list; + /* In case of a snap volume + i.e (is_snap_volume == TRUE) this + is linked to glusterd_snap_t->volumes. + In case of a non-snap volume, this is + linked to glusterd_conf_t->volumes */ + struct list_head snapvol_list; + /* This is a current pointer for + glusterd_volinfo_t->snap_volumes */ struct list_head bricks; - struct list_head snaps; + struct list_head snap_volumes; glusterd_volume_status status; int sub_count; /* backward compatibility */ int stripe_count; @@ -306,7 +319,6 @@ struct glusterd_volinfo_ { gf_store_handle_t *shandle; gf_store_handle_t *rb_shandle; gf_store_handle_t *node_state_shandle; - gf_store_handle_t *snap_list_shandle; /* Defrag/rebalance related */ glusterd_rebalance_t rebal; @@ -347,9 +359,11 @@ typedef enum gd_snap_status_ { struct glusterd_snap_ { gf_lock_t lock; - glusterd_volinfo_t *snap_volume; + struct list_head volumes; + glusterd_volinfo_t *snap_volume; /*TODO: This should be replaced + with volumes list later */ struct list_head snap_list; - char snap_name[256]; + char snapname[GLUSTERD_MAX_SNAP_NAME]; uuid_t snap_id; char cg_name[256]; uuid_t cg_id; @@ -360,8 +374,6 @@ struct glusterd_snap_ { gf_store_handle_t *shandle; }; -typedef struct glusterd_snap_ glusterd_snap_t; - struct glusterd_snap_cg_ { gf_lock_t lock; uuid_t cg_id; @@ -415,6 +427,7 @@ enum glusterd_vol_comp_status_ { #define GLUSTERD_VOLUME_DIR_PREFIX "vols" #define GLUSTERD_PEER_DIR_PREFIX "peers" #define GLUSTERD_VOLUME_INFO_FILE "info" +#define GLUSTERD_SNAP_INFO_FILE "info" #define GLUSTERD_VOLUME_RBSTATE_FILE "rbstate" #define GLUSTERD_BRICK_INFO_DIR "bricks" #define GLUSTERD_CKSUM_FILE "cksum" @@ -444,27 +457,33 @@ enum glusterd_vol_comp_status_ { typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args); -#define GLUSTERD_GET_VOLUME_DIR(path, volinfo, priv) \ - snprintf (path, PATH_MAX, "%s/vols/%s", priv->workdir,\ - volinfo->volname); +#define GLUSTERD_GET_VOLUME_DIR(path, volinfo, priv) \ + if (volinfo->is_snap_volume) { \ + snprintf (path, PATH_MAX, "%s/snaps/%s/%s", priv->workdir, \ + volinfo->snapshot->snapname, volinfo->volname); \ + } else { \ + snprintf (path, PATH_MAX, "%s/vols/%s", priv->workdir, \ + volinfo->volname); \ + } + +#define GLUSTERD_GET_SNAP_DIR(path, snap, priv) \ + snprintf (path, PATH_MAX, "%s/snaps/%s", priv->workdir, \ + snap->snapname); #define GLUSTERD_GET_SNAP_CG_DIR(path, priv) \ snprintf (path, PATH_MAX, "%s/%s", priv->workdir,\ GLUSTERD_VOL_SNAP_CG_DIR_PREFIX); -#define GLUSTERD_GET_SNAP_DIR(path, volinfo, snap_name, priv) \ - snprintf (path, PATH_MAX, "%s/vols/%s/snaps/%s", priv->workdir,\ - volinfo->volname, snap_name); - -#define GLUSTERD_GET_BRICK_DIR(path, volinfo, priv) \ - snprintf (path, PATH_MAX, "%s/%s/%s/%s", priv->workdir,\ - GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname, \ - GLUSTERD_BRICK_INFO_DIR); - -#define GLUSTERD_GET_SNAP_BRICK_DIR(path, volinfo, snap_name, priv) \ - snprintf (path, PATH_MAX, "%s/%s/%s/snaps/%s/%s", priv->workdir,\ - GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname, \ - snap_name, GLUSTERD_BRICK_INFO_DIR); +#define GLUSTERD_GET_BRICK_DIR(path, volinfo, priv) \ + if (volinfo->is_snap_volume) { \ + snprintf (path, PATH_MAX, "%s/snaps/%s/%s/%s", priv->workdir, \ + volinfo->snapshot->snapname, volinfo->volname, \ + GLUSTERD_BRICK_INFO_DIR); \ + } else { \ + snprintf (path, PATH_MAX, "%s/%s/%s/%s", priv->workdir, \ + GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname, \ + GLUSTERD_BRICK_INFO_DIR); \ + } #define GLUSTERD_GET_NFS_DIR(path, priv) \ snprintf (path, PATH_MAX, "%s/nfs", priv->workdir); @@ -487,17 +506,6 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args); volpath, brickinfo->hostname, exp_path); \ } while (0) -#define GLUSTERD_GET_SNAP_BRICK_PIDFILE(pidfile,vol_name,snap_name, \ - brickinfo, priv) do { \ - char exp_path[PATH_MAX] = {0,}; \ - char volpath[PATH_MAX] = {0,}; \ - snprintf (volpath, sizeof (volpath), "%s/vols/%s/snaps/%s", \ - priv->workdir, vol_name, snap_name); \ - GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, exp_path);\ - snprintf (pidfile, sizeof (pidfile), "%s/run/%s-%s.pid", \ - volpath, brickinfo->hostname, exp_path); \ - } while (0) - #define GLUSTERD_GET_NFS_PIDFILE(pidfile,nfspath) { \ snprintf (pidfile, PATH_MAX, "%s/run/nfs.pid", \ nfspath); \ @@ -904,19 +912,20 @@ glusterd_snap_cg_t* glusterd_new_snap_cg_object(int64_t volume_count); int32_t -glusterd_add_snap (glusterd_volinfo_t *volinfo, glusterd_snap_t *snap); +glusterd_list_add_snapvol (glusterd_volinfo_t *origin_vol, + glusterd_volinfo_t *snap_vol); glusterd_snap_t* -glusterd_remove_snap_by_id (glusterd_volinfo_t *volinfo, uuid_t snap_id); +glusterd_remove_snap_by_id (uuid_t snap_id); glusterd_snap_t* -glusterd_remove_snap_by_name (glusterd_volinfo_t *volinfo, char *snap_name); +glusterd_remove_snap_by_name (char *snap_name); glusterd_snap_t* -glusterd_find_snap_by_name (glusterd_volinfo_t *volinfo, char *snap_name); +glusterd_find_snap_by_name (char *snap_name); glusterd_snap_t* -glusterd_find_snap_by_id (glusterd_volinfo_t *volinfo, uuid_t snap_id); +glusterd_find_snap_by_id (uuid_t snap_id); int32_t glusterd_add_snap_cg (glusterd_conf_t *conf, glusterd_snap_cg_t *cg); -- cgit