From 7f66b4369b41964511aed5c68a99333fd5430846 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Fri, 10 Apr 2015 08:29:44 +0200 Subject: [PATCH] track configuration changes inside lxc subdirectories --- data/PVE/Cluster.pm | 8 ++++ data/src/memdb.c | 91 +++++++++++++++++++++++++++++++++++++++------ data/src/pmxcfs.c | 5 +++ data/src/status.c | 20 +++++++++- data/src/status.h | 3 +- 5 files changed, 112 insertions(+), 15 deletions(-) diff --git a/data/PVE/Cluster.pm b/data/PVE/Cluster.pm index 3ca92d0..5d622e9 100644 --- a/data/PVE/Cluster.pm +++ b/data/PVE/Cluster.pm @@ -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}; diff --git a/data/src/memdb.c b/data/src/memdb.c index c1b8796..0a65db3 100644 --- a/data/src/memdb.c +++ b/data/src/memdb.c @@ -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; diff --git a/data/src/pmxcfs.c b/data/src/pmxcfs.c index 5f3b682..4c07988 100644 --- a/data/src/pmxcfs.c +++ b/data/src/pmxcfs.c @@ -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); diff --git a/data/src/status.c b/data/src/status.c index 4e8d183..a2a7fb8 100644 --- a/data/src/status.c +++ b/data/src/status.c @@ -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++; } diff --git a/data/src/status.h b/data/src/status.h index c791605..2e4153a 100644 --- a/data/src/status.h +++ b/data/src/status.h @@ -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) -- 2.39.5