[libvirt] Applying for GSoC project 'Introducing job control to the storage driver' in libvirt
by Taowei Luo
Hello, everyone.
I'm Taowei Luo. A participator in Google Summer of Code last year for
the project rewriting vbox driver in libvirt. I am so glad that my
project isn't found in this year's GSoC project list :)
Having a nice experience last year, libvirt is my top option to join
the GSoC 2015. And my interesting project is “Introducing job control
to the storage driver”.
I have read some materials about this project. Including I noticed
that Tucker had attempted it last year. It seems he didn't make it
through the final evaluation. During his working, some discussion were
made in mail-list. It is really inspiring to me. So I have some basic
ideas for now.
The project requires job control functions (at least, reporting the
progress) in storage driver. Obviously, it contains two part. First
find codes that really do the storage work which may take a long
period and can be asynchronized. Then, extract it to the job control
part so make it under the control. It would not be hard to find codes
that really need asynchronization. Maybe by dumping the debug message
and tracing the function calls. So the big part is design the APIs for
job control. I think the goal for API design is not only make it
workable but also make it reasonable and extendable.
To achieve this, a lot of details were discussed in last year's
proceeding. I summered it and add my own opinion.
Parallel jobs: The idea result is that several jobs work in parallel
and libvirt monitors and controls it. There are two ways for parallel:
thread and process. I prefer process. In process, we can easier
implement the idea of *control* by signal. Process has better
independence than thread. What's more, it is a low coupling design.
Synchronization: process can use system level lock to make sure it
obtain the resources. If the process can't obtain it could exit with
failure (or wait). In process, we can leave most resource competition
handling by OS. If thread is used instead, we need to think about
resource competition between libvirt and other process, and at the
same time, those competitions in libvirt thread.
Management: We execute those asynchronous codes in a new process. In
libvirt, it invokes those processes with parsed arguments. Libvirtd
would have a process pool to store the pids and some attached
information for each process. Signal would be used to communicate
between process and libvirt.
Expandability: Some other jobs like domain migration could be in
implemented under this design. It's all about creating new jobs with
parsed arguments, which tells the child process what to do and what
resources they need.
Privacy: If new jobs are created in process, user may access the
process directly and not noticing libvirt. Function sigaction(), which
provides the pid of sending process, could be used to register
responding functions. Meanwhile, atexit() register functions that
execute when the process is going to exit. It is helpful on notifying
libvirtd the end of the job.
What already have: Besides the discussion, some other resources would
be helpful for this project. qemu has a prototype for job control in
migration. We already have gnulib and tools in util/virprocess.h and
util/virthread.h to achieve parallel.
When undertaking, I would firstly implement the job control part. It
would have some basic functions. Make one storage API work in it.
Then, adding job control support for the rest APIs.
This is all about what I came up with. Maybe those ideas are old and
repeating. But I think it is a workable plan. Waiting for feedback.
Regards,
Taowei
9 years, 8 months
[libvirt] [PATCH 0/5] Allocate virtio-serial addresses
by Ján Tomko
Instead of simply incrementing the port, respect
maximum port values and use multiple controllers.
Ján Tomko (5):
Add test for virtio serial port assignment
Add functions to track virtio-serial addresses
Allocate virtio-serial addresses when starting a domain
Expand the address set when attaching a virtio-serial controller
Assign an address when hotplugging a virtio-serial device
src/conf/domain_addr.c | 382 +++++++++++++++++++++
src/conf/domain_addr.h | 45 +++
src/conf/domain_conf.c | 29 --
src/libvirt_private.syms | 8 +
src/qemu/qemu_command.c | 63 ++++
src/qemu/qemu_domain.c | 1 +
src/qemu/qemu_domain.h | 1 +
src/qemu/qemu_hotplug.c | 32 +-
src/qemu/qemu_process.c | 2 +
tests/qemuhotplugtest.c | 2 +-
.../qemuxml2argv-channel-virtio-auto.args | 8 +-
.../qemuxml2argv-channel-virtio-autoassign.args | 20 ++
.../qemuxml2argv-channel-virtio-autoassign.xml | 50 +++
tests/qemuxml2argvtest.c | 2 +
.../qemuxml2xmlout-channel-virtio-auto.xml | 10 +-
15 files changed, 614 insertions(+), 41 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-autoassign.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-autoassign.xml
--
2.0.5
9 years, 8 months
[libvirt] [PATCH v4 4/4] migration: Expose 'cancelling' status to user
by zhanghailiang
'cancelling' status was introduced by commit 51cf4c1a, mainly to avoid a
possible start of a new migration process while the previous one still exists.
But we didn't expose this status to user, instead we returned the 'active' state.
Here, we expose it to the user (such as libvirt), 'cancelling' status only
occurs for a short window before the migration aborts, so for users,
if they cancel a migration process, it will observe 'cancelling' status
occasionally.
Testing revealed that with older libvirt (anything 1.2.13 or less) will
print an odd error message if the state is seen, but that the migration
is still properly cancelled. Newer libvirt will be patched to recognize
the new state without the odd error message.
Signed-off-by: zhanghailiang <zhang.zhanghailiang(a)huawei.com>
Reviewed-by: Eric Blake <eblake(a)redhat.com>
Cc: libvir-list(a)redhat.com
---
migration/migration.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 035e005..a57928d 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -179,13 +179,11 @@ MigrationInfo *qmp_query_migrate(Error **errp)
break;
case MIGRATION_STATUS_SETUP:
info->has_status = true;
- info->status = MIGRATION_STATUS_SETUP;
info->has_total_time = false;
break;
case MIGRATION_STATUS_ACTIVE:
case MIGRATION_STATUS_CANCELLING:
info->has_status = true;
- info->status = MIGRATION_STATUS_ACTIVE;
info->has_total_time = true;
info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
- s->total_time;
@@ -221,7 +219,6 @@ MigrationInfo *qmp_query_migrate(Error **errp)
get_xbzrle_cache_stats(info);
info->has_status = true;
- info->status = MIGRATION_STATUS_COMPLETED;
info->has_total_time = true;
info->total_time = s->total_time;
info->has_downtime = true;
@@ -243,13 +240,12 @@ MigrationInfo *qmp_query_migrate(Error **errp)
break;
case MIGRATION_STATUS_FAILED:
info->has_status = true;
- info->status = MIGRATION_STATUS_FAILED;
break;
case MIGRATION_STATUS_CANCELLED:
info->has_status = true;
- info->status = MIGRATION_STATUS_CANCELLED;
break;
}
+ info->status = s->state;
return info;
}
--
1.7.12.4
9 years, 8 months
[libvirt] [PATCH v2] qemu: read backing chain names from qemu
by Eric Blake
https://bugzilla.redhat.com/show_bug.cgi?id=1199182 documents that
after a series of disk snapshots into existing destination images,
followed by active commits of the top image, it is possible for
qemu 2.2 and earlier to end up tracking a different name for the
image than what it would have had when opening the chain afresh.
That is, when starting with the chain 'a <- b <- c', the name
associated with 'b' is how it was spelled in the metadata of 'c',
but when starting with 'a', taking two snapshots into 'a <- b <- c',
then committing 'c' back into 'b', the name associated with 'b' is
now the name used when taking the first snapshot.
Sadly, older qemu doesn't know how to treat different spellings of
the same filename as identical files (it uses strcmp() instead of
checking for the same inode), which means libvirt's attempt to
commit an image using solely the names learned from qcow2 metadata
fails with a cryptic:
error: internal error: unable to execute QEMU command 'block-commit': Top image file /tmp/images/c/../b/b not found
even though the file exists. Trying to teach libvirt the rules on
which name qemu will expect is not worth the effort (besides, we'd
have to remember it across libvirtd restarts, and track whether a
file was opened via metadata or via snapshot creation for a given
qemu process); it is easier to just always directly ask qemu what
string it expects to see in the first place.
As a safety valve, we validate that any name returned by qemu
still maps to the same local file as we have tracked it, so that
a compromised qemu cannot accidentally cause us to act on an
incorrect file.
* src/qemu/qemu_monitor.h (qemuMonitorDiskNameLookup): New
prototype.
* src/qemu/qemu_monitor_json.h (qemuMonitorJSONDiskNameLookup):
Likewise.
* src/qemu/qemu_monitor.c (qemuMonitorDiskNameLookup): New function.
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONDiskNameLookup)
(qemuMonitorJSONDiskNameLookupOne): Likewise.
* src/qemu/qemu_driver.c (qemuDomainBlockCommit)
(qemuDomainBlockJobImpl): Use it.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
v2: as suggested by Dan, add a sanity checking valve to ensure we
don't use qemu's string until vetting that it resolves to the same
local name we are already tracking
src/qemu/qemu_driver.c | 28 ++++++-------
src/qemu/qemu_monitor.c | 20 ++++++++-
src/qemu/qemu_monitor.h | 8 +++-
src/qemu/qemu_monitor_json.c | 97 +++++++++++++++++++++++++++++++++++++++++++-
src/qemu/qemu_monitor_json.h | 9 +++-
5 files changed, 144 insertions(+), 18 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b3263ac..f0e530d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16132,9 +16132,6 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
goto endjob;
if (baseSource) {
- if (qemuGetDriveSourceString(baseSource, NULL, &basePath) < 0)
- goto endjob;
-
if (flags & VIR_DOMAIN_BLOCK_REBASE_RELATIVE) {
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CHANGE_BACKING_FILE)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
@@ -16172,8 +16169,12 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
}
qemuDomainObjEnterMonitor(driver, vm);
- ret = qemuMonitorBlockJob(priv->mon, device, basePath, backingPath,
- speed, mode, async);
+ if (baseSource)
+ basePath = qemuMonitorDiskNameLookup(priv->mon, device, disk->src,
+ baseSource);
+ if (!baseSource || basePath)
+ ret = qemuMonitorBlockJob(priv->mon, device, basePath, backingPath,
+ speed, mode, async);
if (qemuDomainObjExitMonitor(driver, vm) < 0)
ret = -1;
if (ret < 0) {
@@ -16903,12 +16904,6 @@ qemuDomainBlockCommit(virDomainPtr dom,
VIR_DISK_CHAIN_READ_WRITE) < 0))
goto endjob;
- if (qemuGetDriveSourceString(topSource, NULL, &topPath) < 0)
- goto endjob;
-
- if (qemuGetDriveSourceString(baseSource, NULL, &basePath) < 0)
- goto endjob;
-
if (flags & VIR_DOMAIN_BLOCK_COMMIT_RELATIVE &&
topSource != disk->src) {
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CHANGE_BACKING_FILE)) {
@@ -16939,9 +16934,14 @@ qemuDomainBlockCommit(virDomainPtr dom,
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT;
}
qemuDomainObjEnterMonitor(driver, vm);
- ret = qemuMonitorBlockCommit(priv->mon, device,
- topPath, basePath, backingPath,
- speed);
+ basePath = qemuMonitorDiskNameLookup(priv->mon, device, disk->src,
+ baseSource);
+ topPath = qemuMonitorDiskNameLookup(priv->mon, device, disk->src,
+ topSource);
+ if (basePath && topPath)
+ ret = qemuMonitorBlockCommit(priv->mon, device,
+ topPath, basePath, backingPath,
+ speed);
if (qemuDomainObjExitMonitor(driver, vm) < 0) {
ret = -1;
goto endjob;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index d869a72..cf7dc5e 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1,7 +1,7 @@
/*
* qemu_monitor.c: interaction with QEMU monitor console
*
- * Copyright (C) 2006-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2015 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -3458,6 +3458,24 @@ qemuMonitorSupportsActiveCommit(qemuMonitorPtr mon)
}
+/* Determine the name that qemu is using for tracking the backing
+ * element TARGET within the chain starting at TOP. */
+char *
+qemuMonitorDiskNameLookup(qemuMonitorPtr mon,
+ const char *device,
+ virStorageSourcePtr top,
+ virStorageSourcePtr target)
+{
+ if (!mon->json) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("JSON monitor is required"));
+ return NULL;
+ }
+
+ return qemuMonitorJSONDiskNameLookup(mon, device, top, target);
+}
+
+
/* Use the block-job-complete monitor command to pivot a block copy
* job. */
int
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index b30da34..e67d800 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1,7 +1,7 @@
/*
* qemu_monitor.h: interaction with QEMU monitor console
*
- * Copyright (C) 2006-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2015 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -734,6 +734,12 @@ int qemuMonitorBlockCommit(qemuMonitorPtr mon,
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
ATTRIBUTE_NONNULL(4);
bool qemuMonitorSupportsActiveCommit(qemuMonitorPtr mon);
+char *qemuMonitorDiskNameLookup(qemuMonitorPtr mon,
+ const char *device,
+ virStorageSourcePtr top,
+ virStorageSourcePtr target)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+ ATTRIBUTE_NONNULL(4);
int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
const char *cmd,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index c16f3ca..522fd17 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -1,7 +1,7 @@
/*
* qemu_monitor_json.c: interaction with QEMU monitor console
*
- * Copyright (C) 2006-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2015 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -3883,6 +3883,101 @@ qemuMonitorJSONDrivePivot(qemuMonitorPtr mon, const char *device,
}
+static char *
+qemuMonitorJSONDiskNameLookupOne(virJSONValuePtr image,
+ virStorageSourcePtr top,
+ virStorageSourcePtr target)
+{
+ virJSONValuePtr backing;
+ char *ret;
+
+ if (!top)
+ return NULL;
+ if (top != target) {
+ backing = virJSONValueObjectGet(image, "backing-image");
+ return qemuMonitorJSONDiskNameLookupOne(backing, top->backingStore,
+ target);
+ }
+ if (VIR_STRDUP(ret, virJSONValueObjectGetString(image, "filename")) < 0)
+ return NULL;
+ /* Sanity check - the name qemu gave us should resolve to the same
+ file tracked by our target description. */
+ if (virStorageSourceIsLocalStorage(target) &&
+ STRNEQ(ret, target->path) &&
+ !virFileLinkPointsTo(ret, target->path)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("qemu block name '%s' doesn't match expected '%s'"),
+ ret, target->path);
+ VIR_FREE(ret);
+ }
+ return ret;
+}
+
+
+char *
+qemuMonitorJSONDiskNameLookup(qemuMonitorPtr mon,
+ const char *device,
+ virStorageSourcePtr top,
+ virStorageSourcePtr target)
+{
+ char *ret = NULL;
+ virJSONValuePtr cmd = NULL;
+ virJSONValuePtr reply = NULL;
+ virJSONValuePtr devices;
+ size_t i;
+
+ cmd = qemuMonitorJSONMakeCommand("query-block", NULL);
+ if (!cmd)
+ return NULL;
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
+
+ devices = virJSONValueObjectGet(reply, "return");
+ if (!devices || devices->type != VIR_JSON_TYPE_ARRAY) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("block info reply was missing device list"));
+ goto cleanup;
+ }
+
+ for (i = 0; i < virJSONValueArraySize(devices); i++) {
+ virJSONValuePtr dev = virJSONValueArrayGet(devices, i);
+ virJSONValuePtr inserted;
+ virJSONValuePtr image;
+ const char *thisdev;
+
+ if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("block info device entry was not in expected format"));
+ goto cleanup;
+ }
+
+ if ((thisdev = virJSONValueObjectGetString(dev, "device")) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("block info device entry was not in expected format"));
+ goto cleanup;
+ }
+
+ if (STREQ(thisdev, device)) {
+ if ((inserted = virJSONValueObjectGet(dev, "inserted")) &&
+ (image = virJSONValueObjectGet(inserted, "image"))) {
+ ret = qemuMonitorJSONDiskNameLookupOne(image, top, target);
+ }
+ break;
+ }
+ }
+ if (!ret && !virGetLastError())
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unable to find backing name for device %s"),
+ device);
+
+ cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+
+ return ret;
+}
+
+
int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
const char *cmd_str,
char **reply_str,
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 8ceea8a..49392b6 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -1,7 +1,7 @@
/*
* qemu_monitor_json.h: interaction with QEMU monitor console
*
- * Copyright (C) 2006-2009, 2011-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2009, 2011-2015 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -277,6 +277,13 @@ int qemuMonitorJSONBlockCommit(qemuMonitorPtr mon,
unsigned long long bandwidth)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+char *qemuMonitorJSONDiskNameLookup(qemuMonitorPtr mon,
+ const char *device,
+ virStorageSourcePtr top,
+ virStorageSourcePtr target)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+ ATTRIBUTE_NONNULL(4);
+
int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
const char *cmd_str,
char **reply_str,
--
2.1.0
9 years, 8 months
[libvirt] logging: how about adding a ProcessName field in logging file?
by zhang bo
Suppose there are 3 or more clients of libvirt:
1)nova
2)bash virsh commands
3)user customized ELF
4)etc....
The env LIBVIRT_DEBUG and LIBVIRT_LOG_OUTPUTS affects all of these clients, thus, they will all
accumulate the logs into *ONE* file set by LIBVIRT_LOG_OUTPUTS.
eg:
[2015-03-07 00:33:30]: 103674: info : virDomainShutdown:3242 : enter virDomainShutdown domainname=VMName
[2015-03-07 00:33:41]: 103674: info : virDomainShutdown:3253 : domain VMName shutted down
[2015-03-13 00:53:44]: 5073: info : libvirt version: 1.2.7
[2015-03-13 00:53:44]: 5034: info : libvirt version: 1.2.7
[2015-03-13 00:53:44]: 5073: error : virNetSocketReadWire:1475 : End of file while reading data: Input/output error
note:
103674: bash virsh command
5037: nova
if we don't know that 103674 is just a virsh command, and suspect that it's nova, time would be wasted to find out
who's the criminal.
The improved log would be:
[2015-03-07 00:33:30]: virsh: 103674: info : virDomainShutdown:3242 : enter virDomainShutdown domainname=VMName
[2015-03-07 00:33:41]: virsh: 103674: info : virDomainShutdown:3253 : domain VMName shutted down
[2015-03-13 00:53:44]: nova: 5073: info : libvirt version: 1.2.7
[2015-03-13 00:53:44]: myProc1: 5034: info : libvirt version: 1.2.7
[2015-03-13 00:53:44]: nova: error : virNetSocketReadWire:1475 : End of file while reading data: Input/output error
So, here's the qeustion:
Is it neccssary to add a ProcessName field in the logging file? if so, I'd like to apply a patch for this.
thank you in advance.
9 years, 8 months
[libvirt] Should logging in the library set its default outputs?
by zhang bo
If the env LIBVIRT_DEBUG and LIBVIRT_LOG_OUTPUTS are not set, the logging in the library would not log into any file.
So: Is it necessary to set the default level and outputs in virGlobalInit(), just in case the maintainer forgets to set the ENVs ?
Thanks in advance.
9 years, 8 months
[libvirt] [libvirt-test-API][PATCH V2 0/2] Add connection_getAllDomainStats test case
by jiahu
The testing case will validate the getAllDomainStats API in class virConnect
V2:
Added new domainListGetStats API in this case
jiahu (2):
Add connection_getAllDomainStats test case to linux_domain.conf
Add connection_getAllDomainStats test case
cases/linux_domain.conf | 14 +
repos/virconn/connection_getAllDomainStats.py | 549 ++++++++++++++++++++++++++
2 files changed, 563 insertions(+)
create mode 100644 repos/virconn/connection_getAllDomainStats.py
--
1.8.1.4
9 years, 8 months
[libvirt] [PATCH] parallels: fix prlsdkCheckUnsupportedParams checks
by Maxim Nestratov
for memory limits since unset ones are no longer zero
Signed-off-by: Maxim Nestratov <mnestratov(a)parallels.com>
---
src/parallels/parallels_sdk.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c
index a775348..4c90a18 100644
--- a/src/parallels/parallels_sdk.c
+++ b/src/parallels/parallels_sdk.c
@@ -1791,10 +1791,10 @@ prlsdkCheckUnsupportedParams(PRL_HANDLE sdkdom, virDomainDefPtr def)
}
if (def->mem.nhugepages ||
- def->mem.hard_limit ||
- def->mem.soft_limit ||
+ virMemoryLimitIsSet(def->mem.hard_limit) ||
+ virMemoryLimitIsSet(def->mem.soft_limit) ||
def->mem.min_guarantee ||
- def->mem.swap_hard_limit) {
+ virMemoryLimitIsSet(def->mem.swap_hard_limit)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Memory parameter is not supported "
--
1.7.1
9 years, 8 months
[libvirt] [PATCH v5 for-2.3 4/4] migration: Expose 'cancelling' status to user
by zhanghailiang
'cancelling' status was introduced by commit 51cf4c1a, mainly to avoid a
possible start of a new migration process while the previous one still exists.
But we didn't expose this status to user, instead we returned the 'active' state.
Here, we expose it to the user (such as libvirt), 'cancelling' status only
occurs for a short window before the migration aborts, so for users,
if they cancel a migration process, it will observe 'cancelling' status
occasionally.
Testing revealed that with older libvirt (anything 1.2.13 or less) will
print an odd error message if the state is seen, but that the migration
is still properly cancelled. Newer libvirt will be patched to recognize
the new state without the odd error message.
Signed-off-by: zhanghailiang <zhang.zhanghailiang(a)huawei.com>
Reviewed-by: Eric Blake <eblake(a)redhat.com>
Cc: libvir-list(a)redhat.com
---
migration/migration.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 035e005..a57928d 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -179,13 +179,11 @@ MigrationInfo *qmp_query_migrate(Error **errp)
break;
case MIGRATION_STATUS_SETUP:
info->has_status = true;
- info->status = MIGRATION_STATUS_SETUP;
info->has_total_time = false;
break;
case MIGRATION_STATUS_ACTIVE:
case MIGRATION_STATUS_CANCELLING:
info->has_status = true;
- info->status = MIGRATION_STATUS_ACTIVE;
info->has_total_time = true;
info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
- s->total_time;
@@ -221,7 +219,6 @@ MigrationInfo *qmp_query_migrate(Error **errp)
get_xbzrle_cache_stats(info);
info->has_status = true;
- info->status = MIGRATION_STATUS_COMPLETED;
info->has_total_time = true;
info->total_time = s->total_time;
info->has_downtime = true;
@@ -243,13 +240,12 @@ MigrationInfo *qmp_query_migrate(Error **errp)
break;
case MIGRATION_STATUS_FAILED:
info->has_status = true;
- info->status = MIGRATION_STATUS_FAILED;
break;
case MIGRATION_STATUS_CANCELLED:
info->has_status = true;
- info->status = MIGRATION_STATUS_CANCELLED;
break;
}
+ info->status = s->state;
return info;
}
--
1.7.12.4
9 years, 8 months
[libvirt] [libvirt-test-API][PATCH 0/2] Add coredump_with_format test case
by jiahu
The coredump_with_format.py uses coreDumpWithFormat() to validate
new API virDomainCoreDumpWithFormat of libvirt.
jiahu (2):
Add coredump_with_format test case
Add coredump_with_format test case to linux_domain conf
cases/linux_domain.conf | 44 +++++++
repos/domain/coredump_with_format.py | 239 +++++++++++++++++++++++++++++++++++
2 files changed, 283 insertions(+)
create mode 100644 repos/domain/coredump_with_format.py
--
1.8.3.1
9 years, 8 months