summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshishir gowda <sgowda@redhat.com>2013-09-24 16:44:24 +0530
committershishir gowda <sgowda@redhat.com>2013-10-03 10:14:16 +0530
commitef02610d4b1b2165e2c076c1aa9584bd634b2b56 (patch)
treec305f86a18db80be48d78d9b2367b2612f8d326c
parenta5ef7bc7de744d1324ddf63207b1172d11086441 (diff)
mgmt/glusterd: Introduce snapshot infrastructure
API's for creating, adding, finding, removing snapshots and consistency groups are provided. Signed-off-by: shishir gowda <sgowda@redhat.com>
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mem-types.h4
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c303
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.c2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h78
4 files changed, 386 insertions, 1 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-mem-types.h b/xlators/mgmt/glusterd/src/glusterd-mem-types.h
index 51057c274..c1009d66f 100644
--- a/xlators/mgmt/glusterd/src/glusterd-mem-types.h
+++ b/xlators/mgmt/glusterd/src/glusterd-mem-types.h
@@ -67,7 +67,9 @@ typedef enum gf_gld_mem_types_ {
gf_gld_mt_hooks_priv_t = gf_common_mt_end + 51,
gf_gld_mt_mop_commit_req_t = gf_common_mt_end + 52,
gf_gld_mt_int = gf_common_mt_end + 53,
- gf_gld_mt_end = gf_common_mt_end + 54,
+ gf_gld_mt_snap_t = gf_common_mt_end + 54,
+ gf_gld_mt_snap_cg_t = gf_common_mt_end + 55,
+ gf_gld_mt_end = gf_common_mt_end + 56,
} gf_gld_mem_types_t;
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index b0f9a210f..6eb508e89 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -430,8 +430,10 @@ glusterd_volinfo_new (glusterd_volinfo_t **volinfo)
if (!new_volinfo)
goto out;
+ LOCK_INIT (&new_volinfo->lock);
INIT_LIST_HEAD (&new_volinfo->vol_list);
INIT_LIST_HEAD (&new_volinfo->bricks);
+ INIT_LIST_HEAD (&new_volinfo->snaps);
new_volinfo->dict = dict_new ();
if (!new_volinfo->dict) {
@@ -7695,3 +7697,304 @@ out:
gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
+
+glusterd_snap_t*
+glusterd_new_snap_object()
+{
+ glusterd_snap_t *snap = NULL;
+
+ snap = GF_CALLOC (1, sizeof (*snap), gf_gld_mt_snap_t);
+
+ if (snap) {
+ LOCK_INIT (&snap->lock);
+ INIT_LIST_HEAD (&snap->snap_list);
+ snap->snap_status = GD_SNAP_STATUS_INIT;
+ }
+
+ return snap;
+
+};
+
+glusterd_snap_cg_t*
+glusterd_new_snap_cg_object(int64_t volume_count)
+{
+ glusterd_snap_cg_t *cg = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+
+ if (volume_count < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Volume count < 0");
+ return NULL;
+ }
+
+ cg = GF_CALLOC (1, (sizeof (*cg) +
+ (volume_count * sizeof (*volinfo))),
+ gf_gld_mt_snap_cg_t);
+
+ if (cg) {
+ LOCK_INIT (&cg->lock);
+ INIT_LIST_HEAD (&cg->cg_list);
+ cg->cg_status = GD_SNAP_STATUS_INIT;
+ cg->volume_count = volume_count;
+ }
+
+ return cg;
+}
+
+int32_t
+glusterd_add_snap (glusterd_volinfo_t *volinfo, glusterd_snap_t *snap)
+{
+ int ret = -1;
+ uint64_t count = -1;
+ glusterd_snap_t *entry = NULL;
+ glusterd_snap_t *last = NULL;
+ glusterd_snap_t *tmp = NULL;
+
+ GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out);
+ GF_VALIDATE_OR_GOTO ("glusterd", snap, 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 (&snap->snap_list, &last->snap_list);
+
+ gf_log (THIS->name, GF_LOG_DEBUG, "Snap %s added @ %"PRIu64,
+ snap->snap_name, count);
+ ret = 0;
+ }
+unlock:
+ UNLOCK (&volinfo->lock);
+out:
+ return ret;
+}
+
+glusterd_snap_t*
+glusterd_find_snap_by_name (glusterd_volinfo_t *volinfo, char *snap_name)
+{
+ uint64_t count = -1;
+ glusterd_snap_t *entry = NULL;
+ glusterd_snap_t *dup = NULL;
+ glusterd_snap_t *tmp = NULL;
+
+ GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out);
+ GF_VALIDATE_OR_GOTO ("glusterd", snap_name, out);
+
+ 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;
+ }
+ }
+ }
+ UNLOCK (&volinfo->lock);
+out:
+ return dup;
+}
+
+glusterd_snap_t*
+glusterd_find_snap_by_id (glusterd_volinfo_t *volinfo, uuid_t snap_id)
+{
+ uint64_t count = -1;
+ glusterd_snap_t *entry = NULL;
+ glusterd_snap_t *dup = NULL;
+ glusterd_snap_t *tmp = NULL;
+
+ 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;
+ }
+ }
+ }
+ UNLOCK (&volinfo->lock);
+out:
+ return dup;
+}
+
+glusterd_snap_t*
+glusterd_remove_snap_by_id (glusterd_volinfo_t *volinfo, uuid_t snap_id)
+{
+ glusterd_snap_t *entry = 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);
+
+ if (entry) {
+ LOCK (&volinfo->lock);
+ {
+ entry->snap_status = GD_SNAP_STATUS_DECOMMISSION;
+ list_del_init (&entry->snap_list);
+ }
+ UNLOCK (&volinfo->lock);
+ }
+out:
+ return entry;
+}
+
+glusterd_snap_t*
+glusterd_remove_snap_by_name (glusterd_volinfo_t *volinfo, char *snap_name)
+{
+ glusterd_snap_t *entry = NULL;
+
+ GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out);
+ GF_VALIDATE_OR_GOTO ("glusterd", snap_name, out);
+
+ entry = glusterd_find_snap_by_name (volinfo, snap_name);
+
+ if (entry) {
+ LOCK (&volinfo->lock);
+ {
+ entry->snap_status = GD_SNAP_STATUS_DECOMMISSION;
+ list_del_init (&entry->snap_list);
+ }
+ UNLOCK (&volinfo->lock);
+ }
+out:
+ return entry;
+}
+
+// Big lock should already acquired before this is called
+int32_t
+glusterd_add_snap_cg (glusterd_conf_t *conf, glusterd_snap_cg_t *cg)
+{
+ int ret = -1;
+ uint64_t count = -1;
+ glusterd_snap_cg_t *entry = NULL;
+ glusterd_snap_cg_t *last = NULL;
+ glusterd_snap_cg_t *tmp = NULL;
+
+ GF_VALIDATE_OR_GOTO (THIS->name, conf, out);
+ GF_VALIDATE_OR_GOTO (THIS->name, cg, out);
+
+ list_for_each_entry_safe (entry, tmp, &conf->snap_cg, cg_list) {
+ count++;
+ if (!strcmp (entry->cg_name, cg->cg_name) ||
+ !uuid_compare (entry->cg_id, cg->cg_id)) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Found duplicate "
+ "CG %s(%s)", entry->cg_name,
+ uuid_utoa(entry->cg_id));
+ goto out;
+ }
+ last = entry;
+ }
+ list_add (&cg->cg_list, &last->cg_list);
+ gf_log (THIS->name, GF_LOG_DEBUG, "Added CG %s (%s) @ %"PRIu64,
+ cg->cg_name, uuid_utoa(cg->cg_id), count);
+ ret = 0;
+out:
+ return ret;
+
+}
+
+
+glusterd_snap_cg_t*
+glusterd_find_snap_cg_by_name (glusterd_conf_t *conf, char *cg_name)
+{
+ glusterd_snap_cg_t *entry = NULL;
+ glusterd_snap_cg_t *dup = NULL;
+ glusterd_snap_cg_t *tmp = NULL;
+
+ GF_VALIDATE_OR_GOTO (THIS->name, conf, out);
+ GF_VALIDATE_OR_GOTO (THIS->name, cg_name, out);
+
+ list_for_each_entry_safe (entry, tmp, &conf->snap_cg, cg_list) {
+ if (!strcmp (entry->cg_name, cg_name)) {
+ gf_log (THIS->name, GF_LOG_DEBUG, "Found CG %s(%s)",
+ entry->cg_name, uuid_utoa(entry->cg_id));
+ dup = entry;
+ break;
+ }
+ }
+out:
+ return dup;
+}
+
+glusterd_snap_cg_t*
+glusterd_find_snap_cg_by_id (glusterd_conf_t *conf, uuid_t cg_id)
+{
+ glusterd_snap_cg_t *entry = NULL;
+ glusterd_snap_cg_t *dup = NULL;
+ glusterd_snap_cg_t *tmp = NULL;
+
+ GF_VALIDATE_OR_GOTO (THIS->name, conf, out);
+ if (uuid_is_null (cg_id))
+ goto out;
+
+ list_for_each_entry_safe (entry, tmp, &conf->snap_cg, cg_list) {
+ if (!uuid_compare (entry->cg_id, cg_id)) {
+ gf_log (THIS->name, GF_LOG_DEBUG, "Found CG %s(%s)",
+ entry->cg_name, uuid_utoa(entry->cg_id));
+ dup = entry;
+ break;
+ }
+ }
+out:
+ return dup;
+}
+
+glusterd_snap_cg_t*
+glusterd_remove_snap_cg_by_name (glusterd_conf_t *conf, char *cg_name)
+{
+ glusterd_snap_cg_t *entry = NULL;
+
+ GF_VALIDATE_OR_GOTO (THIS->name, conf, out);
+ GF_VALIDATE_OR_GOTO (THIS->name, cg_name, out);
+
+ entry = glusterd_find_snap_cg_by_name(conf, cg_name);
+ if (entry) {
+ entry->cg_status = GD_SNAP_STATUS_DECOMMISSION;
+ list_del_init (&entry->cg_list);
+ }
+out:
+ return entry;
+}
+
+glusterd_snap_cg_t*
+glusterd_remove_snap_cg_by_id (glusterd_conf_t *conf, uuid_t cg_id)
+{
+ glusterd_snap_cg_t *entry = NULL;
+
+ GF_VALIDATE_OR_GOTO (THIS->name, conf, out);
+ if (uuid_is_null (cg_id))
+ goto out;
+
+ entry = glusterd_find_snap_cg_by_id (conf, cg_id);
+ if (entry) {
+ entry->cg_status = GD_SNAP_STATUS_DECOMMISSION;
+ list_del_init (&entry->cg_list);
+ }
+out:
+ return entry;
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
index dc35f8bf0..bb03e5ba0 100644
--- a/xlators/mgmt/glusterd/src/glusterd.c
+++ b/xlators/mgmt/glusterd/src/glusterd.c
@@ -1123,6 +1123,8 @@ init (xlator_t *this)
INIT_LIST_HEAD (&conf->peers);
INIT_LIST_HEAD (&conf->volumes);
+ INIT_LIST_HEAD (&conf->snap_cg);
+
pthread_mutex_init (&conf->mutex, NULL);
conf->rpc = rpc;
conf->gfs_mgmt = &gd_brick_prog;
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 26e9b0c0d..e804c9ce8 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -154,6 +154,7 @@ typedef struct {
dict_t *opts;
synclock_t big_lock;
gf_boolean_t restart_done;
+ struct list_head snap_cg;
} glusterd_conf_t;
@@ -263,11 +264,13 @@ struct glusterd_replace_brick_ {
typedef struct glusterd_replace_brick_ glusterd_replace_brick_t;
struct glusterd_volinfo_ {
+ gf_lock_t lock;
char volname[GLUSTERD_MAX_VOLUME_NAME];
int type;
int brick_count;
struct list_head vol_list;
struct list_head bricks;
+ struct list_head snaps;
glusterd_volume_status status;
int sub_count; /* backward compatibility */
int stripe_count;
@@ -310,6 +313,44 @@ struct glusterd_volinfo_ {
int client_op_version;
};
+typedef enum gd_snap_status_ {
+ GD_SNAP_STATUS_NONE,
+ GD_SNAP_STATUS_INIT,
+ GD_SNAP_STATUS_IN_USE,
+ GD_SNAP_STATUS_DECOMMISSION,
+ GD_SNAP_STATUS_RESTORED,
+} gd_snap_status_t;
+
+
+struct glusterd_snap_ {
+ gf_lock_t lock;
+ glusterd_volinfo_t *snap_volume;
+ struct list_head snap_list;
+ char snap_name[256];
+ uuid_t snap_id;
+ uuid_t cg_id;
+ char *description;
+ time_t time_stamp;
+ gd_snap_status_t snap_status;
+};
+
+typedef struct glusterd_snap_ glusterd_snap_t;
+
+struct glusterd_snap_cg_ {
+ gf_lock_t lock;
+ uuid_t cg_id;
+ char cg_name[256];
+ char *description;
+ gd_snap_status_t cg_status;
+ int64_t volume_count;
+ struct list_head cg_list;
+ glusterd_volinfo_t volumes[0];
+};
+
+typedef struct glusterd_snap_cg_ glusterd_snap_cg_t;
+
+
+
typedef enum gd_node_type_ {
GD_NODE_NONE,
GD_NODE_BRICK,
@@ -760,4 +801,41 @@ int32_t glusterd_op_begin_synctask (rpcsvc_request_t *req, glusterd_op_t op,
void *dict);
int32_t
glusterd_defrag_event_notify_handle (dict_t *dict);
+
+/* snapshot */
+glusterd_snap_t*
+glusterd_new_snap_object();
+
+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_snap_t*
+glusterd_remove_snap_by_id (glusterd_volinfo_t *volinfo, uuid_t snap_id);
+
+glusterd_snap_t*
+glusterd_remove_snap_by_name (glusterd_volinfo_t *volinfo, char *snap_name);
+
+glusterd_snap_t*
+glusterd_find_snap_by_name (glusterd_volinfo_t *volinfo, char *snap_name);
+
+glusterd_snap_t*
+glusterd_find_snap_by_id (glusterd_volinfo_t *volinfo, uuid_t snap_id);
+
+int32_t
+glusterd_add_snap_cg (glusterd_conf_t *conf, glusterd_snap_cg_t *cg);
+
+glusterd_snap_cg_t*
+glusterd_remove_snap_cg_by_name (glusterd_conf_t *conf, char *cg_name);
+
+glusterd_snap_cg_t*
+glusterd_remove_snap_cg_by_id (glusterd_conf_t *conf, uuid_t cg_id);
+
+glusterd_snap_cg_t*
+glusterd_find_snap_cg_by_id (glusterd_conf_t *conf, uuid_t cg_id);
+
+glusterd_snap_cg_t*
+glusterd_find_snap_cg_by_name (glusterd_conf_t *conf, char *cg_name);
#endif