[libvirt] parsing url with percent sign when user want to use iso disk via http
by Vasiliy Tolstov
I found a strange thing, when i specify url for iso in libvirt xml like:
qemu gets invalid url in cmdline
i think that problem is
qemu/qemu_command.c:3430: ret = virURIFormat(uri);
test string looks like https://alukardd.org/data/test?t=1
qemu gets url with percent urlencoded %3F , in this case http server
get not test with param t=1 but filename test%3Ft=1 so this is not
right.
why libvirt try to fix contructed url ?
does it safe to delete this line ?
--
Vasiliy Tolstov,
e-mail: v.tolstov(a)selfip.ru
8 years, 10 months
[libvirt] An AB deadlock and libvirtd crash problem the other day with virsh console
by weifuqiang
Hi all:
I encountered with an AB deadlock and libvirtd crash problem the other day.
The process to generate the problems:
1 use the command "virsh create ***.xml" to create a vm
2 after vm is running , use the command "virsh console ***" to connect vm with console
3 after connection, use the command "virsh destroy ****" to destroy vm and delete it
Then, an AB lock problem occurs, or libvirtd got crashed.
AB LOCK stack:
[Switching to thread 1 (Thread 0x7ff96bf3d7a0 (LWP 9772))]
#0 0x00007ff967b49324 in __lll_lock_wait () from /lib64/libpthread.so.0
#0 0x00007ff967b49324 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00007ff967b44669 in _L_lock_1008 () from /lib64/libpthread.so.0
#2 0x00007ff967b4447e in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00007ff96b3bd96c in virChrdevFDStreamCloseCb () from /usr/lib64/libvirt.so.0
#4 0x00007ff96b3c9a34 in virFDStreamCloseInt () from /usr/lib64/libvirt.so.0
#5 0x00007ff96b40ac3e in virStreamAbort () from /usr/lib64/libvirt.so.0
#6 0x00007ff96bfa242a in daemonStreamHandleAbort ()
#7 0x00007ff96bfa2803 in daemonStreamEvent ()
#8 0x00007ff96b3c9bfc in virFDStreamEvent () from /usr/lib64/libvirt.so.0
#9 0x00007ff96b3083aa in virEventPollRunOnce () from /usr/lib64/libvirt.so.0
#10 0x00007ff96b307042 in virEventRunDefaultImpl () from /usr/lib64/libvirt.so.0
#11 0x00007ff96b4503dd in virNetDaemonRun () from /usr/lib64/libvirt.so.0
#12 0x00007ff96bf72528 in main ()
[Switching to thread 12 (Thread 0x7ff9640ff700 (LWP 9778))]
#0 0x00007ff967b49324 in __lll_lock_wait () from /lib64/libpthread.so.0
#0 0x00007ff967b49324 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00007ff967b44669 in _L_lock_1008 () from /lib64/libpthread.so.0
#2 0x00007ff967b4447e in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00007ff96b3c8f26 in virFDStreamSetInternalCloseCb () from /usr/lib64/libvirt.so.0
#4 0x00007ff96b30f7b9 in virHashForEach () from /usr/lib64/libvirt.so.0
#5 0x00007ff96b3be1a2 in virChrdevFree () from /usr/lib64/libvirt.so.0
#6 0x00007ff96055980f in qemuDomainObjPrivateFree () from /usr/lib64/libvirt/connection-driver/libvirt_driver_qemu.so
#7 0x00007ff96b367014 in virDomainObjDispose () from /usr/lib64/libvirt.so.0
#8 0x00007ff96b330c33 in virObjectUnref () from /usr/lib64/libvirt.so.0
#9 0x00007ff96b35edb9 in virDomainObjEndAPI () from /usr/lib64/libvirt.so.0
#10 0x00007ff9605c6e89 in qemuDomainUndefineFlags () from /usr/lib64/libvirt/connection-driver/libvirt_driver_qemu.so
#11 0x00007ff96b3e35ac in virDomainUndefine () from /usr/lib64/libvirt.so.0
#12 0x00007ff96bf996db in remoteDispatchDomainUndefineHelper ()
#13 0x00007ff96b4537ef in virNetServerProgramDispatch () from /usr/lib64/libvirt.so.0
#14 0x00007ff96b45205e in virNetServerProcessMsg () from /usr/lib64/libvirt.so.0
#15 0x00007ff96b4520e8 in virNetServerHandleJob () from /usr/lib64/libvirt.so.0
#16 0x00007ff96b349f94 in virThreadPoolWorker () from /usr/lib64/libvirt.so.0
#17 0x00007ff96b3494a8 in virThreadHelper () from /usr/lib64/libvirt.so.0
#18 0x00007ff967b42806 in start_thread () from /lib64/libpthread.so.0
#19 0x00007ff96789d67d in clone () from /lib64/libc.so.6
#20 0x0000000000000000 in ?? ()
coredump stack
(gdb) f 1
#1 0x00007f1672a7c73f in virMutexLock (m=0x68) at util/virthread.c:89
89 pthread_mutex_lock(&m->lock);
(gdb) bt
#0 0x00007f1670ace444 in pthread_mutex_lock () from /lib64/libpthread.so.0
#1 0x00007f1672a7c73f in virMutexLock (m=0x68) at util/virthread.c:89
#2 0x00007f1672b2fda2 in virFDStreamSetInternalCloseCb (st=0x7f1673a1a370, cb=0x0, opaque=0x0, fcb=0x0) at fdstream.c:796
#3 0x00007f1672b1f5ad in virChrdevFreeClearCallbacks (payload=0x7f1673a1a370, name=0x7f1673a12520, data=0x0) at conf/virchrdev.c:301
#4 0x00007f1672a36c9b in virHashForEach (table=0x7f1673a0ba20, iter=0x7f1672b1f567 <virChrdevFreeClearCallbacks>, data=0x0) at util/virhash.c:521
#5 0x00007f1672b1f626 in virChrdevFree (devs=0x7f1673a2f820) at conf/virchrdev.c:316
#6 0x00007f1669cca988 in qemuDomainObjPrivateFree (data=0x7f1673a1afa0) at qemu/qemu_domain.c:496
#7 0x00007f1672a9e293 in virDomainObjDispose (obj=0x7f1673a16400) at conf/domain_conf.c:2545
#8 0x00007f1672a5b326 in virObjectUnref (anyobj=0x7f1673a16400) at util/virobject.c:265
#9 0x00007f1672a9e7a5 in virDomainObjEndAPI (vm=0x7f166b07d8d0) at conf/domain_conf.c:2684
#10 0x00007f1669d3ff00 in qemuDomainDestroyFlags (dom=0x7f16600017f0, flags=0) at qemu/qemu_driver.c:2264
#11 0x00007f1669d3ff69 in qemuDomainDestroy (dom=0x7f16600017f0) at qemu/qemu_driver.c:2273
#12 0x00007f1672b39333 in virDomainDestroy (domain=0x7f16600017f0) at libvirt-domain.c:483
#13 0x00007f16737167a5 in remoteDispatchDomainDestroy (server=0x7f167398f4f0, client=0x7f1673a172f0, msg=0x7f1673a2fc70, rerr=0x7f166b07db50, args=0x7f1673a2f9b0)
at remote_dispatch.h:4002
#14 0x00007f1673716648 in remoteDispatchDomainDestroyHelper (server=0x7f167398f4f0, client=0x7f1673a172f0, msg=0x7f1673a2fc70, rerr=0x7f166b07db50, args=0x7f1673a2f9b0, ret=
0x7f1673a10e10) at remote_dispatch.h:3977
#15 0x00007f1672bd8a9b in virNetServerProgramDispatchCall (prog=0x7f167399c610, server=0x7f167398f4f0, client=0x7f1673a172f0, msg=0x7f1673a2fc70)
at rpc/virnetserverprogram.c:437
#16 0x00007f1672bd85fd in virNetServerProgramDispatch (prog=0x7f167399c610, server=0x7f167398f4f0, client=0x7f1673a172f0, msg=0x7f1673a2fc70) at rpc/virnetserverprogram.c:307
#17 0x00007f1672bd2a08 in virNetServerProcessMsg (srv=0x7f167398f4f0, client=0x7f1673a172f0, prog=0x7f167399c610, msg=0x7f1673a2fc70) at rpc/virnetserver.c:136
#18 0x00007f1672bd2aed in virNetServerHandleJob (jobOpaque=0x7f1673a1d780, opaque=0x7f167398f4f0) at rpc/virnetserver.c:157
#19 0x00007f1672a7d833 in virThreadPoolWorker (opaque=0x7f167399bad0) at util/virthreadpool.c:145
#20 0x00007f1672a7cbec in virThreadHelper (data=0x7f167399c980) at util/virthread.c:206
#21 0x00007f1670acc806 in start_thread () from /lib64/libpthread.so.0
#22 0x00007f167082767d in clone () from /lib64/libc.so.6
#23 0x0000000000000000 in ?? ()
(gdb) bt
#0 0x00007f1670ad3324 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00007f1670ace669 in _L_lock_1008 () from /lib64/libpthread.so.0
#2 0x00007f1670ace47e in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00007f1672a7c73f in virMutexLock (m=0x7f1673a2f820) at util/virthread.c:89
#4 0x00007f1672b1f3fe in virChrdevFDStreamCloseCb (st=0x7f1673a1a370, opaque=0x7f1673a149e0) at conf/virchrdev.c:254
#5 0x00007f1672b2e8a8 in virFDStreamCloseInt (st=0x7f1673a1a370, streamAbort=true) at fdstream.c:329
#6 0x00007f1672b2e9d5 in virFDStreamAbort (st=0x7f1673a1a370) at fdstream.c:355
#7 0x00007f1672b7d856 in virStreamAbort (stream=0x7f1673a1a370) at libvirt-stream.c:663
#8 0x00007f16737497e8 in daemonStreamHandleAbort (client=0x7f1673a1b1b0, stream=0x7f1673a1ec50, msg=0x7f1673a0d660) at stream.c:613
#9 0x00007f16737499fa in daemonStreamHandleWrite (client=0x7f1673a1b1b0, stream=0x7f1673a1ec50) at stream.c:662
#10 0x00007f167374866b in daemonStreamEvent (st=0x7f1673a1a370, events=14, opaque=0x7f1673a1b1b0) at stream.c:138
#11 0x00007f1672b2e17a in virFDStreamEvent (watch=18, fd=17, events=14, opaque=0x7f1673a1a370) at fdstream.c:173
#12 0x00007f1672a2c2cb in virEventPollDispatchHandles (nfds=12, fds=0x7f1673a2fda0) at util/vireventpoll.c:509
#13 0x00007f1672a2cb08 in virEventPollRunOnce () at util/vireventpoll.c:658
#14 0x00007f1672a2a9e0 in virEventRunDefaultImpl () at util/virevent.c:308
#15 0x00007f1672bd25d2 in virNetDaemonRun (dmn=0x7f1673990ed0) at rpc/virnetdaemon.c:707
#16 0x00007f167370cad4 in main (argc=3, argv=0x7ffd63276288) at libvirtd.c:1581
The reason of this problem is that fdstream abort event or close event occured at the same time, libvirtd doesn't deal with the synchronousness well enough. //ÄãÕâÀïÔÏÈÏë±í´ïµÄ¾ßÌåÒâ˼ÊÇ£¿
the flows about fdStream is bellow
1¡¢qemuDomainDefineXMLFlags -> virDomainObjListAdd -> qemuDomainObjPrivateAlloc -> virChrdevAlloc -> virHashCreate
2¡¢qemuDomainOpenConsole -> virChrdevOpen -> virHashAddEntry(devs->hash, path, st)
3¡¢virDomainObjDispose -> privateDataFreeFunc (qemuDomainObjPrivateFree) - > virChrdevFree(*dev locked*) -> virChrdevFreeClearCallbacks - > virFDStreamSetInternalCloseCb(*fdst locked*)
4¡¢virFDStreamCloseInt (*fdst locked*) -> icbFreeOpaque(virChrdevFDStreamCloseCb (*dev locked*)) -> virHashRemoveEntry
The AB lock problem is obviouse: in step 3, it locks chardev before fdst, and in step 4, it's the opsite way.
The reason of libvirtd crash is that: in virFDStreamCloseInt function we set fdst to NULL, while in virFDStreamSetInternalCloseCb we use fdst->lock, note that fdst has already been freed.
another crash problem occurs because that when virChrdevFree was earlier finished, dev->hash freed and all date of hash is freed, but fdstream event flow use fdStream after hash free. Ahha~~£¬ libvirtd coredump.
All of those problem is because clear vm flow and fdStream flow concurs synchronously.
then I fix this problem by modify virChrdevFree()
void virChrdevFree(virChrdevsPtr devs)
{
if (!devs || !devs->hash)
return;
for (;;) {
virMutexLock(&devs->lock);
if (0 == virHashSize(devs->hash)) {
virMutexUnlock(&devs->lock);
break;
}
virMutexUnlock(&devs->lock);
usleep(10 * 1000);
}
virMutexLock(&devs->lock);
virHashFree(devs->hash);
virMutexUnlock(&devs->lock);
virMutexDestroy(&devs->lock);
VIR_FREE(devs);
}
If the chardev is removed by fdStream close or fdStream abort when vm destroy or shutdown, the modification works well. But I'm not sure is that all chardev would be removed when we clear vm, if not, it would always sleep here.
Another solution is as follows:
virMutexLock(vm);
virChrdevFree();
virMutexUnlock(vm);
virMutexLock(vm);
virFDStreamCloseInt();
virMutexUnlock(vm);
I lock vm before calling these 2 functions, which makes them run sequently.
Do you have other better idea to solve this problem. thanks in advance.
Best Regards
David
8 years, 10 months
[libvirt] [PATCH 1/4] rbd: Add wiping RBD volumes by using rbd_discard() or rbd_write()
by Wido den Hollander
This allows user to use the volume wiping functionality of the libvirt
storage driver.
This patch also adds a new wiping algorithm VIR_STORAGE_VOL_WIPE_ALG_DISCARD
By default the VIR_STORAGE_VOL_WIPE_ALG_ZERO algorithm is used and with
RBD this will called rbd_write() in chunks of the underlying object size
to completely zero out the volume.
With VIR_STORAGE_VOL_WIPE_ALG_DISCARD it will call rbd_discard() in the
same object size chunks which will trim/discard all underlying RADOS objects
in the Ceph cluster.
Signed-off-by: Wido den Hollander <wido(a)widodh.nl>
---
include/libvirt/libvirt-storage.h | 4 +
src/storage/storage_backend_rbd.c | 157 +++++++++++++++++++++++++++++++++++++-
tools/virsh-volume.c | 2 +-
3 files changed, 161 insertions(+), 2 deletions(-)
diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h
index 2c55c93..139add3 100644
--- a/include/libvirt/libvirt-storage.h
+++ b/include/libvirt/libvirt-storage.h
@@ -153,6 +153,10 @@ typedef enum {
VIR_STORAGE_VOL_WIPE_ALG_RANDOM = 8, /* 1-pass random */
+ VIR_STORAGE_VOL_WIPE_ALG_DISCARD = 9, /* 1-pass, discard all data on the
+ volume by using TRIM or
+ DISCARD */
+
# ifdef VIR_ENUM_SENTINELS
VIR_STORAGE_VOL_WIPE_ALG_LAST
/*
diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
index e20a54d..c0001d0 100644
--- a/src/storage/storage_backend_rbd.c
+++ b/src/storage/storage_backend_rbd.c
@@ -32,6 +32,7 @@
#include "base64.h"
#include "viruuid.h"
#include "virstring.h"
+#include "virutil.h"
#include "rados/librados.h"
#include "rbd/librbd.h"
@@ -730,6 +731,159 @@ static int virStorageBackendRBDResizeVol(virConnectPtr conn ATTRIBUTE_UNUSED,
return ret;
}
+static int virStorageBackendRBDVolWipeZero(rbd_image_t image,
+ char *imgname,
+ rbd_image_info_t info,
+ uint64_t stripe_count)
+{
+ int r = -1;
+ size_t offset = 0;
+ uint64_t length;
+ char *writebuf;
+
+ if (VIR_ALLOC_N(writebuf, info.obj_size * stripe_count) < 0)
+ goto cleanup;
+
+ while (offset < info.size) {
+ length = MIN((info.size - offset), (info.obj_size * stripe_count));
+
+ r = rbd_write(image, offset, length, writebuf);
+ if (r < 0) {
+ virReportSystemError(-r, _("writing %llu bytes failed on "
+ " RBD image %s at offset %llu"),
+ (unsigned long long)length,
+ imgname,
+ (unsigned long long)offset);
+ goto cleanup;
+ }
+
+ VIR_DEBUG("Wrote %llu bytes to RBD image %s at offset %llu",
+ (unsigned long long)length,
+ imgname, (unsigned long long)offset);
+
+ offset += length;
+ }
+
+ cleanup:
+ VIR_FREE(writebuf);
+
+ return r;
+}
+
+static int virStorageBackendRBDVolWipeDiscard(rbd_image_t image,
+ char *imgname,
+ rbd_image_info_t info,
+ uint64_t stripe_count)
+{
+ int r = -1;
+ size_t offset = 0;
+ uint64_t length;
+
+ VIR_DEBUG("Wiping RBD %s volume using discard)", imgname);
+
+ while (offset < info.size) {
+ length = MIN((info.size - offset), (info.obj_size * stripe_count));
+
+ r = rbd_discard(image, offset, length);
+ if (r < 0) {
+ virReportSystemError(-r, _("discarding %llu bytes failed on "
+ " RBD image %s at offset %llu"),
+ (unsigned long long)length,
+ imgname,
+ (unsigned long long)offset);
+ goto cleanup;
+ }
+
+ VIR_DEBUG("Discarded %llu bytes of RBD image %s at offset %llu",
+ (unsigned long long)length,
+ imgname, (unsigned long long)offset);
+
+ offset += length;
+ }
+
+ cleanup:
+ return r;
+}
+
+static int virStorageBackendRBDVolWipe(virConnectPtr conn,
+ virStoragePoolObjPtr pool,
+ virStorageVolDefPtr vol,
+ unsigned int algorithm,
+ unsigned int flags)
+{
+ virStorageBackendRBDState ptr;
+ ptr.cluster = NULL;
+ ptr.ioctx = NULL;
+ rbd_image_t image = NULL;
+ rbd_image_info_t info;
+ uint64_t stripe_count;
+ int r = -1;
+
+ virCheckFlags(VIR_STORAGE_VOL_WIPE_ALG_ZERO |
+ VIR_STORAGE_VOL_WIPE_ALG_DISCARD, -1);
+
+ VIR_DEBUG("Wiping RBD image %s/%s", pool->def->source.name, vol->name);
+
+ if (virStorageBackendRBDOpenRADOSConn(&ptr, conn, &pool->def->source) < 0)
+ goto cleanup;
+
+ if (virStorageBackendRBDOpenIoCTX(&ptr, pool) < 0)
+ goto cleanup;
+
+ r = rbd_open(ptr.ioctx, vol->name, &image, NULL);
+ if (r < 0) {
+ virReportSystemError(-r, _("failed to open the RBD image %s"),
+ vol->name);
+ goto cleanup;
+ }
+
+ r = rbd_stat(image, &info, sizeof(info));
+ if (r < 0) {
+ virReportSystemError(-r, _("failed to stat the RBD image %s"),
+ vol->name);
+ goto cleanup;
+ }
+
+ r = rbd_get_stripe_count(image, &stripe_count);
+ if (r < 0) {
+ virReportSystemError(-r, _("failed to get stripe count of RBD image %s"),
+ vol->name);
+ goto cleanup;
+ }
+
+ VIR_DEBUG("Need to wipe %llu bytes from RBD image %s/%s",
+ (unsigned long long)info.size, pool->def->source.name, vol->name);
+
+ switch (algorithm) {
+ case VIR_STORAGE_VOL_WIPE_ALG_ZERO:
+ r = virStorageBackendRBDVolWipeZero(image, vol->name,
+ info, stripe_count);
+ break;
+ case VIR_STORAGE_VOL_WIPE_ALG_DISCARD:
+ r = virStorageBackendRBDVolWipeDiscard(image, vol->name,
+ info, stripe_count);
+ break;
+ default:
+ virReportError(VIR_ERR_INVALID_ARG, _("unsupported algorithm %d"),
+ algorithm);
+ r = -VIR_ERR_INVALID_ARG;
+ goto cleanup;
+ }
+
+ if (r < 0) {
+ virReportSystemError(-r, _("failed to wipe RBD image %s"),
+ vol->name);
+ goto cleanup;
+ }
+
+ cleanup:
+ if (image)
+ rbd_close(image);
+
+ virStorageBackendRBDCloseRADOSConn(&ptr);
+ return r;
+}
+
virStorageBackend virStorageBackendRBD = {
.type = VIR_STORAGE_POOL_RBD,
@@ -738,5 +892,6 @@ virStorageBackend virStorageBackendRBD = {
.buildVol = virStorageBackendRBDBuildVol,
.refreshVol = virStorageBackendRBDRefreshVol,
.deleteVol = virStorageBackendRBDDeleteVol,
- .resizeVol = virStorageBackendRBDResizeVol,
+ .wipeVol = virStorageBackendRBDVolWipe,
+ .resizeVol = virStorageBackendRBDResizeVol
};
diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c
index 661c876..f86980f 100644
--- a/tools/virsh-volume.c
+++ b/tools/virsh-volume.c
@@ -906,7 +906,7 @@ static const vshCmdOptDef opts_vol_wipe[] = {
VIR_ENUM_DECL(virStorageVolWipeAlgorithm)
VIR_ENUM_IMPL(virStorageVolWipeAlgorithm, VIR_STORAGE_VOL_WIPE_ALG_LAST,
"zero", "nnsa", "dod", "bsi", "gutmann", "schneier",
- "pfitzner7", "pfitzner33", "random");
+ "pfitzner7", "pfitzner33", "random", "discard");
static bool
cmdVolWipe(vshControl *ctl, const vshCmd *cmd)
--
1.9.1
8 years, 10 months
[libvirt] [PATCH LIBVIRT v3] libxl: Support cmdline= in xl config files
by Ian Campbell
... and consolidate the cmdline/extra/root parsing to facilitate doing
so.
The logic is the same as xl's parse_cmdline from the current xen.git master
branch (e6f0e099d2c17de47fd86e817b1998db903cab61).
On the formatting side switch to producing cmdline= instead of extra=.
Update a few tests and add serveral more.
- test-cmdline is added to test the exclusive use of cmdline.
- test-fullvirt-direct-kernel-boot.cfg is updated due to the switch
on the formatting side and now tests the exclusive use of cmdline=.
- Tests are added for both paravirt and fullvirt where the .cfg uses
extra= and (paravirt only) root=. These are format (xl->xml) only
since the inverse will generate cmdline= hence is not a round trip
(which was already true if using root=, which used to generate
extra= on the way back).
- Tests are added for both paravirt and fullvirt where the .cfg
declares cmdline= as well as bogus extra= and (paravirt only) root=
entries which should be ignored. Again these are format only tests
since the inverse won't include the bogus lines.
The last two bullets here required splitting the DO_TEST macro into
two halves, as is done in the xmconfigtest.c case.
In order to introduce a use of VIR_WARN for logging I had to add
virerror.h and VIR_LOG_INIT.
Signed-off-by: Ian Campbell <ian.campbell(a)citrix.com>
---
v2: Use VIR_INFO (adding necessary infra)
Don't initialise things to NULL when there is no need.
v3: I know know the answer re VIR_FROM_THIS, because Jim fixed it.
Initialise cmdline to NULL, since neither I nor gcc were smart
enough to spot the uninitialised path I did this in preference to
adding the else case, since that apparently won't be masking the
compiler's ability to spot uninitialised vars in this function.
Add tests
Addjust xenFormatXLOS to produce cmdline= instead of extra=.
---
src/xenconfig/xen_xl.c | 70 +++++++++++++---------
...est-fullvirt-direct-kernel-boot-bogus-extra.cfg | 31 ++++++++++
...est-fullvirt-direct-kernel-boot-bogus-extra.xml | 51 ++++++++++++++++
.../test-fullvirt-direct-kernel-boot-extra.cfg | 30 ++++++++++
.../test-fullvirt-direct-kernel-boot-extra.xml | 51 ++++++++++++++++
.../test-fullvirt-direct-kernel-boot.cfg | 2 +-
.../test-paravirt-cmdline-bogus-extra-root.cfg | 13 ++++
.../test-paravirt-cmdline-bogus-extra-root.xml | 32 ++++++++++
.../test-paravirt-cmdline-extra-root.cfg | 15 +++++
.../test-paravirt-cmdline-extra-root.xml | 32 ++++++++++
tests/xlconfigdata/test-paravirt-cmdline.cfg | 14 +++++
tests/xlconfigdata/test-paravirt-cmdline.xml | 32 ++++++++++
tests/xlconfigtest.c | 24 ++++++--
13 files changed, 365 insertions(+), 32 deletions(-)
create mode 100644 tests/xlconfigdata/test-fullvirt-direct-kernel-boot-bogus-extra.cfg
create mode 100644 tests/xlconfigdata/test-fullvirt-direct-kernel-boot-bogus-extra.xml
create mode 100644 tests/xlconfigdata/test-fullvirt-direct-kernel-boot-extra.cfg
create mode 100644 tests/xlconfigdata/test-fullvirt-direct-kernel-boot-extra.xml
create mode 100644 tests/xlconfigdata/test-paravirt-cmdline-bogus-extra-root.cfg
create mode 100644 tests/xlconfigdata/test-paravirt-cmdline-bogus-extra-root.xml
create mode 100644 tests/xlconfigdata/test-paravirt-cmdline-extra-root.cfg
create mode 100644 tests/xlconfigdata/test-paravirt-cmdline-extra-root.xml
create mode 100644 tests/xlconfigdata/test-paravirt-cmdline.cfg
create mode 100644 tests/xlconfigdata/test-paravirt-cmdline.xml
diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c
index 026cbcc..be194e3 100644
--- a/src/xenconfig/xen_xl.c
+++ b/src/xenconfig/xen_xl.c
@@ -27,6 +27,7 @@
#include "virconf.h"
#include "virerror.h"
+#include "virlog.h"
#include "domain_conf.h"
#include "viralloc.h"
#include "virstring.h"
@@ -35,6 +36,8 @@
#define VIR_FROM_THIS VIR_FROM_XENXL
+VIR_LOG_INIT("xen.xen_xl");
+
/*
* Xen provides a libxl utility library, with several useful functions,
* specifically xlu_disk_parse for parsing xl disk config strings.
@@ -58,11 +61,46 @@ extern int xlu_disk_parse(XLU_Config *cfg,
libxl_device_disk *disk);
#endif
+static int xenParseCmdline(virConfPtr conf, char **r_cmdline)
+{
+ char *cmdline = NULL;
+ const char *root, *extra, *buf;
+
+ if (xenConfigGetString(conf, "cmdline", &buf, NULL) < 0)
+ return -1;
+
+ if (xenConfigGetString(conf, "root", &root, NULL) < 0)
+ return -1;
+
+ if (xenConfigGetString(conf, "extra", &extra, NULL) < 0)
+ return -1;
+
+ if (buf) {
+ if (VIR_STRDUP(cmdline, buf) < 0)
+ return -1;
+ if (root || extra)
+ VIR_WARN("ignoring root= and extra= in favour of cmdline=");
+ } else {
+ if (root && extra) {
+ if (virAsprintf(&cmdline, "root=%s %s", root, extra) < 0)
+ return -1;
+ } else if (root) {
+ if (virAsprintf(&cmdline, "root=%s", root) < 0)
+ return -1;
+ } else if (extra) {
+ if (VIR_STRDUP(cmdline, extra) < 0)
+ return -1;
+ }
+ }
+
+ *r_cmdline = cmdline;
+ return 0;
+}
+
static int
xenParseXLOS(virConfPtr conf, virDomainDefPtr def, virCapsPtr caps)
{
size_t i;
- const char *extra, *root;
if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) {
const char *boot;
@@ -84,19 +122,8 @@ xenParseXLOS(virConfPtr conf, virDomainDefPtr def, virCapsPtr caps)
if (xenConfigCopyStringOpt(conf, "ramdisk", &def->os.initrd) < 0)
return -1;
- if (xenConfigGetString(conf, "extra", &extra, NULL) < 0)
- return -1;
-
- if (xenConfigGetString(conf, "root", &root, NULL) < 0)
+ if (xenParseCmdline(conf, &def->os.cmdline) < 0)
return -1;
-
- if (root) {
- if (virAsprintf(&def->os.cmdline, "root=%s %s", root, extra) < 0)
- return -1;
- } else {
- if (VIR_STRDUP(def->os.cmdline, extra) < 0)
- return -1;
- }
#endif
if (xenConfigGetString(conf, "boot", &boot, "c") < 0)
@@ -132,19 +159,8 @@ xenParseXLOS(virConfPtr conf, virDomainDefPtr def, virCapsPtr caps)
if (xenConfigCopyStringOpt(conf, "ramdisk", &def->os.initrd) < 0)
return -1;
- if (xenConfigGetString(conf, "extra", &extra, NULL) < 0)
- return -1;
-
- if (xenConfigGetString(conf, "root", &root, NULL) < 0)
+ if (xenParseCmdline(conf, &def->os.cmdline) < 0)
return -1;
-
- if (root) {
- if (virAsprintf(&def->os.cmdline, "root=%s %s", root, extra) < 0)
- return -1;
- } else {
- if (VIR_STRDUP(def->os.cmdline, extra) < 0)
- return -1;
- }
}
return 0;
@@ -503,7 +519,7 @@ xenFormatXLOS(virConfPtr conf, virDomainDefPtr def)
return -1;
if (def->os.cmdline &&
- xenConfigSetString(conf, "extra", def->os.cmdline) < 0)
+ xenConfigSetString(conf, "cmdline", def->os.cmdline) < 0)
return -1;
#endif
@@ -554,7 +570,7 @@ xenFormatXLOS(virConfPtr conf, virDomainDefPtr def)
return -1;
if (def->os.cmdline &&
- xenConfigSetString(conf, "extra", def->os.cmdline) < 0)
+ xenConfigSetString(conf, "cmdline", def->os.cmdline) < 0)
return -1;
} /* !hvm */
diff --git a/tests/xlconfigdata/test-fullvirt-direct-kernel-boot-bogus-extra.cfg b/tests/xlconfigdata/test-fullvirt-direct-kernel-boot-bogus-extra.cfg
new file mode 100644
index 0000000..83ab975
--- /dev/null
+++ b/tests/xlconfigdata/test-fullvirt-direct-kernel-boot-bogus-extra.cfg
@@ -0,0 +1,31 @@
+name = "XenGuest2"
+uuid = "c7a5fdb2-cdaf-9455-926a-d65c16db1809"
+maxmem = 579
+memory = 394
+vcpus = 1
+pae = 1
+acpi = 1
+apic = 1
+hap = 0
+viridian = 0
+rtc_timeoffset = 0
+localtime = 0
+on_poweroff = "destroy"
+on_reboot = "restart"
+on_crash = "restart"
+device_model = "/usr/lib/xen/bin/qemu-system-i386"
+sdl = 0
+vnc = 1
+vncunused = 1
+vnclisten = "127.0.0.1"
+vncpasswd = "123poi"
+vif = [ "mac=00:16:3e:66:92:9c,bridge=xenbr1,script=vif-bridge,model=e1000" ]
+parallel = "none"
+serial = "none"
+builder = "hvm"
+kernel = "/tmp/vmlinuz"
+ramdisk = "/tmp/initrd"
+cmdline = "ignore_loglvl"
+extra = "SHOULD BE IGNORED"
+boot = "d"
+disk = [ "/dev/HostVG/XenGuest2,raw,hda,w,backendtype=phy", "/root/boot.iso,raw,hdc,r,backendtype=qdisk,devtype=cdrom" ]
diff --git a/tests/xlconfigdata/test-fullvirt-direct-kernel-boot-bogus-extra.xml b/tests/xlconfigdata/test-fullvirt-direct-kernel-boot-bogus-extra.xml
new file mode 100644
index 0000000..f750e02
--- /dev/null
+++ b/tests/xlconfigdata/test-fullvirt-direct-kernel-boot-bogus-extra.xml
@@ -0,0 +1,51 @@
+<domain type='xen'>
+ <name>XenGuest2</name>
+ <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>592896</memory>
+ <currentMemory unit='KiB'>403456</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='xenfv'>hvm</type>
+ <loader type='rom'>/usr/lib/xen/boot/hvmloader</loader>
+ <kernel>/tmp/vmlinuz</kernel>
+ <initrd>/tmp/initrd</initrd>
+ <cmdline>ignore_loglvl</cmdline>
+ <boot dev='cdrom'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <clock offset='variable' adjustment='0' basis='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/lib/xen/bin/qemu-system-i386</emulator>
+ <disk type='block' device='disk'>
+ <driver name='phy' type='raw'/>
+ <source dev='/dev/HostVG/XenGuest2'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source file='/root/boot.iso'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ <address type='drive' controller='0' bus='1' target='0' unit='0'/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='00:16:3e:66:92:9c'/>
+ <source bridge='xenbr1'/>
+ <script path='vif-bridge'/>
+ <model type='e1000'/>
+ </interface>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1'/>
+ </graphics>
+ </devices>
+</domain>
diff --git a/tests/xlconfigdata/test-fullvirt-direct-kernel-boot-extra.cfg b/tests/xlconfigdata/test-fullvirt-direct-kernel-boot-extra.cfg
new file mode 100644
index 0000000..f452af6
--- /dev/null
+++ b/tests/xlconfigdata/test-fullvirt-direct-kernel-boot-extra.cfg
@@ -0,0 +1,30 @@
+name = "XenGuest2"
+uuid = "c7a5fdb2-cdaf-9455-926a-d65c16db1809"
+maxmem = 579
+memory = 394
+vcpus = 1
+pae = 1
+acpi = 1
+apic = 1
+hap = 0
+viridian = 0
+rtc_timeoffset = 0
+localtime = 0
+on_poweroff = "destroy"
+on_reboot = "restart"
+on_crash = "restart"
+device_model = "/usr/lib/xen/bin/qemu-system-i386"
+sdl = 0
+vnc = 1
+vncunused = 1
+vnclisten = "127.0.0.1"
+vncpasswd = "123poi"
+vif = [ "mac=00:16:3e:66:92:9c,bridge=xenbr1,script=vif-bridge,model=e1000" ]
+parallel = "none"
+serial = "none"
+builder = "hvm"
+kernel = "/tmp/vmlinuz"
+ramdisk = "/tmp/initrd"
+extra = "ignore_loglvl"
+boot = "d"
+disk = [ "/dev/HostVG/XenGuest2,raw,hda,w,backendtype=phy", "/root/boot.iso,raw,hdc,r,backendtype=qdisk,devtype=cdrom" ]
diff --git a/tests/xlconfigdata/test-fullvirt-direct-kernel-boot-extra.xml b/tests/xlconfigdata/test-fullvirt-direct-kernel-boot-extra.xml
new file mode 100644
index 0000000..f750e02
--- /dev/null
+++ b/tests/xlconfigdata/test-fullvirt-direct-kernel-boot-extra.xml
@@ -0,0 +1,51 @@
+<domain type='xen'>
+ <name>XenGuest2</name>
+ <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>592896</memory>
+ <currentMemory unit='KiB'>403456</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='xenfv'>hvm</type>
+ <loader type='rom'>/usr/lib/xen/boot/hvmloader</loader>
+ <kernel>/tmp/vmlinuz</kernel>
+ <initrd>/tmp/initrd</initrd>
+ <cmdline>ignore_loglvl</cmdline>
+ <boot dev='cdrom'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <clock offset='variable' adjustment='0' basis='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/lib/xen/bin/qemu-system-i386</emulator>
+ <disk type='block' device='disk'>
+ <driver name='phy' type='raw'/>
+ <source dev='/dev/HostVG/XenGuest2'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source file='/root/boot.iso'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ <address type='drive' controller='0' bus='1' target='0' unit='0'/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='00:16:3e:66:92:9c'/>
+ <source bridge='xenbr1'/>
+ <script path='vif-bridge'/>
+ <model type='e1000'/>
+ </interface>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1'/>
+ </graphics>
+ </devices>
+</domain>
diff --git a/tests/xlconfigdata/test-fullvirt-direct-kernel-boot.cfg b/tests/xlconfigdata/test-fullvirt-direct-kernel-boot.cfg
index f452af6..32b08e1 100644
--- a/tests/xlconfigdata/test-fullvirt-direct-kernel-boot.cfg
+++ b/tests/xlconfigdata/test-fullvirt-direct-kernel-boot.cfg
@@ -25,6 +25,6 @@ serial = "none"
builder = "hvm"
kernel = "/tmp/vmlinuz"
ramdisk = "/tmp/initrd"
-extra = "ignore_loglvl"
+cmdline = "ignore_loglvl"
boot = "d"
disk = [ "/dev/HostVG/XenGuest2,raw,hda,w,backendtype=phy", "/root/boot.iso,raw,hdc,r,backendtype=qdisk,devtype=cdrom" ]
diff --git a/tests/xlconfigdata/test-paravirt-cmdline-bogus-extra-root.cfg b/tests/xlconfigdata/test-paravirt-cmdline-bogus-extra-root.cfg
new file mode 100644
index 0000000..c5b25af
--- /dev/null
+++ b/tests/xlconfigdata/test-paravirt-cmdline-bogus-extra-root.cfg
@@ -0,0 +1,13 @@
+localtime = 0
+name = "XenGuest2"
+uuid = "c7a5fdb2-cdaf-9455-926a-d65c16db1809"
+maxmem = 579
+memory = 394
+vcpus = 1
+vif = [ "mac=00:16:3e:66:92:9c,bridge=xenbr1,script=vif-bridge" ]
+kernel = "/tmp/vmlinuz"
+ramdisk = "/tmp/initrd"
+cmdline = "root=/dev/xvda1 console=hvc0"
+extra = "SHOULD BE IGNORED"
+root = "SHOULD BE IGNORED"
+disk = [ "/dev/HostVG/XenGuest2,raw,xvda,w" ]
diff --git a/tests/xlconfigdata/test-paravirt-cmdline-bogus-extra-root.xml b/tests/xlconfigdata/test-paravirt-cmdline-bogus-extra-root.xml
new file mode 100644
index 0000000..f4ab9e6
--- /dev/null
+++ b/tests/xlconfigdata/test-paravirt-cmdline-bogus-extra-root.xml
@@ -0,0 +1,32 @@
+<domain type='xen'>
+ <name>XenGuest2</name>
+ <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>592896</memory>
+ <currentMemory unit='KiB'>403456</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='xenpv'>linux</type>
+ <kernel>/tmp/vmlinuz</kernel>
+ <initrd>/tmp/initrd</initrd>
+ <cmdline>root=/dev/xvda1 console=hvc0</cmdline>
+ </os>
+ <clock offset='utc' adjustment='reset'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/dev/HostVG/XenGuest2'/>
+ <target dev='xvda' bus='xen'/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='00:16:3e:66:92:9c'/>
+ <source bridge='xenbr1'/>
+ <script path='vif-bridge'/>
+ </interface>
+ <console type='pty'>
+ <target type='xen' port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/xlconfigdata/test-paravirt-cmdline-extra-root.cfg b/tests/xlconfigdata/test-paravirt-cmdline-extra-root.cfg
new file mode 100644
index 0000000..d0c503b
--- /dev/null
+++ b/tests/xlconfigdata/test-paravirt-cmdline-extra-root.cfg
@@ -0,0 +1,15 @@
+name = "XenGuest2"
+uuid = "c7a5fdb2-cdaf-9455-926a-d65c16db1809"
+maxmem = 579
+memory = 394
+vcpus = 1
+localtime = 0
+on_poweroff = "destroy"
+on_reboot = "restart"
+on_crash = "restart"
+vif = [ "mac=00:16:3e:66:92:9c,bridge=xenbr1,script=vif-bridge" ]
+kernel = "/tmp/vmlinuz"
+ramdisk = "/tmp/initrd"
+root = "/dev/xvda1"
+extra = "console=hvc0"
+disk = [ "/dev/HostVG/XenGuest2,raw,xvda,w,backendtype=qdisk" ]
diff --git a/tests/xlconfigdata/test-paravirt-cmdline-extra-root.xml b/tests/xlconfigdata/test-paravirt-cmdline-extra-root.xml
new file mode 100644
index 0000000..f4ab9e6
--- /dev/null
+++ b/tests/xlconfigdata/test-paravirt-cmdline-extra-root.xml
@@ -0,0 +1,32 @@
+<domain type='xen'>
+ <name>XenGuest2</name>
+ <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>592896</memory>
+ <currentMemory unit='KiB'>403456</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='xenpv'>linux</type>
+ <kernel>/tmp/vmlinuz</kernel>
+ <initrd>/tmp/initrd</initrd>
+ <cmdline>root=/dev/xvda1 console=hvc0</cmdline>
+ </os>
+ <clock offset='utc' adjustment='reset'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/dev/HostVG/XenGuest2'/>
+ <target dev='xvda' bus='xen'/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='00:16:3e:66:92:9c'/>
+ <source bridge='xenbr1'/>
+ <script path='vif-bridge'/>
+ </interface>
+ <console type='pty'>
+ <target type='xen' port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/xlconfigdata/test-paravirt-cmdline.cfg b/tests/xlconfigdata/test-paravirt-cmdline.cfg
new file mode 100644
index 0000000..c512a05
--- /dev/null
+++ b/tests/xlconfigdata/test-paravirt-cmdline.cfg
@@ -0,0 +1,14 @@
+name = "XenGuest2"
+uuid = "c7a5fdb2-cdaf-9455-926a-d65c16db1809"
+maxmem = 579
+memory = 394
+vcpus = 1
+localtime = 0
+on_poweroff = "destroy"
+on_reboot = "restart"
+on_crash = "restart"
+vif = [ "mac=00:16:3e:66:92:9c,bridge=xenbr1,script=vif-bridge" ]
+kernel = "/tmp/vmlinuz"
+ramdisk = "/tmp/initrd"
+cmdline = "root=/dev/xvda1 console=hvc0"
+disk = [ "/dev/HostVG/XenGuest2,raw,xvda,w,backendtype=qdisk" ]
diff --git a/tests/xlconfigdata/test-paravirt-cmdline.xml b/tests/xlconfigdata/test-paravirt-cmdline.xml
new file mode 100644
index 0000000..f4ab9e6
--- /dev/null
+++ b/tests/xlconfigdata/test-paravirt-cmdline.xml
@@ -0,0 +1,32 @@
+<domain type='xen'>
+ <name>XenGuest2</name>
+ <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>592896</memory>
+ <currentMemory unit='KiB'>403456</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='xenpv'>linux</type>
+ <kernel>/tmp/vmlinuz</kernel>
+ <initrd>/tmp/initrd</initrd>
+ <cmdline>root=/dev/xvda1 console=hvc0</cmdline>
+ </os>
+ <clock offset='utc' adjustment='reset'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/dev/HostVG/XenGuest2'/>
+ <target dev='xvda' bus='xen'/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='00:16:3e:66:92:9c'/>
+ <source bridge='xenbr1'/>
+ <script path='vif-bridge'/>
+ </interface>
+ <console type='pty'>
+ <target type='xen' port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/xlconfigtest.c b/tests/xlconfigtest.c
index e997009..bad69ca 100644
--- a/tests/xlconfigtest.c
+++ b/tests/xlconfigtest.c
@@ -180,29 +180,45 @@ mymain(void)
if (!(xmlopt = libxlCreateXMLConf()))
return EXIT_FAILURE;
-#define DO_TEST(name) \
+#define DO_TEST_PARSE(name) \
do { \
struct testInfo info0 = { name, 0 }; \
- struct testInfo info1 = { name, 1 }; \
- if (virtTestRun("Xen XM-2-XML Parse " name, \
+ if (virtTestRun("Xen XL-2-XML Parse " name, \
testCompareHelper, &info0) < 0) \
ret = -1; \
- if (virtTestRun("Xen XM-2-XML Format " name, \
+ } while (0)
+
+#define DO_TEST_FORMAT(name) \
+ do { \
+ struct testInfo info1 = { name, 1 }; \
+ if (virtTestRun("Xen XL-2-XML Format " name, \
testCompareHelper, &info1) < 0) \
ret = -1; \
} while (0)
+#define DO_TEST(name) \
+ do { \
+ DO_TEST_PARSE(name); \
+ DO_TEST_FORMAT(name); \
+ } while (0)
+
DO_TEST("paravirt-maxvcpus");
DO_TEST("new-disk");
DO_TEST("spice");
DO_TEST("spice-features");
DO_TEST("vif-rate");
+ DO_TEST("paravirt-cmdline");
+ DO_TEST_FORMAT("paravirt-cmdline-extra-root");
+ DO_TEST_FORMAT("paravirt-cmdline-bogus-extra-root");
+
#ifdef LIBXL_HAVE_BUILDINFO_USBDEVICE_LIST
DO_TEST("fullvirt-multiusb");
#endif
#ifdef LIBXL_HAVE_BUILDINFO_KERNEL
DO_TEST("fullvirt-direct-kernel-boot");
+ DO_TEST_FORMAT("fullvirt-direct-kernel-boot-extra");
+ DO_TEST_FORMAT("fullvirt-direct-kernel-boot-bogus-extra");
#endif
virObjectUnref(caps);
--
2.1.4
8 years, 10 months
[libvirt] [PATCH v2] libxl: dispose libxl_dominfo after libxl_domain_info()
by Joao Martins
As suggested in a previous thread [0] this patch adds some missing calls
to libxl_dominfo_{init,dispose} when doing some of the libxl_domain_info
operations which would otherwise lead to memory leaks.
[0]
https://www.redhat.com/archives/libvir-list/2015-September/msg00519.html
Signed-off-by: Joao Martins <joao.m.martins(a)oracle.com>
---
Changes since v1:
- Add missing libxl_dominfo_init() on MemoryStats and GetInfo()
---
src/libxl/libxl_driver.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 73ed448..560f2a6 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -358,6 +358,8 @@ libxlReconnectDomain(virDomainObjPtr vm,
virObjectLock(vm);
+ libxl_dominfo_init(&d_info);
+
/* Does domain still exist? */
rc = libxl_domain_info(cfg->ctx, &d_info, vm->def->id);
if (rc == ERROR_INVAL) {
@@ -389,11 +391,13 @@ libxlReconnectDomain(virDomainObjPtr vm,
/* Enable domain death events */
libxl_evenable_domain_death(cfg->ctx, vm->def->id, 0, &priv->deathW);
+ libxl_dominfo_dispose(&d_info);
virObjectUnlock(vm);
virObjectUnref(cfg);
return 0;
out:
+ libxl_dominfo_dispose(&d_info);
libxlDomainCleanup(driver, vm);
if (!vm->persistent)
virDomainObjListRemoveLocked(driver->domains, vm);
@@ -1589,6 +1593,8 @@ libxlDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
info->memory = vm->def->mem.cur_balloon;
info->maxMem = virDomainDefGetMemoryActual(vm->def);
} else {
+ libxl_dominfo_init(&d_info);
+
if (libxl_domain_info(cfg->ctx, &d_info, vm->def->id) != 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("libxl_domain_info failed for domain '%d'"),
@@ -1598,6 +1604,8 @@ libxlDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
info->cpuTime = d_info.cpu_time;
info->memory = d_info.current_memkb;
info->maxMem = d_info.max_memkb;
+
+ libxl_dominfo_dispose(&d_info);
}
info->state = virDomainObjGetState(vm, NULL);
@@ -4791,6 +4799,7 @@ libxlDomainMemoryStats(virDomainPtr dom,
virCheckFlags(0, -1);
+ libxl_dominfo_init(&d_info);
cfg = libxlDriverConfigGet(driver);
if (!(vm = libxlDomObjFromDomain(dom)))
@@ -4822,13 +4831,12 @@ libxlDomainMemoryStats(virDomainPtr dom,
ret = i;
- libxl_dominfo_dispose(&d_info);
-
endjob:
if (!libxlDomainObjEndJob(driver, vm))
vm = NULL;
cleanup:
+ libxl_dominfo_dispose(&d_info);
if (vm)
virObjectUnlock(vm);
virObjectUnref(cfg);
--
2.1.4
8 years, 10 months
[libvirt] [PATCH 0/2] Xen: cleanup use of virErrorDomain enum
by Jim Fehlig
While reviewing a patch from Ian Campbell, I noticed the various
Xen-related elements in the virErrorDomain enum were not used
correctly throughout the corresponding source files.
Patch 1 fixes use of existing Xen-related elements in virErrorDomain.
Patch 2 adds a new element for Xen XL config and uses it in
src/xenconfig/xen_xl.c.
Jim Fehlig (2):
Xen: VIR_FROM_THIS cleanup
Xen: add XENXL to virErrorDomain enum
include/libvirt/virterror.h | 1 +
src/util/virerror.c | 1 +
src/xen/xs_internal.c | 2 +-
src/xenconfig/xen_common.c | 1 +
src/xenconfig/xen_sxpr.c | 2 ++
src/xenconfig/xen_xl.c | 2 +-
src/xenconfig/xen_xm.c | 1 +
src/xenconfig/xenxs_private.h | 2 --
8 files changed, 8 insertions(+), 4 deletions(-)
--
2.6.1
8 years, 10 months
[libvirt] [PATCH LIBVIRT v2] libxl: Support cmdline= in xl config files
by Ian Campbell
... and consolidate the cmdline/extra/root parsing to facilitate doing
so.
The logic is the same as xl's parse_cmdline from the current xen.git master
branch (e6f0e099d2c17de47fd86e817b1998db903cab61).
In order to introduce a use of VIR_WARN for logging I had to add
virerror.h and VIR_LOG_INIT.
Signed-off-by: Ian Campbell <ian.campbell(a)citrix.com>
---
NB: I was unsure if I was supposed to change VIR_FROM_NONE into
VIR_FROM_XEN, so I didn't (but will on advice).
v2: Use VIR_INFO (adding necessary infra)
Don't initialise things to NULL when there is no need.
---
src/xenconfig/xen_xl.c | 66 +++++++++++++++++++++++++++++++-------------------
1 file changed, 41 insertions(+), 25 deletions(-)
diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c
index 91cdff6..3d820cc 100644
--- a/src/xenconfig/xen_xl.c
+++ b/src/xenconfig/xen_xl.c
@@ -27,6 +27,7 @@
#include "virconf.h"
#include "virerror.h"
+#include "virlog.h"
#include "domain_conf.h"
#include "viralloc.h"
#include "virstring.h"
@@ -35,6 +36,8 @@
#define VIR_FROM_THIS VIR_FROM_NONE
+VIR_LOG_INIT("xen.xen_xl");
+
/*
* Xen provides a libxl utility library, with several useful functions,
* specifically xlu_disk_parse for parsing xl disk config strings.
@@ -58,11 +61,46 @@ extern int xlu_disk_parse(XLU_Config *cfg,
libxl_device_disk *disk);
#endif
+static int xenParseCmdline(virConfPtr conf, char **r_cmdline)
+{
+ char *cmdline;
+ const char *root, *extra, *buf;
+
+ if (xenConfigGetString(conf, "cmdline", &buf, NULL) < 0)
+ return -1;
+
+ if (xenConfigGetString(conf, "root", &root, NULL) < 0)
+ return -1;
+
+ if (xenConfigGetString(conf, "extra", &extra, NULL) < 0)
+ return -1;
+
+ if (buf) {
+ if (VIR_STRDUP(cmdline, buf) < 0)
+ return -1;
+ if (root || extra)
+ VIR_WARN("ignoring root= and extra= in favour of cmdline=");
+ } else {
+ if (root && extra) {
+ if (virAsprintf(&cmdline, "root=%s %s", root, extra) < 0)
+ return -1;
+ } else if (root) {
+ if (virAsprintf(&cmdline, "root=%s", root) < 0)
+ return -1;
+ } else if (extra) {
+ if (VIR_STRDUP(cmdline, extra) < 0)
+ return -1;
+ }
+ }
+
+ *r_cmdline = cmdline;
+ return 0;
+}
+
static int
xenParseXLOS(virConfPtr conf, virDomainDefPtr def, virCapsPtr caps)
{
size_t i;
- const char *extra, *root;
if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) {
const char *boot;
@@ -84,19 +122,8 @@ xenParseXLOS(virConfPtr conf, virDomainDefPtr def, virCapsPtr caps)
if (xenConfigCopyStringOpt(conf, "ramdisk", &def->os.initrd) < 0)
return -1;
- if (xenConfigGetString(conf, "extra", &extra, NULL) < 0)
- return -1;
-
- if (xenConfigGetString(conf, "root", &root, NULL) < 0)
+ if (xenParseCmdline(conf, &def->os.cmdline) < 0)
return -1;
-
- if (root) {
- if (virAsprintf(&def->os.cmdline, "root=%s %s", root, extra) < 0)
- return -1;
- } else {
- if (VIR_STRDUP(def->os.cmdline, extra) < 0)
- return -1;
- }
#endif
if (xenConfigGetString(conf, "boot", &boot, "c") < 0)
@@ -132,19 +159,8 @@ xenParseXLOS(virConfPtr conf, virDomainDefPtr def, virCapsPtr caps)
if (xenConfigCopyStringOpt(conf, "ramdisk", &def->os.initrd) < 0)
return -1;
- if (xenConfigGetString(conf, "extra", &extra, NULL) < 0)
- return -1;
-
- if (xenConfigGetString(conf, "root", &root, NULL) < 0)
+ if (xenParseCmdline(conf, &def->os.cmdline) < 0)
return -1;
-
- if (root) {
- if (virAsprintf(&def->os.cmdline, "root=%s %s", root, extra) < 0)
- return -1;
- } else {
- if (VIR_STRDUP(def->os.cmdline, extra) < 0)
- return -1;
- }
}
return 0;
--
2.1.4
8 years, 10 months
[libvirt] [python PATCH] Add support for MIGRATION_ITERATION event
by Jiri Denemark
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
examples/event-test.py | 4 +++
libvirt-override-virConnect.py | 9 +++++++
libvirt-override.c | 57 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 70 insertions(+)
diff --git a/examples/event-test.py b/examples/event-test.py
index 2c6ce7b..615f86c 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -530,6 +530,9 @@ def myDomainEventAgentLifecycleCallback(conn, dom, state, reason, opaque):
def myDomainEventDeviceAddedCallback(conn, dom, dev, opaque):
print("myDomainEventDeviceAddedCallback: Domain %s(%s) device added: %s" % (
dom.name(), dom.ID(), dev))
+def myDomainEventMigrationIteration(conn, dom, iteration, opaque):
+ print("myDomainEventMigrationIteration: Domain %s(%s) started migration iteration %d" % (
+ dom.name(), dom.ID(), iteration))
##########################################################################
# Network events
@@ -642,6 +645,7 @@ def main():
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_TUNABLE, myDomainEventTunableCallback, None)
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE, myDomainEventAgentLifecycleCallback, None)
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_ADDED, myDomainEventDeviceAddedCallback, None)
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION, myDomainEventMigrationIteration, None)
vc.networkEventRegisterAny(None, libvirt.VIR_NETWORK_EVENT_ID_LIFECYCLE, myNetworkEventLifecycleCallback, None)
diff --git a/libvirt-override-virConnect.py b/libvirt-override-virConnect.py
index 821be87..4231195 100644
--- a/libvirt-override-virConnect.py
+++ b/libvirt-override-virConnect.py
@@ -216,6 +216,15 @@
cb(self, virDomain(self, _obj=dom), devAlias, opaque)
return 0
+ def _dispatchDomainEventMigrationIterationCallback(self, dom, iteration, cbData):
+ """Dispatches event to python user domain migration iteration event callbacks
+ """
+ cb = cbData["cb"]
+ opaque = cbData["opaque"]
+
+ cb(self, virDomain(self, _obj=dom), iteration, opaque)
+ return 0
+
def domainEventDeregisterAny(self, callbackID):
"""Removes a Domain Event Callback. De-registering for a
domain callback will disable delivery of this event type """
diff --git a/libvirt-override.c b/libvirt-override.c
index 5f1c98f..a8c019b 100644
--- a/libvirt-override.c
+++ b/libvirt-override.c
@@ -6783,6 +6783,58 @@ libvirt_virConnectDomainEventDeviceAddedCallback(virConnectPtr conn ATTRIBUTE_UN
}
#endif /* VIR_DOMAIN_EVENT_ID_DEVICE_ADDED */
+#ifdef VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION
+static int
+libvirt_virConnectDomainEventMigrationIterationCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int iteration,
+ void *opaque)
+{
+ PyObject *pyobj_cbData = (PyObject*)opaque;
+ PyObject *pyobj_dom;
+ PyObject *pyobj_ret = NULL;
+ PyObject *pyobj_conn;
+ PyObject *dictKey;
+ int ret = -1;
+
+ LIBVIRT_ENSURE_THREAD_STATE;
+
+ if (!(dictKey = libvirt_constcharPtrWrap("conn")))
+ goto cleanup;
+ pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey);
+ Py_DECREF(dictKey);
+
+ /* Create a python instance of this virDomainPtr */
+ virDomainRef(dom);
+ if (!(pyobj_dom = libvirt_virDomainPtrWrap(dom))) {
+ virDomainFree(dom);
+ goto cleanup;
+ }
+ Py_INCREF(pyobj_cbData);
+
+ /* Call the Callback Dispatcher */
+ pyobj_ret = PyObject_CallMethod(pyobj_conn,
+ (char*)"_dispatchDomainEventMigrationIterationCallback",
+ (char*)"OiO",
+ pyobj_dom, iteration, pyobj_cbData);
+
+ Py_DECREF(pyobj_cbData);
+ Py_DECREF(pyobj_dom);
+
+ cleanup:
+ if (!pyobj_ret) {
+ DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret);
+ PyErr_Print();
+ } else {
+ Py_DECREF(pyobj_ret);
+ ret = 0;
+ }
+
+ LIBVIRT_RELEASE_THREAD_STATE;
+ return ret;
+}
+#endif /* VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION */
+
static PyObject *
libvirt_virConnectDomainEventRegisterAny(PyObject *self ATTRIBUTE_UNUSED,
PyObject *args)
@@ -6883,6 +6935,11 @@ libvirt_virConnectDomainEventRegisterAny(PyObject *self ATTRIBUTE_UNUSED,
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventDeviceAddedCallback);
break;
#endif /* VIR_DOMAIN_EVENT_ID_DEVICE_ADDED */
+#ifdef VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION
+ case VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION:
+ cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventMigrationIterationCallback);
+ break;
+#endif /* VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION */
case VIR_DOMAIN_EVENT_ID_LAST:
break;
}
--
2.7.0
8 years, 10 months
[libvirt] [PATCH 0/2] Introduce migration iteration event
by Jiri Denemark
Jiri Denemark (2):
Introduce migration iteration event
qemu: Add support for migration iteration event
daemon/remote.c | 32 ++++++++++++++++++
include/libvirt/libvirt-domain.h | 22 +++++++++++++
src/conf/domain_event.c | 71 ++++++++++++++++++++++++++++++++++++++++
src/conf/domain_event.h | 8 +++++
src/libvirt_private.syms | 2 ++
src/qemu/qemu_monitor.c | 13 ++++++++
src/qemu/qemu_monitor.h | 8 +++++
src/qemu/qemu_monitor_json.c | 17 ++++++++++
src/qemu/qemu_process.c | 30 +++++++++++++++++
src/remote/remote_driver.c | 33 +++++++++++++++++++
src/remote/remote_protocol.x | 14 +++++++-
src/remote_protocol-structs | 6 ++++
tools/virsh-domain.c | 18 ++++++++++
13 files changed, 273 insertions(+), 1 deletion(-)
--
2.7.0
8 years, 10 months
[libvirt] [PATCH v3 0/6] admin: Introduce server listing API
by Erik Skultety
Since v2:
- static names of daemons are passed to virNetServerNew directly, instead
of creating an array of names like the previous version did
- dropped client-side server identification through ID, only name is used
- adjusted naming of some methods (prefixes again...)
- converted the server listing example to virt-admin command (finally)
Erik Skultety (6):
rpc: Introduce new element 'name' to virnetserver structure
virnetdaemon: Add post exec restart support for multiple servers
admin: Move admin_server.{h,c} to admin.{h,c}
admin: Introduce virAdmServer structure
admin: Introduce adminDaemonConnectListServers API
virt-admin: Introduce cmdSrvList
daemon/Makefile.am | 6 +-
daemon/admin.c | 181 +++++++++++++++++++++
daemon/admin.h | 36 ++++
daemon/admin_server.c | 121 +++++---------
daemon/admin_server.h | 23 ++-
daemon/libvirtd.c | 4 +-
include/libvirt/libvirt-admin.h | 11 ++
po/POTFILES.in | 2 +-
src/admin/admin_protocol.x | 26 ++-
src/admin_protocol-structs | 15 ++
src/datatypes.c | 36 ++++
src/datatypes.h | 34 ++++
src/libvirt-admin.c | 148 +++++++++++++++++
src/libvirt_admin_private.syms | 5 +
src/libvirt_admin_public.syms | 3 +
src/locking/lock_daemon.c | 3 +-
src/logging/log_daemon.c | 3 +-
src/lxc/lxc_controller.c | 2 +-
src/rpc/virnetdaemon.c | 15 ++
src/rpc/virnetdaemon.h | 3 +
src/rpc/virnetserver.c | 32 +++-
src/rpc/virnetserver.h | 5 +
.../input-data-admin-server-names.json | 128 +++++++++++++++
.../virnetdaemondata/output-data-admin-nomdns.json | 2 +
.../output-data-admin-server-names.json | 128 +++++++++++++++
.../virnetdaemondata/output-data-anon-clients.json | 1 +
.../output-data-initial-nomdns.json | 1 +
tests/virnetdaemondata/output-data-initial.json | 1 +
tests/virnetdaemontest.c | 40 ++---
tools/virt-admin.c | 62 +++++++
30 files changed, 946 insertions(+), 131 deletions(-)
create mode 100644 daemon/admin.c
create mode 100644 daemon/admin.h
create mode 100644 tests/virnetdaemondata/input-data-admin-server-names.json
create mode 100644 tests/virnetdaemondata/output-data-admin-server-names.json
--
2.4.3
8 years, 10 months