]> git.proxmox.com Git - pve-cluster.git/blobdiff - data/src/status.c
pmxcfs status: fix pointer void* aritmethic
[pve-cluster.git] / data / src / status.c
index 96accfe94841258f401a05b76611885005a0b166..656cf71db8cb86a9769f3b3c494f612ac0c9589f 100644 (file)
 #include <rrd.h>
 #include <rrd_client.h>
 #include <time.h>
+#include <ctype.h>
 
 #include "cfs-utils.h"
 #include "status.h"
+#include "memdb.h"
 #include "logger.h"
 
 #define KVSTORE_CPG_GROUP_NAME "pve_kvstore_v1"
@@ -75,17 +77,28 @@ typedef struct {
 } memdb_change_t;
 
 static memdb_change_t memdb_change_array[] = {
-       { .path = "cluster.conf" },
-       { .path = "cluster.conf.new" },
+       { .path = "corosync.conf" },
+       { .path = "corosync.conf.new" },
        { .path = "storage.cfg" },
        { .path = "user.cfg" },
        { .path = "domains.cfg" },
        { .path = "priv/shadow.cfg" },
+       { .path = "priv/tfa.cfg" },
        { .path = "datacenter.cfg" },
        { .path = "vzdump.cron" },
+       { .path = "ha/crm_commands" },
+       { .path = "ha/manager_status" },
+       { .path = "ha/resources.cfg" },
+       { .path = "ha/groups.cfg" },
+       { .path = "ha/fence.cfg" },
+       { .path = "status.cfg" },
+       { .path = "replication.cfg" },
+       { .path = "ceph.conf" },
+       { .path = "sdn.cfg" },
+       { .path = "sdn.cfg.new" },
 };
 
-static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+static GMutex mutex;
 
 typedef struct {
        time_t start_time;
@@ -150,6 +163,42 @@ static void vminfo_free(vminfo_t *vminfo)
        g_free(vminfo);
 }
 
