[Ocfs2-tools-devel] [PATCH 01/32] o2cb_config: Add support for the heartbeat stanza

Sunil Mushran sunil.mushran at oracle.com
Tue Sep 14 15:54:31 PDT 2010


Teach o2cb_config to parse the heartbeat stanza shown below. The cluster
stanza also has heartbeat_mode that can have values global or local to allow
the user to easily toggle between global and local heartbeat.

heartbeat:
        region = 908A022988C34A0DB6BC38C43C6B1461
        cluster = mycluster

cluster:
        node_count = 10
        heartbeat_mode = global
        name = mycluster

Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>
---
 include/o2cb/o2cb.h    |    3 +
 o2cb_ctl/o2cb_config.c |  227 +++++++++++++++++++++++++++++++++++++++++++++++-
 o2cb_ctl/o2cb_config.h |   13 +++
 3 files changed, 241 insertions(+), 2 deletions(-)

diff --git a/include/o2cb/o2cb.h b/include/o2cb/o2cb.h
index 688817a..4602887 100644
--- a/include/o2cb/o2cb.h
+++ b/include/o2cb/o2cb.h
@@ -50,6 +50,9 @@
 
 #define OCFS2_FS_NAME		"ocfs2"
 
+#define O2CB_GLOBAL_HEARTBEAT_TAG	"global"
+#define O2CB_LOCAL_HEARTBEAT_TAG	"local"
+
 errcode_t o2cb_init(void);
 
 errcode_t o2cb_get_stack_name(const char **name);
