Devel
Threads by month
- ----- 2026 -----
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
April 2009
- 67 participants
- 160 discussions
Hi All,
I have attached a patch which when applied on the HEAD as of today would allow
virtualbox support in libvirt. It takes cares of all the stuff mentioned on
the list earlier. Still if I have missed anything, please do tell me.
The patches are organized as below:
Patch 0/4: contains sample xml file
Patch 1/4: contains diff of files already in libvirt.
Patch 2/4: contains new files needed for VirtualBox support.
Patch 3/4: contains support for host only and internal network.
Patch 4/4: contains support for rdp in libvirt as mentioned by danpb (also had
sent it separately earlier today)
Regards,
Pritesh
3
8
Trying to keep up with last week posted schedule, the new release was
pushed to the usual place:
ftp://libvirt.org/libvirt/
This is mostly a bug fix release, though it also includes a few new
features and some improvements:
* New features:
- support SASL auth for VNC server (Daniel Berrange)
- memory ballooning in QEMU (Daniel Berrange)
- SCSI HBA storage pool support (Dave Allan)
- PCI passthrough in Xen driver (Daniel Berrange)
* Portability:
- be more flexible in QEmu binaries paths (Daniel Berrange)
- Mingw portability fixes (Daniel Berrange)
* Documentation:
- add security attributes in RNG schemas
- cleanup of architecture docs
- missing disk bus values in RNG schemas
* Bug fixes:
- tap vs vbd type on block detach (Cole Robinson and Takahashi
Tomohiro)
- bad free on storage volume error (Daniel Berrange)
- maplenght computations in remote driver (Daniel Berrange)
- event dispatching in the daemon (Daniel Berrange)
- virDomainSetVcpus deadlock (Daniel Berrange)
- save deadlock in test driver (Cole Robinson)
- fix timing of security driver init (Cole Robinson)
- forbid readonly connections from dumping the XML safe info (Cole
Robinson)
- file descriptor leak on remote access
- fix labelling of shared/readonly devices (Dan Walsh)
- virsh missing auth on shell commands (Matthias Bolte)
- avoid zombie on exec pipe errors (Ryota Ozaki)
- memory leak in virNodeDeviceGetParent (Daniel Berrange)
- URI check in migration (Daniel Berrange)
- various memory bug fixes (Daniel Berrange)
- python bindings generator fix (Daniel Berrange)
- NUMA memory fixes (Daniel Berrange)
- various svirt fixes (Daniel Berrange)
- fix sparse volume allocation reporting (Cole Robinson)
- test driver domain restore return value (Cole Robinson)
- do not lose file format info on volume refresh (Cole Robinson)
* Improvements:
- get CPU usage info for LXC (Ryota Ozaki)
- fix domain RNG to add ac97 and tests (Pritesh Kothari)
- OpenVZ support for non-template filesystem root (Florian Vichot)
- improve arch capabilities generation (Daniel Berrange)
- modularization of spec file (Ryota Ozaki)
- better error reports in SEXPR generation (Daniel Berrange)
- support for vifname parameter in VIF config (Daniel Berrange)
- localtime handling for new xen (Daniel Berrange)
- error reporting/ verification of security labels (Dan Walsh)
- add --console arg for create and start virsh commands (Daniel
Berrange)
- refresh volume alloc/capacity when dumping XML (Cole Robinson)
* Cleanups:
- FILE * leaks removal
- unused parameters flagging (Maximilian Wilhelm)
- switch to pre-C99 struct initialization for drivers (Chris
Lalancette)
- symlinks resolving cleanup (Daniel Berrange)
Thanks to everybody who helped with reports, ideas or patches !
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
2
4
In Fedora 10 I've managed to get libvirt to call the emulator with
custom arguments so I can invoke -snapshot. I just replaced the
emulator in /usr/bin with my own script which adds the argument and then
calls the original emulator. This works fine. And the snapshot works
fine. I can make lots of changes and when I shutdown and restart then
all the changes are forgotten. Now after I'm satisfied with some
changes I want to save the snapshot back to the image file. I've tried
"Ctrl-Alt-s", but this does not work. I tried finding the QEMU console,
but Serial Console is grayed out in the menu. I don't know if that
would help anyway since this was a raw image and not qcow2 so I don't
think 'savevm' and 'loadvm' would work with raw.
Can someone tell me how to save these snapshots back to the image file?
Thanks.
Regards,
Gerry
3
3
20 Apr '09
One of the current flaws in the LXC driver is that when doing the better-
chroot-than-chroot mode setup, /dev/pts leaks the parent OS TTYs into
the container.
As of 2.6.29 it is possible to create new instances of /dev/pts by passing
the 'newinstance' flag to mount. In this way /dev/pts inside the container
will be totally independant of the parent OS.
This is a kind of fun / tricky thing to get right, because the monitor
process (libvirt_lxc) actually needs 2 ttys, one in the host's /dev/pts
(which virsh console connects to), and the other in the container's
/dev/pts (which acts as its stdin/out/err).
This means that libvirt_lxc has to mount the new devpts instance on
the containers root filesystem before starting the container itself.
To avoid this then appearing in the host OS, we make libvirt_lxc
call unshare(CLONE_NEWNS). This also has the nice advantage of adding
a guarentee that this new devpts instance is cleaned up with libvirt_lxc
exits.
Now in the container startup sequence, instead of mounting a devpts
instance, it just moves the instance that libvirt_lxc previously
setup into its desired location.
I have arranged this so that if the host OS kernel lacks support for
the 'newinstance' flag with devpts, it'll just use a regular shared
instance. If this happens, then /var/log/libvirt/lxc/$NAME.log
should warn you
16:55:00.454: warning : kernel does not support private devpts, using shared devpts
Also the previous patch to pivot_root() setup added a chroot() call. For
some wierd reason, with this all the host OS's mounts are still visible
in the container's /proc/mounts, even though they are not actually
accessible (since we pivot'd onto a new root)
This change seemed to fix that problem with no ill-effects.
- if (chroot(oldroot) < 0) {
- virReportSystemError(NULL, errno, "%s",
- _("failed to chroot into tmpfs"));
- goto err;
- }
-
- if (chdir("/new") < 0) {
- virReportSystemError(NULL, errno, "%s",
- _("failed to chdir into /new on tmpfs"));
+ if (chdir(newroot) < 0) {
+ virReportSystemError(NULL, errno,
+ _("failed to chroot into %s"), newroot);
goto err;
}
There was also a call added to umount the .oldroot location, but
this was being done too early, because later methods still needed
to access various bits under /.oldroot - eg to mount other (non-root)
filesystems from the host OS in the container.
So I'm removing this chunk:
if (chdir("/") < 0)
goto err;
- if (umount2(".oldroot", MNT_DETACH) < 0) {
- virReportSystemError(NULL, errno, "%s",
- _("failed to lazily unmount old root"));
- goto err;
- }
-
This showed up a different problem though. Our call later on which
would unmount /.oldroot was failing because there were some open
file descriptors on /var/ still.
This was because we didn't setup stdin/out until after we'd dealt
with all the mounts. So my patch also makes sure that the first
thing we do is close all open file descriptors and move stdin/out/err
immdiately onto the TTY allocated for this container. That ensures
all the mounts are able to be released.
I've tested this patch on 2.6.27 (lacking 'newinstance') and on
2.6.29 (with 'newinstance' for devpts). It seemed to work correctly
in both cases, but would appreciate someone else confirming....
domain_conf.c | 15 ++++
domain_conf.h | 2
libvirt_private.syms | 1
lxc_container.c | 175 +++++++++++++++++++++++++++++++--------------------
lxc_container.h | 1
lxc_controller.c | 87 +++++++++++++++++++++++--
util.c | 22 ++++--
util.h | 4 +
8 files changed, 230 insertions(+), 77 deletions(-)
Daniel
Index: src/domain_conf.c
===================================================================
RCS file: /data/cvs/libvirt/src/domain_conf.c,v
retrieving revision 1.75
diff -u -p -r1.75 domain_conf.c
--- src/domain_conf.c 3 Apr 2009 14:10:17 -0000 1.75
+++ src/domain_conf.c 15 Apr 2009 15:44:52 -0000
@@ -3855,6 +3857,21 @@ const char *virDomainDefDefaultEmulator(
return emulator;
}
+virDomainFSDefPtr virDomainGetRootFilesystem(virDomainDefPtr def)
+{
+ int i;
+
+ for (i = 0 ; i < def->nfss ; i++) {
+ if (def->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
+ continue;
+
+ if (STREQ(def->fss[i]->dst, "/"))
+ return def->fss[i];
+ }
+
+ return NULL;
+}
+
void virDomainObjLock(virDomainObjPtr obj)
{
Index: src/domain_conf.h
===================================================================
RCS file: /data/cvs/libvirt/src/domain_conf.h,v
retrieving revision 1.40
diff -u -p -r1.40 domain_conf.h
--- src/domain_conf.h 3 Mar 2009 16:53:13 -0000 1.40
+++ src/domain_conf.h 15 Apr 2009 15:44:52 -0000
@@ -635,6 +635,8 @@ const char *virDomainDefDefaultEmulator(
virDomainDefPtr def,
virCapsPtr caps);
+virDomainFSDefPtr virDomainGetRootFilesystem(virDomainDefPtr def);
+
void virDomainObjLock(virDomainObjPtr obj);
void virDomainObjUnlock(virDomainObjPtr obj);
Index: src/libvirt_private.syms
===================================================================
RCS file: /data/cvs/libvirt/src/libvirt_private.syms,v
retrieving revision 1.28
diff -u -p -r1.28 libvirt_private.syms
--- src/libvirt_private.syms 3 Apr 2009 10:55:51 -0000 1.28
+++ src/libvirt_private.syms 15 Apr 2009 15:44:52 -0000
@@ -78,6 +78,7 @@ virDomainDiskQSort;
virDomainFindByID;
virDomainFindByName;
virDomainFindByUUID;
+virDomainGetRootFilesystem;
virDomainGraphicsTypeFromString;
virDomainGraphicsDefFree;
virDomainInputDefFree;
Index: src/lxc_container.c
===================================================================
RCS file: /data/cvs/libvirt/src/lxc_container.c,v
retrieving revision 1.23
diff -u -p -r1.23 lxc_container.c
--- src/lxc_container.c 14 Apr 2009 17:51:12 -0000 1.23
+++ src/lxc_container.c 15 Apr 2009 15:44:52 -0000
@@ -306,13 +306,13 @@ static int lxcContainerPivotRoot(virDoma
/* Create a tmpfs root since old and new roots must be
* on separate filesystems */
- if (mount("", oldroot, "tmpfs", 0, NULL) < 0) {
+ if (mount("tmprootfs", oldroot, "tmpfs", 0, NULL) < 0) {
virReportSystemError(NULL, errno,
_("failed to mount empty tmpfs at %s"),
oldroot);
goto err;
}
-
+
/* Create a directory called 'new' in tmpfs */
if (virAsprintf(&newroot, "%s/new", oldroot) < 0) {
virReportOOMError(NULL);
@@ -336,15 +336,9 @@ static int lxcContainerPivotRoot(virDoma
/* Now we chroot into the tmpfs, then pivot into the
* root->src bind-mounted onto '/new' */
- if (chroot(oldroot) < 0) {
- virReportSystemError(NULL, errno, "%s",
- _("failed to chroot into tmpfs"));
- goto err;
- }
-
- if (chdir("/new") < 0) {
- virReportSystemError(NULL, errno, "%s",
- _("failed to chdir into /new on tmpfs"));
+ if (chdir(newroot) < 0) {
+ virReportSystemError(NULL, errno,
+ _("failed to chroot into %s"), newroot);
goto err;
}
@@ -360,12 +354,6 @@ static int lxcContainerPivotRoot(virDoma
if (chdir("/") < 0)
goto err;
- if (umount2(".oldroot", MNT_DETACH) < 0) {
- virReportSystemError(NULL, errno, "%s",
- _("failed to lazily unmount old root"));
- goto err;
- }
-
VIR_FREE(oldroot);
VIR_FREE(newroot);
@@ -377,50 +365,77 @@ err:
return -1;
}
-static int lxcContainerPopulateDevices(void)
+
+static int lxcContainerMountBasicFS(virDomainFSDefPtr root)
{
- int i;
- int rc;
const struct {
- int maj;
- int min;
- mode_t mode;
- const char *path;
- } devs[] = {
- { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_NULL, 0666, "/dev/null" },
- { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_ZERO, 0666, "/dev/zero" },
- { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_FULL, 0666, "/dev/full" },
- { LXC_DEV_MAJ_TTY, LXC_DEV_MIN_CONSOLE, 0600, "/dev/console" },
- { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_RANDOM, 0666, "/dev/random" },
- { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_URANDOM, 0666, "/dev/urandom" },
+ const char *src;
+ const char *dst;
+ const char *type;
+ } mnts[] = {
+ { "/dev", "/dev", "tmpfs" },
+ { "/proc", "/proc", "proc" },
+ { "/sys", "/sys", "sysfs" },
+#if WITH_SELINUX
+ { "none", "/selinux", "selinuxfs" },
+#endif
};
+ int i, rc;
+ char *devpts;
- if ((rc = virFileMakePath("/dev")) < 0) {
- virReportSystemError(NULL, rc, "%s",
- _("cannot create /dev/"));
+ if (virAsprintf(&devpts, "/.oldroot%s/dev/pts", root->src) < 0) {
+ virReportOOMError(NULL);
return -1;
}
- if (mount("none", "/dev", "tmpfs", 0, NULL) < 0) {
- virReportSystemError(NULL, errno, "%s",
- _("failed to mount /dev tmpfs"));
- return -1;
+
+ for (i = 0 ; i < ARRAY_CARDINALITY(mnts) ; i++) {
+ if (virFileMakePath(mnts[i].dst) < 0) {
+ virReportSystemError(NULL, errno,
+ _("failed to mkdir %s"),
+ mnts[i].src);
+ return -1;
+ }
+ if (mount(mnts[i].src, mnts[i].dst, mnts[i].type, 0, NULL) < 0) {
+ virReportSystemError(NULL, errno,
+ _("failed to mount %s on %s"),
+ mnts[i].type, mnts[i].type);
+ return -1;
+ }
}
- /* Move old devpts into container, since we have to
- connect to the master ptmx which was opened in
- the parent.
- XXX This sucks, we need to figure out how to get our
- own private devpts for isolation
- */
+
if ((rc = virFileMakePath("/dev/pts") < 0)) {
virReportSystemError(NULL, rc, "%s",
_("cannot create /dev/pts"));
return -1;
}
- if (mount("devpts", "/dev/pts", "devpts", 0, NULL) < 0) {
+
+ VIR_DEBUG("Trying to move %s to %s", devpts, "/dev/pts");
+ if ((rc = mount(devpts, "/dev/pts", NULL, MS_MOVE, NULL)) < 0) {
virReportSystemError(NULL, errno, "%s",
_("failed to mount /dev/pts in container"));
return -1;
}
+ VIR_FREE(devpts);
+
+ return 0;
+}
+
+static int lxcContainerPopulateDevices(void)
+{
+ int i;
+ const struct {
+ int maj;
+ int min;
+ mode_t mode;
+ const char *path;
+ } devs[] = {
+ { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_NULL, 0666, "/dev/null" },
+ { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_ZERO, 0666, "/dev/zero" },
+ { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_FULL, 0666, "/dev/full" },
+ { LXC_DEV_MAJ_TTY, LXC_DEV_MIN_CONSOLE, 0600, "/dev/console" },
+ { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_RANDOM, 0666, "/dev/random" },
+ { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_URANDOM, 0666, "/dev/urandom" },
+ };
/* Populate /dev/ with a few important bits */
for (i = 0 ; i < ARRAY_CARDINALITY(devs) ; i++) {
@@ -434,6 +449,23 @@ static int lxcContainerPopulateDevices(v
}
}
+ if (access("/dev/pts/ptmx", W_OK) == 0) {
+ if (symlink("/dev/pts/ptmx", "/dev/ptmx") < 0) {
+ virReportSystemError(NULL, errno, "%s",
+ _("failed to create symlink /dev/ptmx to /dev/pts/ptmx"));
+ return -1;
+ }
+ } else {
+ dev_t dev = makedev(LXC_DEV_MAJ_TTY, LXC_DEV_MIN_PTMX);
+ if (mknod("/dev/ptmx", 0, dev) < 0 ||
+ chmod("/dev/ptmx", 0666)) {
+ virReportSystemError(NULL, errno, "%s",
+ _("failed to make device /dev/ptmx"));
+ return -1;
+ }
+ }
+
+
return 0;
}
@@ -493,6 +525,7 @@ static int lxcContainerUnmountOldFS(void
return -1;
}
while (getmntent_r(procmnt, &mntent, mntbuf, sizeof(mntbuf)) != NULL) {
+ VIR_DEBUG("Got %s", mntent.mnt_dir);
if (!STRPREFIX(mntent.mnt_dir, "/.oldroot"))
continue;
@@ -513,6 +546,7 @@ static int lxcContainerUnmountOldFS(void
lxcContainerChildMountSort);
for (i = 0 ; i < nmounts ; i++) {
+ VIR_DEBUG("Umount %s", mounts[i]);
if (umount(mounts[i]) < 0) {
virReportSystemError(NULL, errno,
_("failed to unmount '%s'"),
@@ -534,22 +568,23 @@ static int lxcContainerUnmountOldFS(void
static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
virDomainFSDefPtr root)
{
+ /* Gives us a private root, leaving all parent OS mounts on /.oldroot */
if (lxcContainerPivotRoot(root) < 0)
return -1;
- if (virFileMakePath("/proc") < 0 ||
- mount("none", "/proc", "proc", 0, NULL) < 0) {
- virReportSystemError(NULL, errno, "%s",
- _("failed to mount /proc"));
+ /* Mounts the core /proc, /sys, /dev, /dev/pts filesystems */
+ if (lxcContainerMountBasicFS(root) < 0)
return -1;
- }
+ /* Populates device nodes in /dev/ */
if (lxcContainerPopulateDevices() < 0)
return -1;
+ /* Sets up any non-root mounts from guest config */
if (lxcContainerMountNewFS(vmDef) < 0)
return -1;
+ /* Gets rid of all remaining mounts from host OS, including /.oldroot itself */
if (lxcContainerUnmountOldFS() < 0)
return -1;
@@ -595,18 +630,9 @@ static int lxcContainerSetupExtraMounts(
return 0;
}
-static int lxcContainerSetupMounts(virDomainDefPtr vmDef)
+static int lxcContainerSetupMounts(virDomainDefPtr vmDef,
+ virDomainFSDefPtr root)
{
- int i;
- virDomainFSDefPtr root = NULL;
-
- for (i = 0 ; i < vmDef->nfss ; i++) {
- if (vmDef->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
- continue;
- if (STREQ(vmDef->fss[i]->dst, "/"))
- root = vmDef->fss[i];
- }
-
if (root)
return lxcContainerSetupPivotRoot(vmDef, root);
else
@@ -630,6 +656,8 @@ static int lxcContainerChild( void *data
lxc_child_argv_t *argv = data;
virDomainDefPtr vmDef = argv->config;
int ttyfd;
+ char *ttyPath;
+ virDomainFSDefPtr root;
if (NULL == vmDef) {
lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
@@ -637,16 +665,28 @@ static int lxcContainerChild( void *data
return -1;
}
- if (lxcContainerSetupMounts(vmDef) < 0)
- return -1;
+ root = virDomainGetRootFilesystem(vmDef);
- ttyfd = open(argv->ttyPath, O_RDWR|O_NOCTTY);
+ if (root) {
+ if (virAsprintf(&ttyPath, "%s%s", root->src, argv->ttyPath) < 0) {
+ virReportOOMError(NULL);
+ return -1;
+ }
+ } else {
+ if (!(ttyPath = strdup(argv->ttyPath))) {
+ virReportOOMError(NULL);
+ return -1;
+ }
+ }
+
+ ttyfd = open(ttyPath, O_RDWR|O_NOCTTY);
if (ttyfd < 0) {
virReportSystemError(NULL, errno,
- _("failed to open %s"),
- argv->ttyPath);
+ _("failed to open tty %s"),
+ ttyPath);
return -1;
}
+ VIR_FREE(ttyPath);
if (lxcContainerSetStdio(argv->monitor, ttyfd) < 0) {
close(ttyfd);
@@ -654,6 +694,9 @@ static int lxcContainerChild( void *data
}
close(ttyfd);
+ if (lxcContainerSetupMounts(vmDef, root) < 0)
+ return -1;
+
/* Wait for interface devices to show up */
if (lxcContainerWaitForContinue(argv->monitor) < 0)
return -1;
Index: src/lxc_container.h
===================================================================
RCS file: /data/cvs/libvirt/src/lxc_container.h,v
retrieving revision 1.9
diff -u -p -r1.9 lxc_container.h
--- src/lxc_container.h 21 Oct 2008 16:46:47 -0000 1.9
+++ src/lxc_container.h 15 Apr 2009 15:44:52 -0000
@@ -39,6 +39,7 @@ enum {
#define LXC_DEV_MAJ_TTY 5
#define LXC_DEV_MIN_CONSOLE 1
+#define LXC_DEV_MIN_PTMX 2
#define LXC_DEV_MAJ_PTY 136
Index: src/lxc_controller.c
===================================================================
RCS file: /data/cvs/libvirt/src/lxc_controller.c,v
retrieving revision 1.15
diff -u -p -r1.15 lxc_controller.c
--- src/lxc_controller.c 3 Feb 2009 13:09:00 -0000 1.15
+++ src/lxc_controller.c 15 Apr 2009 15:44:52 -0000
@@ -33,6 +33,7 @@
#include <fcntl.h>
#include <signal.h>
#include <getopt.h>
+#include <sys/mount.h>
#include "virterror_internal.h"
#include "logging.h"
@@ -440,6 +441,9 @@ lxcControllerRun(virDomainDefPtr def,
int containerPty;
char *containerPtyPath;
pid_t container = -1;
+ virDomainFSDefPtr root;
+ char *devpts = NULL;
+ char *devptmx = NULL;
if (socketpair(PF_UNIX, SOCK_STREAM, 0, control) < 0) {
virReportSystemError(NULL, errno, "%s",
@@ -447,14 +451,83 @@ lxcControllerRun(virDomainDefPtr def,
goto cleanup;
}
- if (virFileOpenTty(&containerPty,
- &containerPtyPath,
- 0) < 0) {
- virReportSystemError(NULL, errno, "%s",
- _("failed to allocate tty"));
- goto cleanup;
+ root = virDomainGetRootFilesystem(def);
+
+ /*
+ * If doing a chroot style setup, we need to prepare
+ * a private /dev/pts for the child now, which they
+ * will later move into position.
+ *
+ * This is complex because 'virsh console' needs to
+ * use /dev/pts from the host OS, and the guest OS
+ * needs to use /dev/pts from the guest.
+ *
+ * This means that we (libvirt_lxc) need to see and
+ * use both /dev/pts instances. We're running in the
+ * host OS context though and don't want to expose
+ * the guest OS /dev/pts there.
+ *
+ * Thus we call unshare(CLONE_NS) so that we can see
+ * the guest's new /dev/pts, without it becoming
+ * visible to the host OS.
+ */
+ if (root) {
+ VIR_DEBUG0("Setting up private /dev/pts");
+ if (unshare(CLONE_NEWNS) < 0) {
+ virReportSystemError(NULL, errno, "%s",
+ _("cannot unshare mount namespace"));
+ goto cleanup;
+ }
+
+ if (virAsprintf(&devpts, "%s/dev/pts", root->src) < 0 ||
+ virAsprintf(&devptmx, "%s/dev/pts/ptmx", root->src) < 0) {
+ virReportOOMError(NULL);
+ goto cleanup;
+ }
+
+ if (virFileMakePath(devpts) < 0) {
+ virReportSystemError(NULL, errno,
+ _("failed to make path %s"),
+ devpts);
+ goto cleanup;
+ }
+
+ VIR_DEBUG("Mouting 'devpts' on %s", devpts);
+ if (mount("devpts", devpts, "devpts", 0, "newinstance,ptmxmode=0666") < 0) {
+ virReportSystemError(NULL, errno,
+ _("failed to mount devpts on %s"),
+ devpts);
+ goto cleanup;
+ }
+
+ if (access(devptmx, R_OK) < 0) {
+ VIR_WARN0("kernel does not support private devpts, using shared devpts");
+ VIR_FREE(devptmx);
+ }
}
+ if (devptmx) {
+ VIR_DEBUG("Opening tty on private %s", devptmx);
+ if (virFileOpenTtyAt(devptmx,
+ &containerPty,
+ &containerPtyPath,
+ 0) < 0) {
+ virReportSystemError(NULL, errno, "%s",
+ _("failed to allocate tty"));
+ goto cleanup;
+ }
+ } else {
+ VIR_DEBUG0("Opening tty on shared /dev/ptmx");
+ if (virFileOpenTty(&containerPty,
+ &containerPtyPath,
+ 0) < 0) {
+ virReportSystemError(NULL, errno, "%s",
+ _("failed to allocate tty"));
+ goto cleanup;
+ }
+ }
+
+
if (lxcSetContainerResources(def) < 0)
goto cleanup;
@@ -476,6 +549,8 @@ lxcControllerRun(virDomainDefPtr def,
rc = lxcControllerMain(monitor, client, appPty, containerPty);
cleanup:
+ VIR_FREE(devptmx);
+ VIR_FREE(devpts);
if (control[0] != -1)
close(control[0]);
if (control[1] != -1)
Index: src/util.c
===================================================================
RCS file: /data/cvs/libvirt/src/util.c,v
retrieving revision 1.99
diff -u -p -r1.99 util.c
--- src/util.c 2 Apr 2009 18:42:33 -0000 1.99
+++ src/util.c 15 Apr 2009 15:44:52 -0000
@@ -1050,14 +1050,25 @@ int virFileBuildPath(const char *dir,
}
-#ifdef __linux__
int virFileOpenTty(int *ttymaster,
char **ttyName,
int rawmode)
{
+ return virFileOpenTtyAt("/dev/ptmx",
+ ttymaster,
+ ttyName,
+ rawmode);
+}
+
+#ifdef __linux__
+int virFileOpenTtyAt(const char *ptmx,
+ int *ttymaster,
+ char **ttyName,
+ int rawmode)
+{
int rc = -1;
- if ((*ttymaster = posix_openpt(O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0)
+ if ((*ttymaster = open(ptmx, O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0)
goto cleanup;
if (unlockpt(*ttymaster) < 0)
@@ -1100,9 +1111,10 @@ cleanup:
}
#else
-int virFileOpenTty(int *ttymaster ATTRIBUTE_UNUSED,
- char **ttyName ATTRIBUTE_UNUSED,
- int rawmode ATTRIBUTE_UNUSED)
+int virFileOpenTtyAt(const char *ptmx ATTRIBUTE_UNUSED,
+ int *ttymaster ATTRIBUTE_UNUSED,
+ char **ttyName ATTRIBUTE_UNUSED,
+ int rawmode ATTRIBUTE_UNUSED)
{
return -1;
}
Index: src/util.h
===================================================================
RCS file: /data/cvs/libvirt/src/util.h,v
retrieving revision 1.46
diff -u -p -r1.46 util.h
--- src/util.h 1 Apr 2009 10:26:22 -0000 1.46
+++ src/util.h 15 Apr 2009 15:44:52 -0000
@@ -103,6 +103,10 @@ int virFileBuildPath(const char *dir,
int virFileOpenTty(int *ttymaster,
char **ttyName,
int rawmode);
+int virFileOpenTtyAt(const char *ptmx,
+ int *ttymaster,
+ char **ttyName,
+ int rawmode);
char* virFilePid(const char *dir,
const char *name);
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
2
5
While we install our RNG schemas into the filesystem, and users could
use xmllint to validate them, it is a little tedious to use this way.
This patch adds a nice simple command
virt-xml-validate XML-FILE [SCHEMA-NAME]
You can use it on any XML file format that libvirt knows about
# virt-xml-validate ~/rhel5xen.xml
/home/berrange/rhel5xen.xml validates
#$ echo $?
0
I normally figures out the SCHEMA-NAME from the top level element name,
but you can override it if desired
# virt-xml-validate ~/bug.xml
virt-xml-validate: cannot determine schema type for /home/berrange/bug.xml
# virt-xml-validate ~/bug.xml domain
/home/berrange/bug.txt:1: parser error : Start tag expected, '<' not found
From bugzilla(a)redhat.com Fri Feb 27 01:12:11 2009
^
I've included a man page in the command.
This patch also fixes numerous bugs in the virsh man page source
The 'src/' directory is getting over large, so I decided we should have
a separate 'tools' directory for command line programs included in the
main libvirt source. We could consider moving virsh here perhaps.
.hgignore | 12 ++
Makefile.am | 2
b/tools/.cvsignore | 4
b/tools/.gitignore | 4
b/tools/Makefile.am | 14 ++
b/tools/virt-xml-validate.in | 151 ++++++++++++++++++++++++++
configure.in | 1
docs/Makefile.am | 2
docs/virsh.pod | 80 ++++++++++++--
libvirt.spec.in | 4
virsh.1 | 241 ++++++++++++++++++++++++++-----------------
11 files changed, 408 insertions(+), 107 deletions(-)
Daniel
diff -r f861822d43db .hgignore
--- a/.hgignore Thu Apr 16 10:34:11 2009 +0100
+++ b/.hgignore Thu Apr 16 12:44:17 2009 +0100
@@ -46,12 +46,19 @@ docs/examples/info1
docs/examples/python/Makefile
docs/examples/python/Makefile.in
docs/examples/suspend
+docs/schemas/Makefile
+docs/schemas/Makefile.in
examples/domain-events/events-c/*.exe
examples/domain-events/events-c/.deps
examples/domain-events/events-c/.libs
examples/domain-events/events-c/Makefile
examples/domain-events/events-c/Makefile.in
examples/domain-events/events-c/event-test
+examples/hellolibvirt/.deps
+examples/hellolibvirt/.libs
+examples/hellolibvirt/Makefile
+examples/hellolibvirt/Makefile.in
+examples/hellolibvirt/hellolibvirt
gnulib/lib/*.la
gnulib/lib/*.lo
gnulib/lib/.deps
@@ -260,6 +267,7 @@ tests/qemuxml2argvtest
tests/qemuxml2xmltest
tests/qparamtest
tests/reconnect
+tests/seclabeltest
tests/sexpr2xmldata/Makefile
tests/sexpr2xmldata/Makefile.in
tests/sexpr2xmltest
@@ -274,4 +282,8 @@ tests/xmconfigtest
tests/xml2sexprdata/Makefile
tests/xml2sexprdata/Makefile.in
tests/xml2sexprtest
+tools/Makefile
+tools/Makefile.in
+tools/virt-xml-validate
+tools/virt-xml-validate.1
update.log
diff -r f861822d43db Makefile.am
--- a/Makefile.am Thu Apr 16 10:34:11 2009 +0100
+++ b/Makefile.am Thu Apr 16 12:44:17 2009 +0100
@@ -3,7 +3,7 @@
LCOV = lcov
GENHTML = genhtml
-SUBDIRS = gnulib/lib include src qemud proxy docs gnulib/tests \
+SUBDIRS = gnulib/lib include src qemud tools proxy docs gnulib/tests \
python tests po examples/domain-events/events-c examples/hellolibvirt
ACLOCAL_AMFLAGS = -I m4 -I gnulib/m4
diff -r f861822d43db configure.in
--- a/configure.in Thu Apr 16 10:34:11 2009 +0100
+++ b/configure.in Thu Apr 16 12:44:17 2009 +0100
@@ -1342,6 +1342,7 @@ AC_OUTPUT(Makefile src/Makefile include/
include/libvirt/Makefile include/libvirt/libvirt.h \
python/Makefile python/tests/Makefile \
qemud/Makefile \
+ tools/Makefile \
tests/Makefile proxy/Makefile \
tests/xml2sexprdata/Makefile \
tests/sexpr2xmldata/Makefile \
diff -r f861822d43db docs/Makefile.am
--- a/docs/Makefile.am Thu Apr 16 10:34:11 2009 +0100
+++ b/docs/Makefile.am Thu Apr 16 12:44:17 2009 +0100
@@ -66,7 +66,7 @@ EXTRA_DIST= \
all: web $(top_builddir)/NEWS $(man_MANS)
virsh.1: virsh.pod
- pod2man -c "Virtualization Support" $(srcdir)/virsh.pod > $@-t
+ pod2man -c "Virtualization Support" -r "$(PACKAGE)-$(VERSION)" $(srcdir)/virsh.pod > $@-t
mv $@-t $@
cp $@ $(top_builddir)
diff -r f861822d43db docs/virsh.pod
--- a/docs/virsh.pod Thu Apr 16 10:34:11 2009 +0100
+++ b/docs/virsh.pod Thu Apr 16 12:44:17 2009 +0100
@@ -150,13 +150,13 @@ B<virsh> list
Name is the name of the domain. ID the domain numeric id.
State is the run state (see below).
-=over 4
-
B<STATES>
The State field lists 6 states for a domain, and which ones the
current domain is in.
+=over 4
+
=item B<running>
The domain is currently running on a CPU
@@ -198,12 +198,16 @@ crashed.
Prints the available amount of memory on the machine or within a
NUMA cell if I<cellno> is provided.
+=back
+
=head1 DOMAIN COMMANDS
The following commands manipulate domains directly, as stated
previously most commands take domain-id as the first parameter. The
I<domain-id> can be specified as an short integer, a name or a full UUID.
+=over 4
+
=item B<autostart> optional I<--disable> I<domain-id>
Configure a domain to be automatically started at boot.
@@ -401,7 +405,9 @@ and I<cpulist> is a comma separated list
Output the IP address and port number for the VNC display. If the information
is not available the processes will provide an exit code of 1.
-=head1 DEVICES COMMANDS
+=back
+
+=head1 DEVICE COMMANDS
The following commands manipulate devices associated to domains.
The domain-id can be specified as an short integer, a name or a full UUID.
@@ -409,6 +415,8 @@ To better understand the values allowed
reading the documentation at L<http://libvirt.org/format.html> on the
format of the device sections to get the most accurate set of accepted values.
+=over 4
+
=item B<attach-device> I<domain-id> I<FILE>
Attach a device to the domain, using a device definition in an XML file.
@@ -449,7 +457,9 @@ I<type> can be either I<network> to indi
It is recommended to use the I<mac> option to distinguish between the interfaces
if more than one are present on the domain.
-=head1 VIRTUAL NETWORKS COMMANDS
+=back
+
+=head1 VIRTUAL NETWORK COMMANDS
The following commands manipulate networks. Libvirt has the capability to
define virtual networks which can then be used by domains and linked to
@@ -458,6 +468,8 @@ see the documentation at L<http://libvir
of the command for virtual networks are similar to the one used for domains,
but the way to name a virtual network is either by its name or UUID.
+=over 4
+
=item B<net-autostart> I<network> optional I<--disable>
Configure a virtual network to be automatically started at boot.
@@ -517,18 +529,55 @@ Undefine the configuration for an inacti
Convert a network name to network UUID.
+=back
+
=head1 ENVIRONMENT
+The following environment variables can be set to alter the behaviour
+of C<virsh>
+
+=over 4
+
=item VIRSH_DEFAULT_CONNECT_URI
The hypervisor to connect to by default. Set this to a URI, in the same
format as accepted by the B<connect> option.
-=head1 SEE ALSO
+=item LIBVIRT_DEBUG=LEVEL
-L<virt-install(1)>, L<xm(1)>, L<virt-top(1)>, L<virt-mem(1)>, L<virt-df(1)>, L<http://www.libvirt.org/>
+Turn on verbose debugging of all libvirt API calls. Valid levels are
-=head1 AUTHOR
+=over 4
+
+=item * LIBVIRT_DEBUG=1
+
+Messages at level DEBUG or above
+
+=item * LIBVIRT_DEBUG=2
+
+Messages at level INFO or above
+
+=item * LIBVIRT_DEBUG=3
+
+Messages at level WARNING or above
+
+=item * LIBVIRT_DEBUG=4
+
+Messages at level ERROR or above
+
+=back
+
+For further information about debugging options consult C<http://libvirt.org/logging.html>
+
+=back
+
+=head1 BUGS
+
+Report any bugs discovered to the libvirt community via the mailing
+list C<http://libvirt.org/contact.html> or bug tracker C<http://libvirt.org/bugs.html>.
+Alternatively report bugs to your software distributor / vendor.
+
+=head1 AUTHORS
Andrew Puch <apuch @ redhat.com>
Daniel Veillard <veillard @ redhat.com>
@@ -537,12 +586,19 @@ L<virt-install(1)>, L<xm(1)>, L<virt-top
Sean Dague <sean at dague dot net>
Daniel Stekloff <dsteklof at us dot ibm dot com>
+=head1 COPYRIGHT
-=head1 BUGS
+Copyright (C) 2005, 2007-2009 Red Hat, Inc.
-Bugs can be filed in Red Hat bugzilla under the Virtualization Tools/libvirt
-L<https://bugzilla.redhat.com/>
+=head1 LICENSE
-L<https://bugzilla.redhat.com/buglist.cgi?product=Virtualization+Tools&compon…>
+virsh is distributed under the terms of the GNU LGPL v2+.
+This is free software; see the source for copying conditions. There
+is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE
-=end
+=head1 SEE ALSO
+
+L<virt-install(1)>, L<virt-xml-validate(1)>, L<virt-top(1)>, L<virt-mem(1)>, L<virt-df(1)>, L<http://www.libvirt.org/>
+
+=cut
diff -r f861822d43db libvirt.spec.in
--- a/libvirt.spec.in Thu Apr 16 10:34:11 2009 +0100
+++ b/libvirt.spec.in Thu Apr 16 12:44:17 2009 +0100
@@ -372,8 +372,10 @@ fi
%defattr(-, root, root)
%doc AUTHORS ChangeLog NEWS README COPYING.LIB TODO
-%doc %{_mandir}/man1/virsh.1*
+%{_mandir}/man1/virsh.1*
+%{_mandir}/man1/virt-xml-validate.1*
%{_bindir}/virsh
+%{_bindir}/virt-xml-validate
%{_libdir}/lib*.so.*
%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/
diff -r f861822d43db tools/.cvsignore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/.cvsignore Thu Apr 16 12:44:17 2009 +0100
@@ -0,0 +1,4 @@
+virt-xml-validate
+virt-xml-validate.1
+Makefile
+Makefile.in
diff -r f861822d43db tools/.gitignore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/.gitignore Thu Apr 16 12:44:17 2009 +0100
@@ -0,0 +1,4 @@
+virt-xml-validate
+virt-xml-validate.1
+Makefile
+Makefile.in
diff -r f861822d43db tools/Makefile.am
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/Makefile.am Thu Apr 16 12:44:17 2009 +0100
@@ -0,0 +1,14 @@
+
+bin_SCRIPTS = \
+ virt-xml-validate
+
+virt-xml-validate: virt-xml-validate.in Makefile
+ sed -e 's,@SCHEMADIR@,$(pkgdatadir)/schemas,' < $< > $@ || (rm $@ && exit 1)
+ chmod +x $@
+
+man1_MANS = virt-xml-validate.1
+
+CLEANFILES = $(bin_SCRIPTS) $(man1_MANS)
+
+%.1: %
+ pod2man -c "Virtualization Support" -r "$(PACKAGE)-$(VERSION)" $< $@
diff -r f861822d43db tools/virt-xml-validate.in
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/virt-xml-validate.in Thu Apr 16 12:44:17 2009 +0100
@@ -0,0 +1,151 @@
+#!/bin/sh
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+set -e
+
+XMLFILE=$1
+TYPE=$2
+
+if [ -z "$XMLFILE" ]; then
+ echo "syntax: $0 XMLFILE [TYPE]"
+ exit 1
+fi
+
+if [ ! -f "$XMLFILE" ]; then
+ echo "$0: document $XMLFILE does not exist"
+ exit 2
+fi
+
+if [ -z "$TYPE" ]; then
+ ROOT=`xmllint --format $XMLFILE 2>/dev/null| head -2 | tail -1`
+ case $ROOT in
+ *domain*)
+ TYPE="domain"
+ ;;
+ *network*)
+ TYPE="network"
+ ;;
+ *pool*)
+ TYPE="storagepool"
+ ;;
+ *volume*)
+ TYPE="storagevol"
+ ;;
+ *capabilities*)
+ TYPE="capability"
+ ;;
+ *device*)
+ TYPE="nodedev"
+ ;;
+ *)
+ echo "$0: cannot determine schema type for $XMLFILE"
+ exit 3
+ esac
+fi
+
+SCHEMA="@SCHEMADIR@/${TYPE}.rng"
+
+if [ ! -f "$SCHEMA" ]; then
+ echo "$0: schema $SCHEMA does not exist"
+ exit 4
+fi
+
+xmllint --noout --relaxng $SCHEMA $XMLFILE
+
+exit 0
+
+: <<=cut
+=pod
+
+=head1 NAME
+
+ virt-xml-validate - validate libvirt XML files against a schema
+
+=head1 SYNOPSIS
+
+ virt-xml-validate XML-FILE [SCHEMA-NAME]
+
+=head1 DESCRIPTION
+
+Validates a libvirt XML for compliance with the published schema.
+The first compulsory argument is the path to the XML file to be
+validated. The optional second argument is the name of the schema
+to validate against. If omitted, the schema name will be inferred
+from the name of the root element in the XML document.
+
+Valid schema names currently include
+
+=over 4
+
+=item C<domain>
+
+The schema for the XML format used by guest domains configuration
+
+=item C<network>
+
+The schema for the XML format used by virtual network configuration
+
+=item C<storagepool>
+
+The schema for the XML format used by storage pool configuration
+
+=item C<storagevol>
+
+The schema for the XML format used by storage volume descriptions
+
+=item C<nodedev>
+
+The schema for the XML format used by node device descriptions
+
+=item C<capability>
+
+The schema for the XML format used to declare driver capabilities
+
+=back
+
+=head1 EXIT STATUS
+
+Upon successful validation, an exit status of 0 will be set. Upon
+failure a non-zero status will be set.
+
+=head1 AUTHOR
+
+Daniel P.Berrange
+
+=head1 BUGS
+
+Report any bugs discovered to the libvirt community via the
+mailing list C<http://libvirt.org/contact.html> or bug tracker C<http://libvirt.org/bugs.html>.
+Alternatively report bugs to your software distributor / vendor.
+
+=head1 COPYRIGHT
+
+Copyright 2009 by Red Hat, Inc
+Copyright 2009 by Daniel P. Berrange
+
+=head1 LICENSE
+
+virt-xml-validate is distributed under the terms of the GNU GPL v2+.
+This is free software; see the source for copying conditions. There
+is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE
+
+=head1 SEE ALSO
+
+C<virsh(1)>, online XML format descriptions C<http://libvirt.org/format.html>
+
+=cut
diff -r f861822d43db virsh.1
--- a/virsh.1 Thu Apr 16 10:34:11 2009 +0100
+++ b/virsh.1 Thu Apr 16 12:44:17 2009 +0100
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
+.\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.07)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -25,11 +25,11 @@
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
-.\" double quote, and \*(R" will give a right double quote. | will give a
-.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
-.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
-.\" expand to `' in nroff, nothing in troff, for use with C<>.
-.tr \(*W-|\(bv\*(Tr
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
@@ -48,22 +48,25 @@
. ds R" ''
'br\}
.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
-.if \nF \{\
+.ie \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. nr % 0
. rr F
.\}
-.\"
-.\" For nroff, turn off justification. Always turn off hyphenation; it makes
-.\" way too many mistakes in technical documents.
-.hy 0
-.if n .na
+.el \{\
+. de IX
+..
+.\}
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
@@ -129,7 +132,11 @@
.\" ========================================================================
.\"
.IX Title "VIRSH 1"
-.TH VIRSH 1 "2008-04-15" "perl v5.8.8" "Virtualization Support"
+.TH VIRSH 1 "2009-04-16" "libvirt-0.6.2" "Virtualization Support"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
.SH "NAME"
virsh \- management user interface
.SH "SYNOPSIS"
@@ -144,7 +151,7 @@ domains. It can also be used to list cur
The basic structure of most virsh usage is:
.PP
.Vb 1
-\& virsh <command> <domain-id> [OPTIONS]
+\& virsh <command> <domain\-id> [OPTIONS]
.Ve
.PP
Where \fIcommand\fR is one of the commands listed below, \fIdomain-id\fR
@@ -222,7 +229,7 @@ this is used to connect to the local Xen
allow to connect locally as root to the daemon supervising QEmu and \s-1KVM\s0 domains
.IP "qemu:///session" 4
.IX Item "qemu:///session"
-allow to connect locally as a normal user to the his own set of QEmu and \s-1KVM\s0 domains
+allow to connect locally as a normal user to his own set of QEmu and \s-1KVM\s0 domains
.RE
.RS 4
.Sp
@@ -261,54 +268,53 @@ An example format for the list is as fol
\&\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
.Sp
.Vb 2
-\& 0 Domain-0 running
+\& 0 Domain\-0 running
\& 2 fedora paused
.Ve
.Sp
Name is the name of the domain. \s-1ID\s0 the domain numeric id.
- State is the run state (see below).
+State is the run state (see below).
+.Sp
+\&\fB\s-1STATES\s0\fR
+.Sp
+The State field lists 6 states for a domain, and which ones the
+current domain is in.
+.RS 4
+.IP "\fBrunning\fR" 4
+.IX Item "running"
+The domain is currently running on a \s-1CPU\s0
+.IP "\fBidle\fR" 4
+.IX Item "idle"
+The domain is idle, and not running or runnable. This can be caused
+because the domain is waiting on \s-1IO\s0 (a traditional wait state) or has
+gone to sleep because there was nothing else for it to do.
+.IP "\fBpaused\fR" 4
+.IX Item "paused"
+The domain has been paused, usually occurring through the administrator
+running \fBvirsh suspend\fR. When in a paused state the domain will still
+consume allocated resources like memory, but will not be eligible for
+scheduling by the hypervisor.
+.IP "\fBshutdown\fR" 4
+.IX Item "shutdown"
+The domain is in the process of shutting down, i.e. the guest operating system
+has been notified and should be in the process of stopping its operations
+gracefully.
+.IP "\fBcrashed\fR" 4
+.IX Item "crashed"
+The domain has crashed, which is always a violent ending. Usually
+this state can only occur if the domain has been configured not to
+restart on crash.
+.IP "\fBdying\fR" 4
+.IX Item "dying"
+The domain is in process of dying, but hasn't completely shutdown or
+crashed.
+.RE
+.RS 4
+.RE
.IP "\fBfreecell\fR optional \fIcellno\fR" 4
.IX Item "freecell optional cellno"
Prints the available amount of memory on the machine or within a
\&\s-1NUMA\s0 cell if \fIcellno\fR is provided.
-.RS 4
-.Sp
-.RS 4
-\&\fB\s-1STATES\s0\fR
-.Sp
-The State field lists 6 states for a Xen Domain, and which ones the
-current Domain is in.
-.RE
-.IP "\fBr \- running\fR" 4
-.IX Item "r - running"
-The domain is currently running on a \s-1CPU\s0
-.IP "\fBb \- blocked\fR" 4
-.IX Item "b - blocked"
-The domain is blocked, and not running or runnable. This can be caused
-because the domain is waiting on \s-1IO\s0 (a traditional wait state) or has
-gone to sleep because there was nothing else for it to do.
-.IP "\fBp \- paused\fR" 4
-.IX Item "p - paused"
-The domain has been paused, usually occurring through the administrator
-running \fBxm pause\fR. When in a paused state the domain will still
-consume allocated resources like memory, but will not be eligible for
-scheduling by the Xen hypervisor.
-.IP "\fBs \- shutdown\fR" 4
-.IX Item "s - shutdown"
-The domain is in the process of shutting down, i.e. the guest operating system
-has been notified and should be in the process of stopping its operations
-gracefully.
-.IP "\fBc \- crashed\fR" 4
-.IX Item "c - crashed"
-The domain has crashed, which is always a violent ending. Usually
-this state can only occur if the domain has been configured not to
-restart on crash. See xmdomain.cfg for more info.
-.IP "\fBd \- dying\fR" 4
-.IX Item "d - dying"
-The domain is in process of dying, but hasn't completely shutdown or
-crashed.
-.RE
-.RS 4
.SH "DOMAIN COMMANDS"
.IX Header "DOMAIN COMMANDS"
The following commands manipulate domains directly, as stated
@@ -324,7 +330,7 @@ The option \fI\-\-disable\fR disable aut
Connect the virtual serial console for the guest.
.IP "\fBcreate\fR \fI\s-1FILE\s0\fR" 4
.IX Item "create FILE"
-Create a domain from an \s-1XML\s0 <file> an easy way to create one if you have a pre-existing xen guest created via \fBxm\fR create <\s-1XMLFILE\s0>.
+Create a domain from an \s-1XML\s0 <file>. An easy way to create the \s-1XML\s0 <file> is to use the \fBdumpxml\fR command to obtain the definition of a pre-existing guest.
.Sp
\&\fBExample\fR
.Sp
@@ -335,7 +341,7 @@ Define a domain from an \s-1XML\s0 <file
but not started.
.IP "\fBdestroy\fR \fIdomain-id\fR" 4
.IX Item "destroy domain-id"
-Immediately terminate the domain domain\-id. This doesn't give the domain
+Immediately terminate the domain domain-id. This doesn't give the domain
\&\s-1OS\s0 any chance to react, and it the equivalent of ripping the power
cord out on a physical machine. In most cases you will want to use
the \fBshutdown\fR command instead.
@@ -369,6 +375,18 @@ Dumps the core of a domain to a file for
.IP "\fBdumpxml\fR \fIdomain-id\fR" 4
.IX Item "dumpxml domain-id"
Output the domain information as an \s-1XML\s0 dump to stdout, this format can be used by the \fBcreate\fR command.
+.IP "\fBedit\fR \fIdomain-id\fR" 4
+.IX Item "edit domain-id"
+Edit the \s-1XML\s0 configuration file for a domain.
+.Sp
+This is equivalent to:
+ virsh dumpxml domain > domain.xml
+ edit domain.xml
+ virsh define domain.xml
+except that it does some error checking.
+.Sp
+The editor used can be supplied by the \f(CW$EDITOR\fR environment
+variable, or if that is not defined defaults to \f(CW\*(C`vi\*(C'\fR.
.IP "\fBmigrate\fR optional \fI\-\-live\fR \fIdomain-id\fR \fIdesturi\fR \fImigrateuri\fR" 4
.IX Item "migrate optional --live domain-id desturi migrateuri"
Migrate domain to another host. Add \-\-live for live migration. The \fIdesturi\fR
@@ -381,9 +399,8 @@ command run from the console. The comma
executed the reboot action, which may be significantly before the
domain actually reboots.
.Sp
-For xen vm the behavior of what happens to a domain when it reboots is set by the
-\&\fIon_reboot\fR parameter of the xmdomain.cfg file when the domain was
-created.
+The exact behavior of a domain when it reboots is set by the
+\&\fIon_reboot\fR parameter in the domain's \s-1XML\s0 definition.
.IP "\fBrestore\fR \fIstate-file\fR" 4
.IX Item "restore state-file"
Restores a domain from an \fBvirsh save\fR state file. See \fIsave\fR for more info.
@@ -397,12 +414,16 @@ other domains to use. \fBvirsh restore\
This is roughly equivalent to doing a hibernate on a running computer,
with all the same limitations. Open network connections may be
severed upon restore, as \s-1TCP\s0 timeouts may have expired.
+.IP "\fBschedinfo\fR optional \fI\-\-set\fR \fBparameter=value\fR \fIdomain-id\fR" 4
+.IX Item "schedinfo optional --set parameter=value domain-id"
+.PD 0
.IP "\fBschedinfo\fR optional \fI\-\-weight\fR \fBnumber\fR optional \fI\-\-cap\fR \fBnumber\fR \fIdomain-id\fR" 4
.IX Item "schedinfo optional --weight number optional --cap number domain-id"
-Allows to show (and set) the domain scheduler parameters. This is currently
-only defined for \s-1XEN_CREDIT\s0 scheduler, and the optional weight and cap
-arguments allows to set the associated parameters in that scheduler if
-provided.
+.PD
+Allows to show (and set) the domain scheduler parameters.
+.Sp
+\&\fBNote\fR: The weight and cap parameters are defined only for the
+\&\s-1XEN_CREDIT\s0 scheduler and are now \fI\s-1DEPRECATED\s0\fR.
.IP "\fBsetmem\fR \fIdomain-id\fR \fBkilobytes\fR" 4
.IX Item "setmem domain-id kilobytes"
Change the current memory allocation in the guest domain. This should take
@@ -431,9 +452,8 @@ to perform graceful shutdown, so there i
succeed, and may take a variable length of time depending on what
services must be shutdown in the domain.
.Sp
-For a xen guest vm the behavior of what happens to a domain when it reboots is set by the
-\&\fIon_shutdown\fR parameter of the xmdomain.cfg file when the domain was
-created.
+The exact behavior of a domain when it shuts down is set by the
+\&\fIon_shutdown\fR parameter in the domain's \s-1XML\s0 definition.
.IP "\fBstart\fR \fIdomain-name\fR" 4
.IX Item "start domain-name"
Start a (previously defined) inactive domain.
@@ -466,10 +486,8 @@ and \fIcpulist\fR is a comma separated l
.IX Item "vncdisplay domain-id"
Output the \s-1IP\s0 address and port number for the \s-1VNC\s0 display. If the information
is not available the processes will provide an exit code of 1.
-.RE
-.RS 4
-.SH "DEVICES COMMANDS"
-.IX Header "DEVICES COMMANDS"
+.SH "DEVICE COMMANDS"
+.IX Header "DEVICE COMMANDS"
The following commands manipulate devices associated to domains.
The domain-id can be specified as an short integer, a name or a full \s-1UUID\s0.
To better understand the values allowed as options for the command
@@ -509,10 +527,8 @@ Detach a network interface from a domain
\&\fItype\fR can be either \fInetwork\fR to indicate a physical network device or \fIbridge\fR to indicate a bridge to a device.
It is recommended to use the \fImac\fR option to distinguish between the interfaces
if more than one are present on the domain.
-.RE
-.RS 4
-.SH "VIRTUAL NETWORKS COMMANDS"
-.IX Header "VIRTUAL NETWORKS COMMANDS"
+.SH "VIRTUAL NETWORK COMMANDS"
+.IX Header "VIRTUAL NETWORK COMMANDS"
The following commands manipulate networks. Libvirt has the capability to
define virtual networks which can then be used by domains and linked to
actual network devices. For more detailed information about this feature
@@ -538,6 +554,18 @@ effect immediately.
.IP "\fBnet-dumpxml\fR \fInetwork\fR" 4
.IX Item "net-dumpxml network"
Output the virtual network information as an \s-1XML\s0 dump to stdout.
+.IP "\fBnet-edit\fR \fInetwork\fR" 4
+.IX Item "net-edit network"
+Edit the \s-1XML\s0 configuration file for a network.
+.Sp
+This is equivalent to:
+ virsh net-dumpxml network > network.xml
+ edit network.xml
+ virsh define network.xml
+except that it does some error checking.
+.Sp
+The editor used can be supplied by the \f(CW$EDITOR\fR environment
+variable, or if that is not defined defaults to \f(CW\*(C`vi\*(C'\fR.
.IP "\fBnet-list\fR optional \fI\-\-inactive\fR or \fI\-\-all\fR" 4
.IX Item "net-list optional --inactive or --all"
Returns the list of active networks, if \fI\-\-all\fR is specified this will also
@@ -555,34 +583,63 @@ Undefine the configuration for an inacti
.IP "\fBnet-uuid\fR \fInetwork-name\fR" 4
.IX Item "net-uuid network-name"
Convert a network name to network \s-1UUID\s0.
-.RE
-.RS 4
.SH "ENVIRONMENT"
.IX Header "ENVIRONMENT"
+The following environment variables can be set to alter the behaviour
+of \f(CW\*(C`virsh\*(C'\fR
.IP "\s-1VIRSH_DEFAULT_CONNECT_URI\s0" 4
.IX Item "VIRSH_DEFAULT_CONNECT_URI"
The hypervisor to connect to by default. Set this to a \s-1URI\s0, in the same
format as accepted by the \fBconnect\fR option.
+.IP "LIBVIRT_DEBUG=LEVEL" 4
+.IX Item "LIBVIRT_DEBUG=LEVEL"
+Turn on verbose debugging of all libvirt \s-1API\s0 calls. Valid levels are
+.RS 4
+.IP "\(bu" 4
+LIBVIRT_DEBUG=1
+.Sp
+Messages at level \s-1DEBUG\s0 or above
+.IP "\(bu" 4
+LIBVIRT_DEBUG=2
+.Sp
+Messages at level \s-1INFO\s0 or above
+.IP "\(bu" 4
+LIBVIRT_DEBUG=3
+.Sp
+Messages at level \s-1WARNING\s0 or above
+.IP "\(bu" 4
+LIBVIRT_DEBUG=4
+.Sp
+Messages at level \s-1ERROR\s0 or above
.RE
.RS 4
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIxm\fR\|(1), \fIxmdomain.cfg\fR\|(5), \fIxentop\fR\|(1) , <http://www.libvirt.org/>
-.SH "AUTHOR"
-.IX Header "AUTHOR"
+.Sp
+For further information about debugging options consult \f(CW\*(C`http://libvirt.org/logging.html\*(C'\fR
+.RE
+.SH "BUGS"
+.IX Header "BUGS"
+Report any bugs discovered to the libvirt community via the mailing
+list \f(CW\*(C`http://libvirt.org/contact.html\*(C'\fR or bug tracker \f(CW\*(C`http://libvirt.org/bugs.html\*(C'\fR.
+Alternatively report bugs to your software distributor / vendor.
+.SH "AUTHORS"
+.IX Header "AUTHORS"
.Vb 2
\& Andrew Puch <apuch @ redhat.com>
\& Daniel Veillard <veillard @ redhat.com>
-.Ve
-.Sp
-.Vb 3
-\& Based on the xm man paged by
+\&
+\& Based on the xm man page by:
\& Sean Dague <sean at dague dot net>
\& Daniel Stekloff <dsteklof at us dot ibm dot com>
.Ve
-.SH "BUGS"
-.IX Header "BUGS"
-Bugs can be view on the RedHat buzilla page under the libvirt
-<https://bugzilla.redhat.com/>
-.Sp
-<https://bugzilla.redhat.com/bugzilla/buglist.cgi?product=Fedora+Core&compon…>
+.SH "COPYRIGHT"
+.IX Header "COPYRIGHT"
+Copyright (C) 2005, 2007\-2009 Red Hat, Inc.
+.SH "LICENSE"
+.IX Header "LICENSE"
+virsh is distributed under the terms of the \s-1GNU\s0 \s-1LGPL\s0 v2+.
+This is free software; see the source for copying conditions. There
+is \s-1NO\s0 warranty; not even for \s-1MERCHANTABILITY\s0 or \s-1FITNESS\s0 \s-1FOR\s0 A \s-1PARTICULAR\s0
+\&\s-1PURPOSE\s0
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIvirt\-install\fR\|(1), \fIvirt\-xml\-validate\fR\|(1), \fIvirt\-top\fR\|(1), \fIvirt\-mem\fR\|(1), \fIvirt\-df\fR\|(1), <http://www.libvirt.org/>
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
2
5
[libvirt] PATCH: Use virDomainDefPtr to build QEMU args instead of virDomainObjPtr
by Daniel P. Berrange 20 Apr '09
by Daniel P. Berrange 20 Apr '09
20 Apr '09
This is a fairly simple NFC patch which changes the QEMU driver to use
the virDomainDefPtr object when building command line arguments instead
of the virDomainObjPtr. The command line building only needs the config,
and none of the state, so virDomainDefPtr was more applicable.
This was a pre-requisite for another patch I wrote, but have since
thrown away. I think this one is worth applying anyway as a general
cleanup.
Daniel
diff -r bd965abde333 src/qemu_conf.c
--- a/src/qemu_conf.c Tue Apr 14 13:00:20 2009 +0100
+++ b/src/qemu_conf.c Thu Apr 16 10:34:10 2009 +0100
@@ -756,7 +756,7 @@ static int qemudBuildCommandLineChrDevSt
*/
int qemudBuildCommandLine(virConnectPtr conn,
struct qemud_driver *driver,
- virDomainObjPtr vm,
+ virDomainDefPtr def,
unsigned int qemuCmdFlags,
const char ***retargv,
const char ***retenv,
@@ -782,7 +782,7 @@ int qemudBuildCommandLine(virConnectPtr
uname_normalize(&ut);
- virUUIDFormat(vm->def->uuid, uuid);
+ virUUIDFormat(def->uuid, uuid);
/* Migration is very annoying due to wildly varying syntax & capabilities
* over time of KVM / QEMU codebases
@@ -811,9 +811,9 @@ int qemudBuildCommandLine(virConnectPtr
}
}
- emulator = vm->def->emulator;
+ emulator = def->emulator;
if (!emulator)
- emulator = virDomainDefDefaultEmulator(conn, vm->def, driver->caps);
+ emulator = virDomainDefDefaultEmulator(conn, def, driver->caps);
if (!emulator)
return -1;
@@ -824,8 +824,8 @@ int qemudBuildCommandLine(virConnectPtr
* 3. The qemu binary has the -no-kqemu flag
*/
if ((qemuCmdFlags & QEMUD_CMD_FLAG_KQEMU) &&
- STREQ(ut.machine, vm->def->os.arch) &&
- vm->def->virtType == VIR_DOMAIN_VIRT_QEMU)
+ STREQ(ut.machine, def->os.arch) &&
+ def->virtType == VIR_DOMAIN_VIRT_QEMU)
disableKQEMU = 1;
/* Need to explicitly disable KVM if
@@ -834,8 +834,8 @@ int qemudBuildCommandLine(virConnectPtr
* 3. The qemu binary has the -no-kvm flag
*/
if ((qemuCmdFlags & QEMUD_CMD_FLAG_KVM) &&
- STREQ(ut.machine, vm->def->os.arch) &&
- vm->def->virtType == VIR_DOMAIN_VIRT_QEMU)
+ STREQ(ut.machine, def->os.arch) &&
+ def->virtType == VIR_DOMAIN_VIRT_QEMU)
disableKVM = 1;
/*
@@ -850,7 +850,7 @@ int qemudBuildCommandLine(virConnectPtr
* 1. guest OS is i686
* 2. emulator is qemu-system-x86_64
*/
- if (STREQ(vm->def->os.arch, "i686") &&
+ if (STREQ(def->os.arch, "i686") &&
((STREQ(ut.machine, "x86_64") &&
strstr(emulator, "kvm")) ||
strstr(emulator, "x86_64")))
@@ -931,10 +931,10 @@ int qemudBuildCommandLine(virConnectPtr
* is set post-startup using the balloon driver. If balloon driver
* is not supported, then they're out of luck anyway
*/
- snprintf(memory, sizeof(memory), "%lu", vm->def->maxmem/1024);
- snprintf(vcpus, sizeof(vcpus), "%lu", vm->def->vcpus);
- snprintf(domid, sizeof(domid), "%d", vm->def->id);
- pidfile = virFilePid(driver->stateDir, vm->def->name);
+ snprintf(memory, sizeof(memory), "%lu", def->maxmem/1024);
+ snprintf(vcpus, sizeof(vcpus), "%lu", def->vcpus);
+ snprintf(domid, sizeof(domid), "%d", def->id);
+ pidfile = virFilePid(driver->stateDir, def->name);
if (!pidfile)
goto error;
@@ -955,9 +955,9 @@ int qemudBuildCommandLine(virConnectPtr
* a machine in the capabilities data for QEMU. So this
* check is just here as a safety in case the unexpected
* happens */
- if (vm->def->os.machine) {
+ if (def->os.machine) {
ADD_ARG_LIT("-M");
- ADD_ARG_LIT(vm->def->os.machine);
+ ADD_ARG_LIT(def->os.machine);
}
if (cpu) {
ADD_ARG_LIT("-cpu");
@@ -975,7 +975,7 @@ int qemudBuildCommandLine(virConnectPtr
if (qemuCmdFlags & QEMUD_CMD_FLAG_NAME) {
ADD_ARG_LIT("-name");
- ADD_ARG_LIT(vm->def->name);
+ ADD_ARG_LIT(def->name);
}
if (qemuCmdFlags & QEMUD_CMD_FLAG_UUID) {
ADD_ARG_LIT("-uuid");
@@ -993,7 +993,7 @@ int qemudBuildCommandLine(virConnectPtr
* if you ask for nographic. So we have to make sure we override
* these defaults ourselves...
*/
- if (!vm->def->graphics)
+ if (!def->graphics)
ADD_ARG_LIT("-nographic");
ADD_ARG_LIT("-monitor");
@@ -1002,19 +1002,19 @@ int qemudBuildCommandLine(virConnectPtr
ADD_ARG_LIT("-pidfile");
ADD_ARG(pidfile);
- if (vm->def->localtime)
+ if (def->localtime)
ADD_ARG_LIT("-localtime");
if ((qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT) &&
- vm->def->onReboot != VIR_DOMAIN_LIFECYCLE_RESTART)
+ def->onReboot != VIR_DOMAIN_LIFECYCLE_RESTART)
ADD_ARG_LIT("-no-reboot");
- if (!(vm->def->features & (1 << VIR_DOMAIN_FEATURE_ACPI)))
+ if (!(def->features & (1 << VIR_DOMAIN_FEATURE_ACPI)))
ADD_ARG_LIT("-no-acpi");
- if (!vm->def->os.bootloader) {
- for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
- switch (vm->def->os.bootDevs[i]) {
+ if (!def->os.bootloader) {
+ for (i = 0 ; i < def->os.nBootDevs ; i++) {
+ switch (def->os.bootDevs[i]) {
case VIR_DOMAIN_BOOT_CDROM:
boot[i] = 'd';
break;
@@ -1032,29 +1032,29 @@ int qemudBuildCommandLine(virConnectPtr
break;
}
}
- boot[vm->def->os.nBootDevs] = '\0';
+ boot[def->os.nBootDevs] = '\0';
ADD_ARG_LIT("-boot");
ADD_ARG_LIT(boot);
- if (vm->def->os.kernel) {
+ if (def->os.kernel) {
ADD_ARG_LIT("-kernel");
- ADD_ARG_LIT(vm->def->os.kernel);
+ ADD_ARG_LIT(def->os.kernel);
}
- if (vm->def->os.initrd) {
+ if (def->os.initrd) {
ADD_ARG_LIT("-initrd");
- ADD_ARG_LIT(vm->def->os.initrd);
+ ADD_ARG_LIT(def->os.initrd);
}
- if (vm->def->os.cmdline) {
+ if (def->os.cmdline) {
ADD_ARG_LIT("-append");
- ADD_ARG_LIT(vm->def->os.cmdline);
+ ADD_ARG_LIT(def->os.cmdline);
}
} else {
ADD_ARG_LIT("-bootloader");
- ADD_ARG_LIT(vm->def->os.bootloader);
+ ADD_ARG_LIT(def->os.bootloader);
}
- for (i = 0 ; i < vm->def->ndisks ; i++) {
- virDomainDiskDefPtr disk = vm->def->disks[i];
+ for (i = 0 ; i < def->ndisks ; i++) {
+ virDomainDiskDefPtr disk = def->disks[i];
if (disk->driverName != NULL &&
!STREQ(disk->driverName, "qemu")) {
@@ -1071,8 +1071,8 @@ int qemudBuildCommandLine(virConnectPtr
/* If QEMU supports boot=on for -drive param... */
if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_BOOT) {
- for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
- switch (vm->def->os.bootDevs[i]) {
+ for (i = 0 ; i < def->os.nBootDevs ; i++) {
+ switch (def->os.bootDevs[i]) {
case VIR_DOMAIN_BOOT_CDROM:
bootCD = 1;
break;
@@ -1086,11 +1086,11 @@ int qemudBuildCommandLine(virConnectPtr
}
}
- for (i = 0 ; i < vm->def->ndisks ; i++) {
+ for (i = 0 ; i < def->ndisks ; i++) {
virBuffer opt = VIR_BUFFER_INITIALIZER;
char *optstr;
int bootable = 0;
- virDomainDiskDefPtr disk = vm->def->disks[i];
+ virDomainDiskDefPtr disk = def->disks[i];
int idx = virDiskNameToIndex(disk->dst);
const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
@@ -1159,10 +1159,10 @@ int qemudBuildCommandLine(virConnectPtr
ADD_ARG(optstr);
}
} else {
- for (i = 0 ; i < vm->def->ndisks ; i++) {
+ for (i = 0 ; i < def->ndisks ; i++) {
char dev[NAME_MAX];
char file[PATH_MAX];
- virDomainDiskDefPtr disk = vm->def->disks[i];
+ virDomainDiskDefPtr disk = def->disks[i];
if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
@@ -1200,14 +1200,14 @@ int qemudBuildCommandLine(virConnectPtr
}
}
- if (!vm->def->nnets) {
+ if (!def->nnets) {
ADD_ARG_LIT("-net");
ADD_ARG_LIT("none");
} else {
int vlan = 0;
- for (i = 0 ; i < vm->def->nnets ; i++) {
+ for (i = 0 ; i < def->nnets ; i++) {
char nic[100];
- virDomainNetDefPtr net = vm->def->nets[i];
+ virDomainNetDefPtr net = def->nets[i];
if (snprintf(nic, sizeof(nic),
"nic,macaddr=%02x:%02x:%02x:%02x:%02x:%02x,vlan=%d%s%s",
@@ -1306,13 +1306,13 @@ int qemudBuildCommandLine(virConnectPtr
}
}
- if (!vm->def->nserials) {
+ if (!def->nserials) {
ADD_ARG_LIT("-serial");
ADD_ARG_LIT("none");
} else {
- for (i = 0 ; i < vm->def->nserials ; i++) {
+ for (i = 0 ; i < def->nserials ; i++) {
char buf[4096];
- virDomainChrDefPtr serial = vm->def->serials[i];
+ virDomainChrDefPtr serial = def->serials[i];
if (qemudBuildCommandLineChrDevStr(serial, buf, sizeof(buf)) < 0)
goto error;
@@ -1322,13 +1322,13 @@ int qemudBuildCommandLine(virConnectPtr
}
}
- if (!vm->def->nparallels) {
+ if (!def->nparallels) {
ADD_ARG_LIT("-parallel");
ADD_ARG_LIT("none");
} else {
- for (i = 0 ; i < vm->def->nparallels ; i++) {
+ for (i = 0 ; i < def->nparallels ; i++) {
char buf[4096];
- virDomainChrDefPtr parallel = vm->def->parallels[i];
+ virDomainChrDefPtr parallel = def->parallels[i];
if (qemudBuildCommandLineChrDevStr(parallel, buf, sizeof(buf)) < 0)
goto error;
@@ -1339,8 +1339,8 @@ int qemudBuildCommandLine(virConnectPtr
}
ADD_ARG_LIT("-usb");
- for (i = 0 ; i < vm->def->ninputs ; i++) {
- virDomainInputDefPtr input = vm->def->inputs[i];
+ for (i = 0 ; i < def->ninputs ; i++) {
+ virDomainInputDefPtr input = def->inputs[i];
if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
ADD_ARG_LIT("-usbdevice");
@@ -1348,21 +1348,21 @@ int qemudBuildCommandLine(virConnectPtr
}
}
- if (vm->def->graphics &&
- vm->def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
+ if (def->graphics &&
+ def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
virBuffer opt = VIR_BUFFER_INITIALIZER;
char *optstr;
if (qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) {
- if (vm->def->graphics->data.vnc.listenAddr)
- virBufferAdd(&opt, vm->def->graphics->data.vnc.listenAddr, -1);
+ if (def->graphics->data.vnc.listenAddr)
+ virBufferAdd(&opt, def->graphics->data.vnc.listenAddr, -1);
else if (driver->vncListen)
virBufferAdd(&opt, driver->vncListen, -1);
virBufferVSprintf(&opt, ":%d",
- vm->def->graphics->data.vnc.port - 5900);
+ def->graphics->data.vnc.port - 5900);
- if (vm->def->graphics->data.vnc.passwd ||
+ if (def->graphics->data.vnc.passwd ||
driver->vncPassword)
virBufferAddLit(&opt, ",password");
@@ -1387,7 +1387,7 @@ int qemudBuildCommandLine(virConnectPtr
}
} else {
virBufferVSprintf(&opt, "%d",
- vm->def->graphics->data.vnc.port - 5900);
+ def->graphics->data.vnc.port - 5900);
}
if (virBufferError(&opt))
goto no_memory;
@@ -1396,22 +1396,22 @@ int qemudBuildCommandLine(virConnectPtr
ADD_ARG_LIT("-vnc");
ADD_ARG(optstr);
- if (vm->def->graphics->data.vnc.keymap) {
+ if (def->graphics->data.vnc.keymap) {
ADD_ARG_LIT("-k");
- ADD_ARG_LIT(vm->def->graphics->data.vnc.keymap);
+ ADD_ARG_LIT(def->graphics->data.vnc.keymap);
}
- } else if (vm->def->graphics &&
- vm->def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
+ } else if (def->graphics &&
+ def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
char *xauth = NULL;
char *display = NULL;
- if (vm->def->graphics->data.sdl.xauth &&
+ if (def->graphics->data.sdl.xauth &&
virAsprintf(&xauth, "XAUTHORITY=%s",
- vm->def->graphics->data.sdl.xauth) < 0)
+ def->graphics->data.sdl.xauth) < 0)
goto no_memory;
- if (vm->def->graphics->data.sdl.display &&
+ if (def->graphics->data.sdl.display &&
virAsprintf(&display, "DISPLAY=%s",
- vm->def->graphics->data.sdl.display) < 0) {
+ def->graphics->data.sdl.display) < 0) {
VIR_FREE(xauth);
goto no_memory;
}
@@ -1420,19 +1420,19 @@ int qemudBuildCommandLine(virConnectPtr
ADD_ENV(xauth);
if (display)
ADD_ENV(display);
- if (vm->def->graphics->data.sdl.fullscreen)
+ if (def->graphics->data.sdl.fullscreen)
ADD_ARG_LIT("-full-screen");
}
/* Add sound hardware */
- if (vm->def->nsounds) {
+ if (def->nsounds) {
int size = 100;
char *modstr;
if (VIR_ALLOC_N(modstr, size+1) < 0)
goto no_memory;
- for (i = 0 ; i < vm->def->nsounds && size > 0 ; i++) {
- virDomainSoundDefPtr sound = vm->def->sounds[i];
+ for (i = 0 ; i < def->nsounds && size > 0 ; i++) {
+ virDomainSoundDefPtr sound = def->sounds[i];
const char *model = virDomainSoundModelTypeToString(sound->model);
if (!model) {
VIR_FREE(modstr);
@@ -1442,7 +1442,7 @@ int qemudBuildCommandLine(virConnectPtr
}
strncat(modstr, model, size);
size -= strlen(model);
- if (i < (vm->def->nsounds - 1))
+ if (i < (def->nsounds - 1))
strncat(modstr, ",", size--);
}
ADD_ARG_LIT("-soundhw");
@@ -1450,11 +1450,11 @@ int qemudBuildCommandLine(virConnectPtr
}
/* Add host passthrough hardware */
- for (i = 0 ; i < vm->def->nhostdevs ; i++) {
+ for (i = 0 ; i < def->nhostdevs ; i++) {
int ret;
char* usbdev;
char* pcidev;
- virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
+ virDomainHostdevDefPtr hostdev = def->hostdevs[i];
/* USB */
if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
diff -r bd965abde333 src/qemu_conf.h
--- a/src/qemu_conf.h Tue Apr 14 13:00:20 2009 +0100
+++ b/src/qemu_conf.h Thu Apr 16 10:34:10 2009 +0100
@@ -124,7 +124,7 @@ int qemudExtractVersionInfo
int qemudBuildCommandLine (virConnectPtr conn,
struct qemud_driver *driver,
- virDomainObjPtr dom,
+ virDomainDefPtr def,
unsigned int qemuCmdFlags,
const char ***retargv,
const char ***retenv,
diff -r bd965abde333 src/qemu_driver.c
--- a/src/qemu_driver.c Tue Apr 14 13:00:20 2009 +0100
+++ b/src/qemu_driver.c Thu Apr 16 10:34:10 2009 +0100
@@ -1390,7 +1390,7 @@ static int qemudStartVMDaemon(virConnect
goto cleanup;
vm->def->id = driver->nextvmid++;
- if (qemudBuildCommandLine(conn, driver, vm,
+ if (qemudBuildCommandLine(conn, driver, vm->def,
qemuCmdFlags, &argv, &progenv,
&tapfds, &ntapfds, migrateFrom) < 0)
goto cleanup;
diff -r bd965abde333 tests/qemuxml2argvtest.c
--- a/tests/qemuxml2argvtest.c Tue Apr 14 13:00:20 2009 +0100
+++ b/tests/qemuxml2argvtest.c Thu Apr 16 10:34:10 2009 +0100
@@ -34,7 +34,6 @@ static int testCompareXMLToArgvFiles(con
const char **tmp = NULL;
int ret = -1, len, flags;
virDomainDefPtr vmdef = NULL;
- virDomainObj vm;
if (virtTestLoadFile(cmd, &expectargv, MAX_FILE) < 0)
goto fail;
@@ -43,20 +42,17 @@ static int testCompareXMLToArgvFiles(con
VIR_DOMAIN_XML_INACTIVE)))
goto fail;
- memset(&vm, 0, sizeof vm);
- vm.def = vmdef;
if (extraFlags & QEMUD_CMD_FLAG_DOMID)
- vm.def->id = 6;
+ vmdef->id = 6;
else
- vm.def->id = -1;
- vm.pid = -1;
+ vmdef->id = -1;
flags = QEMUD_CMD_FLAG_VNC_COLON |
QEMUD_CMD_FLAG_NO_REBOOT |
extraFlags;
if (qemudBuildCommandLine(NULL, &driver,
- &vm, flags, &argv, &qenv,
+ vmdef, flags, &argv, &qenv,
NULL, NULL, migrateFrom) < 0)
goto fail;
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
2
2
20 Apr '09
The virDomainAssignDef method currently uses the 'name' field to lookup
domains. The UUID is the best internal identifier, so this changes over
to use that instead.
Daniel
diff -r 4b9560b57861 src/domain_conf.c
--- a/src/domain_conf.c Fri Apr 17 11:50:54 2009 +0100
+++ b/src/domain_conf.c Fri Apr 17 12:05:11 2009 +0100
@@ -498,7 +498,7 @@ virDomainObjPtr virDomainAssignDef(virCo
{
virDomainObjPtr domain;
- if ((domain = virDomainFindByName(doms, def->name))) {
+ if ((domain = virDomainFindByUUID(doms, def->uuid))) {
if (!virDomainIsActive(domain)) {
virDomainDefFree(domain->def);
domain->def = def;
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
2
2
[libvirt] PATCH: Fix remote driver create/destroy methods to update ID field
by Daniel P. Berrange 20 Apr '09
by Daniel P. Berrange 20 Apr '09
20 Apr '09
If you have an existing virDomainPtr object, and start it using the
virDomainCreate(virDomainPtr dom) method, then internal cached 'id'
field in the virDomainPtr object is never updated. Even more annoyingly
the remote protocol for the 'create' method doesn't even bother to
return the ID of the newly started guest. Thre is a similar problem
with the virDomainDestroy method, not resetting the cached 'id' back
to -1.
We can't guarentee that the 'id' field is up2date wrt to changes made
by another libvirt client, but we can at least make sure its accurate
wrt to changes this client is making. For the destroy method the fix
is trivial. For the create method, after a successful creation, we do
a lookup based on UUID to fetch the real live ID, since the create
method didn't return it for us.
This fixes a significant number of problems identified by the TCK on
the QEMU driver usage.
Regards,
Daniel
diff -r 9ff786a7908d src/remote_internal.c
--- a/src/remote_internal.c Fri Apr 17 12:05:11 2009 +0100
+++ b/src/remote_internal.c Fri Apr 17 12:06:21 2009 +0100
@@ -1939,6 +1939,7 @@ remoteDomainDestroy (virDomainPtr domain
goto done;
rv = 0;
+ domain->id = -1;
done:
remoteDriverUnlock(priv);
@@ -2735,6 +2736,8 @@ remoteDomainCreate (virDomainPtr domain)
{
int rv = -1;
remote_domain_create_args args;
+ remote_domain_lookup_by_uuid_args args2;
+ remote_domain_lookup_by_uuid_ret ret2;
struct private_data *priv = domain->conn->privateData;
remoteDriverLock(priv);
@@ -2746,6 +2749,16 @@ remoteDomainCreate (virDomainPtr domain)
(xdrproc_t) xdr_void, (char *) NULL) == -1)
goto done;
+ memcpy (args2.uuid, domain->uuid, VIR_UUID_BUFLEN);
+ memset (&ret2, 0, sizeof ret2);
+ if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_LOOKUP_BY_UUID,
+ (xdrproc_t) xdr_remote_domain_lookup_by_uuid_args, (char *) &args2,
+ (xdrproc_t) xdr_remote_domain_lookup_by_uuid_ret, (char *) &ret2) == -1)
+ goto done;
+
+ domain->id = ret2.dom.id;
+ xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_uuid_ret, (char *) &ret2);
+
rv = 0;
done:
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
2
2
[libvirt] PATCH: Improve error reporting for operations on inactive domains
by Daniel P. Berrange 20 Apr '09
by Daniel P. Berrange 20 Apr '09
20 Apr '09
If you try todo an operation on an inactive QEMU guest which is not
applicable, eg ask to pause an inactive guest, then you currently get
a useless message
# virsh suspend demo
error: Failed to suspend domain demo
error: invalid domain pointer in no domain with matching id -1
There are two issues here
- The QEMU driver is mistakenly doing a lookup-by-id when locating the
guest in question. It should in fact do lookup-by-uuid for all APIs
since that's the best unique identifier.
- It was using VIR_ERR_INVALID_DOMAIN code instead of VIR_ERR_NO_DOMAIN
code, hence the 'invalid domain pointer' bogus message.
This patch changes all QEMU APIs to lookup based on UUID, and use the
correct VIR_ERR_NO_DOMAIN code when reporting failures.
You now get to see the real useful error message later in the API where
it validates whether the guest is running or not
# virsh suspend demo
error: Failed to suspend domain demo
error: operation failed: domain is not running
One thing I'm wondering, is whether we should introduce an explicit error
code for operations that are not applicable.
eg, instead of giving VIR_ERR_OPERATION_FAILED, we could give back a code
like VIR_ERR_OPERATION_INVALID. This would let callers distinguish
real failure of the operation, vs the fact that it simply isn't applicable
for inactive guests.
Daniel
diff -r 5b88ef324d90 src/qemu_driver.c
--- a/src/qemu_driver.c Fri Apr 17 12:06:21 2009 +0100
+++ b/src/qemu_driver.c Fri Apr 17 12:32:54 2009 +0100
@@ -1984,7 +1984,8 @@ static virDomainPtr qemudDomainLookupByI
qemuDriverUnlock(driver);
if (!vm) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching id %d"), id);
goto cleanup;
}
@@ -2008,7 +2009,10 @@ static virDomainPtr qemudDomainLookupByU
qemuDriverUnlock(driver);
if (!vm) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(uuid, uuidstr);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuid);
goto cleanup;
}
@@ -2032,7 +2036,8 @@ static virDomainPtr qemudDomainLookupByN
qemuDriverUnlock(driver);
if (!vm) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching name '%s'"), name);
goto cleanup;
}
@@ -2182,11 +2187,14 @@ static int qemudDomainSuspend(virDomainP
virDomainEventPtr event = NULL;
qemuDriverLock(driver);
- vm = virDomainFindByID(&driver->domains, dom->id);
- qemuDriverUnlock(driver);
-
- if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, _("no domain with matching id %d"), dom->id);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
if (!virDomainIsActive(vm)) {
@@ -2232,12 +2240,14 @@ static int qemudDomainResume(virDomainPt
virDomainEventPtr event = NULL;
qemuDriverLock(driver);
- vm = virDomainFindByID(&driver->domains, dom->id);
- qemuDriverUnlock(driver);
-
- if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- _("no domain with matching id %d"), dom->id);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
if (!virDomainIsActive(vm)) {
@@ -2281,12 +2291,14 @@ static int qemudDomainShutdown(virDomain
int ret = -1;
qemuDriverLock(driver);
- vm = virDomainFindByID(&driver->domains, dom->id);
- qemuDriverUnlock(driver);
-
- if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- _("no domain with matching id %d"), dom->id);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -2312,10 +2324,12 @@ static int qemudDomainDestroy(virDomainP
virDomainEventPtr event = NULL;
qemuDriverLock(driver);
- vm = virDomainFindByID(&driver->domains, dom->id);
- if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- _("no domain with matching id %d"), dom->id);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -2349,8 +2363,10 @@ static char *qemudDomainGetOSType(virDom
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
qemuDriverUnlock(driver);
if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -2375,9 +2391,8 @@ static unsigned long qemudDomainGetMaxMe
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
-
- virUUIDFormat(dom->uuid, uuidstr);
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
_("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -2401,9 +2416,8 @@ static int qemudDomainSetMaxMemory(virDo
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
-
- virUUIDFormat(dom->uuid, uuidstr);
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
_("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -2525,9 +2539,8 @@ static int qemudDomainSetMemory(virDomai
qemuDriverUnlock(driver);
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
-
- virUUIDFormat(dom->uuid, uuidstr);
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
_("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -2566,8 +2579,10 @@ static int qemudDomainGetInfo(virDomainP
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
qemuDriverUnlock(driver);
if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -2713,11 +2728,13 @@ static int qemudDomainSave(virDomainPtr
header.version = QEMUD_SAVE_VERSION;
qemuDriverLock(driver);
- vm = virDomainFindByID(&driver->domains, dom->id);
-
- if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- _("no domain with matching id %d"), dom->id);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -2850,9 +2867,8 @@ static int qemudDomainSetVcpus(virDomain
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
-
- virUUIDFormat(dom->uuid, uuidstr);
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
_("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -3045,9 +3061,8 @@ static int qemudDomainGetMaxVcpus(virDom
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
-
- virUUIDFormat(dom->uuid, uuidstr);
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
_("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -3080,9 +3095,8 @@ static int qemudDomainGetSecurityLabel(v
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
-
- virUUIDFormat(dom->uuid, uuidstr);
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
_("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -3294,8 +3308,10 @@ static char *qemudDomainDumpXML(virDomai
qemuDriverUnlock(driver);
if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -3496,8 +3512,10 @@ static int qemudDomainStart(virDomainPtr
qemuDriverUnlock(driver);
if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -3586,8 +3604,10 @@ static int qemudDomainUndefine(virDomain
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -3979,9 +3999,11 @@ static int qemudDomainAttachDevice(virDo
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
- qemuDriverUnlock(driver);
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ qemuDriverUnlock(driver);
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -4129,9 +4151,11 @@ static int qemudDomainDetachDevice(virDo
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
- qemuDriverUnlock(driver);
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ qemuDriverUnlock(driver);
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -4182,8 +4206,10 @@ static int qemudDomainGetAutostart(virDo
qemuDriverUnlock(driver);
if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -4208,8 +4234,10 @@ static int qemudDomainSetAutostart(virDo
qemuDriverUnlock(driver);
if (!vm) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -4283,11 +4311,13 @@ qemudDomainBlockStats (virDomainPtr dom,
virDomainDiskDefPtr disk = NULL;
qemuDriverLock(driver);
- vm = virDomainFindByID(&driver->domains, dom->id);
- qemuDriverUnlock(driver);
- if (!vm) {
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- _("no domain with matching id %d"), dom->id);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
if (!virDomainIsActive (vm)) {
@@ -4418,12 +4448,14 @@ qemudDomainInterfaceStats (virDomainPtr
int ret = -1;
qemuDriverLock(driver);
- vm = virDomainFindByID(&driver->domains, dom->id);
- qemuDriverUnlock(driver);
-
- if (!vm) {
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- _("no domain with matching id %d"), dom->id);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -4486,8 +4518,10 @@ qemudDomainBlockPeek (virDomainPtr dom,
qemuDriverUnlock(driver);
if (!vm) {
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- "%s", _("no domain with matching uuid"));
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -4554,12 +4588,14 @@ qemudDomainMemoryPeek (virDomainPtr dom,
int fd = -1, ret = -1;
qemuDriverLock(driver);
- vm = virDomainFindByID(&driver->domains, dom->id);
- qemuDriverUnlock(driver);
-
- if (!vm) {
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- _("no domain with matching id %d"), dom->id);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -4887,10 +4923,12 @@ qemudDomainMigratePerform (virDomainPtr
int paused = 0;
qemuDriverLock(driver);
- vm = virDomainFindByID(&driver->domains, dom->id);
- if (!vm) {
- qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
- _("no domain with matching id %d"), dom->id);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
@@ -5018,8 +5056,8 @@ qemudDomainMigrateFinish2 (virConnectPtr
qemuDriverLock(driver);
vm = virDomainFindByName(&driver->domains, dname);
if (!vm) {
- qemudReportError (dconn, NULL, NULL, VIR_ERR_INVALID_DOMAIN,
- _("no domain with matching name %s"), dname);
+ qemudReportError (dconn, NULL, NULL, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching name '%s'"), dname);
goto cleanup;
}
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
2
2
[libvirt] [PATCH 1/1] lxc: only do CLONE_NEWUSER when kernel supports it
by Serge E. Hallyn 20 Apr '09
by Serge E. Hallyn 20 Apr '09
20 Apr '09
I was trying to get the lxc driver to work on ubuntu jaunty. This
patch gets me further than I was getting before. Like I say below,
it's probably not the right way though.
-serge
>From 2513f8a7e0654e84570fe0ef2204dabe276b9e4e Mon Sep 17 00:00:00 2001
From: root <root(a)jaunty.(none)>
Date: Fri, 17 Apr 2009 16:41:01 -0500
Subject: [PATCH 1/1] lxc: only do CLONE_NEWUSER when kernel supports it
The ubuntu jaunty kernel is not compiled with USER_NS. Since
libvirt-lxc always does clone(CLONE_NEWUSER) it gets -EINVAL
and mysteriously claims to be unable to contact hypervisor.
This patch isn't the right thing to do, but I'm not sure what
is. User namespaces do (since recently) isolate the in-kernel
keyring. So the right thing might be to add a flag to the
xml definition file to specify whether to use a user namespace.
This patch doesn't do that, rather it always does CLONE_NEWUSER
if the kernel supports it, and never if not.
Signed-off-by: Serge Hallyn <serue(a)us.ibm.com>
---
src/lxc_container.c | 15 +++++++++++++--
src/lxc_container.h | 1 +
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/lxc_container.c b/src/lxc_container.c
index 67c66bd..8069af7 100644
--- a/src/lxc_container.c
+++ b/src/lxc_container.c
@@ -666,6 +666,11 @@ static int lxcContainerChild( void *data )
return lxcContainerExecInit(vmDef);
}
+int userns_supported(void)
+{
+ return lxcContainerAvailable(LXC_CONTAINER_FEATURE_USER) == 0;
+}
+
/**
* lxcContainerStart:
* @driver: pointer to driver structure
@@ -694,7 +699,10 @@ int lxcContainerStart(virDomainDefPtr def,
}
stacktop = stack + stacksize;
- flags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWUSER|CLONE_NEWIPC|SIGCHLD;
+ flags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC|SIGCHLD;
+
+ if (userns_supported())
+ flags |= CLONE_NEWUSER;
if (def->nets != NULL)
flags |= CLONE_NEWNET;
@@ -719,13 +727,16 @@ static int lxcContainerDummyChild(void *argv ATTRIBUTE_UNUSED)
int lxcContainerAvailable(int features)
{
- int flags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWUSER|
+ int flags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|
CLONE_NEWIPC|SIGCHLD;
int cpid;
char *childStack;
char *stack;
int childStatus;
+ if (features & LXC_CONTAINER_FEATURE_USER)
+ flags |= CLONE_NEWUSER;
+
if (features & LXC_CONTAINER_FEATURE_NET)
flags |= CLONE_NEWNET;
diff --git a/src/lxc_container.h b/src/lxc_container.h
index 5d037b0..b99e83e 100644
--- a/src/lxc_container.h
+++ b/src/lxc_container.h
@@ -28,6 +28,7 @@
enum {
LXC_CONTAINER_FEATURE_NET = (1 << 0),
+ LXC_CONTAINER_FEATURE_USER = (1 << 1),
};
#define LXC_DEV_MAJ_MEMORY 1
--
1.6.0.4
3
2
Hey,
Just committed this simple patch.
Cheers,
Mark.
Subject: [PATCH] Fix typo in manpage
It's "service libvirtd start", not "service start libvirtd".
Reported-by: Robert P. J. Day <rpjday(a)crashcourse.ca>
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
---
docs/virsh.pod | 2 +-
virsh.1 | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/virsh.pod b/docs/virsh.pod
index 2438984..6434d78 100644
--- a/docs/virsh.pod
+++ b/docs/virsh.pod
@@ -34,7 +34,7 @@ the program.
All B<virsh> operations rely upon the libvirt library.
For any virsh commands to run xend/qemu, or what ever virtual library that libvirt supports. For this reason you should start xend/qemu as a service when your system first boots using xen/qemu. This can usually be done using the command
-B<service start libvirtd> .
+B<service libvirtd start> .
Most B<virsh> commands require root privileges to run due to the
communications channels used to talk to the hypervisor. Running as
diff --git a/virsh.1 b/virsh.1
index 2197c20..45ea614 100644
--- a/virsh.1
+++ b/virsh.1
@@ -171,7 +171,7 @@ the program.
.IX Header "NOTES"
All \fBvirsh\fR operations rely upon the libvirt library.
For any virsh commands to run xend/qemu, or what ever virtual library that libvirt supports. For this reason you should start xend/qemu as a service when your system first boots using xen/qemu. This can usually be done using the command
-\&\fBservice start libvirtd\fR .
+\&\fBservice libvirtd start\fR .
.PP
Most \fBvirsh\fR commands require root privileges to run due to the
communications channels used to talk to the hypervisor. Running as
--
1.6.0.6
1
0
Hi.
The absense of SIOCBRADDBR causes compile error:
> bridge.c:143: error: conflicting types for 'brAddBridge'
> bridge.h:50: error: previous declaration of 'brAddBridge' was here
See attached patch for fix.
By the way, what functionality do one loose if his system isn't supporting
SIOCBRADDBR?
2
1
What is the meaning of using virDomainMigrate () with NULL uri.
Looking at the code of qemudDomainMigratePrepare2 ()/ qemu_driver.c, I
understand that it tries to perform a migration to another
VM on the same node . Is that correct ?
Anyhow the code gets stuck while doing this with KVM-84 driver which does
ok a live migration between 2 different nodes via QEMU monitor
thanks
Zvi Dubitzky
Virtualization and System Architecture Email:dubi@il.ibm.com
IBM Haifa Research Laboratory Phone: +972-4-8296182
Haifa, 31905, ISRAEL
3
2
18 Apr '09
The following three patches rearrange storage volume creation so that we
can drop the pool lock during the long allocation process. This also has
the nice side effect of allowing storage allocation progress reporting,
if the API user polls the volume in a separate thread. This is currently
only implemented for FS volumes: all other volume creation will maintain
existing behavior.
Thanks,
Cole
3
12
while trying a live migration for KVM with libvirt I call virDomainMigrate
() with the following parameters
virDomainMigrate (localDomain,
(virConnectPtr)dconn,
VIR_MIGRATE_LIVE,
"vm_mig_dubi",
"tcp:9.148.4.95:4444",
0
);
The connection with the target VM was established ok
Still I get the following error:
libvir: QEMU error : invalid argument in only tcp URIs are supported for
KVM migrations
looking at the code of qemu_driver.c /qemudDomainMigratePrepare2() is
see the following code (for version2 case):
if (!STREQLEN (uri_in, "tcp:", 6)) {
qemudReportError (dconn, NULL, NULL, VIR_ERR_INVALID_ARG,
"%s", _("only tcp URIs are supported for KVM
migrations"));
goto cleanup;
}
why is the strncmp using length 6 and not 4 . I think this is the reason
for the failure . If I put a NULL af ter the "tcp:" then
I do not fail here (strncmp stop at the first NULL) but I fail one step
later pasrsing the port because the NULL terminates the string
Do we need a fix here ?
thanks
Zvi Dubitzky
Virtualization and System Architecture Email:dubi@il.ibm.com
IBM Haifa Research Laboratory Phone: +972-4-8296182
Haifa, 31905, ISRAEL
2
1
Hi All,
I have attached a patch which when applied on the HEAD as of today would allow
virtualbox support in libvirt. It takes cares of all the stuff mentioned on
the list earlier. Still if I have missed anything, please do tell me.
The patches are organized as below:
Patch 0/4: contains sample xml file
Patch 1/4: contains diff of files already in libvirt.
Patch 2/4: contains new files needed for VirtualBox support.
Patch 3/4: contains support for host only and internal network.
Patch 4/4: contains support for rdp in libvirt as mentioned by danpb (also had
sent it separately earlier)
Regards,
Pritesh
2
1
virNodeGetInfo() returns .cpus as 2 but the /proc/cpuinfo of the node
shows 2 processors with 2 cores each ('cpu cores') . Or maybe the 'core
id' is what
counts in the /proc/cpuinfo and that one gets vaue 0 , 1 only i.e
totally 2
can you clarify ?
Here is the output of /proc/cpuinfo:
processor : 0
vendor_id : AuthenticAMD
cpu family : 15
model : 65
model name : Dual-Core AMD Opteron(tm) Processor 2210 HE
stepping : 2
cpu MHz : 1800.034
cache size : 1024 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 1
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca
cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt
rdtscp lm 3dnowext 3dnow pni cx16 lahf_lm cmp_legacy svm extapic
cr8_legacy
bogomips : 3600.06
clflush size : 64
power management: ts fid vid ttp tm stc
processor : 1
vendor_id : AuthenticAMD
cpu family : 15
model : 65
model name : Dual-Core AMD Opteron(tm) Processor 2210 HE
stepping : 2
cpu MHz : 1800.034
cache size : 1024 KB
physical id : 0
siblings : 2
core id : 1
cpu cores : 2
apicid : 1
initial apicid : 1
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 1
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca
cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt
rdtscp lm 3dnowext 3dnow pni cx16 lahf_lm cmp_legacy svm extapic
cr8_legacy
bogomips : 3600.23
clflush size : 64
power management: ts fid vid ttp tm stc
Zvi Dubitzky
Virtualization and System Architecture Email:dubi@il.ibm.com
IBM Haifa Research Laboratory Phone: +972-4-8296182
Haifa, 31905, ISRAEL
3
3
17 Apr '09
The libvirt API states that the return value of virNodeGetFreeMemory() is
in kilobytes. When making this call against a Xen hypervisor and comparing
the returned value with what is listed by "xm info" it appears that libvirt
is returning the free memory in bytes and not kilobytes. Can anybody
confirm this behavior?
This code snippet:
conn = virConnectOpen("xen:///localhost/");
hostmem = virNodeGetFreeMemory(conn);
fprintf(stdout, "Host free memory = %llu\n", hostmem);
produces the following output:
Host free memory = 3236012032
The following comes from running "xm info" on the Xen host:
free_memory : 3086
The libvirt value is convertable into the "xm" returned value if bytes is
assumed.
Regards,
Tyrel Datwyler
Linux Software Engineer
eServer Systems Management
IBM Systems and Technology Group
Email: tyreld(a)us.ibm.com
External: (503) 578-3489, T/L: 775-3489
2
1
All,
I've finally gotten the third implementation of secure migration basically
working, and have some performance numbers to share. Just to refresh everyone's
memory, I'm looking both at host CPU usage and total time to migrate a guest,
using 4 different implementations:
1) Qemu->qemu migration. This is today's, unencrypted, migration
2) GnuTLS->GnutTLS migration. This implementation opens a side-band gnutls
channel, and then dumps the data over that side channel.
3) RPC migration. This version of the RPC migration uses the standard RPC
mechanisms to dump all of the migration over the wire.
4) "Fire and forget" RPC migration. This version of the RPC migration uses the
in-place RPC mechanism, but doesn't wait for an explicit acknowlegement from the
other side.
In all cases, I took a RHEL-5 KVM guest running on an F-11 host, booted up the
guest with 3GB of memory, ran a program that touched all of memory in the guest
until it started to swap, and then live-migrated the guest. This isn't *quite*
worst case (worst case would be a program that allocates all of memory and
continually changes it as fast as possible), but it's a good baseline.
For case 1, the migrations took an average of 29 seconds to complete. During
the migration, idle CPU percentage on the host varied between 33 and 97 percent.
This is our baseline.
For case 2, the migrations took an average of 44 seconds to complete. During
the migration, idle CPU percentage on the host was pretty uniformly 0 (all
processor time was approximately evenly split between user and system).
For case 3, the migrations took an average of 42 seconds to complete. During
the migration, idle CPU percentage on the host varied between 12 and 48 percent.
For case 4, the migrations took an average of 112 seconds to complete. During
the migration, idle CPU percentage on the host varied between 18 and 50 percent.
One thing of note; I'm least confident in the implementation of case 4. It
still has a race condition that hits sometimes (which effectively kills the
test), and it's the most invasive in terms of the areas of code it touches. The
patch is really ugly at the moment, but if people want their eyes to bleed, I
can post it.
Based on the above, it actually looks like case 3 might be the best to pursue.
While it may be possible to get better results out of case 4, I have some
concerns with the approach, particularly around error reporting. The "fire and
forget" nature of the implementation, combined with the departure from the
normal RPC mechanism, makes it less attractive in my opinion. Thoughts?
--
Chris Lalancette
1
0
17 Apr '09
This is an initial patch providing an API to import and export the Domain
XML from/to native hypervisor formats.
This implementation provides
- Import from Xen XM config file format
- Export to Xen XM config file format
- Import from Xen SEXPR format
- Export to Xen SEXPR format
- Export to QEMU argv list
Still todo is the more complex,
- Import from QEMU argv list
which is actually the most interesting & useful one, since that helps
people currently using QEMU migrate over to using libvirt.
The two new public APIs are
/**
* virConnectImportDomainXML:
* @conn: a connection object
* @format: configuration format importing from
* @config: the configuration data to import
* @flags: currently unused, pass 0
*
* Reads native configuration data describing a domain, and
* generates libvirt domain XML. The format of the native
* data is hypervisor dependant.
*
* Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
* the caller must free() the returned value.
*/
char * virConnectImportDomainXML(virConnectPtr conn,
const char *format,
const char *config,
unsigned int flags);
/**
* virConnectExportDomainXML:
* @conn: a connection object
* @format: configuration format exporting to
* @xml: the domain configuration to export
* @flags: currently unused, pass 0
*
* Reads a domain XML configuration document, and generates
* generates a native configuration file describing the domain.
* The format of the native data is hypervisor dependant.
*
* Returns a 0 terminated UTF-8 encoded native config datafile, or NULL in case of error.
* the caller must free() the returned value.
*/
char * virConnectExportDomainXML(virConnectPtr conn,
const char *format,
const char *xml,
unsigned int flags);
This is integrated via virsh
eg import a Xen SEXPR config to libvirt domain XML
# virsh import-domxml xen-sxpr demo.sxpr
<domain type='xen' id='78'>
<name>rhel5pv</name>
<uuid>8f07fe28-753f-2729-d76d-bdbd892f949a</uuid>
<memory>2560000</memory>
<currentMemory>307200</currentMemory>
...snip rest...
<graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'/>
</devices>
</domain>
eg, export libvirt domain XML to Xen SEXPR format
# virsh export-domxml xen-sxpr demo.xml
(vm (name 'Xen')(memory 256)(maxmem 256)(vcpus 1)
(uuid '971784f4-523b-1a8c-99eb-7e66a539c3ac')
...snip...
(script 'vif-bridge'))))
eg import a Xen XM config file
# virsh import-domxml xen-xm demo.cfg
<domain type='xen'>
<name>rhel5pv</name>
<uuid>8f07fe28-753f-2729-d76d-bdbd892f949a</uuid>
<memory>2560000</memory>
<currentMemory>307200</currentMemory>
<vcpu>4</vcpu>
<bootloader>/usr/bin/pygrub</bootloader>
....snip...
</domain>
eg export to Xen XM config file
# virsh export-domxml xen-xm demo.xml
name = "Xen"
uuid = "971784f4-523b-1a8c-99eb-7e66a539c3ac"
maxmem = 256
memory = 256
vcpus = 1
kernel = "/var/lib/xen/vmlinuz"
...snip...
vif = [ "mac=00:16:3e:53:45:a9,bridge=virbr0" ]
eg export to QEMU ARGV format
# virsh -c qemu:///session export-domxml qemu-argv ~/rhel5xen.xml
LC_ALL=C LD_LIBRARY_PATH=/home/berrange/usr/lib
PATH=/usr/bin:/bin HOME=/home/berrange USER=berrange LOGNAME=berrange
/usr/bin/qemu-kvm -S -M pc -m 1967 -smp 4 -name rhel5xen -uuid
be8b4f9a-492a-db25-7aed-f831dcec9127 -monitor pty -pidfile
/home/berrange/.libvirt/qemu/run/rhel5xen.pid -boot c -drive
file=/dev/HostVG/rhel5xen,if=ide,index=0,boot=on -net
nic,macaddr=00:16:3e:09:f2:eb,vlan=0 -net tap,vlan=0 -net
nic,macaddr=00:16:3e:09:f3:eb,vlan=1 -net tap,vlan=1 -net
nic,macaddr=00:16:3e:09:f4:eb,vlan=2 -net tap,vlan=2 -net
nic,macaddr=00:16:3e:09:f5:eb,vlan=3 -net tap,vlan=3 -serial
file:/tmp/rhel5xen.log -parallel none -usb -vnc 0.0.0.0:0 -k en-us
The import thing to note here is that the import/export process is done
via the real libvirt drivers, but the destination / source configs are
not loaded into the hypervisor / mangement app at all. It is purely a
put a string in, get a string out process. What you do with the generated
config is up to you. Also note that you can't export a Xen config using
the QEMU driver, and vica-verca.
The openvz, test, uml drivers don't implement these new APIs, though
openvz & uml could be made to. The Remote driver & daemon is implemented
here, and python bindings are provided too.
docs/devhelp/libvirt-libvirt.html | 12 ++
docs/html/libvirt-libvirt.html | 8 +
docs/libvirt-api.xml | 20 ++++
docs/libvirt-refs.xml | 158 +++++++++++++++++++++++++------------
include/libvirt/libvirt.h | 10 ++
include/libvirt/libvirt.h.in | 10 ++
qemud/remote.c | 34 +++++++
qemud/remote_dispatch_args.h | 2
qemud/remote_dispatch_prototypes.h | 14 +++
qemud/remote_dispatch_ret.h | 2
qemud/remote_dispatch_table.h | 14 ++-
qemud/remote_protocol.c | 44 ++++++++++
qemud/remote_protocol.h | 34 +++++++
qemud/remote_protocol.x | 27 ++++++
src/driver.h | 12 ++
src/libvirt.c | 99 +++++++++++++++++++++++
src/libvirt_public.syms | 6 +
src/lxc_driver.c | 2
src/openvz_driver.c | 2
src/qemu_conf.c | 25 ++---
src/qemu_conf.h | 3
src/qemu_driver.c | 127 +++++++++++++++++++++++++++++
src/remote_internal.c | 64 ++++++++++++++
src/test.c | 2
src/uml_driver.c | 2
src/virsh.c | 94 ++++++++++++++++++++++
src/xen_unified.c | 93 +++++++++++++++++++++
src/xen_unified.h | 3
28 files changed, 853 insertions(+), 70 deletions(-)
Daniel
diff -r ba47cd6949a4 docs/devhelp/libvirt-libvirt.html
--- a/docs/devhelp/libvirt-libvirt.html Thu Apr 16 12:44:17 2009 +0100
+++ b/docs/devhelp/libvirt-libvirt.html Fri Apr 17 10:22:22 2009 +0100
@@ -126,6 +126,7 @@ int <a href="#virNodeDeviceDettach">virN
int <a href="#virDomainGetSecurityLabel">virDomainGetSecurityLabel</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br/> <a href="libvirt-libvirt.html#virSecurityLabelPtr">virSecurityLabelPtr</a> seclabel);
int <a href="#virConnectDomainEventDeregister">virConnectDomainEventDeregister</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> <a href="libvirt-libvirt.html#virConnectDomainEventCallback">virConnectDomainEventCallback</a> cb);
int <a href="#virDomainGetSchedulerParameters">virDomainGetSchedulerParameters</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br/> <a href="libvirt-libvirt.html#virSchedParameterPtr">virSchedParameterPtr</a> params, <br/> int * nparams);
+char * <a href="#virConnectImportDomainXML">virConnectImportDomainXML</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * format, <br/> const char * config, <br/> unsigned int flags);
<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> <a href="#virDomainLookupByUUIDString">virDomainLookupByUUIDString</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * uuidstr);
int <a href="#virConnectNumOfDefinedNetworks">virConnectNumOfDefinedNetworks</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn);
int <a href="#virConnectNumOfDomains">virConnectNumOfDomains</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn);
@@ -218,7 +219,7 @@ int <a href="#virDomainResume">virDomain
int <a href="#virNodeListDevices">virNodeListDevices</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * cap, <br/> char ** const names, <br/> int maxnames, <br/> unsigned int flags);
int <a href="#virNetworkRef">virNetworkRef</a> (<a href="libvirt-libvirt.html#virNetworkPtr">virNetworkPtr</a> network);
int <a href="#virStoragePoolRefresh">virStoragePoolRefresh</a> (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br/> unsigned int flags);
-int <a href="#virConnectNumOfDefinedDomains">virConnectNumOfDefinedDomains</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn);
+char * <a href="#virConnectExportDomainXML">virConnectExportDomainXML</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * format, <br/> const char * xml, <br/> unsigned int flags);
<a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> <a href="#virStorageVolLookupByKey">virStorageVolLookupByKey</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * key);
int <a href="#virDomainUndefine">virDomainUndefine</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain);
int <a href="#virDomainReboot">virDomainReboot</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br/> unsigned int flags);
@@ -260,6 +261,7 @@ int <a href="#virConnectNumOfDefinedStor
const char * <a href="#virNodeDeviceGetParent">virNodeDeviceGetParent</a> (<a href="libvirt-libvirt.html#virNodeDevicePtr">virNodeDevicePtr</a> dev);
<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> <a href="#virConnectOpen">virConnectOpen</a> (const char * name);
<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> <a href="#virDomainCreateXML">virDomainCreateXML</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * xmlDesc, <br/> unsigned int flags);
+int <a href="#virConnectNumOfDefinedDomains">virConnectNumOfDefinedDomains</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn);
int <a href="#virNodeDeviceRef">virNodeDeviceRef</a> (<a href="libvirt-libvirt.html#virNodeDevicePtr">virNodeDevicePtr</a> dev);
int <a href="#virDomainSetVcpus">virDomainSetVcpus</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br/> unsigned int nvcpus);
int <a href="#virDomainRef">virDomainRef</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain);
@@ -792,6 +794,10 @@ The content of this structure is not mad
</pre><p>Adds a Domain Event Callback. Registering for a domain callback will enable delivery of the events The <a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> object handle passed into the callback upon delivery of an event is only valid for the duration of execution of the callback. If the callback wishes to keep the domain object after the callback</p>
<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the connection</td></tr><tr><td><span class="term"><i><tt>cb</tt></i>:</span></td><td>callback to the function handling domain events</td></tr><tr><td><span class="term"><i><tt>opaque</tt></i>:</span></td><td>opaque data to pass on to the callback</td></tr><tr><td><span class="term"><i><tt>freecb</tt></i>:</span></td><td>optional function to deallocate opaque when not used anymore</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>it shall take a reference to it, by calling virDomainRef. The reference can be released once the object is no longer required by calling virDomainFree. Returns 0 on success, -1 on failure</td></tr></tbody></table></div></div>
<hr/>
+ <div class="refsect2" lang="en"><h3><a name="virConnectExportDomainXML"/>virConnectExportDomainXML ()</h3><pre class="programlisting">char * virConnectExportDomainXML (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * format, <br/> const char * xml, <br/> unsigned int flags)<br/>
+</pre><p>Reads a domain XML configuration document, and generates generates a native configuration file describing the domain. The format of the native data is hypervisor dependant.</p>
+<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>a connection object</td></tr><tr><td><span class="term"><i><tt>format</tt></i>:</span></td><td>configuration format exporting to</td></tr><tr><td><span class="term"><i><tt>xml</tt></i>:</span></td><td>the domain configuration to export</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>currently unused, pass 0</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a 0 terminated UTF-8 encoded native config datafile, or NULL in case of error. the caller must free() the returned value.</td></tr></tbody></table></div></div>
+ <hr/>
<div class="refsect2" lang="en"><h3><a name="virConnectFindStoragePoolSources"/>virConnectFindStoragePoolSources ()</h3><pre class="programlisting">char * virConnectFindStoragePoolSources (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * type, <br/> const char * srcSpec, <br/> unsigned int flags)<br/>
</pre><p>Talks to a storage backend and attempts to auto-discover the set of available storage pool sources. e.g. For iSCSI this would be a set of iSCSI targets. For NFS this would be a list of exported paths. The srcSpec (optional for some storage pool types, e.g. local ones) is an instance of the storage pool's source element specifying where to look for the pools. srcSpec is not required for some types (e.g., those querying local storage resources only)</p>
<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to hypervisor connection</td></tr><tr><td><span class="term"><i><tt>type</tt></i>:</span></td><td>type of storage pool sources to discover</td></tr><tr><td><span class="term"><i><tt>srcSpec</tt></i>:</span></td><td>XML document specifying discovery source</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>flags for discovery (unused, pass 0)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>an xml document consisting of a SourceList element containing a source document appropriate to the given pool type for each discovered source.</td></tr></tbody></table></div></div>
@@ -820,6 +826,10 @@ The content of this structure is not mad
</pre><p>Get the version level of the Hypervisor running. This may work only with hypervisor call, i.e. with privileged access to the hypervisor, not with a Read-Only connection.</p>
<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>hvVer</tt></i>:</span></td><td>return value for the version of the running hypervisor (OUT)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>-1 in case of error, 0 otherwise. if the version can't be extracted by lack of capacities returns 0 and @hvVer is 0, otherwise @hvVer value is major * 1,000,000 + minor * 1,000 + release</td></tr></tbody></table></div></div>
<hr/>
+ <div class="refsect2" lang="en"><h3><a name="virConnectImportDomainXML"/>virConnectImportDomainXML ()</h3><pre class="programlisting">char * virConnectImportDomainXML (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * format, <br/> const char * config, <br/> unsigned int flags)<br/>
+</pre><p>Reads native configuration data describing a domain, and generates libvirt domain XML. The format of the native data is hypervisor dependant.</p>
+<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>a connection object</td></tr><tr><td><span class="term"><i><tt>format</tt></i>:</span></td><td>configuration format importing from</td></tr><tr><td><span class="term"><i><tt>config</tt></i>:</span></td><td>the configuration data to import</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>currently unused, pass 0</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a 0 terminated UTF-8 encoded XML instance, or NULL in case of error. the caller must free() the returned value.</td></tr></tbody></table></div></div>
+ <hr/>
<div class="refsect2" lang="en"><h3><a name="virConnectListDefinedDomains"/>virConnectListDefinedDomains ()</h3><pre class="programlisting">int virConnectListDefinedDomains (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> char ** const names, <br/> int maxnames)<br/>
</pre><p>list the defined but inactive domains, stores the pointers to the names in @names</p>
<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>pointer to an array to store the names</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of the array</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of names provided in the array or -1 in case of error</td></tr></tbody></table></div></div>
diff -r ba47cd6949a4 docs/html/libvirt-libvirt.html
--- a/docs/html/libvirt-libvirt.html Thu Apr 16 12:44:17 2009 +0100
+++ b/docs/html/libvirt-libvirt.html Fri Apr 17 10:22:22 2009 +0100
@@ -84,6 +84,7 @@ int <a href="#virConnectDomainEventCallb
int <a href="#virConnectDomainEventDeregister">virConnectDomainEventDeregister</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> <a href="libvirt-libvirt.html#virConnectDomainEventCallback">virConnectDomainEventCallback</a> cb)
int <a href="#virConnectDomainEventRegister">virConnectDomainEventRegister</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> <a href="libvirt-libvirt.html#virConnectDomainEventCallback">virConnectDomainEventCallback</a> cb, <br /> void * opaque, <br /> <a href="libvirt-libvirt.html#virFreeCallback">virFreeCallback</a> freecb)
+char * <a href="#virConnectExportDomainXML">virConnectExportDomainXML</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * format, <br /> const char * xml, <br /> unsigned int flags)
char * <a href="#virConnectFindStoragePoolSources">virConnectFindStoragePoolSources</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * type, <br /> const char * srcSpec, <br /> unsigned int flags)
char * <a href="#virConnectGetCapabilities">virConnectGetCapabilities</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)
char * <a href="#virConnectGetHostname">virConnectGetHostname</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)
@@ -91,6 +92,7 @@ int <a href="#virConnectGetMaxVcpus">vir
const char * <a href="#virConnectGetType">virConnectGetType</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)
char * <a href="#virConnectGetURI">virConnectGetURI</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)
int <a href="#virConnectGetVersion">virConnectGetVersion</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> unsigned long * hvVer)
+char * <a href="#virConnectImportDomainXML">virConnectImportDomainXML</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * format, <br /> const char * config, <br /> unsigned int flags)
int <a href="#virConnectListDefinedDomains">virConnectListDefinedDomains</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)
int <a href="#virConnectListDefinedNetworks">virConnectListDefinedNetworks</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)
int <a href="#virConnectListDefinedStoragePools">virConnectListDefinedStoragePools</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)
@@ -359,14 +361,16 @@ int <a href="#virStorageVolRef">virStora
</pre><p>This function closes the connection to the Hypervisor. This should not be called if further interaction with the Hypervisor are needed especially if there is running domain which need further monitoring by the application.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 in case of success or -1 in case of error.</td></tr></tbody></table></div><h3><a name="virConnectDomainEventCallback" id="virConnectDomainEventCallback"><code>virConnectDomainEventCallback</code></a></h3><pre class="programlisting">typedef int (*virConnectDomainEventCallback) (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> <a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> dom, <br /> int event, <br /> int detail, <br /> void * opaque)
</pre><p>A callback function to be registered, and called when a domain event occurs</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>dom</tt></i>:</span></td><td>The domain on which the event occured</td></tr><tr><td><span class="term"><i><tt>event</tt></i>:</span></td><td>The specfic <a href="libvirt-libvirt.html#virDomainEventType">virDomainEventType</a> which occured</td></tr><tr><td><span class="term"><i><tt>detail</tt></i>:</span></td><td>event specific detail information</td></tr><tr><td><span class="term"><i><tt>opaque</tt></i>:</span></td><td>opaque user data</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td></td></tr></tbody></table></div><br /><h3><a name="virConnectDomainEventDeregister" id="virConnectDomainEventDeregister"><code>virConnectDomainEventDeregister</code></a></h3><pre class="programlisting">int virConnectDomainEventDeregister (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> <a href="libvirt-libvirt.html#virConnectDomainEventCallback">virConnectDomainEventCallback</a> cb)<br />
</pre><p>Removes a Domain Event Callback. De-registering for a domain callback will disable delivery of this event type</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the connection</td></tr><tr><td><span class="term"><i><tt>cb</tt></i>:</span></td><td>callback to the function handling domain events</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, -1 on failure</td></tr></tbody></table></div><h3><a name="virConnectDomainEventRegister" id="virConnectDomainEventRegister"><code>virConnectDomainEventRegister</code></a></h3><pre class="programlisting">int virConnectDomainEventRegister (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> <a href="libvirt-libvirt.html#virConnectDomainEventCallback">virConnectDomainEventCallback</a> cb, <br /> void * opaque, <br /> <a href="libvirt-libvirt.html#virFreeCallback">virFreeCallback</a> freecb)<br />
-</pre><p>Adds a Domain Event Callback. Registering for a domain callback will enable delivery of the events The <a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> object handle passed into the callback upon delivery of an event is only valid for the duration of execution of the callback. If the callback wishes to keep the domain object after the callback</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the connection</td></tr><tr><td><span class="term"><i><tt>cb</tt></i>:</span></td><td>callback to the function handling domain events</td></tr><tr><td><span class="term"><i><tt>opaque</tt></i>:</span></td><td>opaque data to pass on to the callback</td></tr><tr><td><span class="term"><i><tt>freecb</tt></i>:</span></td><td>optional function to deallocate opaque when not used anymore</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>it shall take a reference to it, by calling virDomainRef. The reference can be released once the object is no longer required by calling virDomainFree. Returns 0 on success, -1 on failure</td></tr></tbody></table></div><h3><a name="virConnectFindStoragePoolSources" id="virConnectFindStoragePoolSources"><code>virConnectFindStoragePoolSources</code></a></h3><pre class="programlisting">char * virConnectFindStoragePoolSources (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * type, <br /> const char * srcSpec, <br /> unsigned int flags)<br />
+</pre><p>Adds a Domain Event Callback. Registering for a domain callback will enable delivery of the events The <a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> object handle passed into the callback upon delivery of an event is only valid for the duration of execution of the callback. If the callback wishes to keep the domain object after the callback</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the connection</td></tr><tr><td><span class="term"><i><tt>cb</tt></i>:</span></td><td>callback to the function handling domain events</td></tr><tr><td><span class="term"><i><tt>opaque</tt></i>:</span></td><td>opaque data to pass on to the callback</td></tr><tr><td><span class="term"><i><tt>freecb</tt></i>:</span></td><td>optional function to deallocate opaque when not used anymore</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>it shall take a reference to it, by calling virDomainRef. The reference can be released once the object is no longer required by calling virDomainFree. Returns 0 on success, -1 on failure</td></tr></tbody></table></div><h3><a name="virConnectExportDomainXML" id="virConnectExportDomainXML"><code>virConnectExportDomainXML</code></a></h3><pre class="programlisting">char * virConnectExportDomainXML (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * format, <br /> const char * xml, <br /> unsigned int flags)<br />
+</pre><p>Reads a domain XML configuration document, and generates generates a native configuration file describing the domain. The format of the native data is hypervisor dependant.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>a connection object</td></tr><tr><td><span class="term"><i><tt>format</tt></i>:</span></td><td>configuration format exporting to</td></tr><tr><td><span class="term"><i><tt>xml</tt></i>:</span></td><td>the domain configuration to export</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>currently unused, pass 0</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a 0 terminated UTF-8 encoded native config datafile, or NULL in case of error. the caller must free() the returned value.</td></tr></tbody></table></div><h3><a name="virConnectFindStoragePoolSources" id="virConnectFindStoragePoolSources"><code>virConnectFindStoragePoolSources</code></a></h3><pre class="programlisting">char * virConnectFindStoragePoolSources (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * type, <br /> const char * srcSpec, <br /> unsigned int flags)<br />
</pre><p>Talks to a storage backend and attempts to auto-discover the set of available storage pool sources. e.g. For iSCSI this would be a set of iSCSI targets. For NFS this would be a list of exported paths. The srcSpec (optional for some storage pool types, e.g. local ones) is an instance of the storage pool's source element specifying where to look for the pools. srcSpec is not required for some types (e.g., those querying local storage resources only)</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to hypervisor connection</td></tr><tr><td><span class="term"><i><tt>type</tt></i>:</span></td><td>type of storage pool sources to discover</td></tr><tr><td><span class="term"><i><tt>srcSpec</tt></i>:</span></td><td>XML document specifying discovery source</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>flags for discovery (unused, pass 0)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>an xml document consisting of a SourceList element containing a source document appropriate to the given pool type for each discovered source.</td></tr></tbody></table></div><h3><a name="virConnectGetCapabilities" id="virConnectGetCapabilities"><code>virConnectGetCapabilities</code></a></h3><pre class="programlisting">char * virConnectGetCapabilities (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br />
</pre><p>Provides capabilities of the hypervisor / driver.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>NULL in case of error, or an XML string defining the capabilities. The client must free the returned string after use.</td></tr></tbody></table></div><h3><a name="virConnectGetHostname" id="virConnectGetHostname"><code>virConnectGetHostname</code></a></h3><pre class="programlisting">char * virConnectGetHostname (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br />
</pre><p>This returns the system hostname on which the hypervisor is running (the result of the gethostname(2) system call). If we are connected to a remote system, then this returns the hostname of the remote system.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to a hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the hostname which must be freed by the caller, or NULL if there was an error.</td></tr></tbody></table></div><h3><a name="virConnectGetMaxVcpus" id="virConnectGetMaxVcpus"><code>virConnectGetMaxVcpus</code></a></h3><pre class="programlisting">int virConnectGetMaxVcpus (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * type)<br />
</pre><p>Provides the maximum number of virtual CPUs supported for a guest VM of a specific type. The 'type' parameter here corresponds to the 'type' attribute in the <domain> element of the XML.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>type</tt></i>:</span></td><td>value of the 'type' attribute in the <domain> element</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the maximum of virtual CPU or -1 in case of error.</td></tr></tbody></table></div><h3><a name="virConnectGetType" id="virConnectGetType"><code>virConnectGetType</code></a></h3><pre class="programlisting">const char * virConnectGetType (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br />
</pre><p>Get the name of the Hypervisor software used.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>NULL in case of error, a static zero terminated string otherwise. See also: http://www.redhat.com/archives/libvir-list/2007-February/msg00096.html</td></tr></tbody></table></div><h3><a name="virConnectGetURI" id="virConnectGetURI"><code>virConnectGetURI</code></a></h3><pre class="programlisting">char * virConnectGetURI (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br />
</pre><p>This returns the URI (name) of the hypervisor connection. Normally this is the same as or similar to the string passed to the virConnectOpen/virConnectOpenReadOnly call, but the driver may make the URI canonical. If name == NULL was passed to virConnectOpen, then the driver will return a non-NULL URI which can be used to connect to the same hypervisor later.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to a hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the URI string which must be freed by the caller, or NULL if there was an error.</td></tr></tbody></table></div><h3><a name="virConnectGetVersion" id="virConnectGetVersion"><code>virConnectGetVersion</code></a></h3><pre class="programlisting">int virConnectGetVersion (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> unsigned long * hvVer)<br />
-</pre><p>Get the version level of the Hypervisor running. This may work only with hypervisor call, i.e. with privileged access to the hypervisor, not with a Read-Only connection.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>hvVer</tt></i>:</span></td><td>return value for the version of the running hypervisor (OUT)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>-1 in case of error, 0 otherwise. if the version can't be extracted by lack of capacities returns 0 and @hvVer is 0, otherwise @hvVer value is major * 1,000,000 + minor * 1,000 + release</td></tr></tbody></table></div><h3><a name="virConnectListDefinedDomains" id="virConnectListDefinedDomains"><code>virConnectListDefinedDomains</code></a></h3><pre class="programlisting">int virConnectListDefinedDomains (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)<br />
+</pre><p>Get the version level of the Hypervisor running. This may work only with hypervisor call, i.e. with privileged access to the hypervisor, not with a Read-Only connection.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>hvVer</tt></i>:</span></td><td>return value for the version of the running hypervisor (OUT)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>-1 in case of error, 0 otherwise. if the version can't be extracted by lack of capacities returns 0 and @hvVer is 0, otherwise @hvVer value is major * 1,000,000 + minor * 1,000 + release</td></tr></tbody></table></div><h3><a name="virConnectImportDomainXML" id="virConnectImportDomainXML"><code>virConnectImportDomainXML</code></a></h3><pre class="programlisting">char * virConnectImportDomainXML (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * format, <br /> const char * config, <br /> unsigned int flags)<br />
+</pre><p>Reads native configuration data describing a domain, and generates libvirt domain XML. The format of the native data is hypervisor dependant.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>a connection object</td></tr><tr><td><span class="term"><i><tt>format</tt></i>:</span></td><td>configuration format importing from</td></tr><tr><td><span class="term"><i><tt>config</tt></i>:</span></td><td>the configuration data to import</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>currently unused, pass 0</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a 0 terminated UTF-8 encoded XML instance, or NULL in case of error. the caller must free() the returned value.</td></tr></tbody></table></div><h3><a name="virConnectListDefinedDomains" id="virConnectListDefinedDomains"><code>virConnectListDefinedDomains</code></a></h3><pre class="programlisting">int virConnectListDefinedDomains (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)<br />
</pre><p>list the defined but inactive domains, stores the pointers to the names in @names</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>pointer to an array to store the names</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of the array</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of names provided in the array or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectListDefinedNetworks" id="virConnectListDefinedNetworks"><code>virConnectListDefinedNetworks</code></a></h3><pre class="programlisting">int virConnectListDefinedNetworks (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)<br />
</pre><p>list the inactive networks, stores the pointers to the names in @names</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>pointer to an array to store the names</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of the array</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of names provided in the array or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectListDefinedStoragePools" id="virConnectListDefinedStoragePools"><code>virConnectListDefinedStoragePools</code></a></h3><pre class="programlisting">int virConnectListDefinedStoragePools (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)<br />
</pre><p>Provides the list of names of inactive storage pools upto maxnames. If there are more than maxnames, the remaining names will be silently ignored.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>array of char * to fill with pool names (allocated by caller)</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of the names array</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, -1 on error</td></tr></tbody></table></div><h3><a name="virConnectListDomains" id="virConnectListDomains"><code>virConnectListDomains</code></a></h3><pre class="programlisting">int virConnectListDomains (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> int * ids, <br /> int maxids)<br />
diff -r ba47cd6949a4 docs/libvirt-api.xml
--- a/docs/libvirt-api.xml Thu Apr 16 12:44:17 2009 +0100
+++ b/docs/libvirt-api.xml Fri Apr 17 10:22:22 2009 +0100
@@ -176,6 +176,7 @@
<exports symbol='virDomainGetSecurityLabel' type='function'/>
<exports symbol='virConnectDomainEventDeregister' type='function'/>
<exports symbol='virDomainGetSchedulerParameters' type='function'/>
+ <exports symbol='virConnectImportDomainXML' type='function'/>
<exports symbol='virDomainLookupByUUIDString' type='function'/>
<exports symbol='virConnectNumOfDefinedNetworks' type='function'/>
<exports symbol='virConnectNumOfDomains' type='function'/>
@@ -268,7 +269,7 @@
<exports symbol='virNodeListDevices' type='function'/>
<exports symbol='virNetworkRef' type='function'/>
<exports symbol='virStoragePoolRefresh' type='function'/>
- <exports symbol='virConnectNumOfDefinedDomains' type='function'/>
+ <exports symbol='virConnectExportDomainXML' type='function'/>
<exports symbol='virStorageVolLookupByKey' type='function'/>
<exports symbol='virDomainUndefine' type='function'/>
<exports symbol='virDomainReboot' type='function'/>
@@ -310,6 +311,7 @@
<exports symbol='virNodeDeviceGetParent' type='function'/>
<exports symbol='virConnectOpen' type='function'/>
<exports symbol='virDomainCreateXML' type='function'/>
+ <exports symbol='virConnectNumOfDefinedDomains' type='function'/>
<exports symbol='virNodeDeviceRef' type='function'/>
<exports symbol='virDomainSetVcpus' type='function'/>
<exports symbol='virDomainRef' type='function'/>
@@ -864,6 +866,14 @@ see note above'/>
<arg name='opaque' type='void *' info='opaque data to pass on to the callback'/>
<arg name='freecb' type='virFreeCallback' info='optional function to deallocate opaque when not used anymore'/>
</function>
+ <function name='virConnectExportDomainXML' file='libvirt' module='libvirt'>
+ <info>Reads a domain XML configuration document, and generates generates a native configuration file describing the domain. The format of the native data is hypervisor dependant.</info>
+ <return type='char *' info='a 0 terminated UTF-8 encoded native config datafile, or NULL in case of error. the caller must free() the returned value.'/>
+ <arg name='conn' type='virConnectPtr' info='a connection object'/>
+ <arg name='format' type='const char *' info='configuration format exporting to'/>
+ <arg name='xml' type='const char *' info='the domain configuration to export'/>
+ <arg name='flags' type='unsigned int' info='currently unused, pass 0'/>
+ </function>
<function name='virConnectFindStoragePoolSources' file='libvirt' module='libvirt'>
<info>Talks to a storage backend and attempts to auto-discover the set of available storage pool sources. e.g. For iSCSI this would be a set of iSCSI targets. For NFS this would be a list of exported paths. The srcSpec (optional for some storage pool types, e.g. local ones) is an instance of the storage pool's source element specifying where to look for the pools. srcSpec is not required for some types (e.g., those querying local storage resources only)</info>
<return type='char *' info='an xml document consisting of a SourceList element containing a source document appropriate to the given pool type for each discovered source.'/>
@@ -904,6 +914,14 @@ see note above'/>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
<arg name='hvVer' type='unsigned long *' info='return value for the version of the running hypervisor (OUT)'/>
</function>
+ <function name='virConnectImportDomainXML' file='libvirt' module='libvirt'>
+ <info>Reads native configuration data describing a domain, and generates libvirt domain XML. The format of the native data is hypervisor dependant.</info>
+ <return type='char *' info='a 0 terminated UTF-8 encoded XML instance, or NULL in case of error. the caller must free() the returned value.'/>
+ <arg name='conn' type='virConnectPtr' info='a connection object'/>
+ <arg name='format' type='const char *' info='configuration format importing from'/>
+ <arg name='config' type='const char *' info='the configuration data to import'/>
+ <arg name='flags' type='unsigned int' info='currently unused, pass 0'/>
+ </function>
<function name='virConnectListDefinedDomains' file='libvirt' module='libvirt'>
<info>list the defined but inactive domains, stores the pointers to the names in @names</info>
<return type='int' info='the number of names provided in the array or -1 in case of error'/>
diff -r ba47cd6949a4 docs/libvirt-refs.xml
--- a/docs/libvirt-refs.xml Thu Apr 16 12:44:17 2009 +0100
+++ b/docs/libvirt-refs.xml Fri Apr 17 10:22:22 2009 +0100
@@ -197,6 +197,7 @@
<reference name='virConnectDomainEventCallback' href='html/libvirt-libvirt.html#virConnectDomainEventCallback'/>
<reference name='virConnectDomainEventDeregister' href='html/libvirt-libvirt.html#virConnectDomainEventDeregister'/>
<reference name='virConnectDomainEventRegister' href='html/libvirt-libvirt.html#virConnectDomainEventRegister'/>
+ <reference name='virConnectExportDomainXML' href='html/libvirt-libvirt.html#virConnectExportDomainXML'/>
<reference name='virConnectFindStoragePoolSources' href='html/libvirt-libvirt.html#virConnectFindStoragePoolSources'/>
<reference name='virConnectFlags' href='html/libvirt-libvirt.html#virConnectFlags'/>
<reference name='virConnectGetCapabilities' href='html/libvirt-libvirt.html#virConnectGetCapabilities'/>
@@ -205,6 +206,7 @@
<reference name='virConnectGetType' href='html/libvirt-libvirt.html#virConnectGetType'/>
<reference name='virConnectGetURI' href='html/libvirt-libvirt.html#virConnectGetURI'/>
<reference name='virConnectGetVersion' href='html/libvirt-libvirt.html#virConnectGetVersion'/>
+ <reference name='virConnectImportDomainXML' href='html/libvirt-libvirt.html#virConnectImportDomainXML'/>
<reference name='virConnectListDefinedDomains' href='html/libvirt-libvirt.html#virConnectListDefinedDomains'/>
<reference name='virConnectListDefinedNetworks' href='html/libvirt-libvirt.html#virConnectListDefinedNetworks'/>
<reference name='virConnectListDefinedStoragePools' href='html/libvirt-libvirt.html#virConnectListDefinedStoragePools'/>
@@ -622,6 +624,7 @@
<ref name='virConnectDomainEventCallback'/>
<ref name='virConnectDomainEventDeregister'/>
<ref name='virConnectDomainEventRegister'/>
+ <ref name='virConnectExportDomainXML'/>
<ref name='virConnectFindStoragePoolSources'/>
<ref name='virConnectFlags'/>
<ref name='virConnectGetCapabilities'/>
@@ -630,6 +633,7 @@
<ref name='virConnectGetType'/>
<ref name='virConnectGetURI'/>
<ref name='virConnectGetVersion'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virConnectListDefinedDomains'/>
<ref name='virConnectListDefinedNetworks'/>
<ref name='virConnectListDefinedStoragePools'/>
@@ -942,7 +946,9 @@
</type>
<type name='unsigned int'>
<ref name='virConnectAuthCallbackPtr'/>
+ <ref name='virConnectExportDomainXML'/>
<ref name='virConnectFindStoragePoolSources'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virDomainBlockPeek'/>
<ref name='virDomainCreateLinux'/>
<ref name='virDomainCreateXML'/>
@@ -999,6 +1005,7 @@
<ref name='virConnectDomainEventCallback'/>
<ref name='virConnectDomainEventDeregister'/>
<ref name='virConnectDomainEventRegister'/>
+ <ref name='virConnectExportDomainXML'/>
<ref name='virConnectFindStoragePoolSources'/>
<ref name='virConnectGetCapabilities'/>
<ref name='virConnectGetHostname'/>
@@ -1006,6 +1013,7 @@
<ref name='virConnectGetType'/>
<ref name='virConnectGetURI'/>
<ref name='virConnectGetVersion'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virConnectListDefinedDomains'/>
<ref name='virConnectListDefinedNetworks'/>
<ref name='virConnectListDefinedStoragePools'/>
@@ -1349,6 +1357,7 @@
<ref name='virConnectDomainEventCallback'/>
<ref name='virConnectDomainEventDeregister'/>
<ref name='virConnectDomainEventRegister'/>
+ <ref name='virConnectExportDomainXML'/>
<ref name='virConnectFindStoragePoolSources'/>
<ref name='virConnectFlags'/>
<ref name='virConnectGetCapabilities'/>
@@ -1357,6 +1366,7 @@
<ref name='virConnectGetType'/>
<ref name='virConnectGetURI'/>
<ref name='virConnectGetVersion'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virConnectListDefinedDomains'/>
<ref name='virConnectListDefinedNetworks'/>
<ref name='virConnectListDefinedStoragePools'/>
@@ -2162,6 +2172,10 @@
<word name='Read-Only'>
<ref name='virConnectGetVersion'/>
</word>
+ <word name='Reads'>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectImportDomainXML'/>
+ </word>
<word name='Reboot'>
<ref name='virDomainReboot'/>
</word>
@@ -2294,6 +2308,8 @@
<ref name='VIR_USE_CPU'/>
</word>
<word name='UTF-8'>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virDomainDefineXML'/>
<ref name='virDomainGetXMLDesc'/>
<ref name='virNetworkDefineXML'/>
@@ -2381,26 +2397,6 @@
</word>
</letter>
<letter name='X'>
- <word name='XML'>
- <ref name='virConnectFindStoragePoolSources'/>
- <ref name='virConnectGetCapabilities'/>
- <ref name='virConnectGetMaxVcpus'/>
- <ref name='virDomainAttachDevice'/>
- <ref name='virDomainCreateLinux'/>
- <ref name='virDomainCreateXML'/>
- <ref name='virDomainDefineXML'/>
- <ref name='virDomainDetachDevice'/>
- <ref name='virDomainGetXMLDesc'/>
- <ref name='virNetworkCreateXML'/>
- <ref name='virNetworkDefineXML'/>
- <ref name='virNetworkGetXMLDesc'/>
- <ref name='virNodeDeviceGetXMLDesc'/>
- <ref name='virStoragePoolCreateXML'/>
- <ref name='virStoragePoolDefineXML'/>
- <ref name='virStoragePoolGetXMLDesc'/>
- <ref name='virStorageVolCreateXML'/>
- <ref name='virStorageVolGetXMLDesc'/>
- </word>
<word name='Xen'>
<ref name='_virDomainBlockStats'/>
<ref name='virDomainCoreDump'/>
@@ -2902,8 +2898,10 @@
</word>
<word name='caller'>
<ref name='cpumap'/>
- <ref name='virConnectGetHostname'/>
- <ref name='virConnectGetURI'/>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectGetHostname'/>
+ <ref name='virConnectGetURI'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virConnectListDefinedStoragePools'/>
<ref name='virConnectListStoragePools'/>
<ref name='virConnectRef'/>
@@ -3074,9 +3072,12 @@
<ref name='virResetLastError'/>
</word>
<word name='config'>
+ <ref name='virConnectExportDomainXML'/>
<ref name='virStoragePoolDestroy'/>
</word>
<word name='configuration'>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virStorageVolGetPath'/>
</word>
<word name='configured'>
@@ -3224,6 +3225,8 @@
<ref name='virStorageVolGetInfo'/>
</word>
<word name='currently'>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virDomainCoreDump'/>
<ref name='virNodeDeviceReAttach'/>
<ref name='virNodeDeviceReset'/>
@@ -3237,16 +3240,21 @@
<ref name='virConnSetErrorFunc'/>
<ref name='virConnectDomainEventCallback'/>
<ref name='virConnectDomainEventRegister'/>
- <ref name='virDomainFree'/>
- <ref name='virErrorFunc'/>
- <ref name='virEventAddHandleFunc'/>
- <ref name='virEventAddTimeoutFunc'/>
- <ref name='virEventHandleCallback'/>
- <ref name='virEventRemoveHandleFunc'/>
- <ref name='virEventRemoveTimeoutFunc'/>
- <ref name='virEventTimeoutCallback'/>
- <ref name='virNetworkFree'/>
- <ref name='virSetErrorFunc'/>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectImportDomainXML'/>
+ <ref name='virDomainFree'/>
+ <ref name='virErrorFunc'/>
+ <ref name='virEventAddHandleFunc'/>
+ <ref name='virEventAddTimeoutFunc'/>
+ <ref name='virEventHandleCallback'/>
+ <ref name='virEventRemoveHandleFunc'/>
+ <ref name='virEventRemoveTimeoutFunc'/>
+ <ref name='virEventTimeoutCallback'/>
+ <ref name='virNetworkFree'/>
+ <ref name='virSetErrorFunc'/>
+ </word>
+ <word name='datafile'>
+ <ref name='virConnectExportDomainXML'/>
</word>
<word name='dconn'>
<ref name='virDomainMigrate'/>
@@ -3297,6 +3305,10 @@
<ref name='virConnectDomainEventDeregister'/>
<ref name='virConnectDomainEventRegister'/>
</word>
+ <word name='dependant'>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectImportDomainXML'/>
+ </word>
<word name='depends'>
<ref name='virNodeDeviceReset'/>
</word>
@@ -3307,6 +3319,8 @@
<ref name='virDomainGetVcpus'/>
</word>
<word name='describing'>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virNodeDeviceGetXMLDesc'/>
<ref name='virStoragePoolGetXMLDesc'/>
<ref name='virStorageVolGetXMLDesc'/>
@@ -3406,6 +3420,7 @@
<ref name='virDomainShutdown'/>
</word>
<word name='document'>
+ <ref name='virConnectExportDomainXML'/>
<ref name='virConnectFindStoragePoolSources'/>
<ref name='virNodeDeviceGetXMLDesc'/>
<ref name='virStoragePoolGetXMLDesc'/>
@@ -3521,6 +3536,8 @@
<ref name='virConnectDomainEventRegister'/>
</word>
<word name='encoded'>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virDomainGetXMLDesc'/>
<ref name='virNetworkGetXMLDesc'/>
</word>
@@ -3594,9 +3611,15 @@
<ref name='virDomainDefineXML'/>
<ref name='virStoragePoolDefineXML'/>
</word>
+ <word name='export'>
+ <ref name='virConnectExportDomainXML'/>
+ </word>
<word name='exported'>
<ref name='virConnectFindStoragePoolSources'/>
</word>
+ <word name='exporting'>
+ <ref name='virConnectExportDomainXML'/>
+ </word>
<word name='extra'>
<ref name='_virError'/>
<ref name='virDomainCoreDump'/>
@@ -3658,6 +3681,7 @@
<ref name='virDomainInterfaceStats'/>
</word>
<word name='file'>
+ <ref name='virConnectExportDomainXML'/>
<ref name='virDomainBlockPeek'/>
<ref name='virDomainCoreDump'/>
<ref name='virDomainSave'/>
@@ -3738,6 +3762,8 @@
<ref name='virDomainMigrate'/>
</word>
<word name='format'>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virDomainGetVcpus'/>
<ref name='virGetVersion'/>
<ref name='virStoragePoolGetXMLDesc'/>
@@ -3773,7 +3799,9 @@
<word name='free'>
<ref name='_virStoragePoolInfo'/>
<ref name='virConnCopyLastError'/>
- <ref name='virConnectGetCapabilities'/>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectGetCapabilities'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virCopyLastError'/>
<ref name='virDomainDestroy'/>
<ref name='virDomainGetSchedulerType'/>
@@ -3817,6 +3845,7 @@
<ref name='_virVcpuInfo'/>
<ref name='virConnCopyLastError'/>
<ref name='virConnGetLastError'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virDomainBlockPeek'/>
<ref name='virDomainCreate'/>
<ref name='virDomainGetVcpus'/>
@@ -3855,6 +3884,10 @@
<word name='general'>
<ref name='virDomainShutdown'/>
</word>
+ <word name='generates'>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectImportDomainXML'/>
+ </word>
<word name='generation'>
<ref name='virNodeDeviceGetXMLDesc'/>
<ref name='virStorageVolGetXMLDesc'/>
@@ -4049,6 +4082,12 @@
<word name='image'>
<ref name='virDomainMemoryPeek'/>
</word>
+ <word name='import'>
+ <ref name='virConnectImportDomainXML'/>
+ </word>
+ <word name='importing'>
+ <ref name='virConnectImportDomainXML'/>
+ </word>
<word name='imposed'>
<ref name='virDomainMigrate'/>
</word>
@@ -4139,6 +4178,7 @@
<word name='instance'>
<ref name='nodeinfo'/>
<ref name='virConnectFindStoragePoolSources'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virDomainDestroy'/>
<ref name='virDomainFree'/>
<ref name='virDomainGetXMLDesc'/>
@@ -4349,6 +4389,7 @@
<ref name='virConnectGetType'/>
</word>
<word name='libvirt'>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virConnectOpen'/>
<ref name='virConnectOpenAuth'/>
<ref name='virConnectOpenReadOnly'/>
@@ -4662,9 +4703,11 @@
</word>
<word name='must'>
<ref name='cpumap'/>
- <ref name='virConnectGetCapabilities'/>
- <ref name='virConnectGetHostname'/>
- <ref name='virConnectGetURI'/>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectGetCapabilities'/>
+ <ref name='virConnectGetHostname'/>
+ <ref name='virConnectGetURI'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virDomainBlockPeek'/>
<ref name='virDomainGetOSType'/>
<ref name='virDomainGetSchedulerType'/>
@@ -4700,6 +4743,10 @@
<ref name='_virDomainInfo'/>
<ref name='_virVcpuInfo'/>
</word>
+ <word name='native'>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectImportDomainXML'/>
+ </word>
<word name='necessary'>
<ref name='VIR_NODEINFO_MAXCPUS'/>
<ref name='virConnectOpenAuth'/>
@@ -4972,7 +5019,9 @@
<word name='pass'>
<ref name='virConnSetErrorFunc'/>
<ref name='virConnectDomainEventRegister'/>
- <ref name='virConnectFindStoragePoolSources'/>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectFindStoragePoolSources'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virDomainBlockPeek'/>
<ref name='virDomainCreateLinux'/>
<ref name='virDomainCreateXML'/>
@@ -5402,7 +5451,9 @@
<ref name='virNodeGetCellsFreeMemory'/>
</word>
<word name='returned'>
- <ref name='virConnectGetCapabilities'/>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectGetCapabilities'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virDomainBlockPeek'/>
<ref name='virDomainBlockStats'/>
<ref name='virDomainCreateXML'/>
@@ -5464,6 +5515,8 @@
<ref name='virDomainSetMemory'/>
</word>
</letter>
+ </chunk>
+ <chunk name='chunk9'>
<letter name='s'>
<word name='safe'>
<ref name='virEventRemoveHandleFunc'/>
@@ -5844,7 +5897,7 @@
</word>
</letter>
</chunk>
- <chunk name='chunk9'>
+ <chunk name='chunk10'>
<letter name='t'>
<word name='take'>
<ref name='virConnectDomainEventRegister'/>
@@ -5865,7 +5918,9 @@
<ref name='virDomainMigrate'/>
</word>
<word name='terminated'>
- <ref name='virConnectGetType'/>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectGetType'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virDomainGetXMLDesc'/>
<ref name='virNetworkGetBridgeName'/>
<ref name='virNetworkGetXMLDesc'/>
@@ -6092,7 +6147,9 @@
<ref name='virStorageVolRef'/>
</word>
<word name='unused'>
- <ref name='virConnectFindStoragePoolSources'/>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectFindStoragePoolSources'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virDomainBlockPeek'/>
<ref name='virDomainCoreDump'/>
<ref name='virNodeDeviceGetXMLDesc'/>
@@ -6228,7 +6285,7 @@
</word>
</letter>
</chunk>
- <chunk name='chunk10'>
+ <chunk name='chunk11'>
<letter name='v'>
<word name='valid'>
<ref name='virConnectDomainEventRegister'/>
@@ -6237,8 +6294,10 @@
<ref name='VIR_CPU_USABLE'/>
<ref name='VIR_SECURITY_LABEL_BUFLEN'/>
<ref name='_virVcpuInfo'/>
- <ref name='virConnectGetMaxVcpus'/>
- <ref name='virConnectGetVersion'/>
+ <ref name='virConnectExportDomainXML'/>
+ <ref name='virConnectGetMaxVcpus'/>
+ <ref name='virConnectGetVersion'/>
+ <ref name='virConnectImportDomainXML'/>
<ref name='virDomainGetAutostart'/>
<ref name='virDomainGetSchedulerParameters'/>
<ref name='virDomainGetSchedulerType'/>
@@ -6633,7 +6692,7 @@
</word>
</letter>
</chunk>
- <chunk name='chunk11'>
+ <chunk name='chunk12'>
<letter name='x'>
<word name='xen'>
<ref name='virConnectOpen'/>
@@ -6679,10 +6738,11 @@
<chunk name='chunk5' start='h' end='k'/>
<chunk name='chunk6' start='l' end='m'/>
<chunk name='chunk7' start='n' end='p'/>
- <chunk name='chunk8' start='q' end='s'/>
- <chunk name='chunk9' start='t' end='u'/>
- <chunk name='chunk10' start='v' end='w'/>
- <chunk name='chunk11' start='x' end='z'/>
+ <chunk name='chunk8' start='q' end='r'/>
+ <chunk name='chunk9' start='s' end='s'/>
+ <chunk name='chunk10' start='t' end='u'/>
+ <chunk name='chunk11' start='v' end='w'/>
+ <chunk name='chunk12' start='x' end='z'/>
</chunks>
</index>
</apirefs>
diff -r ba47cd6949a4 include/libvirt/libvirt.h
--- a/include/libvirt/libvirt.h Thu Apr 16 12:44:17 2009 +0100
+++ b/include/libvirt/libvirt.h Fri Apr 17 10:22:22 2009 +0100
@@ -591,6 +591,16 @@ typedef enum {
char * virDomainGetXMLDesc (virDomainPtr domain,
int flags);
+
+char * virConnectImportDomainXML(virConnectPtr conn,
+ const char *format,
+ const char *config,
+ unsigned int flags);
+char * virConnectExportDomainXML(virConnectPtr conn,
+ const char *format,
+ const char *xml,
+ unsigned int flags);
+
int virDomainBlockStats (virDomainPtr dom,
const char *path,
virDomainBlockStatsPtr stats,
diff -r ba47cd6949a4 include/libvirt/libvirt.h.in
--- a/include/libvirt/libvirt.h.in Thu Apr 16 12:44:17 2009 +0100
+++ b/include/libvirt/libvirt.h.in Fri Apr 17 10:22:22 2009 +0100
@@ -591,6 +591,16 @@ typedef enum {
char * virDomainGetXMLDesc (virDomainPtr domain,
int flags);
+
+char * virConnectImportDomainXML(virConnectPtr conn,
+ const char *format,
+ const char *config,
+ unsigned int flags);
+char * virConnectExportDomainXML(virConnectPtr conn,
+ const char *format,
+ const char *xml,
+ unsigned int flags);
+
int virDomainBlockStats (virDomainPtr dom,
const char *path,
virDomainBlockStatsPtr stats,
diff -r ba47cd6949a4 qemud/remote.c
--- a/qemud/remote.c Thu Apr 16 12:44:17 2009 +0100
+++ b/qemud/remote.c Fri Apr 17 10:22:22 2009 +0100
@@ -1236,6 +1236,40 @@ remoteDispatchDomainDumpXml (struct qemu
}
static int
+remoteDispatchImportDomainXml (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_import_domain_xml_args *args,
+ remote_import_domain_xml_ret *ret)
+{
+ /* remoteDispatchClientRequest will free this. */
+ ret->xml = virConnectImportDomainXML (conn, args->format, args->config, args->flags);
+ if (!ret->xml) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+ return 0;
+}
+
+static int
+remoteDispatchExportDomainXml (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_export_domain_xml_args *args,
+ remote_export_domain_xml_ret *ret)
+{
+ /* remoteDispatchClientRequest will free this. */
+ ret->config = virConnectExportDomainXML (conn, args->format, args->xml, args->flags);
+ if (!ret->config) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+ return 0;
+}
+
+static int
remoteDispatchDomainGetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
struct qemud_client *client ATTRIBUTE_UNUSED,
virConnectPtr conn,
diff -r ba47cd6949a4 qemud/remote_dispatch_args.h
--- a/qemud/remote_dispatch_args.h Thu Apr 16 12:44:17 2009 +0100
+++ b/qemud/remote_dispatch_args.h Fri Apr 17 10:22:22 2009 +0100
@@ -103,3 +103,5 @@
remote_node_device_re_attach_args val_remote_node_device_re_attach_args;
remote_node_device_reset_args val_remote_node_device_reset_args;
remote_domain_get_security_label_args val_remote_domain_get_security_label_args;
+ remote_import_domain_xml_args val_remote_import_domain_xml_args;
+ remote_export_domain_xml_args val_remote_export_domain_xml_args;
diff -r ba47cd6949a4 qemud/remote_dispatch_prototypes.h
--- a/qemud/remote_dispatch_prototypes.h Thu Apr 16 12:44:17 2009 +0100
+++ b/qemud/remote_dispatch_prototypes.h Fri Apr 17 10:22:22 2009 +0100
@@ -359,6 +359,13 @@ static int remoteDispatchDomainUndefine(
remote_error *err,
remote_domain_undefine_args *args,
void *ret);
+static int remoteDispatchExportDomainXml(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_export_domain_xml_args *args,
+ remote_export_domain_xml_ret *ret);
static int remoteDispatchFindStoragePoolSources(
struct qemud_server *server,
struct qemud_client *client,
@@ -408,6 +415,13 @@ static int remoteDispatchGetVersion(
remote_error *err,
void *args,
remote_get_version_ret *ret);
+static int remoteDispatchImportDomainXml(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_import_domain_xml_args *args,
+ remote_import_domain_xml_ret *ret);
static int remoteDispatchListDefinedDomains(
struct qemud_server *server,
struct qemud_client *client,
diff -r ba47cd6949a4 qemud/remote_dispatch_ret.h
--- a/qemud/remote_dispatch_ret.h Thu Apr 16 12:44:17 2009 +0100
+++ b/qemud/remote_dispatch_ret.h Fri Apr 17 10:22:22 2009 +0100
@@ -88,3 +88,5 @@
remote_node_device_list_caps_ret val_remote_node_device_list_caps_ret;
remote_domain_get_security_label_ret val_remote_domain_get_security_label_ret;
remote_node_get_security_model_ret val_remote_node_get_security_model_ret;
+ remote_import_domain_xml_ret val_remote_import_domain_xml_ret;
+ remote_export_domain_xml_ret val_remote_export_domain_xml_ret;
diff -r ba47cd6949a4 qemud/remote_dispatch_table.h
--- a/qemud/remote_dispatch_table.h Thu Apr 16 12:44:17 2009 +0100
+++ b/qemud/remote_dispatch_table.h Fri Apr 17 10:22:22 2009 +0100
@@ -607,13 +607,23 @@
.args_filter = (xdrproc_t) xdr_remote_node_device_reset_args,
.ret_filter = (xdrproc_t) xdr_void,
},
-{ /* DomainGetSecurityLabel => 118 */
+{ /* DomainGetSecurityLabel => 121 */
.fn = (dispatch_fn) remoteDispatchDomainGetSecurityLabel,
.args_filter = (xdrproc_t) xdr_remote_domain_get_security_label_args,
.ret_filter = (xdrproc_t) xdr_remote_domain_get_security_label_ret,
},
-{ /* NodeGetSecurityModel => 119 */
+{ /* NodeGetSecurityModel => 122 */
.fn = (dispatch_fn) remoteDispatchNodeGetSecurityModel,
.args_filter = (xdrproc_t) xdr_void,
.ret_filter = (xdrproc_t) xdr_remote_node_get_security_model_ret,
},
+{ /* ImportDomainXml => 123 */
+ .fn = (dispatch_fn) remoteDispatchImportDomainXml,
+ .args_filter = (xdrproc_t) xdr_remote_import_domain_xml_args,
+ .ret_filter = (xdrproc_t) xdr_remote_import_domain_xml_ret,
+},
+{ /* ExportDomainXml => 124 */
+ .fn = (dispatch_fn) remoteDispatchExportDomainXml,
+ .args_filter = (xdrproc_t) xdr_remote_export_domain_xml_args,
+ .ret_filter = (xdrproc_t) xdr_remote_export_domain_xml_ret,
+},
diff -r ba47cd6949a4 qemud/remote_protocol.c
--- a/qemud/remote_protocol.c Thu Apr 16 12:44:17 2009 +0100
+++ b/qemud/remote_protocol.c Fri Apr 17 10:22:22 2009 +0100
@@ -2261,6 +2261,50 @@ xdr_remote_domain_event_ret (XDR *xdrs,
}
bool_t
+xdr_remote_import_domain_xml_args (XDR *xdrs, remote_import_domain_xml_args *objp)
+{
+
+ if (!xdr_remote_nonnull_string (xdrs, &objp->format))
+ return FALSE;
+ if (!xdr_remote_nonnull_string (xdrs, &objp->config))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->flags))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_import_domain_xml_ret (XDR *xdrs, remote_import_domain_xml_ret *objp)
+{
+
+ if (!xdr_remote_nonnull_string (xdrs, &objp->xml))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_export_domain_xml_args (XDR *xdrs, remote_export_domain_xml_args *objp)
+{
+
+ if (!xdr_remote_nonnull_string (xdrs, &objp->format))
+ return FALSE;
+ if (!xdr_remote_nonnull_string (xdrs, &objp->xml))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->flags))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_export_domain_xml_ret (XDR *xdrs, remote_export_domain_xml_ret *objp)
+{
+
+ if (!xdr_remote_nonnull_string (xdrs, &objp->config))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_remote_procedure (XDR *xdrs, remote_procedure *objp)
{
diff -r ba47cd6949a4 qemud/remote_protocol.h
--- a/qemud/remote_protocol.h Thu Apr 16 12:44:17 2009 +0100
+++ b/qemud/remote_protocol.h Fri Apr 17 10:22:22 2009 +0100
@@ -1271,6 +1271,30 @@ struct remote_domain_event_ret {
int detail;
};
typedef struct remote_domain_event_ret remote_domain_event_ret;
+
+struct remote_import_domain_xml_args {
+ remote_nonnull_string format;
+ remote_nonnull_string config;
+ u_int flags;
+};
+typedef struct remote_import_domain_xml_args remote_import_domain_xml_args;
+
+struct remote_import_domain_xml_ret {
+ remote_nonnull_string xml;
+};
+typedef struct remote_import_domain_xml_ret remote_import_domain_xml_ret;
+
+struct remote_export_domain_xml_args {
+ remote_nonnull_string format;
+ remote_nonnull_string xml;
+ u_int flags;
+};
+typedef struct remote_export_domain_xml_args remote_export_domain_xml_args;
+
+struct remote_export_domain_xml_ret {
+ remote_nonnull_string config;
+};
+typedef struct remote_export_domain_xml_ret remote_export_domain_xml_ret;
#define REMOTE_PROGRAM 0x20008086
#define REMOTE_PROTOCOL_VERSION 1
@@ -1397,6 +1421,8 @@ enum remote_procedure {
REMOTE_PROC_NODE_DEVICE_RESET = 120,
REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL = 121,
REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122,
+ REMOTE_PROC_IMPORT_DOMAIN_XML = 123,
+ REMOTE_PROC_EXPORT_DOMAIN_XML = 124,
};
typedef enum remote_procedure remote_procedure;
@@ -1632,6 +1658,10 @@ extern bool_t xdr_remote_node_device_re
extern bool_t xdr_remote_domain_events_register_ret (XDR *, remote_domain_events_register_ret*);
extern bool_t xdr_remote_domain_events_deregister_ret (XDR *, remote_domain_events_deregister_ret*);
extern bool_t xdr_remote_domain_event_ret (XDR *, remote_domain_event_ret*);
+extern bool_t xdr_remote_import_domain_xml_args (XDR *, remote_import_domain_xml_args*);
+extern bool_t xdr_remote_import_domain_xml_ret (XDR *, remote_import_domain_xml_ret*);
+extern bool_t xdr_remote_export_domain_xml_args (XDR *, remote_export_domain_xml_args*);
+extern bool_t xdr_remote_export_domain_xml_ret (XDR *, remote_export_domain_xml_ret*);
extern bool_t xdr_remote_procedure (XDR *, remote_procedure*);
extern bool_t xdr_remote_message_direction (XDR *, remote_message_direction*);
extern bool_t xdr_remote_message_status (XDR *, remote_message_status*);
@@ -1843,6 +1873,10 @@ extern bool_t xdr_remote_node_device_res
extern bool_t xdr_remote_domain_events_register_ret ();
extern bool_t xdr_remote_domain_events_deregister_ret ();
extern bool_t xdr_remote_domain_event_ret ();
+extern bool_t xdr_remote_import_domain_xml_args ();
+extern bool_t xdr_remote_import_domain_xml_ret ();
+extern bool_t xdr_remote_export_domain_xml_args ();
+extern bool_t xdr_remote_export_domain_xml_ret ();
extern bool_t xdr_remote_procedure ();
extern bool_t xdr_remote_message_direction ();
extern bool_t xdr_remote_message_status ();
diff -r ba47cd6949a4 qemud/remote_protocol.x
--- a/qemud/remote_protocol.x Thu Apr 16 12:44:17 2009 +0100
+++ b/qemud/remote_protocol.x Fri Apr 17 10:22:22 2009 +0100
@@ -1130,6 +1130,29 @@ struct remote_domain_event_ret {
int detail;
};
+
+struct remote_import_domain_xml_args {
+ remote_nonnull_string format;
+ remote_nonnull_string config;
+ unsigned flags;
+};
+
+struct remote_import_domain_xml_ret {
+ remote_nonnull_string xml;
+};
+
+
+struct remote_export_domain_xml_args {
+ remote_nonnull_string format;
+ remote_nonnull_string xml;
+ unsigned flags;
+};
+
+struct remote_export_domain_xml_ret {
+ remote_nonnull_string config;
+};
+
+
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@@ -1270,7 +1293,9 @@ enum remote_procedure {
REMOTE_PROC_NODE_DEVICE_RESET = 120,
REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL = 121,
- REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122
+ REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122,
+ REMOTE_PROC_IMPORT_DOMAIN_XML = 123,
+ REMOTE_PROC_EXPORT_DOMAIN_XML = 124
};
/* Custom RPC structure. */
diff -r ba47cd6949a4 src/driver.h
--- a/src/driver.h Thu Apr 16 12:44:17 2009 +0100
+++ b/src/driver.h Fri Apr 17 10:22:22 2009 +0100
@@ -151,6 +151,16 @@ typedef int
typedef char *
(*virDrvDomainDumpXML) (virDomainPtr dom,
int flags);
+typedef char *
+ (*virDrvConnectImportDomainXML) (virConnectPtr conn,
+ const char *configType,
+ const char *configData,
+ unsigned int flags);
+typedef char *
+ (*virDrvConnectExportDomainXML) (virConnectPtr conn,
+ const char *configType,
+ const char *xmlDesc,
+ unsigned int flags);
typedef int
(*virDrvListDefinedDomains) (virConnectPtr conn,
char **const names,
@@ -380,6 +390,8 @@ struct _virDriver {
virDrvDomainGetSecurityLabel domainGetSecurityLabel;
virDrvNodeGetSecurityModel nodeGetSecurityModel;
virDrvDomainDumpXML domainDumpXML;
+ virDrvConnectImportDomainXML importDomainXML;
+ virDrvConnectExportDomainXML exportDomainXML;
virDrvListDefinedDomains listDefinedDomains;
virDrvNumOfDefinedDomains numOfDefinedDomains;
virDrvDomainCreate domainCreate;
diff -r ba47cd6949a4 src/libvirt.c
--- a/src/libvirt.c Thu Apr 16 12:44:17 2009 +0100
+++ b/src/libvirt.c Fri Apr 17 10:22:22 2009 +0100
@@ -2633,6 +2633,105 @@ error:
}
/**
+ * virConnectImportDomainXML:
+ * @conn: a connection object
+ * @format: configuration format importing from
+ * @config: the configuration data to import
+ * @flags: currently unused, pass 0
+ *
+ * Reads native configuration data describing a domain, and
+ * generates libvirt domain XML. The format of the native
+ * data is hypervisor dependant.
+ *
+ * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
+ * the caller must free() the returned value.
+ */
+char *virConnectImportDomainXML(virConnectPtr conn,
+ const char *format,
+ const char *config,
+ unsigned int flags)
+{
+ DEBUG("conn=%p, format=%s config=%s flags=%u", conn, format, config, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (format == NULL || config == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (conn->driver->importDomainXML) {
+ char *ret;
+ ret = conn->driver->importDomainXML (conn, format, config, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return NULL;
+}
+
+/**
+ * virConnectExportDomainXML:
+ * @conn: a connection object
+ * @format: configuration format exporting to
+ * @xml: the domain configuration to export
+ * @flags: currently unused, pass 0
+ *
+ * Reads a domain XML configuration document, and generates
+ * generates a native configuration file describing the domain.
+ * The format of the native data is hypervisor dependant.
+ *
+ * Returns a 0 terminated UTF-8 encoded native config datafile, or NULL in case of error.
+ * the caller must free() the returned value.
+ */
+char *virConnectExportDomainXML(virConnectPtr conn,
+ const char *format,
+ const char *xml,
+ unsigned int flags)
+{
+ DEBUG("conn=%p, format=%s xml=%s flags=%u", conn, format, xml, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (format == NULL || xml == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (conn->driver->exportDomainXML) {
+ char *ret;
+ ret = conn->driver->exportDomainXML (conn, format, xml, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return NULL;
+}
+
+
+/**
* virDomainMigrate:
* @domain: a domain object
* @dconn: destination host (a connection object)
diff -r ba47cd6949a4 src/libvirt_public.syms
--- a/src/libvirt_public.syms Thu Apr 16 12:44:17 2009 +0100
+++ b/src/libvirt_public.syms Fri Apr 17 10:22:22 2009 +0100
@@ -258,4 +258,10 @@ LIBVIRT_0.6.1 {
virNodeGetSecurityModel;
} LIBVIRT_0.6.0;
+LIBVIRT_0.6.3 {
+ global:
+ virConnectImportDomainXML;
+ virConnectExportDomainXML;
+} LIBVIRT_0.6.1;
+
# .... define new API here using predicted next version number ....
diff -r ba47cd6949a4 src/lxc_driver.c
--- a/src/lxc_driver.c Thu Apr 16 12:44:17 2009 +0100
+++ b/src/lxc_driver.c Fri Apr 17 10:22:22 2009 +0100
@@ -1443,6 +1443,8 @@ static virDriver lxcDriver = {
NULL, /* domainGetSecurityLabel */
NULL, /* nodeGetSecurityModel */
lxcDomainDumpXML, /* domainDumpXML */
+ NULL, /* importDomainXML */
+ NULL, /* exportDomainXML */
lxcListDefinedDomains, /* listDefinedDomains */
lxcNumDefinedDomains, /* numOfDefinedDomains */
lxcDomainStart, /* domainCreate */
diff -r ba47cd6949a4 src/openvz_driver.c
--- a/src/openvz_driver.c Thu Apr 16 12:44:17 2009 +0100
+++ b/src/openvz_driver.c Fri Apr 17 10:22:22 2009 +0100
@@ -1344,6 +1344,8 @@ static virDriver openvzDriver = {
NULL, /* domainGetSecurityLabel */
NULL, /* nodeGetSecurityModel */
openvzDomainDumpXML, /* domainDumpXML */
+ NULL, /* importDomainXML */
+ NULL, /* exportDomainXML */
openvzListDefinedDomains, /* listDefinedDomains */
openvzNumDefinedDomains, /* numOfDefinedDomains */
openvzDomainCreate, /* domainCreate */
diff -r ba47cd6949a4 src/qemu_conf.c
--- a/src/qemu_conf.c Thu Apr 16 12:44:17 2009 +0100
+++ b/src/qemu_conf.c Fri Apr 17 10:22:22 2009 +0100
@@ -1245,21 +1245,18 @@ int qemudBuildCommandLine(virConnectPtr
case VIR_DOMAIN_NET_TYPE_ETHERNET:
{
- char arg[PATH_MAX];
- if (net->ifname) {
- if (snprintf(arg, PATH_MAX-1, "tap,ifname=%s,script=%s,vlan=%d",
- net->ifname,
- net->data.ethernet.script,
- vlan) >= (PATH_MAX-1))
- goto error;
- } else {
- if (snprintf(arg, PATH_MAX-1, "tap,script=%s,vlan=%d",
- net->data.ethernet.script,
- vlan) >= (PATH_MAX-1))
- goto error;
- }
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
- ADD_ARG_LIT(arg);
+ virBufferAddLit(&buf, "tap");
+ if (net->ifname)
+ virBufferVSprintf(&buf, ",ifname=%s", net->ifname);
+ if (net->data.ethernet.script)
+ virBufferVSprintf(&buf, ",script=%s", net->data.ethernet.script);
+ virBufferVSprintf(&buf, ",vlan=%d", vlan);
+ if (virBufferError(&buf))
+ goto error;
+
+ ADD_ARG(virBufferContentAndReset(&buf));
}
break;
diff -r ba47cd6949a4 src/qemu_conf.h
--- a/src/qemu_conf.h Thu Apr 16 12:44:17 2009 +0100
+++ b/src/qemu_conf.h Fri Apr 17 10:22:22 2009 +0100
@@ -106,6 +106,9 @@ struct _qemudDomainStatus {
#define QEMUD_MIGRATION_FIRST_PORT 49152
#define QEMUD_MIGRATION_NUM_PORTS 64
+/* Config type for XML import/export conversions */
+#define QEMU_CONFIG_FORMAT_ARGV "qemu-argv"
+
#define qemudReportError(conn, dom, net, code, fmt...) \
virReportErrorHelper(conn, VIR_FROM_QEMU, code, __FILE__, \
__FUNCTION__, __LINE__, fmt)
diff -r ba47cd6949a4 src/qemu_driver.c
--- a/src/qemu_driver.c Thu Apr 16 12:44:17 2009 +0100
+++ b/src/qemu_driver.c Fri Apr 17 10:22:22 2009 +0100
@@ -3333,6 +3333,131 @@ cleanup:
return ret;
}
+#if 0
+static char *qemuImportDomainXML(virConnectPtr conn,
+ const char *format,
+ const char *config,
+ unsigned int flags) {
+}
+#endif
+
+
+static char *qemuExportDomainXML(virConnectPtr conn,
+ const char *format,
+ const char *xmlData,
+ unsigned int flags ATTRIBUTE_UNUSED) {
+ struct qemud_driver *driver = conn->privateData;
+ virDomainDefPtr def = NULL;
+ const char *emulator;
+ unsigned int qemuCmdFlags;
+ struct stat sb;
+ const char **retargv = NULL;
+ const char **retenv = NULL;
+ const char **tmp;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ char *ret = NULL;
+ int i;
+
+ if (STRNEQ(format, QEMU_CONFIG_FORMAT_ARGV)) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INVALID_ARG,
+ _("unsupported config type %s"), format);
+ goto cleanup;
+ }
+
+ def = virDomainDefParseString(conn, driver->caps, xmlData, 0);
+ if (!def)
+ goto cleanup;
+
+ /* Since we're just exporting args, we can't do bridge/network
+ * setups, since libvirt will normally create TAP devices
+ * directly. We convert those configs into generic 'ethernet'
+ * config and assume the user has suitable 'ifup-qemu' scripts
+ */
+ for (i = 0 ; i < def->nnets ; i++) {
+ virDomainNetDefPtr net = def->nets[i];
+ if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+ VIR_FREE(net->data.network.name);
+ net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
+ net->data.ethernet.dev = NULL;
+ net->data.ethernet.script = NULL;
+ net->data.ethernet.ipaddr = NULL;
+ } else if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
+ net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
+ /* Rely on fact that the 'ethernet' and 'bridge'
+ * union structs have members in same place */
+ }
+ }
+ if (def->graphics &&
+ def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
+ def->graphics->data.vnc.autoport) {
+ def->graphics->data.vnc.port = 5900;
+ }
+ emulator = def->emulator;
+ if (!emulator)
+ emulator = virDomainDefDefaultEmulator(conn, def, driver->caps);
+ if (!emulator)
+ goto cleanup;
+
+ /* Make sure the binary we are about to try exec'ing exists.
+ * Technically we could catch the exec() failure, but that's
+ * in a sub-process so its hard to feed back a useful error
+ */
+ if (stat(emulator, &sb) < 0) {
+ virReportSystemError(conn, errno,
+ _("Cannot find QEMU binary %s"),
+ emulator);
+ goto cleanup;
+ }
+
+ if (qemudExtractVersionInfo(emulator,
+ NULL,
+ &qemuCmdFlags) < 0) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Cannot determine QEMU argv syntax %s"),
+ emulator);
+ goto cleanup;
+ }
+
+
+ if (qemudBuildCommandLine(conn, driver, def,
+ qemuCmdFlags,
+ &retargv, &retenv,
+ NULL, NULL, /* Don't want it to create TAP devices */
+ NULL) < 0) {
+ goto cleanup;
+ }
+
+ tmp = retenv;
+ while (*tmp) {
+ virBufferAdd(&buf, *tmp, strlen(*tmp));
+ virBufferAddLit(&buf, " ");
+ tmp++;
+ }
+ tmp = retargv;
+ while (*tmp) {
+ virBufferAdd(&buf, *tmp, strlen(*tmp));
+ virBufferAddLit(&buf, " ");
+ tmp++;
+ }
+
+ if (virBufferError(&buf))
+ goto cleanup;
+
+ ret = virBufferContentAndReset(&buf);
+
+cleanup:
+ for (tmp = retargv ; tmp && *tmp ; tmp++)
+ VIR_FREE(*tmp);
+ VIR_FREE(retargv);
+
+ for (tmp = retenv ; tmp && *tmp ; tmp++)
+ VIR_FREE(*tmp);
+ VIR_FREE(retenv);
+
+ virDomainDefFree(def);
+ return ret;
+}
+
static int qemudListDefinedDomains(virConnectPtr conn,
char **const names, int nnames) {
@@ -5098,6 +5223,8 @@ static virDriver qemuDriver = {
qemudDomainGetSecurityLabel, /* domainGetSecurityLabel */
qemudNodeGetSecurityModel, /* nodeGetSecurityModel */
qemudDomainDumpXML, /* domainDumpXML */
+ NULL, /* importDomainXML */
+ qemuExportDomainXML, /* exportDomainXML */
qemudListDefinedDomains, /* listDefinedDomains */
qemudNumDefinedDomains, /* numOfDefinedDomains */
qemudDomainStart, /* domainCreate */
diff -r ba47cd6949a4 src/remote_internal.c
--- a/src/remote_internal.c Thu Apr 16 12:44:17 2009 +0100
+++ b/src/remote_internal.c Fri Apr 17 10:22:22 2009 +0100
@@ -2409,6 +2409,68 @@ done:
return rv;
}
+static char *
+remoteImportDomainXML (virConnectPtr conn,
+ const char *format,
+ const char *config,
+ unsigned int flags)
+{
+ char *rv = NULL;
+ remote_import_domain_xml_args args;
+ remote_import_domain_xml_ret ret;
+ struct private_data *priv = conn->privateData;
+
+ remoteDriverLock(priv);
+
+ args.format = (char *)format;
+ args.config = (char *)config;
+ args.flags = flags;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_IMPORT_DOMAIN_XML,
+ (xdrproc_t) xdr_remote_import_domain_xml_args, (char *) &args,
+ (xdrproc_t) xdr_remote_import_domain_xml_ret, (char *) &ret) == -1)
+ goto done;
+
+ /* Caller frees. */
+ rv = ret.xml;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+static char *
+remoteExportDomainXML (virConnectPtr conn,
+ const char *format,
+ const char *xml,
+ unsigned int flags)
+{
+ char *rv = NULL;
+ remote_export_domain_xml_args args;
+ remote_export_domain_xml_ret ret;
+ struct private_data *priv = conn->privateData;
+
+ remoteDriverLock(priv);
+
+ args.format = (char *)format;
+ args.xml = (char *)xml;
+ args.flags = flags;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_EXPORT_DOMAIN_XML,
+ (xdrproc_t) xdr_remote_export_domain_xml_args, (char *) &args,
+ (xdrproc_t) xdr_remote_export_domain_xml_ret, (char *) &ret) == -1)
+ goto done;
+
+ /* Caller frees. */
+ rv = ret.config;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
static int
remoteDomainMigratePrepare (virConnectPtr dconn,
char **cookie, int *cookielen,
@@ -6875,6 +6937,8 @@ static virDriver driver = {
remoteDomainGetSecurityLabel, /* domainGetSecurityLabel */
remoteNodeGetSecurityModel, /* nodeGetSecurityModel */
remoteDomainDumpXML, /* domainDumpXML */
+ remoteImportDomainXML, /* importDomainXML */
+ remoteExportDomainXML, /* exportDomainXML */
remoteListDefinedDomains, /* listDefinedDomains */
remoteNumOfDefinedDomains, /* numOfDefinedDomains */
remoteDomainCreate, /* domainCreate */
diff -r ba47cd6949a4 src/test.c
--- a/src/test.c Thu Apr 16 12:44:17 2009 +0100
+++ b/src/test.c Fri Apr 17 10:22:22 2009 +0100
@@ -3504,6 +3504,8 @@ static virDriver testDriver = {
NULL, /* domainGetSecurityLabel */
NULL, /* nodeGetSecurityModel */
testDomainDumpXML, /* domainDumpXML */
+ NULL, /* importDomainXML */
+ NULL, /* exportDomainXML */
testListDefinedDomains, /* listDefinedDomains */
testNumOfDefinedDomains, /* numOfDefinedDomains */
testDomainCreate, /* domainCreate */
diff -r ba47cd6949a4 src/uml_driver.c
--- a/src/uml_driver.c Thu Apr 16 12:44:17 2009 +0100
+++ b/src/uml_driver.c Fri Apr 17 10:22:22 2009 +0100
@@ -1859,6 +1859,8 @@ static virDriver umlDriver = {
NULL, /* domainGetSecurityLabel */
NULL, /* nodeGetSecurityModel */
umlDomainDumpXML, /* domainDumpXML */
+ NULL, /* importDomainXML */
+ NULL, /* exportDomainXML */
umlListDefinedDomains, /* listDefinedDomains */
umlNumDefinedDomains, /* numOfDefinedDomains */
umlDomainStart, /* domainCreate */
diff -r ba47cd6949a4 src/virsh.c
--- a/src/virsh.c Thu Apr 16 12:44:17 2009 +0100
+++ b/src/virsh.c Fri Apr 17 10:22:22 2009 +0100
@@ -2210,6 +2210,98 @@ cmdDumpXML(vshControl *ctl, const vshCmd
}
/*
+ * "domxml-import" command
+ */
+static const vshCmdInfo info_domxmlimport[] = {
+ {"help", gettext_noop("Import native config as domain XML")},
+ {"desc", gettext_noop("Import native guest configuration format to domain XML format.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_domxmlimport[] = {
+ {"format", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("source config data format")},
+ {"config", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("config data file to import from")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdImportDomXML(vshControl *ctl, const vshCmd *cmd)
+{
+ int ret = TRUE;
+ char *format;
+ char *configFile;
+ char *configData;
+ char *xmlData;
+ int flags = 0;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ format = vshCommandOptString(cmd, "format", NULL);
+ configFile = vshCommandOptString(cmd, "config", NULL);
+
+ if (virFileReadAll(configFile, 1024*1024, &configData) < 0) {
+ return FALSE;
+ }
+
+ xmlData = virConnectImportDomainXML(ctl->conn, format, configData, flags);
+ if (xmlData != NULL) {
+ printf("%s", xmlData);
+ free(xmlData);
+ } else {
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+/*
+ * "domxml-export" command
+ */
+static const vshCmdInfo info_domxmlexport[] = {
+ {"help", gettext_noop("Export domain XML as native config")},
+ {"desc", gettext_noop("Export domain XML config to a native guest configuration format.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_domxmlexport[] = {
+ {"format", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("target config data type format")},
+ {"xml", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("xml data file to export from")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdExportDomXML(vshControl *ctl, const vshCmd *cmd)
+{
+ int ret = TRUE;
+ char *format;
+ char *xmlFile;
+ char *configData;
+ char *xmlData;
+ int flags = 0;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ format = vshCommandOptString(cmd, "format", NULL);
+ xmlFile = vshCommandOptString(cmd, "xml", NULL);
+
+ if (virFileReadAll(xmlFile, 1024*1024, &xmlData) < 0) {
+ return FALSE;
+ }
+
+ configData = virConnectExportDomainXML(ctl->conn, format, xmlData, flags);
+ if (configData != NULL) {
+ printf("%s", configData);
+ free(configData);
+ } else {
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+/*
* "domname" command
*/
static const vshCmdInfo info_domname[] = {
@@ -5867,12 +5959,14 @@ static const vshCmdDef commands[] = {
{"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat},
{"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml},
{"edit", cmdEdit, opts_edit, info_edit},
+ {"export-domxml", cmdExportDomXML, opts_domxmlexport, info_domxmlexport},
{"find-storage-pool-sources", cmdPoolDiscoverSources,
opts_find_storage_pool_sources, info_find_storage_pool_sources},
{"find-storage-pool-sources-as", cmdPoolDiscoverSourcesAs,
opts_find_storage_pool_sources_as, info_find_storage_pool_sources_as},
{"freecell", cmdFreecell, opts_freecell, info_freecell},
{"hostname", cmdHostname, NULL, info_hostname},
+ {"import-domxml", cmdImportDomXML, opts_domxmlimport, info_domxmlimport},
{"list", cmdList, opts_list, info_list},
{"migrate", cmdMigrate, opts_migrate, info_migrate},
diff -r ba47cd6949a4 src/xen_unified.c
--- a/src/xen_unified.c Thu Apr 16 12:44:17 2009 +0100
+++ b/src/xen_unified.c Fri Apr 17 10:22:22 2009 +0100
@@ -1043,6 +1043,97 @@ xenUnifiedDomainDumpXML (virDomainPtr do
return NULL;
}
+
+static char *
+xenUnifiedImportDomainXML(virConnectPtr conn,
+ const char *format,
+ const char *config,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ virDomainDefPtr def = NULL;
+ char *ret = NULL;
+ virConfPtr conf = NULL;
+ GET_PRIVATE(conn);
+
+ if (STRNEQ(format, XEN_CONFIG_FORMAT_XM) &&
+ STRNEQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
+ xenUnifiedError(conn, VIR_ERR_INVALID_ARG,
+ _("unsupported config type %s"), format);
+ return NULL;
+ }
+
+ if (STREQ(format, XEN_CONFIG_FORMAT_XM)) {
+ conf = virConfReadMem(config, strlen(config));
+ if (!conf)
+ goto cleanup;
+
+ def = xenXMDomainConfigParse(conn, conf);
+ } else if (STREQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
+ def = xenDaemonParseSxprString(conn, config, priv->xendConfigVersion);
+ }
+ if (!def)
+ goto cleanup;
+
+ ret = virDomainDefFormat(conn, def, 0);
+
+cleanup:
+ virDomainDefFree(def);
+ return ret;
+}
+
+
+#define MAX_CONFIG_SIZE (1024 * 65)
+static char *
+xenUnifiedExportDomainXML(virConnectPtr conn,
+ const char *format,
+ const char *xmlData,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ virDomainDefPtr def = NULL;
+ char *ret = NULL;
+ virConfPtr conf = NULL;
+ GET_PRIVATE(conn);
+
+ if (STRNEQ(format, XEN_CONFIG_FORMAT_XM) &&
+ STRNEQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
+ xenUnifiedError(conn, VIR_ERR_INVALID_ARG,
+ _("unsupported config type %s"), format);
+ goto cleanup;
+ }
+
+ if (!(def = virDomainDefParseString(conn,
+ priv->caps,
+ xmlData,
+ 0)))
+ goto cleanup;
+
+ if (STREQ(format, XEN_CONFIG_FORMAT_XM)) {
+ int len = MAX_CONFIG_SIZE;
+ conf = xenXMDomainConfigFormat(conn, def);
+ if (!conf)
+ goto cleanup;
+
+ if (VIR_ALLOC_N(ret, len) < 0) {
+ virReportOOMError(conn);
+ goto cleanup;
+ }
+
+ if (virConfWriteMem(ret, &len, conf) < 0) {
+ VIR_FREE(ret);
+ goto cleanup;
+ }
+ } else if (STREQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
+ ret = xenDaemonFormatSxpr(conn, def, priv->xendConfigVersion);
+ }
+
+cleanup:
+ virDomainDefFree(def);
+ if (conf)
+ virConfFree(conf);
+ return ret;
+}
+
+
static int
xenUnifiedDomainMigratePrepare (virConnectPtr dconn,
char **cookie,
@@ -1580,6 +1671,8 @@ static virDriver xenUnifiedDriver = {
NULL, /* domainGetSecurityLabel */
NULL, /* nodeGetSecurityModel */
xenUnifiedDomainDumpXML, /* domainDumpXML */
+ xenUnifiedImportDomainXML, /* importDomainXML */
+ xenUnifiedExportDomainXML, /* exportDomainXML */
xenUnifiedListDefinedDomains, /* listDefinedDomains */
xenUnifiedNumOfDefinedDomains, /* numOfDefinedDomains */
xenUnifiedDomainCreate, /* domainCreate */
diff -r ba47cd6949a4 src/xen_unified.h
--- a/src/xen_unified.h Thu Apr 16 12:44:17 2009 +0100
+++ b/src/xen_unified.h Fri Apr 17 10:22:22 2009 +0100
@@ -46,6 +46,9 @@ extern int xenRegister (void);
#define MIN_XEN_GUEST_SIZE 64 /* 64 megabytes */
+#define XEN_CONFIG_FORMAT_XM "xen-xm"
+#define XEN_CONFIG_FORMAT_SEXPR "xen-sxpr"
+
/* _xenUnifiedDriver:
*
* Entry points into the underlying Xen drivers. This structure
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
1
0
Hi,
I broke "make syntax-check" by forgetting to set a C locale. O.k. to
apply:
diff --git a/ChangeLog b/ChangeLog
index 18845e1..96ac44a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,4 @@
-Do Apr 16 17:48:30 CEST 2009 Guido Günther <agx(a)sigxcpu.org>
+Thu Apr 16 17:48:30 CEST 2009 Guido Günther <agx(a)sigxcpu.org>
* src/qemu_driver.c (qemudMonitorCommandExtra): don't log monitor
output to domain log file. It's logged via the logging system
@@ -10,7 +10,7 @@ Do Apr 16 17:48:30 CEST 2009 Guido Günther <agx(a)sigxcpu.org>
qemudDomainMemoryPeek, qemudDomainMigratePerform): prefix monitor
debug output with vm name.
-Do Apr 16 16:48:51 CEST 2009 Guido Günther <agx(a)sigxcpu.org>
+Thu Apr 16 16:48:51 CEST 2009 Guido Günther <agx(a)sigxcpu.org>
* src/qemud.c (remoteReadConfigFile): don't hardcode buffer for
getgrnam_r to 1024 bytes and increase it on ERANGE.
Would we make a changelog entry for modifying the changelog?
-- Guido
2
2
17 Apr '09
Hi.
When I am trying to attach an interface
<interface type='bridge'>
<mac address='52:54:00:db:1a:bb'/>
<source bridge='mkvebr0'/>
</interface>
libvirt reports me, that
libvirt.libvirtError: this function is not supported by the hypervisor:
this device type cannot be attached
Is there a legal way to attach a network interface to QEMU/KVM machine?
2
4
I remember seeing this problem before, but I can't remember what the
resolution was, nor can I find a discussion of the issue in
the list archives or Bugzilla.
I've had my setup working for a while now, on both Fedora 8 and Fedora 10.
Now I'm trying to get it to work with CentOS 5 and
running into an old bug. My guest VM has multiple virtual network
interfaces, with the MAC address defined in the XML file used to
define the VM. However, I'm seeing each network interface getting the
same MAC addrss (the last one defined in the XML file) on
all if the interfaces when I run ifconfig in the guest.
Was there a workaround for this, or do I need to upgrade libvirt? CentOS
5.2 is what I'm working with; they haven't released 5.3
yet so I don't know if that will have a newer version.
# rpm -qa libvirt
libvirt-0.3.3-7.el5
# virsh version
Compiled against library: libvir 0.3.3
Using library: libvir 0.3.3
Using API: QEMU 0.3.3
Running hypervisor: QEMU 0.9.1
- David
2
6
Thanks for getting back to me. The permissions on that directory look ok
to me, see below (cadc is the group specified in my libvirtd.conf).
Which leads me to think it could be something else.
labrosse@proc5-09$ ls -la /var/run/libvirt
total 16
drwxr-xr-x 2 root root 4096 Apr 15 03:25 .
drwxr-xr-x 21 root root 4096 Apr 15 04:02 ..
srwxrwx--- 1 root cadc 0 Apr 15 03:25 libvirt-sock
srwxrwxrwx 1 root cadc 0 Apr 15 03:25 libvirt-sock-ro
labrosse@proc5-09$ ls -l /var/run/libvirt/libvirt-sock
srwxrwx--- 1 root cadc 0 Apr 15 03:25 /var/run/libvirt/libvirt-sock
It seems as if its xen causing the issue (although i cannot see any
issues in the logs). I get a 'Xen Daemon error' when connecting as my
user. I have verified the xen daemon is running and I can sudo virsh
list without seeing any errors.
> labrosse@proc5-09$ virsh list
> libvir: Xen Daemon error : internal error failed to connect to xend
> libvir: Xen Daemon error : internal error failed to connect to xend
> Id Name State
> ----------------------------------
> 0 Domain-0 running
> 7 1-d462220a-8dfe-4b7b-b853-a89f3cac2d46 blocked
>
> labrosse@proc5-09$ sudo virsh list
> Id Name State
> ----------------------------------
> 0 Domain-0 running
> 7 1-d462220a-8dfe-4b7b-b853-a89f3cac2d46 blocked
>
Are you aware of any other configuration that needs to be done elsewhere?
thanks
Daniel
On Wed, 2009-04-15 at 10:08 +0100, Daniel P. Berrange wrote:
> On Tue, Apr 14, 2009 at 02:06:52PM -0700, Daniel Labrosse wrote:
> > Hi All,
> >
> > I've been using libvirt 0..4.4 for a few weeks now. I have
> > unix_sock_group = "mygroup" set so that i can perform non-root
> > management capabilities on the host.
> >
> > I have recently installed a new host running Scientific Linux 5.3 and
> > libvirt 0.3.3 comes as default. First off, there is no libvirtd.conf
> > file included with 0.3.3, so I copied the file from libvirt 0.4.4 (which
> > is running on my Fedora 8 box).
>
> The 'unix_sock_group' config param *is* supported in 0.3.3, but the
> libvirtd daemon will not change the group ownership in the directory
> /var/run/libvirt where the socket is created. So you almost certainly
> won't be able to access the socket itself. You could try chgrp'ing the
> directory. A good test is to make sure you can access the socket as
> non-root, eg
>
> ls -l /var/run/libvirt/libvirt-sock
>
>
> Daniel
1
0
I've been looking for a binary package for x86_64/fc10 of
libvirt/libvirt-python, but can only find the F11 versions.
Have none been created and I'll need to build my own, or am I (and
google/rpmfind/koji/etc) being vision impaired?
Thanks,
// Thomas
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.
4
4