/* Copyright (c) 2010-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "globals.h" #include "compat.h" #include "protocol-common.h" #include "xlator.h" #include "logging.h" #include "timer.h" #include "glusterd-mem-types.h" #include "glusterd.h" #include "glusterd-sm.h" #include "glusterd-op-sm.h" #include "glusterd-utils.h" #include "glusterd-store.h" #include "run.h" #include "glusterd-volgen.h" #include "syscall.h" #include "cli1-xdr.h" #include "xdr-generic.h" 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; }