+static const char *vminfo_type_to_string(vminfo_t *vminfo)
+{
+       if (vminfo->vmtype == VMTYPE_QEMU) {
+               return "qemu";
+       } else if (vminfo->vmtype == VMTYPE_OPENVZ) {
+               return "openvz";
+       } else if (vminfo->vmtype == VMTYPE_LXC) {
+               return "lxc";
+       } else {
+               return "unknown";
+       }
+}
+
+static const char *vminfo_type_to_path_type(vminfo_t *vminfo)
+{
+       if (vminfo->vmtype == VMTYPE_QEMU) {
+               return "qemu-server"; // special case..
+       } else {
+               return vminfo_type_to_string(vminfo);
+       }
+}
+
+int vminfo_to_path(vminfo_t *vminfo, GString *path)
+{
+       g_return_val_if_fail(vminfo != NULL, -1);
+       g_return_val_if_fail(path != NULL, -1);
+
+       if (!vminfo->nodename)
+               return 0;
+
+       const char *type = vminfo_type_to_path_type(vminfo);
+       g_string_printf(path, "/nodes/%s/%s/%u.conf", vminfo->nodename, type, vminfo->vmid);
+
+       return 1;
+}
+
 void cfs_clnode_destroy(
        cfs_clnode_t *clnode)
 {
@@ -249,7 +298,7 @@ cfs_create_memberlist_msg(
 {
        g_return_val_if_fail(str != NULL, -EINVAL);
 
-       g_static_mutex_lock(&mutex);
+       g_mutex_lock (&mutex);
 
        g_string_append_printf(str,"{\n");
 
@@ -305,7 +354,7 @@ cfs_create_memberlist_msg(
 
        g_string_append_printf(str,"}\n");
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 
        return 0;
 }
@@ -362,13 +411,14 @@ cfs_cluster_log(clog_entry_t *entry)
                iov[0].iov_base = (char *)entry;
                iov[0].iov_len = clog_entry_size(entry);
 
-               dfsm_send_message(cfs_status.kvstore, KVSTORE_MESSAGE_LOG, iov, 1);
+               if (dfsm_is_initialized(cfs_status.kvstore))
+                       dfsm_send_message(cfs_status.kvstore, KVSTORE_MESSAGE_LOG, iov, 1);
        }
 }
 
 void cfs_status_init(void)
 {
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        cfs_status.start_time = time(NULL);
 
@@ -394,12 +444,12 @@ void cfs_status_init(void)
        clusterlog_add(cfs_status.clusterlog, "root", "cluster", getpid(),
                       LOG_INFO, "starting cluster log");
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 }
 
 void cfs_status_cleanup(void)
 {
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        cfs_status.clinfo_version++;
 
@@ -431,7 +481,7 @@ void cfs_status_cleanup(void)
        if (cfs_status.clusterlog)
                clusterlog_destroy(cfs_status.clusterlog);
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 }
 
 void cfs_status_set_clinfo(
@@ -439,7 +489,7 @@ void cfs_status_set_clinfo(
 {
        g_return_if_fail(clinfo != NULL);
 
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        cfs_status.clinfo_version++;
 
@@ -462,7 +512,7 @@ void cfs_status_set_clinfo(
                while (g_hash_table_iter_next (&iter, &key, &value)) {
                        cfs_clnode_t *node = (cfs_clnode_t *)value;
                        cfs_clnode_t *oldnode;
-                       if ((oldnode = g_hash_table_lookup(old->nodes_byid, &key))) {
+                       if ((oldnode = g_hash_table_lookup(old->nodes_byid, key))) {
                                node->online = oldnode->online;
                                node->kvhash = oldnode->kvhash;
                                oldnode->kvhash = NULL;
@@ -475,7 +525,7 @@ void cfs_status_set_clinfo(
                cfs_clinfo_destroy(old);
 
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 }
 
 static void
@@ -512,7 +562,7 @@ cfs_create_version_msg(GString *str)
 {
        g_return_val_if_fail(str != NULL, -EINVAL);
 
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        g_string_append_printf(str,"{\n");
 
@@ -554,7 +604,7 @@ cfs_create_version_msg(GString *str)
 
        g_string_append_printf(str,"}\n");
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 
        return 0;
 }
@@ -577,7 +627,8 @@ vmlist_hash_insert_vm(
        g_return_val_if_fail(vmlist != NULL, FALSE);
        g_return_val_if_fail(nodename != NULL, FALSE);
        g_return_val_if_fail(vmid != 0, FALSE);
-       g_return_val_if_fail(vmtype == VMTYPE_QEMU || vmtype == VMTYPE_OPENVZ, FALSE);
+       g_return_val_if_fail(vmtype == VMTYPE_QEMU || vmtype == VMTYPE_OPENVZ ||
+                            vmtype == VMTYPE_LXC, FALSE);
 
        if (!replace && g_hash_table_lookup(vmlist, &vmid)) {
                cfs_critical("detected duplicate VMID %d", vmid);
@@ -606,17 +657,18 @@ vmlist_register_vm(
        g_return_if_fail(cfs_status.vmlist != NULL);
        g_return_if_fail(nodename != NULL);
        g_return_if_fail(vmid != 0);
-       g_return_if_fail(vmtype == VMTYPE_QEMU || vmtype == VMTYPE_OPENVZ);
+       g_return_if_fail(vmtype == VMTYPE_QEMU || vmtype == VMTYPE_OPENVZ ||
+                        vmtype == VMTYPE_LXC);
 
        cfs_debug("vmlist_register_vm: %s/%u %d", nodename, vmid, vmtype);
 
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        cfs_status.vmlist_version++;
 
        vmlist_hash_insert_vm(cfs_status.vmlist, vmtype, vmid, nodename, TRUE);
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 }
 
 gboolean
@@ -630,14 +682,14 @@ vmlist_different_vm_exists(
 
        gboolean res = FALSE;
 
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        vminfo_t *vminfo;
        if ((vminfo = (vminfo_t *)g_hash_table_lookup(cfs_status.vmlist, &vmid))) {
                if (!(vminfo->vmtype == vmtype && strcmp(vminfo->nodename, nodename) == 0))
                        res = TRUE;
        }
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 
        return res;
 }
@@ -649,11 +701,11 @@ vmlist_vm_exists(
        g_return_val_if_fail(cfs_status.vmlist != NULL, FALSE);
        g_return_val_if_fail(vmid != 0, FALSE);
 
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        gpointer res = g_hash_table_lookup(cfs_status.vmlist, &vmid);
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 
        return res != NULL;
 }
@@ -665,13 +717,13 @@ vmlist_delete_vm(
        g_return_if_fail(cfs_status.vmlist != NULL);
        g_return_if_fail(vmid != 0);
 
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        cfs_status.vmlist_version++;
 
        g_hash_table_remove(cfs_status.vmlist, &vmid);
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 }
 
 void cfs_status_set_vmlist(
@@ -679,7 +731,7 @@ void cfs_status_set_vmlist(
 {
        g_return_if_fail(vmlist != NULL);
 
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        cfs_status.vmlist_version++;
 
@@ -688,7 +740,7 @@ void cfs_status_set_vmlist(
 
        cfs_status.vmlist = vmlist;
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 }
 
 int
@@ -697,7 +749,7 @@ cfs_create_vmlist_msg(GString *str)
        g_return_val_if_fail(cfs_status.vmlist != NULL, -EINVAL);
        g_return_val_if_fail(str != NULL, -EINVAL);
 
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        g_string_append_printf(str,"{\n");
 
@@ -720,14 +772,7 @@ cfs_create_vmlist_msg(GString *str)
                int first = 1;
                while (g_hash_table_iter_next (&iter, &key, &value)) {
                        vminfo_t *vminfo = (vminfo_t *)value;
-                       char *type;
-                       if (vminfo->vmtype == VMTYPE_QEMU) {
-                               type = "qemu";
-                       } else if (vminfo->vmtype == VMTYPE_OPENVZ) {
-                               type = "openvz";
-                       } else {
-                               type = "unknown";
-                       }
+                       const char *type = vminfo_type_to_string(vminfo);
 
                        if (!first)
                                g_string_append_printf(str, ",\n");
@@ -741,11 +786,155 @@ cfs_create_vmlist_msg(GString *str)
        }
        g_string_append_printf(str,"\n}\n");
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 
        return 0;
 }
 
+// checks the conf for a line starting with '$prop:' and returns the value
+// afterwards, whitout initial whitespace(s), we only deal with the format
+// restricion imposed by our perl VM config parser, main reference is
+// PVE::QemuServer::parse_vm_config this allows to be very fast and still
+// relatively simple
+// main restrictions used for our advantage is the properties match reges:
+// ($line =~ m/^([a-z][a-z_]*\d*):\s*(.+?)\s*$/) from parse_vm_config
+// currently we only look at the current configuration in place, i.e., *no*
+// snapshort and *no* pending changes
+static char *
+_get_property_value(char *conf, const char *prop, int prop_len)
+{
+       char *line = NULL, *temp = NULL;
+
+       line = strtok_r(conf, "\n", &temp);
+       while (line != NULL) {
+               if (!line[0]) goto next;
+
+               // snapshot or pending section start and nothing found yet
+               if (line[0] == '[') return NULL;
+               // properties start with /^[a-z]/, so continue early if not
+               if (line[0] < 'a' || line[0] > 'z') goto next;
+
+               int line_len = strlen(line);
+               if (line_len <= prop_len + 1) goto next;
+
+               if (line[prop_len] == ':' && memcmp(line, prop, prop_len) == 0) { // found
+                       char *v_start = &line[prop_len + 1];
+
+                       // drop initial value whitespaces here already
+                       while (*v_start && isspace(*v_start)) v_start++;
+
+                       if (!*v_start) return NULL;
+
+                       char *v_end = &line[line_len - 1];
+                       while (v_end > v_start && isspace(*v_end)) v_end--;
+                       v_end[1] = '\0';
+
+                       return v_start;
+               }
+next:
+               line = strtok_r(NULL, "\n", &temp);
+       }
+
+       return NULL; // not found
+}
+
+static void
+_g_str_append_kv_jsonescaped(GString *str, const char *k, const char *v)
+{
+       g_string_append_printf(str, "\"%s\": \"", k);
+
+       for (; *v; v++) {
+               if (*v == '\\' || *v == '"') {
+                       g_string_append_c(str, '\\');
+               }
+               g_string_append_c(str, *v);
+       }
+
+       g_string_append_c(str, '"');
+}
+
+int
+cfs_create_guest_conf_property_msg(GString *str, memdb_t *memdb, const char *prop, uint32_t vmid)
+{
+       g_return_val_if_fail(cfs_status.vmlist != NULL, -EINVAL);
+       g_return_val_if_fail(str != NULL, -EINVAL);
+
+       int prop_len = strlen(prop);
+       int res = 0;
+       GString *path = NULL;
+
+       g_mutex_lock (&mutex);
+
+       g_string_printf(str,"{\n");
+
+       GHashTable *ht = cfs_status.vmlist;
+       gpointer tmp = NULL;
+       if (!g_hash_table_size(ht)) {
+               goto ret;
+       }
+
+       path = g_string_sized_new(256);
+       if (vmid >= 100) {
+               vminfo_t *vminfo = (vminfo_t *) g_hash_table_lookup(cfs_status.vmlist, &vmid);
+               if (vminfo == NULL) goto enoent;
+
+               if (!vminfo_to_path(vminfo, path)) goto err;
+
+               int size = memdb_read(memdb, path->str, &tmp);
+               if (tmp == NULL) goto err;
+               if (size <= prop_len) goto ret;
+
+               char *val = _get_property_value(tmp, prop, prop_len);
+               if (val == NULL) goto ret;
+
+               g_string_append_printf(str, "\"%u\":{", vmid);
+               _g_str_append_kv_jsonescaped(str, prop, val);
+               g_string_append_c(str, '}');
+
+       } else {
+               GHashTableIter iter;
+               g_hash_table_iter_init (&iter, ht);
+
+               gpointer key, value;
+               int first = 1;
+               while (g_hash_table_iter_next (&iter, &key, &value)) {
+                       vminfo_t *vminfo = (vminfo_t *)value;
+
+                       if (!vminfo_to_path(vminfo, path)) goto err;
+
+                       g_free(tmp); // no-op if already null
+                       tmp = NULL;
+                       int size = memdb_read(memdb, path->str, &tmp);
+                       if (tmp == NULL || size <= prop_len) continue;
+
+                       char *val = _get_property_value(tmp, prop, prop_len);
+                       if (val == NULL) continue;
+
+                       if (!first) g_string_append_printf(str, ",\n");
+                       else first = 0;
+
+                       g_string_append_printf(str, "\"%u\":{", vminfo->vmid);
+                       _g_str_append_kv_jsonescaped(str, prop, val);
+                       g_string_append_c(str, '}');
+               }
+       }
+ret:
+       g_free(tmp);
+       if (path != NULL) {
+               g_string_free(path, TRUE);
+       }
+       g_string_append_printf(str,"\n}\n");
+       g_mutex_unlock (&mutex);
+
+       return res;
+err:
+       res = -EIO;
+       goto ret;
+enoent:
+       res = -ENOENT;
+       goto ret;
+}
+
 void
 record_memdb_change(const char *path)
 {
@@ -778,7 +967,9 @@ kventry_hash_set(
        g_return_val_if_fail(data != NULL, FALSE);
 
        kventry_t *entry;
-       if ((entry = (kventry_t *)g_hash_table_lookup(kvhash, key))) {
+       if (!len) {
+               g_hash_table_remove(kvhash, key);
+       } else if ((entry = (kventry_t *)g_hash_table_lookup(kvhash, key))) {
                g_free(entry->data);
                entry->data = g_memdup(data, len);
                entry->len = len;
@@ -807,8 +998,8 @@ static const char *rrd_def_node[] = {
        "DS:swapused:GAUGE:120:0:U",
        "DS:roottotal:GAUGE:120:0:U",
        "DS:rootused:GAUGE:120:0:U",
-       "DS:netin:COUNTER:120:0:U",
-       "DS:netout:COUNTER:120:0:U",
+       "DS:netin:DERIVE:120:0:U",
+       "DS:netout:DERIVE:120:0:U",
 
        "RRA:AVERAGE:0.5:1:70", // 1 min avg - one hour
        "RRA:AVERAGE:0.5:30:70", // 30 min avg - one day
@@ -831,10 +1022,10 @@ static const char *rrd_def_vm[] = {
        "DS:mem:GAUGE:120:0:U",
        "DS:maxdisk:GAUGE:120:0:U",
        "DS:disk:GAUGE:120:0:U",
-       "DS:netin:COUNTER:120:0:U",
-       "DS:netout:COUNTER:120:0:U",
-       "DS:diskread:COUNTER:120:0:U",
-       "DS:diskwrite:COUNTER:120:0:U",
+       "DS:netin:DERIVE:120:0:U",
+       "DS:netout:DERIVE:120:0:U",
+       "DS:diskread:DERIVE:120:0:U",
+       "DS:diskwrite:DERIVE:120:0:U",
 
        "RRA:AVERAGE:0.5:1:70", // 1 min avg - one hour
        "RRA:AVERAGE:0.5:30:70", // 30 min avg - one day
@@ -920,14 +1111,14 @@ update_rrd_data(
         if (rrdc_connect(rrdcsock) != 0)
                use_daemon = 0;
 
-       char *filename = g_strdup_printf(RRDDIR "/%s", key);
+       char *filename = NULL;
 
        int skip = 0;
 
        if (strncmp(key, "pve2-node/", 10) == 0) {
                const char *node = key + 10;
 
-               skip = 1;
+               skip = 2;
 
                if (strchr(node, '/') != NULL)
                        goto keyerror;
@@ -935,6 +1126,8 @@ update_rrd_data(
                if (strlen(node) < 1)
                        goto keyerror;
 
+               filename = g_strdup_printf(RRDDIR "/%s", key);
+
                if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
 
                        mkdir(RRDDIR "/pve2-node", 0755);
@@ -942,10 +1135,17 @@ update_rrd_data(
                        create_rrd_file(filename, argcount, rrd_def_node);
                }
 
-       } else if (strncmp(key, "pve2-vm/", 8) == 0) {
-               const char *vmid = key + 8;
+       } else if ((strncmp(key, "pve2-vm/", 8) == 0) ||
+                  (strncmp(key, "pve2.3-vm/", 10) == 0)) {
+               const char *vmid;
 
-               skip = 2;
+               if (strncmp(key, "pve2-vm/", 8) == 0) {
+                       vmid = key + 8;
+                       skip = 2;
+               } else {
+                       vmid = key + 10;
+                       skip = 4;
+               }
 
                if (strchr(vmid, '/') != NULL)
                        goto keyerror;
@@ -953,6 +1153,8 @@ update_rrd_data(
                if (strlen(vmid) < 1)
                        goto keyerror;
 
+               filename = g_strdup_printf(RRDDIR "/%s/%s", "pve2-vm", vmid);
+
                if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
 
                        mkdir(RRDDIR "/pve2-vm", 0755);
@@ -978,6 +1180,8 @@ update_rrd_data(
                if (strlen(storage) < 1)
                        goto keyerror;
 
+               filename = g_strdup_printf(RRDDIR "/%s", key);
+
                if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
 
                        mkdir(RRDDIR "/pve2-storage", 0755);
@@ -1017,7 +1221,9 @@ update_rrd_data(
        }
 
 ret:
-       g_free(filename);
+       if (filename) 
+               g_free(filename);
+
        return;
 
 keyerror:
@@ -1049,10 +1255,13 @@ void
 cfs_rrd_dump(GString *str)
 {
        time_t ctime;
-       time(&ctime);
 
+       g_mutex_lock (&mutex);
+
+       time(&ctime);
        if (rrd_dump_buf && (ctime - rrd_dump_last) < 2) {
                g_string_assign(str, rrd_dump_buf);
+               g_mutex_unlock (&mutex);
                return;
        }
 
@@ -1081,6 +1290,8 @@ cfs_rrd_dump(GString *str)
        if (rrd_dump_buf)
                g_free(rrd_dump_buf);
        rrd_dump_buf = g_strdup(str->str);
+
+       g_mutex_unlock (&mutex);
 }
 
 static gboolean
@@ -1150,6 +1361,8 @@ kvstore_send_update_message(
        gpointer data,
        guint32 len)
 {
+       if (!dfsm_is_initialized(dfsm))
+               return -EACCES;
 
        struct iovec iov[2];
 
@@ -1176,7 +1389,7 @@ kvstore_parse_log_message(
        g_return_val_if_fail(msg != NULL, NULL);
 
        if (msg_len < sizeof(clog_entry_t)) {
-               cfs_critical("received short log message (%lu < %lu)", msg_len, sizeof(clog_entry_t));
+               cfs_critical("received short log message (%zu < %zu)", msg_len, sizeof(clog_entry_t));
                return NULL;
        }
 
@@ -1186,31 +1399,31 @@ kvstore_parse_log_message(
                entry->ident_len + entry->tag_len + entry->msg_len;
 
        if (msg_len != size) {
-               cfs_critical("received log message with wrong size (%lu != %u)", msg_len, size);
+               cfs_critical("received log message with wrong size (%zu != %u)", msg_len, size);
                return NULL;
        }
 
-       msg = entry->data;
+       char *msgptr = entry->data;
 
-       if (*((char *)msg + entry->node_len - 1)) {
+       if (*((char *)msgptr + entry->node_len - 1)) {
                cfs_critical("unterminated string in log message");
                return NULL;
        }
-       msg += entry->node_len;
+       msgptr += entry->node_len;
 
-       if (*((char *)msg + entry->ident_len - 1)) {
+       if (*((char *)msgptr + entry->ident_len - 1)) {
                cfs_critical("unterminated string in log message");
                return NULL;
        }
-       msg += entry->ident_len;
+       msgptr += entry->ident_len;
 
-       if (*((char *)msg + entry->tag_len - 1)) {
+       if (*((char *)msgptr + entry->tag_len - 1)) {
                cfs_critical("unterminated string in log message");
                return NULL;
        }
-       msg += entry->tag_len;
+       msgptr += entry->tag_len;
 
-       if (*((char *)msg + entry->msg_len - 1)) {
+       if (*((char *)msgptr + entry->msg_len - 1)) {
                cfs_critical("unterminated string in log message");
                return NULL;
        }
@@ -1232,7 +1445,7 @@ kvstore_parse_update_message(
        g_return_val_if_fail(len != NULL, FALSE);
 
        if (msg_len < 256) {
-               cfs_critical("received short kvstore message (%lu < 256)", msg_len);
+               cfs_critical("received short kvstore message (%zu < 256)", msg_len);
                return FALSE;
        }
 
@@ -1248,7 +1461,7 @@ kvstore_parse_update_message(
 
        *len = msg_len - 256;
        *key = msg;
-       *data = msg + 256;
+       *data = (char *) msg + 256;
 
        return TRUE;
 }
@@ -1266,11 +1479,11 @@ cfs_create_status_msg(
 
        GHashTable *kvhash = NULL;
 
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        if (!nodename || !nodename[0] || !strcmp(nodename, cfs.nodename)) {
                kvhash = cfs_status.kvhash;
-       } else {
+       } else if (cfs_status.clinfo && cfs_status.clinfo->nodes_byname) {
                cfs_clnode_t *clnode;
                if ((clnode = g_hash_table_lookup(cfs_status.clinfo->nodes_byname, nodename)))
                        kvhash = clnode->kvhash;
@@ -1282,7 +1495,7 @@ cfs_create_status_msg(
                res = 0;
        }
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 
        return res;
 }
@@ -1300,7 +1513,7 @@ cfs_status_set(
        if (len > CFS_MAX_STATUS_SIZE)
                return -EFBIG;
 
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        gboolean res;
 
@@ -1311,7 +1524,7 @@ cfs_status_set(
        } else {
                res = kventry_hash_set(cfs_status.kvhash, key, data, len);
        }
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 
        if (cfs_status.kvstore)
                kvstore_send_update_message(cfs_status.kvstore, key, data, len);
@@ -1330,7 +1543,7 @@ cfs_kvstore_node_set(
        g_return_val_if_fail(key != NULL, FALSE);
        g_return_val_if_fail(data != NULL, FALSE);
 
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        if (!cfs_status.clinfo || !cfs_status.clinfo->nodes_byid)
                goto ret; /* ignore */
@@ -1356,7 +1569,7 @@ cfs_kvstore_node_set(
 
        }
 ret:
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 
        return TRUE;
 }
@@ -1369,7 +1582,7 @@ cfs_kvstore_sync(void)
 
        gboolean res = TRUE;
 
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        GHashTable *ht = cfs_status.kvhash;
        GHashTableIter iter;
@@ -1382,7 +1595,7 @@ cfs_kvstore_sync(void)
                kvstore_send_update_message(cfs_status.kvstore, entry->key, entry->data, entry->len);
        }
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 
        return res;
 }
@@ -1450,7 +1663,7 @@ dfsm_confchg(
 
        cfs_debug("enter %s", __func__);
 
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        cfs_clinfo_t *clinfo = cfs_status.clinfo;
 
@@ -1477,7 +1690,7 @@ dfsm_confchg(
                cfs_status.clinfo_version++;
        }
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 }
 
 static gpointer
@@ -1593,11 +1806,11 @@ static dfsm_callbacks_t kvstore_dfsm_callbacks = {
 dfsm_t *
 cfs_status_dfsm_new(void)
 {
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        cfs_status.kvstore = dfsm_new(NULL, KVSTORE_CPG_GROUP_NAME, G_LOG_DOMAIN,
                                      0, &kvstore_dfsm_callbacks);
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 
        return cfs_status.kvstore;
 }
@@ -1605,9 +1818,9 @@ cfs_status_dfsm_new(void)
 gboolean
 cfs_is_quorate(void)
 {
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
        gboolean res =  cfs_status.quorate;
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 
        return res;
 }
@@ -1617,7 +1830,7 @@ cfs_set_quorate(
        uint32_t quorate,
        gboolean quiet)
 {
-       g_static_mutex_lock (&mutex);
+       g_mutex_lock (&mutex);
 
        uint32_t prev_quorate = cfs_status.quorate;
        cfs_status.quorate = quorate;
@@ -1632,6 +1845,5 @@ cfs_set_quorate(
                        cfs_message("node lost quorum");
        }
 
-       g_static_mutex_unlock (&mutex);
+       g_mutex_unlock (&mutex);
 }
-