]> git.proxmox.com Git - pve-cluster.git/commitdiff
track configuration changes inside lxc subdirectories
authorDietmar Maurer <dietmar@proxmox.com>
Fri, 10 Apr 2015 06:29:44 +0000 (08:29 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Fri, 10 Apr 2015 06:29:44 +0000 (08:29 +0200)
data/PVE/Cluster.pm
data/src/memdb.c
data/src/pmxcfs.c
data/src/status.c
data/src/status.h

index 3ca92d08fa14e873bd1f158a04c49e65b0519070..5d622e906931b3fd417daf7b6309defbd44549b5 100644 (file)
@@ -66,6 +66,7 @@ my $observed = {
     'priv/shadow.cfg' => 1,
     '/qemu-server/' => 1,
     '/openvz/' => 1,
+    '/lxc/' => 1,
     'ha/crm_commands' => 1,
     'ha/manager_status' => 1,
     'ha/resources.cfg' => 1,
@@ -129,6 +130,7 @@ sub gen_local_dirs {
        "$basedir/priv",
        "$basedir/nodes", 
        "$basedir/nodes/$nodename",
+       "$basedir/nodes/$nodename/lxc",
        "$basedir/nodes/$nodename/qemu-server",
        "$basedir/nodes/$nodename/openvz",
        "$basedir/nodes/$nodename/priv");
@@ -794,6 +796,12 @@ sub cfs_file_version {
            $version = $vmlist->{ids}->{$vmid}->{version};
        }
        $infotag = "/$type/";
+    } elsif ($filename =~ m!^nodes/[^/]+/lxc/(\d+)/config$!) {
+       my $vmid = $1;
+       if ($vmlist && $vmlist->{ids} && $vmlist->{ids}->{$vmid}) {
+           $version = $vmlist->{ids}->{$vmid}->{version};
+       }
+       $infotag = "/lxc/";
     } else {
        $infotag = $filename;
        $version = $versions->{$filename};
index c1b87967fa365b25736848a9a31275a9541ded06..0a65db3c6af12e999844f2b530a6346685c3a584 100644 (file)
@@ -222,6 +222,26 @@ name_is_vm_config(
        return TRUE;
 }
 
+static gboolean 
+name_is_vm_config_dir(
+       const char *name, 
+       guint32 *vmid_ret)
+{
+       if (!name || name[0] < '1' || name[0] > '9')
+               return FALSE;
+
+       char *end = NULL;
+       guint32 vmid =  strtoul(name, &end, 10);
+
+       if (!end || end[0] != 0)
+               return FALSE;
+
+       if (vmid_ret)
+               *vmid_ret = vmid;
+
+       return TRUE;
+}
+
 static gboolean
 valid_nodename(
        const char *nodename) 
@@ -272,6 +292,9 @@ dir_contain_vm_config(
                } else if (strcmp(sa[1], "openvz") == 0) {
                        *vmtype_ret = VMTYPE_OPENVZ;
                        nodename = g_strdup(sa[0]);
+               } else if (strcmp(sa[1], "lxc") == 0) {
+                       *vmtype_ret = VMTYPE_LXC;
+                       nodename = g_strdup(sa[0]);
                } 
        }
 
@@ -295,9 +318,20 @@ path_contain_vm_config(
 
        split_path(path, &dirname, &base);
 
-       if (name_is_vm_config(base, vmid_ret))
-               nodename = dir_contain_vm_config(dirname, vmtype_ret);
-
+       if ((nodename = dir_contain_vm_config(dirname, vmtype_ret))) {
+               if (*vmtype_ret == VMTYPE_LXC) {
+                       if (!name_is_vm_config_dir(base, vmid_ret)) {
+                               g_free(nodename);
+                               nodename = NULL;
+                       }
+               } else {
+                       if (!name_is_vm_config(base, vmid_ret)) {
+                               g_free(nodename);
+                               nodename = NULL;
+                       }
+               }
+       }
+       
        if (dirname) g_free (dirname);
        if (base) g_free (base);
 
@@ -330,15 +364,28 @@ vmlist_add_dir(
 
                memdb_tree_entry_t *node_te = (memdb_tree_entry_t *)value;
 
-               if (node_te->type != DT_REG)
-                       continue;
+               if (vmtype == VMTYPE_LXC) {
+                       if (node_te->type != DT_DIR)
+                               continue;
 
-               guint32 vmid = 0;
-               if (!name_is_vm_config(node_te->name, &vmid))
-                       continue;
+                       guint32 vmid = 0;
+                       if (!name_is_vm_config_dir(node_te->name, &vmid))
+                               continue;
+
+                       if (!vmlist_hash_insert_vm(vmlist, vmtype, vmid, nodename, FALSE))
+                               ret = FALSE;
 
-               if (!vmlist_hash_insert_vm(vmlist, vmtype, vmid, nodename, FALSE))
-                       ret = FALSE;
+               } else {
+                       if (node_te->type != DT_REG)
+                               continue;
+
+                       guint32 vmid = 0;
+                       if (!name_is_vm_config(node_te->name, &vmid))
+                               continue;
+
+                       if (!vmlist_hash_insert_vm(vmlist, vmtype, vmid, nodename, FALSE))
+                               ret = FALSE;
+               }
        }
 
        return ret;
@@ -476,6 +523,10 @@ memdb_recreate_vmlist(
                        if (!vmlist_add_dir(memdb, vmlist, node_te->name, VMTYPE_OPENVZ, te))
                                ret = FALSE;
                }
+               if ((te = g_hash_table_lookup(node_te->data.entries, "lxc"))) {
+                       if (!vmlist_add_dir(memdb, vmlist, node_te->name, VMTYPE_LXC, te))
+                               ret = FALSE;
+               }
        }
 
        /* always update list - even if we detected duplicates */
@@ -568,6 +619,7 @@ int memdb_mkdir(
 
        char *dirname = NULL;
        char *base = NULL;
+       char *nodename = NULL;
 
        g_mutex_lock (&memdb->mutex);
 
@@ -598,6 +650,17 @@ int memdb_mkdir(
                goto ret;
        }
 
+       guint32 vmid = 0;
+       int vmtype = 0;
+
+       if ((nodename = path_contain_vm_config(path, &vmtype, &vmid))) {
+               if (vmlist_different_vm_exists(vmtype, vmid, nodename)) {
+                       ret = -EEXIST;
+                       goto ret;
+               }
+       }
+       
+
        memdb_tree_entry_t *te;
        if ((te = memdb_lookup_dir_entry(memdb, base, parent))) {
                ret = -EEXIST;
@@ -636,11 +699,15 @@ int memdb_mkdir(
                }
        }
 
+       if (nodename)
+               vmlist_register_vm(vmtype, vmid, nodename);
+
        ret = 0;
 
  ret:
        g_mutex_unlock (&memdb->mutex);
 
+       if (nodename) g_free (nodename);
        if (dirname) g_free (dirname);
        if (base) g_free (base);
 
@@ -897,7 +964,7 @@ memdb_mtime(
         int is_lock = (strcmp(dirname, "priv/lock") == 0) && (te->type == DT_DIR);
 
        /* NOTE: we use utime(0,0) to trigger 'unlock', so we do not
-        * allow to change mtime for locks (only it mtime is newer).
+        * allow to change mtime for locks (only if mtime is newer).
         * See README for details about locks.
         */
         if (is_lock) {
@@ -1132,7 +1199,7 @@ memdb_rename(
 
        from_node = path_contain_vm_config(from, &from_vmtype, &from_vmid);
 
-       if (from_te->type == DT_REG && (nodename = path_contain_vm_config(to, &vmtype, &vmid))) {
+       if ((nodename = path_contain_vm_config(to, &vmtype, &vmid))) {
                if (vmlist_different_vm_exists(vmtype, vmid, nodename)) {
                        if (!(from_node && vmid == from_vmid)) {
                                ret = -EEXIST;
index 5f3b682579ae38dfd8743452ea29d3f002986312..4c079883aee8bbeca1838e5bb4099124f99ea5b8 100644 (file)
@@ -652,6 +652,11 @@ create_symlinks(cfs_plug_base_t *bplug, const char *nodename)
        g_free(lnktarget);
        cfs_plug_base_insert(bplug, (cfs_plug_t*)lnk);
 
+       lnktarget = g_strdup_printf("nodes/%s/lxc", nodename);
+       lnk = cfs_plug_link_new("lxc", lnktarget);
+       g_free(lnktarget);
+       cfs_plug_base_insert(bplug, (cfs_plug_t*)lnk);
+
        cfs_plug_func_t *fplug = cfs_plug_func_new(".version", 0440, create_dot_version_cb, NULL);
        cfs_plug_base_insert(bplug, (cfs_plug_t*)fplug);
        
index 4e8d183f0603047c0bbdb4b30bca0c787db685ff..a2a7fb84ad8f64a7f95b003671452faa152eb573 100644 (file)
@@ -581,7 +581,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);
@@ -610,7 +611,8 @@ 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);
 
@@ -729,6 +731,8 @@ cfs_create_vmlist_msg(GString *str)
                                type = "qemu";
                        } else if (vminfo->vmtype == VMTYPE_OPENVZ) {
                                type = "openvz";
+                       } else if (vminfo->vmtype == VMTYPE_LXC) {
+                               type = "lxc";
                        } else {
                                type = "unknown";
                        }
@@ -757,6 +761,18 @@ record_memdb_change(const char *path)
 
        memdb_change_t *ce;
 
+       unsigned int vmid = 0;
+       char nodename[256];
+       char rest[4096];
+       if (cfs_status.vmlist &&
+           sscanf(path, "nodes/%255[^/]/lxc/%u/%4095s", nodename, &vmid, rest) == 3) {
+               vminfo_t *vminfo = (vminfo_t *)g_hash_table_lookup(cfs_status.vmlist, &vmid);
+               if (vminfo && (vminfo->vmtype == VMTYPE_LXC && strcmp(vminfo->nodename, nodename) == 0)) {
+                       cfs_status.vmlist_version++;
+                       vminfo->version = ++vminfo_version_counter;
+               }
+       }
+       
        if ((ce = (memdb_change_t *)g_hash_table_lookup(cfs_status.memdb_changes, path))) {
                ce->version++;
        }
index c7916055d6ac8d1de09d5cf8c110e1c7fb8f0819..2e4153a90dca75bfb0c68355d25d1c8585a1f431 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2010 Proxmox Server Solutions GmbH
+  Copyright (C) 2010-2015 Proxmox Server Solutions GmbH
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published by
@@ -28,6 +28,7 @@
 
 #define VMTYPE_QEMU 1
 #define VMTYPE_OPENVZ 2
+#define VMTYPE_LXC 3
 
 #define CFS_MAX_STATUS_SIZE (32*1024)