[libvirt] [PATCH] Add autostart support to libxl driver
by Markus Groß
This patch is rebased against the patchset from here:
https://www.redhat.com/archives/libvir-list/2011-March/msg01260.html
The domainSetAutostart function is nearly identical to the one from qemu.
---
src/libxl/libxl_driver.c | 137 ++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 131 insertions(+), 6 deletions(-)
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 3409340..9d882ba 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -176,6 +176,29 @@ libxlDomainObjUnref(void *data)
ignore_value(virDomainObjUnref(vm));
}
+static void
+libxlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ libxlDriverPrivatePtr driver = opaque;
+ virDomainObjPtr vm = payload;
+ virErrorPtr err;
+
+ virDomainObjLock(vm);
+ virResetLastError();
+
+ if (vm->autostart && !virDomainObjIsActive(vm) &&
+ libxlVmStart(driver, vm, false) < 0) {
+ err = virGetLastError();
+ VIR_ERROR(_("Failed to autostart VM '%s': %s"),
+ vm->def->name,
+ err ? err->message : _("unknown error"));
+ }
+
+ if (vm)
+ virDomainObjUnlock(vm);
+}
+
/*
* Cleanup function for domain that has reached shutoff state.
*
@@ -703,9 +726,10 @@ libxlStartup(int privileged) {
0, NULL, NULL) < 0)
goto error;
- libxlDriverUnlock(libxl_driver);
+ virHashForEach(libxl_driver->domains.objs, libxlAutostartDomain,
+ libxl_driver);
- /* TODO: autostart domains */
+ libxlDriverUnlock(libxl_driver);
return 0;
@@ -731,9 +755,11 @@ libxlReload(void)
libxl_driver->configDir,
libxl_driver->autostartDir,
0, NULL, libxl_driver);
- libxlDriverUnlock(libxl_driver);
- /* TODO: autostart domains */
+ virHashForEach(libxl_driver->domains.objs, libxlAutostartDomain,
+ libxl_driver);
+
+ libxlDriverUnlock(libxl_driver);
return 0;
}
@@ -2102,6 +2128,105 @@ libxlDomainEventDeregister(virConnectPtr conn,
return ret;
}
+static int
+libxlDomainGetAutostart(virDomainPtr dom, int *autostart)
+{
+ libxlDriverPrivatePtr driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -1;
+
+ libxlDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ libxlDriverUnlock(driver);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ libxlError(VIR_ERR_NO_DOMAIN,
+ _("No domain with matching uuid '%s'"), uuidstr);
+ goto cleanup;
+ }
+
+ *autostart = vm->autostart;
+ ret = 0;
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ return ret;
+}
+
+static int
+libxlDomainSetAutostart(virDomainPtr dom, int autostart)
+{
+ libxlDriverPrivatePtr driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ char *configFile = NULL, *autostartLink = NULL;
+ int ret = -1;
+
+ libxlDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ libxlError(VIR_ERR_NO_DOMAIN,
+ _("No domain with matching uuid '%s'"), uuidstr);
+ goto cleanup;
+ }
+
+ if (!vm->persistent) {
+ libxlError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("cannot set autostart for transient domain"));
+ goto cleanup;
+ }
+
+ autostart = (autostart != 0);
+
+ if (vm->autostart != autostart) {
+ if (!(configFile = virDomainConfigFile(driver->configDir, vm->def->name)))
+ goto cleanup;
+ if (!(autostartLink = virDomainConfigFile(driver->autostartDir, vm->def->name)))
+ goto cleanup;
+
+ if (autostart) {
+ int err;
+
+ if ((err = virFileMakePath(driver->autostartDir))) {
+ virReportSystemError(err,
+ _("cannot create autostart directory %s"),
+ driver->autostartDir);
+ goto cleanup;
+ }
+
+ if (symlink(configFile, autostartLink) < 0) {
+ virReportSystemError(errno,
+ _("Failed to create symlink '%s to '%s'"),
+ autostartLink, configFile);
+ goto cleanup;
+ }
+ } else {
+ if (unlink(autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
+ virReportSystemError(errno,
+ _("Failed to delete symlink '%s'"),
+ autostartLink);
+ goto cleanup;
+ }
+ }
+
+ vm->autostart = autostart;
+ }
+ ret = 0;
+
+cleanup:
+ VIR_FREE(configFile);
+ VIR_FREE(autostartLink);
+ if (vm)
+ virDomainObjUnlock(vm);
+ libxlDriverUnlock(driver);
+ return ret;
+}
+
static char *
libxlDomainGetSchedulerType(virDomainPtr dom, int *nparams)
{
@@ -2304,8 +2429,8 @@ static virDriver libxlDriver = {
NULL, /* domainDetachDevice */
NULL, /* domainDetachDeviceFlags */
NULL, /* domainUpdateDeviceFlags */
- NULL, /* domainGetAutostart */
- NULL, /* domainSetAutostart */
+ libxlDomainGetAutostart, /* domainGetAutostart */
+ libxlDomainSetAutostart, /* domainSetAutostart */
libxlDomainGetSchedulerType,/* domainGetSchedulerType */
NULL, /* domainGetSchedulerParameters */
NULL, /* domainSetSchedulerParameters */
--
1.7.4.1
13 years, 12 months
[libvirt] FYI, "Unable to create cgroup for ..."
by Jim Meyering
In case someone else encounters this...
Today none of my VMs would start on F15:
# virsh create rawhide.xml
error: Failed to create domain from rawhide.xml
error: Unable to create cgroup for rawhide: No such file or directory
Luckily, I noticed that Rich Jones had the same problem
a week ago and he found that restarting libvirtd was enough
to solve the problem:
# service libvirtd restart
That did it for me, too.
13 years, 12 months
[libvirt] [PATCH] fix memory leak in qemuProcessHandleGraphics()
by Wen Congyang
If strdup("x509dname") or strdup("saslUsername") success, but
strdup(x509dname) or strdup(saslUsername) failed, subject->nidentity
is not the num elements of subject->identities, and we will leak some
memory.
---
src/qemu/qemu_process.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e74e0f1..0d2ccdc 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -544,18 +544,18 @@ qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
if (x509dname) {
if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0)
goto no_memory;
- if (!(subject->identities[subject->nidentity].type = strdup("x509dname")) ||
- !(subject->identities[subject->nidentity].name = strdup(x509dname)))
- goto no_memory;
subject->nidentity++;
+ if (!(subject->identities[subject->nidentity-1].type = strdup("x509dname")) ||
+ !(subject->identities[subject->nidentity-1].name = strdup(x509dname)))
+ goto no_memory;
}
if (saslUsername) {
if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0)
goto no_memory;
- if (!(subject->identities[subject->nidentity].type = strdup("saslUsername")) ||
- !(subject->identities[subject->nidentity].name = strdup(saslUsername)))
- goto no_memory;
subject->nidentity++;
+ if (!(subject->identities[subject->nidentity-1].type = strdup("saslUsername")) ||
+ !(subject->identities[subject->nidentity-1].name = strdup(saslUsername)))
+ goto no_memory;
}
virDomainObjLock(vm);
--
1.7.1
14 years
[libvirt] [PATCH] do not lock vm while allocating memory
by Wen Congyang
There is no need to lock vm while allocating memory. If allocating
memory failed, we forgot to unlock vm.
---
src/qemu/qemu_process.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e31e1b4..e74e0f1 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -525,8 +525,6 @@ qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainEventGraphicsSubjectPtr subject = NULL;
int i;
- virDomainObjLock(vm);
-
if (VIR_ALLOC(localAddr) < 0)
goto no_memory;
localAddr->family = localFamily;
@@ -560,6 +558,7 @@ qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
subject->nidentity++;
}
+ virDomainObjLock(vm);
event = virDomainEventGraphicsNewFromObj(vm, phase, localAddr, remoteAddr, authScheme, subject);
virDomainObjUnlock(vm);
--
1.7.1
14 years
[libvirt] mingw: virsh event loop failure in current git
by Matthias Bolte
Commit 2ed6cc7bec41dd344d41ea1531f6760c93099128 "Expose event loop
implementation as a public API" turned a failure to initialize the
default event loop into a fatal error in virsh on Windows. Before that
commit such a failure was ignored.
virEventRegisterDefaultImpl calls virEventPollInit that calls
virSetNonBlock that calls ioctl that is replaced by gnulib and calls
ioctlsocket. ioctlsocket fails because the given FD is a pipe but
ioctlsocket expects a socket.
A version that works on pipes on Windows looks like this. Although the
pipe is actually not a named pipe the call to SetNamedPipeHandleState
doesn't fail at least.
int
virSetPipeNonBlock(int fd)
{
DWORD mode = PIPE_NOWAIT;
HANDLE handle = _get_osfhandle(fd)
BOOL result = SetNamedPipeHandleState(handle, &mode, NULL, NULL);
return result ? 0 : -1;
}
So, is the event loop stuff supposed to work on Windows at all and we
should get it fixed? Or do we just put an #ifndef WIN32 around
virEventRegisterDefaultImpl in virsh, because the only event loop user
in virsh is the console command that is disabled on Windows anyway?
Matthias
14 years
[libvirt] [PATCH] Fix several formatting mistakes in doc
by Michal Privoznik
---
docs/formatdomain.html.in | 2 +-
docs/hooks.html.in | 6 +++---
src/libvirt.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 8b50814..438cbf0 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -353,7 +353,7 @@
<dd> The optional <code>vcpupin</code> element specifies which of host
physical CPUS the domain VCPU will be pinned to. If this is ommited,
each VCPU pinned to all the physical CPUS by default. It contains two
- required attributes, the attribute <code>vcpu</vcpu> specifies vcpu id,
+ required attributes, the attribute <code>vcpu</code> specifies vcpu id,
and the attribute <code>cpuset</code> is same as attribute <code>cpuset</code>
of element <code>vcpu</code>. NB, Only qemu driver supports</dd>
<dt><code>shares</code></dt>
diff --git a/docs/hooks.html.in b/docs/hooks.html.in
index eec7a6a..890359e 100644
--- a/docs/hooks.html.in
+++ b/docs/hooks.html.in
@@ -105,16 +105,16 @@
is not started. The first location, <span class="since">since
0.9.0</span>, is before libvirt performs any resource
labeling, and the hook can allocate resources not managed by
- libvirt such as DRBD or missing bridges. This is called as:</br>
+ libvirt such as DRBD or missing bridges. This is called as:<br/>
<pre>/etc/libvirt/hooks/qemu guest_name prepare begin -</pre>
The second location, available <span class="since">Since
0.8.0</span>, occurs after libvirt has finished labeling
- all resources, but has not yet started the guest, called as:</br>
+ all resources, but has not yet started the guest, called as:<br/>
<pre>/etc/libvirt/hooks/qemu guest_name start begin -</pre></li>
<li>When a QEMU guest is stopped, the qemu hook script is called
in two locations, to match the startup.
First, <span class="since">since 0.8.0</span>, the hook is
- called before libvirt restores any labels:</br>
+ called before libvirt restores any labels:<br/>
<pre>/etc/libvirt/hooks/qemu guest_name stopped end -</pre>
Then, after libvirt has released all resources, the hook is
called again, <span class="since">since 0.9.0</span>, to allow
diff --git a/src/libvirt.c b/src/libvirt.c
index 9bdb4c8..8be18d4 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -2852,7 +2852,7 @@ error:
}
/*
- * virDomainSetMemoryFlags
+ * virDomainSetMemoryFlags:
* @domain: a domain object or NULL
* @memory: the memory size in kilobytes
* @flags: an OR'ed set of virDomainMemoryModFlags
--
1.7.4
14 years
[libvirt] [PATCH] virsh: fix mingw failure on creating nonblocking pipe
by Eric Blake
* .gnulib: Update to latest, for nonblocking module.
* bootstrap.conf (gnulib_modules): Add nonblocking.
* src/util/util.c (virSetBlocking): Defer to gnulib.
---
Matthias, does this work for you on your mingw build? So far,
I have only tested that it cross-compiles, and that the new
gnulib module passes its self-test when run in isolation on mingw.
.gnulib | 2 +-
bootstrap.conf | 1 +
src/util/util.c | 22 ++--------------------
3 files changed, 4 insertions(+), 21 deletions(-)
diff --git a/.gnulib b/.gnulib
index 790645d..dec3475 160000
--- a/.gnulib
+++ b/.gnulib
@@ -1 +1 @@
-Subproject commit 790645d837f8084991421107fba639b110d58335
+Subproject commit dec3475763be252103922a887920012eeb32dc26
diff --git a/bootstrap.conf b/bootstrap.conf
index 733c354..ca0c3de 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -49,6 +49,7 @@ mkstemp
mkstemps
mktempd
netdb
+nonblocking
perror
physmem
pipe-posix
diff --git a/src/util/util.c b/src/util/util.c
index 035036b..e54b02b 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -77,6 +77,7 @@
#include "verify.h"
#include "files.h"
#include "command.h"
+#include "nonblocking.h"
#ifndef NSIG
# define NSIG 32
@@ -246,26 +247,7 @@ virArgvToString(const char *const *argv)
}
int virSetBlocking(int fd, bool blocking) {
-#ifndef WIN32
- int flags;
- if ((flags = fcntl(fd, F_GETFL)) < 0)
- return -1;
- if (blocking)
- flags &= ~O_NONBLOCK;
- else
- flags |= O_NONBLOCK;
- if ((fcntl(fd, F_SETFL, flags)) < 0)
- return -1;
-#else
- unsigned long flag = blocking ? 0 : 1;
-
- /* This is actually Gnulib's replacement rpl_ioctl function.
- * We can't call ioctlsocket directly in any case.
- */
- if (ioctl (fd, FIONBIO, (void *) &flag) == -1)
- return -1;
-#endif
- return 0;
+ return set_nonblocking_flag (fd, blocking);
}
int virSetNonBlock(int fd) {
--
1.7.4
14 years