/* Copyright (c) 2013 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. */ #include //#include #include #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include "call-stub.h" #include "defaults.h" #include "xlator.h" #include "api/src/glfs.h" #include "api/src/glfs-internal.h" #ifndef NSR_SIM_ETCD #include "etcd-api.h" #endif #include "nsr-internal.h" #include "../../nsr-recon/src/recon_driver.h" #include "../../nsr-recon/src/recon_xlator.h" #define NSR_KEY "xyzzy" #define NSR_TTL 5 static void nsr_set_leader (xlator_t *this, etcd_session etcd) { long term = 0; etcd_result res; nsr_private_t *priv = this->private; char *term_key = priv->term_uuid; char n_t[sizeof(long)+1]; char *text = NULL; gf_log (this->name, GF_LOG_INFO, "Just became leader"); text = etcd_get(etcd, priv->term_uuid); if(text == NULL) { term = 0; } else { term = strtol(text, NULL, 10); } sprintf(n_t,"%ld",term+1); res = etcd_set(etcd, term_key,n_t,text,0); if(res != ETCD_OK) { gf_log (this->name, GF_LOG_ERROR, "failed to set term"); return; } priv->leader = _gf_true; priv->current_term = term + 1; if (priv->nsr_recon_start == _gf_false) { atomic_fetch_and(&(priv->fence_io), 0); return; } // Move this inside recon notify??? atomic_fetch_or(&(priv->fence_io), 1); nsr_recon_notify_event_set_leader(priv); return; } void * nsr_leader_thread (void *arg) { xlator_t *this = (xlator_t *) arg; nsr_private_t *priv = this->private; etcd_result res; char *index_in = NULL; char *index_out = NULL; gf_log (this->name, GF_LOG_INFO, "calling glfs_open_str on servers %s", priv->etcd_servers); priv->etcd = etcd_open_str(priv->etcd_servers); if (!(priv->etcd)) { gf_log (this->name, GF_LOG_ERROR, "failed to open etcd session\n"); return NULL; } priv->leader_inited = 1; for (;;) { /* Not leader yet. Try to become leader. */ for (;;) { res = etcd_lock (priv->etcd, NSR_KEY, NSR_TTL, index_in, &index_out); if (res == ETCD_OK) { break; } gf_log (this->name, GF_LOG_WARNING, "etcd_lock failed (%d)", res); sleep(1); } /* We're there. Notify other parts of the code. */ nsr_set_leader(this,priv->etcd); /* Try to retain leadership. */ for (;;) { index_in = index_out; index_out = NULL; res = etcd_lock (priv->etcd, NSR_KEY, NSR_TTL, index_in, &index_out); if (index_in && (index_in != index_out)) { free(index_in); } if (res != ETCD_OK) { gf_log (this->name, GF_LOG_WARNING, "lost leadership (%d)", res); if (index_out) { free(index_out); } break; } sleep(1); } } etcd_close_str(priv->etcd); return NULL; }