[libvirt] [PATCHv2 0/3] openvz: allow for runtime quota updates

Hi, attached patches allow to change disk quota at runtime. This can later be extended to update network configuration as well. The patch revealed a problem of the openvz driver in genral: the openvzLoadDomains only reads the on disk configuration but doesn't check if running domains have (non persistent) diverging values due to openvz calls without the "--save" option but that's part of another patch. Changes since last time: * add virDomainFSIndexByName to libvirt_private.syms * check for unallowed updates in openvzUpdateDevice Cheers, -- Guido Guido Günther (3): Introduce virDomainFSIndexByName openvz: add persist parameter to openvzSetDiskQuota openvz: wire up domainUpdateDeviceFlags src/conf/domain_conf.c | 16 ++++++ src/conf/domain_conf.h | 1 + src/libvirt_private.syms | 1 + src/openvz/openvz_driver.c | 116 ++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 130 insertions(+), 4 deletions(-) -- 1.7.10.4

for containers matching virDomainDiskIndexByName. --- src/conf/domain_conf.c | 16 ++++++++++++++++ src/conf/domain_conf.h | 1 + src/libvirt_private.syms | 1 + 3 files changed, 18 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index bd7b520..c34ce26 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -11265,6 +11265,22 @@ virDomainControllerDefFormat(virBufferPtr buf, return 0; } + +int +virDomainFSIndexByName(virDomainDefPtr def, const char *name) +{ + virDomainFSDefPtr fs; + int i; + + for (i = 0; i < def->nfss; i++) { + fs = def->fss[i]; + if (STREQ(fs->dst, name)) + return i; + } + return -1; +} + + static int virDomainFSDefFormat(virBufferPtr buf, virDomainFSDefPtr def, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7642720..e2f56fb 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2087,6 +2087,7 @@ int virDiskNameToBusDeviceIndex(virDomainDiskDefPtr disk, int *devIdx); virDomainFSDefPtr virDomainGetRootFilesystem(virDomainDefPtr def); +int virDomainFSIndexByName(virDomainDefPtr def, const char *name); int virDomainVideoDefaultType(virDomainDefPtr def); int virDomainVideoDefaultRAM(virDomainDefPtr def, int type); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fdf2186..a452e62 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -319,6 +319,7 @@ virDomainDiskSnapshotTypeToString; virDomainDiskTypeFromString; virDomainDiskTypeToString; virDomainFSDefFree; +virDomainFSIndexByName; virDomainFSTypeFromString; virDomainFSTypeToString; virDomainFSWrpolicyTypeFromString; -- 1.7.10.4

with persist=false the domain config file will not be updated. --- src/openvz/openvz_driver.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index fb72cde..02a0133 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -191,7 +191,8 @@ cleanup: static int openvzSetDiskQuota(virDomainDefPtr vmdef, - virDomainFSDefPtr fss) + virDomainFSDefPtr fss, + bool persist) { int ret = -1; unsigned long long sl, hl; @@ -199,8 +200,9 @@ openvzSetDiskQuota(virDomainDefPtr vmdef, "--quiet", "set", vmdef->name, - "--save", NULL); + if (persist) + virCommandAddArg(cmd, "--save"); if (fss->type == VIR_DOMAIN_FS_TYPE_TEMPLATE) { if (fss->space_hard_limit) { @@ -938,7 +940,7 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml) } if (vm->def->nfss == 1) { - if (openvzSetDiskQuota(vm->def, vm->def->fss[0]) < 0) { + if (openvzSetDiskQuota(vm->def, vm->def->fss[0], true) < 0) { openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not set disk quota")); goto cleanup; @@ -1026,7 +1028,7 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml, } if (vm->def->nfss == 1) { - if (openvzSetDiskQuota(vm->def, vm->def->fss[0]) < 0) { + if (openvzSetDiskQuota(vm->def, vm->def->fss[0], true) < 0) { openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not set disk quota")); goto cleanup; -- 1.7.10.4

so we can update file system quota --- src/openvz/openvz_driver.c | 106 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 02a0133..2014072 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -1948,6 +1948,111 @@ cleanup: } +static int +openvzUpdateDevice(virDomainDefPtr vmdef, + virDomainDeviceDefPtr dev, + bool persist) +{ + virDomainFSDefPtr fs, cur; + int pos; + + if (dev->type == VIR_DOMAIN_DEVICE_FS) { + fs = dev->data.fs; + pos = virDomainFSIndexByName(vmdef, fs->dst); + + if (pos < 0) { + openvzError(VIR_ERR_INVALID_ARG, + _("target %s doesn't exist."), fs->dst); + return -1; + } + cur = vmdef->fss[pos]; + + /* We only allow updating the quota */ + if (!STREQ(cur->src, fs->src) + || cur->type != fs->type + || cur->accessmode != fs->accessmode + || cur->wrpolicy != fs->wrpolicy + || cur->readonly != fs->readonly) { + openvzError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Can only modify disk quota")); + return -1; + } + + if (openvzSetDiskQuota(vmdef, fs, persist) < 0) { + return -1; + } + cur->space_hard_limit = fs->space_hard_limit; + cur->space_soft_limit = fs->space_soft_limit; + } else { + openvzError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Can't modify device type '%s'"), + virDomainDeviceTypeToString(dev->type)); + return -1; + } + + return 0; +} + + +static int +openvzDomainUpdateDeviceFlags(virDomainPtr dom, const char *xml, + unsigned int flags) +{ + int ret = -1; + int veid; + struct openvz_driver *driver = dom->conn->privateData; + virDomainDeviceDefPtr dev = NULL; + virDomainObjPtr vm = NULL; + virDomainDefPtr vmdef = NULL; + bool persist = false; + + virCheckFlags(VIR_DOMAIN_DEVICE_MODIFY_LIVE | + VIR_DOMAIN_DEVICE_MODIFY_CONFIG, -1); + + openvzDriverLock(driver); + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + vmdef = vm->def; + + if (!vm) { + openvzError(VIR_ERR_NO_DOMAIN, "%s", + _("no domain with matching uuid")); + goto cleanup; + } + + if (virStrToLong_i(vmdef->name, NULL, 10, &veid) < 0) { + openvzError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not convert domain name to VEID")); + goto cleanup; + } + + if (virDomainLiveConfigHelperMethod(driver->caps, + vm, + &flags, + &vmdef) < 0) + goto cleanup; + + dev = virDomainDeviceDefParse(driver->caps, vmdef, xml, + VIR_DOMAIN_XML_INACTIVE); + if (!dev) + goto cleanup; + + if (flags & VIR_DOMAIN_AFFECT_CONFIG) + persist = true; + + if (openvzUpdateDevice(vmdef, dev, persist) < 0) + goto cleanup; + + ret = 0; + +cleanup: + openvzDriverUnlock(driver); + virDomainDeviceDefFree(dev); + if (vm) + virDomainObjUnlock(vm); + return ret; +} + + static virDriver openvzDriver = { .no = VIR_DRV_OPENVZ, .name = "OPENVZ", @@ -2002,6 +2107,7 @@ static virDriver openvzDriver = { .domainIsPersistent = openvzDomainIsPersistent, /* 0.7.3 */ .domainIsUpdated = openvzDomainIsUpdated, /* 0.8.6 */ .isAlive = openvzIsAlive, /* 0.9.8 */ + .domainUpdateDeviceFlags = openvzDomainUpdateDeviceFlags, /* 0.9.14 */ }; int openvzRegister(void) { -- 1.7.10.4

On Mon, Jun 11, 2012 at 10:57:07PM +0200, Guido Günther wrote: [..snip..]
@@ -2002,6 +2107,7 @@ static virDriver openvzDriver = { .domainIsPersistent = openvzDomainIsPersistent, /* 0.7.3 */ .domainIsUpdated = openvzDomainIsUpdated, /* 0.8.6 */ .isAlive = openvzIsAlive, /* 0.9.8 */ + .domainUpdateDeviceFlags = openvzDomainUpdateDeviceFlags, /* 0.9.14 */
This should be 0.9.13. Fixed locally. -- Guido

On 11.06.2012 22:57, Guido Günther wrote:
Hi, attached patches allow to change disk quota at runtime. This can later be extended to update network configuration as well.
The patch revealed a problem of the openvz driver in genral: the openvzLoadDomains only reads the on disk configuration but doesn't check if running domains have (non persistent) diverging values due to openvz calls without the "--save" option but that's part of another patch.
Changes since last time:
* add virDomainFSIndexByName to libvirt_private.syms * check for unallowed updates in openvzUpdateDevice
Cheers, -- Guido
Guido Günther (3): Introduce virDomainFSIndexByName openvz: add persist parameter to openvzSetDiskQuota openvz: wire up domainUpdateDeviceFlags
src/conf/domain_conf.c | 16 ++++++ src/conf/domain_conf.h | 1 + src/libvirt_private.syms | 1 + src/openvz/openvz_driver.c | 116 ++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 130 insertions(+), 4 deletions(-)
Okay, you've fixed all nits I've pointed out. And as you've spotted in 3/3 it should be 0.9.13. Assuming you'll push the correct version number. ACK series Michal

On Tue, Jun 12, 2012 at 11:22:58AM +0200, Michal Privoznik wrote:
On 11.06.2012 22:57, Guido Günther wrote:
Hi, attached patches allow to change disk quota at runtime. This can later be extended to update network configuration as well.
The patch revealed a problem of the openvz driver in genral: the openvzLoadDomains only reads the on disk configuration but doesn't check if running domains have (non persistent) diverging values due to openvz calls without the "--save" option but that's part of another patch.
Changes since last time:
* add virDomainFSIndexByName to libvirt_private.syms * check for unallowed updates in openvzUpdateDevice
Cheers, -- Guido
Guido Günther (3): Introduce virDomainFSIndexByName openvz: add persist parameter to openvzSetDiskQuota openvz: wire up domainUpdateDeviceFlags
src/conf/domain_conf.c | 16 ++++++ src/conf/domain_conf.h | 1 + src/libvirt_private.syms | 1 + src/openvz/openvz_driver.c | 116 ++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 130 insertions(+), 4 deletions(-)
Okay, you've fixed all nits I've pointed out. And as you've spotted in 3/3 it should be 0.9.13. Assuming you'll push the correct version number.
ACK series Pushed. Thanks! -- Guido
participants (2)
-
Guido Günther
-
Michal Privoznik