[libvirt] [PATCH RFC] qemu: make time adjustment persistent if RTC changes in guest
by Wang Rui
Domain's clock xml is as below.
<clock offset='variable' basis='utc' adjustment='10'/>
If the guest modifies its RTC, libvirt will hanlde the time offset
and save the active status in qemuProcessHandleRTCChange(). However,
libvirt won't save the persistent config. So next time when vm is
restarted(shutdown and start), the time adjuestment(RTC change)
set by user will be lost.
This patch make the adjustment persistent for persistent domain.
Signed-off-by: Wang Rui <moon.wangrui(a)huawei.com>
---
I'm not sure about the current purpose so I sent a RFC patch. Is it
for some reason that RTC change from guest isn't saved to persistent
config ?
I have tested this patch by changing RTC, starting, shutting down and
migrating. It seems good. There's only a nit I have found. Some guests
will set hardware clock to current system time when shut down. So if
hardware clock is different from system clock(the difference doesn't
come from user setting, maybe from clock shift by system), the
persistent config file will be saved to a new adjustment after shutdown
with this patch. But I think the hypervisor or guest OS should fix
the nit, not libvirt.
---
src/qemu/qemu_process.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 407da5e..b03bf02 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -863,7 +863,13 @@ qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
vm->def->clock.data.variable.adjustment = offset;
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
- VIR_WARN("unable to save domain status with RTC change");
+ VIR_WARN("unable to save domain status with RTC change");
+
+ if (vm->persistent && vm->newDef) {
+ vm->newDef->clock.data.variable.adjustment = offset;
+ if (virDomainSaveConfig(cfg->configDir, vm->newDef) < 0)
+ VIR_WARN("unable to save domain config with RTC change");
+ }
}
event = virDomainEventRTCChangeNewFromObj(vm, offset);
--
1.7.12.4
10 years, 2 months
[libvirt] [PATCH 1/1] libvirtd crash when defining scsi storage pool
by Pradipta Kr. Banerjee
libvirtd crashes when there is an existing SCSI pool
with adapter type as 'scsi_host' and defining a new SCSI pool with adapter
type as 'fc_host' and parent attribute missing.
For eg when defining a storage-pool with the following XML will crash libvirtd
if there already exists a SCSI pool with adapter type 'scsi_host'
<pool type='scsi'>
<name>TEST_SCSI_FC_POOL</name>
<source>
<adapter type='fc_host' wwnn='1234567890abcdef' wwpn='abcdef1234567890'/>
</source>
<target>
<path>/dev/disk/by-path</path>
</target>
</pool>
This happens because for fc_host, adapter 'name' is not relevant whereas
for scsi_host its mandatory attribute. However the check in libvirt for
finding duplicate storage pools doesn't take that into account while comparing,
resulting into crash
This patch fixes the issue
Signed-off-by: Pradipta Kr. Banerjee <bpradip(a)in.ibm.com>
---
src/conf/storage_conf.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 8b6fd79..54a4589 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -2126,8 +2126,10 @@ virStoragePoolSourceFindDuplicate(virStoragePoolObjListPtr pools,
STREQ(pool->def->source.adapter.data.fchost.wwpn,
def->source.adapter.data.fchost.wwpn))
matchpool = pool;
- } else if (pool->def->source.adapter.type ==
- VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST){
+ } else if ((pool->def->source.adapter.type ==
+ VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST)\
+ && (def->source.adapter.type ==
+ VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST)) {
if (STREQ(pool->def->source.adapter.data.name,
def->source.adapter.data.name))
matchpool = pool;
--
1.9.3
10 years, 2 months
[libvirt] [PATCH RFC] LXC: add HOME environment variable
by Chen Hanxiao
We lacked of HOME environment variable,
set 'HOME=/' as default.
Signed-off-by: Chen Hanxiao <chenhanxiao(a)cn.fujitsu.com>
---
src/lxc/lxc_container.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 1cf2c8f..9df9c04 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -236,6 +236,7 @@ static virCommandPtr lxcContainerBuildInitCmd(virDomainDefPtr vmDef,
virCommandAddEnvString(cmd, "PATH=/bin:/sbin");
virCommandAddEnvString(cmd, "TERM=linux");
virCommandAddEnvString(cmd, "container=lxc-libvirt");
+ virCommandAddEnvString(cmd, "HOME=/");
virCommandAddEnvPair(cmd, "container_uuid", uuidstr);
if (nttyPaths > 1)
virCommandAddEnvPair(cmd, "container_ttys", virBufferCurrentContent(&buf));
--
1.9.0
10 years, 2 months
[libvirt] [PATCH 0/4] Introduce new cputune event
by Pavel Hrdina
This patch series introduces new cputune event to inform
management applications about every change of cputune values
for running domains.
Pavel Hrdina (4):
domain_conf: separate cputune struct from virDomainDef
event: introduce new event for cputune
add an example how to use cputune event
cputune_event: queue the event for cputune updates
daemon/remote.c | 87 ++++++++++++++++++++++++++
examples/object-events/event-test.c | 39 +++++++++++-
include/libvirt/libvirt.h.in | 62 +++++++++++++++++++
src/conf/domain_conf.h | 27 ++++----
src/conf/domain_event.c | 120 ++++++++++++++++++++++++++++++++++++
src/conf/domain_event.h | 7 +++
src/libvirt_private.syms | 2 +
src/qemu/qemu_cgroup.c | 6 ++
src/qemu/qemu_driver.c | 27 ++++++++
src/remote/remote_driver.c | 110 +++++++++++++++++++++++++++++++++
src/remote/remote_protocol.x | 39 +++++++++++-
src/remote_protocol-structs | 32 ++++++++++
tools/virsh-domain.c | 49 +++++++++++++++
13 files changed, 594 insertions(+), 13 deletions(-)
--
1.8.5.5
10 years, 2 months
[libvirt] [PATCH] selinux: Avoid label reservations for type = none during restart
by Shivaprasad G Bhat
The problem is libvirt kills the guests during libvirt restart if more than
guest has security type as none. This is because, libvirt as part of guest-
reconnect tries to reserve the security labels. In case of type=none, the range
of security context happen to be same for several guests. During reservation,
the second attempt to reserve the same range fails and the Guests would be
killed. The fix is to avoid reserving labels for type = none during libvirt
restart.
Signed-off-by: Shivaprasad G Bhat <sbhat(a)linux.vnet.ibm.com>
---
src/security/security_selinux.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 008c58c..2f8a7f2 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -739,7 +739,8 @@ virSecuritySELinuxReserveSecurityLabel(virSecurityManagerPtr mgr,
virSecurityLabelDefPtr seclabel;
seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
- if (!seclabel || seclabel->type == VIR_DOMAIN_SECLABEL_STATIC)
+ if (!seclabel || seclabel->type == VIR_DOMAIN_SECLABEL_STATIC ||
+ seclabel->type == VIR_DOMAIN_SECLABEL_NONE)
return 0;
if (getpidcon_raw(pid, &pctx) == -1) {
10 years, 2 months
[libvirt] [PATCH v1 0/6] ivshmem support
by Maxime Leroy
The following patches are an implementation of
a new shmem device to support ivshmem in libvirt.
Any feedback is welcome.
Changes since RFC:
- replace <ivshmem> by a more generic term <shmem>
- remove role attribute
- libvirt is able to start and stop an ivshmem server
- update xml format from:
<ivshmem use_server='yes' role='master'>
<source file='/tmp/socket-ivshmem0'/>
<size unit='M'>32</size>
<msi vectors='32' ioeventfd='on'/>
</ivshmem>
to:
<shmem name='shmem0' model='ivshmem'>
<server path='/tmp/sockect-ivshem0' start='yes'/>
<size unit='M'>32</size>
<msi vectors='32' ioeventfd='on'/>
</shmem>
Maxime Leroy (6):
doc: schema: Add documentation for the shmem support
conf: Parse and format shmem device XML
qemu: Add cap flag QEMU_CAPS_IVSHMEM
qemu: Build command line for ivshmem device
tests: Add tests for ivshmem device handling
ivshmem: add start param to server attribute
configure.ac | 4 +
docs/formatdomain.html.in | 71 ++++++
docs/schemas/domaincommon.rng | 52 +++++
po/POTFILES.in | 1 +
src/Makefile.am | 1 +
src/conf/domain_conf.c | 264 ++++++++++++++++++++++-
src/conf/domain_conf.h | 42 ++++
src/libvirt_private.syms | 7 +
src/qemu/qemu_capabilities.c | 3 +
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 112 +++++++++-
src/qemu/qemu_command.h | 4 +
src/qemu/qemu_hotplug.c | 1 +
src/qemu/qemu_process.c | 10 +
src/util/virivshmemserver.c | 141 ++++++++++++
src/util/virivshmemserver.h | 28 +++
tests/qemucapabilitiesdata/caps_1.2.2-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.3.1-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.4.2-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.5.3-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.6.0-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.6.50-1.caps | 1 +
tests/qemuhelptest.c | 17 +-
tests/qemuxml2argvdata/qemuxml2argv-ivshmem.args | 10 +
tests/qemuxml2argvdata/qemuxml2argv-ivshmem.xml | 35 +++
tests/qemuxml2argvtest.c | 3 +
tests/qemuxml2xmltest.c | 2 +
27 files changed, 808 insertions(+), 7 deletions(-)
create mode 100644 src/util/virivshmemserver.c
create mode 100644 src/util/virivshmemserver.h
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-ivshmem.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-ivshmem.xml
--
1.9.3
10 years, 2 months
[libvirt] [PATCH 0/2] bulk api: implement block group
by Li Wei
This patchset implement the block group for bulk stats, currently only
support JSON monitor.
Li Wei (2):
qemu: implement block group for bulk stats.
virsh: add block group for bulk stats.
include/libvirt/libvirt.h.in | 1 +
src/libvirt.c | 13 ++++
src/qemu/qemu_driver.c | 31 ++++++++
src/qemu/qemu_monitor.c | 23 ++++++
src/qemu/qemu_monitor.h | 5 ++
src/qemu/qemu_monitor_json.c | 170 +++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 5 ++
tools/virsh-domain-monitor.c | 7 ++
tools/virsh.pod | 4 +-
9 files changed, 257 insertions(+), 2 deletions(-)
--
1.9.3
10 years, 2 months
[libvirt] [PATCH RFC] qemu: add some synchronizations for snapshot
by Jincheng Miao
Currently it lacks synchronization to modify domain's snapshot object list,
that race condition causes unsafe access to some freed snapshot objects.
Therefore, this patch wraps all access of snapshot object list in vm job lock.
Only the qemuDomainSnapshotCreateXML is not synchronized, it is related to
QEMU_ASYNC_JOB_SNAPSHOT async job for --disk-only snapshot. I am not sure
if it's ok to remove it, so need your ideas for qemuDomainSnapshotCreateXML.
Signed-off-by: Jincheng Miao <jmiao(a)redhat.com>
---
src/qemu/qemu_driver.c | 137 +++++++++++++++++++++++++++++++++++++++---------
1 files changed, 112 insertions(+), 25 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 73959da..7329aa9 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13609,6 +13609,7 @@ static int qemuDomainSnapshotListNames(virDomainPtr domain, char **names,
{
virDomainObjPtr vm = NULL;
int n = -1;
+ virQEMUDriverPtr driver = domain->conn->privateData;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS |
VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1);
@@ -13619,8 +13620,12 @@ static int qemuDomainSnapshotListNames(virDomainPtr domain, char **names,
if (virDomainSnapshotListNamesEnsureACL(domain->conn, vm->def) < 0)
goto cleanup;
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
+ goto cleanup;
+
n = virDomainSnapshotObjListGetNames(vm->snapshots, NULL, names, nameslen,
flags);
+ ignore_value(qemuDomainObjEndJob(driver, vm));
cleanup:
if (vm)
@@ -13633,6 +13638,7 @@ static int qemuDomainSnapshotNum(virDomainPtr domain,
{
virDomainObjPtr vm = NULL;
int n = -1;
+ virQEMUDriverPtr driver = domain->conn->privateData;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS |
VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1);
@@ -13643,8 +13649,13 @@ static int qemuDomainSnapshotNum(virDomainPtr domain,
if (virDomainSnapshotNumEnsureACL(domain->conn, vm->def) < 0)
goto cleanup;
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
+ goto cleanup;
+
n = virDomainSnapshotObjListNum(vm->snapshots, NULL, flags);
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
cleanup:
if (vm)
virObjectUnlock(vm);
@@ -13657,6 +13668,7 @@ qemuDomainListAllSnapshots(virDomainPtr domain, virDomainSnapshotPtr **snaps,
{
virDomainObjPtr vm = NULL;
int n = -1;
+ virQEMUDriverPtr driver = domain->conn->privateData;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS |
VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1);
@@ -13667,8 +13679,13 @@ qemuDomainListAllSnapshots(virDomainPtr domain, virDomainSnapshotPtr **snaps,
if (virDomainListAllSnapshotsEnsureACL(domain->conn, vm->def) < 0)
goto cleanup;
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
+ goto cleanup;
+
n = virDomainListSnapshots(vm->snapshots, NULL, domain, snaps, flags);
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
cleanup:
if (vm)
virObjectUnlock(vm);
@@ -13684,6 +13701,7 @@ qemuDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot,
virDomainObjPtr vm = NULL;
virDomainSnapshotObjPtr snap = NULL;
int n = -1;
+ virQEMUDriverPtr driver = snapshot->domain->conn->privateData;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1);
@@ -13694,12 +13712,18 @@ qemuDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot,
if (virDomainSnapshotListChildrenNamesEnsureACL(snapshot->domain->conn, vm->def) < 0)
goto cleanup;
- if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
+ if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ goto endjob;
+
n = virDomainSnapshotObjListGetNames(vm->snapshots, snap, names, nameslen,
flags);
+ endjob:
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
cleanup:
if (vm)
virObjectUnlock(vm);
@@ -13713,6 +13737,7 @@ qemuDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot,
virDomainObjPtr vm = NULL;
virDomainSnapshotObjPtr snap = NULL;
int n = -1;
+ virQEMUDriverPtr driver = snapshot->domain->conn->privateData;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1);
@@ -13723,11 +13748,17 @@ qemuDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot,
if (virDomainSnapshotNumChildrenEnsureACL(snapshot->domain->conn, vm->def) < 0)
goto cleanup;
- if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
+ if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ goto endjob;
+
n = virDomainSnapshotObjListNum(vm->snapshots, snap, flags);
+ endjob:
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
cleanup:
if (vm)
virObjectUnlock(vm);
@@ -13742,6 +13773,7 @@ qemuDomainSnapshotListAllChildren(virDomainSnapshotPtr snapshot,
virDomainObjPtr vm = NULL;
virDomainSnapshotObjPtr snap = NULL;
int n = -1;
+ virQEMUDriverPtr driver = snapshot->domain->conn->privateData;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1);
@@ -13752,12 +13784,18 @@ qemuDomainSnapshotListAllChildren(virDomainSnapshotPtr snapshot,
if (virDomainSnapshotListAllChildrenEnsureACL(snapshot->domain->conn, vm->def) < 0)
goto cleanup;
- if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
+ if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ goto endjob;
+
n = virDomainListSnapshots(vm->snapshots, snap, snapshot->domain, snaps,
flags);
+ endjob:
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
cleanup:
if (vm)
virObjectUnlock(vm);
@@ -13771,6 +13809,7 @@ static virDomainSnapshotPtr qemuDomainSnapshotLookupByName(virDomainPtr domain,
virDomainObjPtr vm;
virDomainSnapshotObjPtr snap = NULL;
virDomainSnapshotPtr snapshot = NULL;
+ virQEMUDriverPtr driver = domain->conn->privateData;
virCheckFlags(0, NULL);
@@ -13780,11 +13819,17 @@ static virDomainSnapshotPtr qemuDomainSnapshotLookupByName(virDomainPtr domain,
if (virDomainSnapshotLookupByNameEnsureACL(domain->conn, vm->def) < 0)
goto cleanup;
- if (!(snap = qemuSnapObjFromName(vm, name)))
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
+ if (!(snap = qemuSnapObjFromName(vm, name)))
+ goto endjob;
+
snapshot = virGetDomainSnapshot(domain, snap->def->name);
+ endjob:
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
cleanup:
if (vm)
virObjectUnlock(vm);
@@ -13796,6 +13841,7 @@ static int qemuDomainHasCurrentSnapshot(virDomainPtr domain,
{
virDomainObjPtr vm;
int ret = -1;
+ virQEMUDriverPtr driver = domain->conn->privateData;
virCheckFlags(0, -1);
@@ -13805,8 +13851,13 @@ static int qemuDomainHasCurrentSnapshot(virDomainPtr domain,
if (virDomainHasCurrentSnapshotEnsureACL(domain->conn, vm->def) < 0)
goto cleanup;
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
+ goto cleanup;
+
ret = (vm->current_snapshot != NULL);
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
cleanup:
if (vm)
virObjectUnlock(vm);
@@ -13820,6 +13871,7 @@ qemuDomainSnapshotGetParent(virDomainSnapshotPtr snapshot,
virDomainObjPtr vm;
virDomainSnapshotObjPtr snap = NULL;
virDomainSnapshotPtr parent = NULL;
+ virQEMUDriverPtr driver = snapshot->domain->conn->privateData;
virCheckFlags(0, NULL);
@@ -13829,18 +13881,24 @@ qemuDomainSnapshotGetParent(virDomainSnapshotPtr snapshot,
if (virDomainSnapshotGetParentEnsureACL(snapshot->domain->conn, vm->def) < 0)
goto cleanup;
- if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
+ if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ goto endjob;
+
if (!snap->def->parent) {
virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
_("snapshot '%s' does not have a parent"),
snap->def->name);
- goto cleanup;
+ goto endjob;
}
parent = virGetDomainSnapshot(snapshot->domain, snap->def->parent);
+ endjob:
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
cleanup:
if (vm)
virObjectUnlock(vm);
@@ -13852,6 +13910,7 @@ static virDomainSnapshotPtr qemuDomainSnapshotCurrent(virDomainPtr domain,
{
virDomainObjPtr vm;
virDomainSnapshotPtr snapshot = NULL;
+ virQEMUDriverPtr driver = domain->conn->privateData;
virCheckFlags(0, NULL);
@@ -13861,14 +13920,20 @@ static virDomainSnapshotPtr qemuDomainSnapshotCurrent(virDomainPtr domain,
if (virDomainSnapshotCurrentEnsureACL(domain->conn, vm->def) < 0)
goto cleanup;
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
+ goto cleanup;
+
if (!vm->current_snapshot) {
virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, "%s",
_("the domain does not have a current snapshot"));
- goto cleanup;
+ goto endjob;
}
snapshot = virGetDomainSnapshot(domain, vm->current_snapshot->def->name);
+ endjob:
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
cleanup:
if (vm)
virObjectUnlock(vm);
@@ -13882,6 +13947,7 @@ static char *qemuDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
char *xml = NULL;
virDomainSnapshotObjPtr snap = NULL;
char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virQEMUDriverPtr driver = snapshot->domain->conn->privateData;
virCheckFlags(VIR_DOMAIN_XML_SECURE, NULL);
@@ -13891,13 +13957,19 @@ static char *qemuDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
if (virDomainSnapshotGetXMLDescEnsureACL(snapshot->domain->conn, vm->def) < 0)
goto cleanup;
- if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
+ if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ goto endjob;
+
virUUIDFormat(snapshot->domain->uuid, uuidstr);
xml = virDomainSnapshotDefFormat(uuidstr, snap->def, flags, 0);
+ endjob:
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
cleanup:
if (vm)
virObjectUnlock(vm);
@@ -13911,6 +13983,7 @@ qemuDomainSnapshotIsCurrent(virDomainSnapshotPtr snapshot,
virDomainObjPtr vm = NULL;
int ret = -1;
virDomainSnapshotObjPtr snap = NULL;
+ virQEMUDriverPtr driver = snapshot->domain->conn->privateData;
virCheckFlags(0, -1);
@@ -13920,12 +13993,18 @@ qemuDomainSnapshotIsCurrent(virDomainSnapshotPtr snapshot,
if (virDomainSnapshotIsCurrentEnsureACL(snapshot->domain->conn, vm->def) < 0)
goto cleanup;
- if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
+ if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ goto endjob;
+
ret = (vm->current_snapshot &&
STREQ(snapshot->name, vm->current_snapshot->def->name));
+ endjob:
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
cleanup:
if (vm)
virObjectUnlock(vm);
@@ -13940,6 +14019,7 @@ qemuDomainSnapshotHasMetadata(virDomainSnapshotPtr snapshot,
virDomainObjPtr vm = NULL;
int ret = -1;
virDomainSnapshotObjPtr snap = NULL;
+ virQEMUDriverPtr driver = snapshot->domain->conn->privateData;
virCheckFlags(0, -1);
@@ -13949,14 +14029,20 @@ qemuDomainSnapshotHasMetadata(virDomainSnapshotPtr snapshot,
if (virDomainSnapshotHasMetadataEnsureACL(snapshot->domain->conn, vm->def) < 0)
goto cleanup;
- if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
+ if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ goto endjob;
+
/* XXX Someday, we should recognize internal snapshots in qcow2
* images that are not tied to a libvirt snapshot; if we ever do
* that, then we would have a reason to return 0 here. */
ret = 1;
+ endjob:
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
cleanup:
if (vm)
virObjectUnlock(vm);
@@ -14027,9 +14113,12 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
goto cleanup;
}
- if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
+ if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ goto endjob;
+
if (!vm->persistent &&
snap->def->state != VIR_DOMAIN_RUNNING &&
snap->def->state != VIR_DOMAIN_PAUSED &&
@@ -14038,13 +14127,13 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("transient domain needs to request run or pause "
"to revert to inactive snapshot"));
- goto cleanup;
+ goto endjob;
}
if (virDomainSnapshotIsExternal(snap)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("revert to external snapshot not supported yet"));
- goto cleanup;
+ goto endjob;
}
if (!(flags & VIR_DOMAIN_SNAPSHOT_REVERT_FORCE)) {
@@ -14052,7 +14141,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
virReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY,
_("snapshot '%s' lacks domain '%s' rollback info"),
snap->def->name, vm->def->name);
- goto cleanup;
+ goto endjob;
}
if (virDomainObjIsActive(vm) &&
!(snap->def->state == VIR_DOMAIN_RUNNING
@@ -14061,7 +14150,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED))) {
virReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY, "%s",
_("must respawn qemu to start inactive snapshot"));
- goto cleanup;
+ goto endjob;
}
}
@@ -14070,7 +14159,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
vm->current_snapshot->def->current = false;
if (qemuDomainSnapshotWriteMetadata(vm, vm->current_snapshot,
cfg->snapshotDir) < 0)
- goto cleanup;
+ goto endjob;
vm->current_snapshot = NULL;
/* XXX Should we restore vm->current_snapshot after this point
* in the failure cases where we know there was no change? */
@@ -14085,12 +14174,9 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
if (snap->def->dom) {
config = virDomainDefCopy(snap->def->dom, caps, driver->xmlopt, true);
if (!config)
- goto cleanup;
+ goto endjob;
}
- if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
- goto cleanup;
-
switch ((virDomainState) snap->def->state) {
case VIR_DOMAIN_RUNNING:
case VIR_DOMAIN_PAUSED:
@@ -14400,9 +14486,13 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
if (virDomainSnapshotDeleteEnsureACL(snapshot->domain->conn, vm->def) < 0)
goto cleanup;
- if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
+ if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ goto endjob;
+
if (!metadata_only) {
if (!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) &&
virDomainSnapshotIsExternal(snap))
@@ -14415,13 +14505,10 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("deletion of %d external disk snapshots not "
"supported yet"), external);
- goto cleanup;
+ goto endjob;
}
}
- if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
- goto cleanup;
-
if (flags & (VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)) {
rem.driver = driver;
--
1.7.1
10 years, 2 months
[libvirt] [PATCH] virsh: Implement command to rename domain
by Tomas Meszaros
I've recently worked with rather large number of virtual machines
and needed to rename all domains. I couldn't find better way how
to rename domain other than:
virsh dumpxml domain > domain.xml
(change domain name in domain.xml)
virsh undefine domain
virsh define domain.xml
This is rather pain to do every time I want to rename domain.
I think there should be simple way to change domain name.
So, I decided to implement new command which will basically perform
all actions listed above. When running:
virsh rename foo bar
domain foo will be renamed to bar.
Command rename is implemented using cmdUndefine options with addition
of option name-name.
I included opts_undefine into the opts_rename because I couldn't find
any other way how to call cmdUndefine directly from the cmdRename and
not getting vshCommandOpt assertion fails.
In order to hide undefine options, I added VSH_OFLAG_HIDDEN flag to
the Command Option Flags, so options flagged as hidden wont show up
in help and autocompletion results.
But it is still possible to run rename command with undefine flags:
virsh rename foo bar --managed-save
I would like to call cmdUndefine from cmdRename and not having to
use undefine options as a part of rename options but I just don't
know how to do it at this point.
---
tools/virsh-domain.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++
tools/virsh.c | 10 ++++
tools/virsh.h | 2 +
tools/virsh.pod | 12 +++++
4 files changed, 157 insertions(+)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index c75cd73..cd8c663 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -5103,6 +5103,133 @@ cmdReboot(vshControl *ctl, const vshCmd *cmd)
}
/*
+ * "rename" command
+ */
+static const vshCmdInfo info_rename[] = {
+ {.name = "help",
+ .data = N_("rename a domain")
+ },
+ {.name = "desc",
+ .data = N_("Change domain name.")
+ },
+ {.name = NULL}
+};
+
+static const vshCmdOptDef opts_rename[] = {
+ {.name = "domain",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("domain name or uuid")
+ },
+ {.name = "new-name",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("new domain name")
+ },
+ {.name = "managed-save",
+ .type = VSH_OT_BOOL,
+ .flags = VSH_OFLAG_HIDDEN,
+ },
+ {.name = "storage",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_HIDDEN,
+ },
+ {.name = "remove-all-storage",
+ .type = VSH_OT_BOOL,
+ .flags = VSH_OFLAG_HIDDEN,
+ },
+ {.name = "wipe-storage",
+ .type = VSH_OT_BOOL,
+ .flags = VSH_OFLAG_HIDDEN,
+ },
+ {.name = "snapshots-metadata",
+ .type = VSH_OT_BOOL,
+ .flags = VSH_OFLAG_HIDDEN,
+ },
+ {.name = NULL}
+};
+
+static bool
+cmdRename(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ virDomainPtr new_dom = NULL;
+ bool ret = false;
+ int dom_state;
+ int xml_size;
+ char *dom_xml = NULL;
+ const char *new_name = NULL;
+ xmlDocPtr doc = NULL;
+ xmlChar *new_dom_xml = NULL;
+ xmlNodePtr name_node = NULL;
+ xmlXPathObjectPtr obj = NULL;
+ xmlXPathContextPtr ctxt = NULL;
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+ return false;
+
+ if (virDomainGetState(dom, &dom_state, NULL, 0) < 0) {
+ vshError(ctl, "%s", _("Failed to get domain state"));
+ goto cleanup;
+ }
+
+ if (dom_state != VIR_DOMAIN_SHUTOFF) {
+ vshError(ctl, _("Please shutdown domain before renaming"));
+ goto cleanup;
+ }
+
+ if (vshCommandOptString(cmd, "new-name", &new_name) <= 0) {
+ vshError(ctl, _("Failed to parse --new-name parameter"));
+ goto cleanup;
+ }
+
+ if (!(dom_xml = virDomainGetXMLDesc(dom, 0)))
+ goto cleanup;
+ if (!(doc = virXMLParseStringCtxt(dom_xml, NULL, &ctxt)))
+ goto cleanup;
+
+ obj = xmlXPathEval(BAD_CAST "/domain/name", ctxt);
+ if (obj == NULL || obj->type != XPATH_NODESET || obj->nodesetval == NULL ||
+ obj->nodesetval->nodeNr == 0 || obj->nodesetval->nodeTab == NULL) {
+ vshError(ctl, _("Failed to extract domain name"));
+ goto cleanup;
+ }
+
+ if (!(name_node = obj->nodesetval->nodeTab[0]->children))
+ goto cleanup;
+
+ xmlNodeSetContent(name_node, BAD_CAST new_name);
+ xmlDocDumpMemory(doc, &new_dom_xml, &xml_size);
+ if (new_dom_xml == NULL || xml_size <= 0) {
+ vshError(ctl, _("Failed to format new XML for domain %s"), new_name);
+ goto cleanup;
+ }
+
+ if (!cmdUndefine(ctl, cmd))
+ goto cleanup;
+
+ if (!(new_dom = virDomainDefineXML(ctl->conn, (char *)new_dom_xml))) {
+ vshError(ctl, _("Failed to define domain %s"), new_name);
+ goto cleanup;
+ }
+
+ vshPrint(ctl, _("Domain %s has been renamed to %s\n"),
+ virDomainGetName(dom), virDomainGetName(new_dom));
+ ret = true;
+
+ cleanup:
+ virDomainFree(dom);
+ if (new_dom)
+ virDomainFree(new_dom);
+ VIR_FREE(dom_xml);
+ VIR_FREE(new_dom_xml);
+ xmlFreeDoc(doc);
+ xmlXPathFreeObject(obj);
+ xmlXPathFreeContext(ctxt);
+ return ret;
+}
+
+/*
* "reset" command
*/
static const vshCmdInfo info_reset[] = {
@@ -12057,6 +12184,12 @@ const vshCmdDef domManagementCmds[] = {
.info = info_reboot,
.flags = 0
},
+ {.name = "rename",
+ .handler = cmdRename,
+ .opts = opts_rename,
+ .info = info_rename,
+ .flags = 0
+ },
{.name = "reset",
.handler = cmdReset,
.opts = opts_reset,
diff --git a/tools/virsh.c b/tools/virsh.c
index 713c9a5..ef0d2df 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1299,6 +1299,10 @@ vshCmddefHelp(vshControl *ctl, const char *cmdname)
const vshCmdOptDef *opt;
for (opt = def->opts; opt->name; opt++) {
const char *fmt = "%s";
+
+ if (opt->flags & VSH_OFLAG_HIDDEN)
+ continue;
+
switch (opt->type) {
case VSH_OT_BOOL:
fmt = "[--%s]";
@@ -1352,6 +1356,9 @@ vshCmddefHelp(vshControl *ctl, const char *cmdname)
const vshCmdOptDef *opt;
fputs(_("\n OPTIONS\n"), stdout);
for (opt = def->opts; opt->name; opt++) {
+ if (opt->flags & VSH_OFLAG_HIDDEN)
+ continue;
+
switch (opt->type) {
case VSH_OT_BOOL:
snprintf(buf, sizeof(buf), "--%s", opt->name);
@@ -3001,6 +3008,9 @@ vshReadlineOptionsGenerator(const char *text, int state)
/* ignore non --option */
continue;
+ if (opt->flags & VSH_OFLAG_HIDDEN)
+ continue;
+
if (len > 2) {
if (STRNEQLEN(name, text + 2, len - 2))
continue;
diff --git a/tools/virsh.h b/tools/virsh.h
index b4df24b..5fa22d0 100644
--- a/tools/virsh.h
+++ b/tools/virsh.h
@@ -136,6 +136,8 @@ enum {
VSH_OFLAG_REQ = (1 << 0), /* option required */
VSH_OFLAG_EMPTY_OK = (1 << 1), /* empty string option allowed */
VSH_OFLAG_REQ_OPT = (1 << 2), /* --optionname required */
+ VSH_OFLAG_HIDDEN = (1 << 4), /* option doesn't show up in help
+ * messages and autocompletion */
};
/* forward declarations */
diff --git a/tools/virsh.pod b/tools/virsh.pod
index ea9267e..3c56695 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1512,6 +1512,18 @@ try each mode is undefined, and not related to the order specified to virsh.
For strict control over ordering, use a single mode at a time and
repeat the command.
+=item B<rename> I<domain> I<new-name>
+
+Rename a domain. This command changes current domain name to the new name
+specified by the user. This is equivalent to:
+
+ virsh dumpxml domain > domain.xml
+ (edit domain.xml, change <name>domain</name> to <name>new-name</name>)
+ virsh undefine domain
+ virsh define domain.xml
+
+B<Note>: Domain must be shut down before renaming.
+
=item B<reset> I<domain>
Reset a domain immediately without any guest shutdown. B<reset>
--
1.9.3
10 years, 2 months
[libvirt] [python PATCH 0/5] Implement bindings for bulk stats API
by Peter Krempa
The last patch is to ease review to be able to build the series.
Peter Krempa (5):
generator: enum: Don't sort enums by names
API: Skip 'virDomainStatsRecordListFree'
API: Implement bindings for virConnectGetAllDomainStats
API: Implement bindings for virDomainListGetStats
DO NOT APPLY: Fix build with missing virDomainBlockCopy API
generator.py | 6 +-
libvirt-override-virConnect.py | 100 ++++++++++++++++++++++++++++
libvirt-override.c | 144 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 248 insertions(+), 2 deletions(-)
--
2.0.2
10 years, 2 months