diff --git a/o2cb_ctl/o2cb_config.c b/o2cb_ctl/o2cb_config.c
index cdb37cf..328c118 100644
--- a/o2cb_ctl/o2cb_config.c
+++ b/o2cb_ctl/o2cb_config.c
@@ -45,8 +45,10 @@ struct _O2CBConfig {
 
 struct _O2CBCluster {
     gchar *c_name;
+    gchar *c_hb_mode;
     guint c_num_nodes;
     GList *c_nodes;
+    GList *c_heartbeat;
 };
 
 struct _O2CBNode {
@@ -56,9 +58,17 @@ struct _O2CBNode {
     guint n_port;
 };
 
+struct _O2CBHeartbeat {
+    gchar *h_region;
+};
 
-static void o2cb_node_free(O2CBNode *node);
+gchar *valid_heartbeat_modes[] = {
+	O2CB_LOCAL_HEARTBEAT_TAG,
+	O2CB_GLOBAL_HEARTBEAT_TAG,
+	NULL,
+};
 
+static void o2cb_node_free(O2CBNode *node);
 
 O2CBConfig *o2cb_config_initialize(void)
 {
@@ -74,6 +84,30 @@ O2CBConfig *o2cb_config_initialize(void)
     return config;
 }  /* o2cb_config_initialize() */
 
+static gint o2cb_cluster_fill_heartbeat(O2CBCluster *cluster,
+                                        JConfigStanza *cfs)
+{
+    O2CBHeartbeat *hb;
+    gchar *region;
+    gint rc;
+
+    rc = -EINVAL;
+    region = j_config_get_attribute(cfs, "region");
+    if (!region || !*region)
+        goto out_error;
+
+    hb = o2cb_cluster_add_heartbeat(cluster, region);
+    if (!hb)
+        return -ENOMEM;
+
+    rc = 0;
+
+out_error:
+    g_free(region);
+
+    return rc;
+}  /* o2cb_config_fill_heartbeat() */
+
 static gint o2cb_cluster_fill_node(O2CBCluster *cluster,
                                    JConfigStanza *cfs)
 {
@@ -144,12 +178,13 @@ static gint o2cb_config_fill_cluster(O2CBConfig *config, JConfig *cf,
 {
     gint rc;
     gulong val;
-    gchar *count, *ptr;
+    gchar *count, *ptr, *hb_mode = NULL;
     O2CBCluster *cluster;
     JIterator *iter;
     JConfigStanza *n_cfs;
     JConfigMatch match = {J_CONFIG_MATCH_VALUE, "cluster", NULL};
 
+    /* cluster: name */
     rc = -ENOENT;
     match.value = j_config_get_attribute(c_cfs, "name");
     if (!match.value && !*match.value)
@@ -159,6 +194,18 @@ static gint o2cb_config_fill_cluster(O2CBConfig *config, JConfig *cf,
     if (!cluster)
         goto out_error;
 
+    /* cluster: heartbeat_mode */
+    rc = -ENOMEM;
+    hb_mode = j_config_get_attribute(c_cfs, "heartbeat_mode");
+    if (!hb_mode)
+        hb_mode = g_strdup("local");
+    if (!hb_mode)
+        goto out_error;
+    rc = o2cb_cluster_set_heartbeat_mode(cluster, hb_mode);
+    if (rc)
+        goto out_error;
+
+    /* node: */
     rc = -ENOMEM;
     iter = j_config_get_stanzas(cf, "node", &match, 1);
     if (!iter)
@@ -177,6 +224,7 @@ static gint o2cb_config_fill_cluster(O2CBConfig *config, JConfig *cf,
     if (rc)
         goto out_error;
 
+    /* cluster: node_count */
     rc = -EINVAL;
     count = j_config_get_attribute(c_cfs, "node_count");
     if (!count || !*count)
@@ -189,9 +237,29 @@ static gint o2cb_config_fill_cluster(O2CBConfig *config, JConfig *cf,
         goto out_error;
     cluster->c_num_nodes = val;
 
+    /* heartbeat: */
+    rc = -ENOMEM;
+    iter = j_config_get_stanzas(cf, "heartbeat", &match, 1);
+    if (!iter)
+        goto out_error;
+
+    rc = 0;
+    while (j_iterator_has_more(iter))
+    {
+        n_cfs = (JConfigStanza *)j_iterator_get_next(iter);
+        rc = o2cb_cluster_fill_heartbeat(cluster, n_cfs);
+        if (rc)
+            break;
+    }
+    j_iterator_free(iter);
+
+    if (rc)
+        goto out_error;
+
     rc = 0;
 
 out_error:
+    g_free(hb_mode);
     g_free(match.value);
 
     return rc;
@@ -279,6 +347,22 @@ gint o2cb_config_load(const gchar *filename, O2CBConfig **config)
     return rc;
 }  /* o2cb_config_load() */
 
+static gint o2cb_heartbeat_store(JConfig *cf, O2CBCluster *cluster,
+                                 O2CBHeartbeat *hb)
+{
+    JConfigStanza *cfs;
+
+    cfs = j_config_add_stanza(cf, "heartbeat");
+    if (!cfs)
+        return -ENOMEM;
+
+    j_config_set_attribute(cfs, "cluster", cluster->c_name);
+
+    j_config_set_attribute(cfs, "region", hb->h_region);
+
+    return 0;
+}  /* o2cb_heartbeat_store() */
+
 static gint o2cb_node_store(JConfig *cf, O2CBCluster *cluster,
                             O2CBNode *node)
 {
@@ -316,16 +400,29 @@ static gint o2cb_cluster_store(JConfig *cf, O2CBCluster *cluster)
     GList *list;
     JConfigStanza *cfs;
     O2CBNode *node;
+    O2CBHeartbeat *hb;
 
     cfs = j_config_add_stanza(cf, "cluster");
 
     j_config_set_attribute(cfs, "name", cluster->c_name);
+    j_config_set_attribute(cfs, "heartbeat_mode", cluster->c_hb_mode);
 
     count = g_strdup_printf("%u", cluster->c_num_nodes);
     j_config_set_attribute(cfs, "node_count", count);
     g_free(count);
 
     rc = 0;
+    list = cluster->c_heartbeat;
+    while (list)
+    {
+        hb = (O2CBHeartbeat *)list->data;
+        rc = o2cb_heartbeat_store(cf, cluster, hb);
+        if (rc)
+            break;
+
+        list = list->next;
+    }
+
     list = cluster->c_nodes;
     while (list)
     {
@@ -462,10 +559,19 @@ static void o2cb_node_free(O2CBNode *node)
     g_free(node);
 }  /* o2cb_node_free() */
 
+static void o2cb_heartbeat_free(O2CBHeartbeat *hb)
+{
+    if (hb->h_region)
+        g_free(hb->h_region);
+
+    g_free(hb);
+}  /* o2cb_heartbeat_free() */
+
 static void o2cb_cluster_free(O2CBCluster *cluster)
 {
     GList *list;
     O2CBNode *node;
+    O2CBHeartbeat *hb;
 
     while (cluster->c_nodes)
     {
@@ -476,6 +582,15 @@ static void o2cb_cluster_free(O2CBCluster *cluster)
         o2cb_node_free(node);
     }
 
+    while (cluster->c_heartbeat)
+    {
+        list = cluster->c_heartbeat;
+        hb = (O2CBHeartbeat *)list->data;
+
+        cluster->c_heartbeat = g_list_delete_link(list, list);
+        o2cb_heartbeat_free(hb);
+    }
+
     if (cluster->c_name)
         g_free(cluster->c_name);
 
@@ -515,8 +630,10 @@ O2CBCluster *o2cb_config_add_cluster(O2CBConfig *config,
     cluster = g_new(O2CBCluster, 1);
 
     cluster->c_name = g_strdup(name);
+    cluster->c_hb_mode = g_strdup("local");
     cluster->c_num_nodes = 0;
     cluster->c_nodes = NULL;
+    cluster->c_heartbeat = NULL;
 
     config->co_clusters = g_list_append(config->co_clusters, cluster);
 
@@ -573,6 +690,112 @@ gint o2cb_cluster_set_name(O2CBCluster *cluster, const gchar *name)
     return 0;
 }  /* o2cb_config_set_cluster_name() */
 
+gchar *o2cb_cluster_get_heartbeat_mode(O2CBCluster *cluster)
+{
+    g_return_val_if_fail(cluster != NULL, NULL);
+
+    return g_strdup(cluster->c_hb_mode);
+}  /* o2cb_cluster_get_hb_mode() */
+
+gint o2cb_cluster_set_heartbeat_mode(O2CBCluster *cluster, const gchar *hb_mode)
+{
+    gchar *new_hb_mode;
+    gint i, valid = 0;
+
+    if (cluster->c_hb_mode && !g_ascii_strcasecmp(hb_mode, cluster->c_hb_mode))
+        return 0;
+
+    for (i = 0; valid_heartbeat_modes[i]; i++) {
+        if (!g_ascii_strcasecmp(hb_mode, valid_heartbeat_modes[i])) {
+                valid = 1;
+                break;
+	}
+    }
+
+    if (!valid)
+        return -EINVAL;
+
+    new_hb_mode = g_ascii_strdown(hb_mode, -1);
+    if (!new_hb_mode)
+        return -ENOMEM;
+
+    g_free(cluster->c_hb_mode);
+    cluster->c_hb_mode = new_hb_mode;
+
+    return 0;
+}  /* o2cb_config_set_cluster_hb_mode() */
+
+JIterator *o2cb_cluster_get_heartbeat_regions(O2CBCluster *cluster)
+{
+    g_return_val_if_fail(cluster != NULL, NULL);
+
+    return j_iterator_new_from_list(cluster->c_heartbeat);
+}  /* o2cb_cluster_get_heartbeat_regions() */
+
+O2CBHeartbeat *o2cb_cluster_get_heartbeat_by_region(O2CBCluster *cluster,
+						    const gchar *region)
+{
+    GList *list;
+    O2CBHeartbeat *hb;
+
+    g_return_val_if_fail(cluster != NULL, NULL);
+
+    list = cluster->c_heartbeat;
+    while (list)
+    {
+        hb = (O2CBHeartbeat *)list->data;
+        if (!strcmp(hb->h_region, region))
+            return hb;
+        list = list->next;
+    }
+
+    return NULL;
+}  /* o2cb_cluster_get_heartbeat_by_region() */
+
+gint o2cb_cluster_remove_heartbeat(O2CBCluster *cluster, const gchar *region)
+{
+    O2CBHeartbeat *hb;
+
+    g_return_val_if_fail(cluster != NULL, -1);
+
+    hb = o2cb_cluster_get_heartbeat_by_region(cluster, region);
+    if (!hb)
+        return -1;
+
+    cluster->c_heartbeat = g_list_remove(cluster->c_heartbeat, hb);
+    g_free(hb->h_region);
+    g_free(hb);
+
+    return 0;
+}  /* o2cb_cluster_remove_heartbeat() */
+
+O2CBHeartbeat *o2cb_cluster_add_heartbeat(O2CBCluster *cluster,
+                                          const gchar *region)
+{
+    O2CBHeartbeat *hb;
+
+    g_return_val_if_fail(cluster != NULL, NULL);
+
+    hb = o2cb_cluster_get_heartbeat_by_region(cluster, region);
+    if (hb)
+        return NULL;
+
+    hb = g_new(O2CBHeartbeat, 1);
+
+    hb->h_region = g_strdup(region);
+
+    cluster->c_heartbeat = g_list_append(cluster->c_heartbeat, hb);
+
+    return hb;
+}  /* o2cb_cluster_add_heartbeat() */
+
+gchar *o2cb_heartbeat_get_region(O2CBHeartbeat *heartbeat)
+{
+    g_return_val_if_fail(heartbeat != NULL, NULL);
+
+    return g_strdup(heartbeat->h_region);
+} /* o2cb_heartbeat_get_region */
+
 guint o2cb_cluster_get_node_count(O2CBCluster *cluster)
 {
     g_return_val_if_fail(cluster != NULL, 0);
diff --git a/o2cb_ctl/o2cb_config.h b/o2cb_ctl/o2cb_config.h
index b6af8d4..6f41dba 100644
--- a/o2cb_ctl/o2cb_config.h
+++ b/o2cb_ctl/o2cb_config.h
@@ -28,6 +28,7 @@
 typedef struct _O2CBConfig	O2CBConfig;
 typedef struct _O2CBCluster	O2CBCluster;
 typedef struct _O2CBNode	O2CBNode;
+typedef struct _O2CBHeartbeat	O2CBHeartbeat;
 
 O2CBConfig *o2cb_config_initialize(void);
 gint o2cb_config_load(const gchar *filename, O2CBConfig **config);
@@ -44,6 +45,18 @@ O2CBCluster *o2cb_config_get_cluster_by_name(O2CBConfig *config,
 
 gchar *o2cb_cluster_get_name(O2CBCluster *cluster);
 gint o2cb_cluster_set_name(O2CBCluster *cluster, const gchar *name);
+
+gchar *o2cb_heartbeat_get_region(O2CBHeartbeat *heartbeat);
+JIterator *o2cb_cluster_get_heartbeat_regions(O2CBCluster *cluster);
+gchar *o2cb_cluster_get_heartbeat_mode(O2CBCluster *cluster);
+gint o2cb_cluster_set_heartbeat_mode(O2CBCluster *cluster,
+				     const gchar *hb_mode);
+O2CBHeartbeat *o2cb_cluster_get_heartbeat_by_region(O2CBCluster *cluster,
+						    const gchar *region);
+gint o2cb_cluster_remove_heartbeat(O2CBCluster *cluster, const gchar *region);
+O2CBHeartbeat *o2cb_cluster_add_heartbeat(O2CBCluster *cluster,
+					  const gchar *region);
+
 guint o2cb_cluster_get_node_count(O2CBCluster *cluster);
 JIterator *o2cb_cluster_get_nodes(O2CBCluster *cluster);
 O2CBNode *o2cb_cluster_get_node(O2CBCluster *cluster, guint n);
-- 
1.7.0.4




More information about the Ocfs2-tools-devel mailing list