[libvirt] [PATCH] Allow byte[] arrays to be set as a secretValue
by Wido den Hollander
Signed-off-by: Wido den Hollander <wido(a)widodh.nl>
---
src/main/java/org/libvirt/Secret.java | 11 +++++++++++
src/main/java/org/libvirt/jna/Libvirt.java | 1 +
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/src/main/java/org/libvirt/Secret.java b/src/main/java/org/libvirt/Secret.java
index e536cf4..48f7895 100644
--- a/src/main/java/org/libvirt/Secret.java
+++ b/src/main/java/org/libvirt/Secret.java
@@ -146,6 +146,17 @@ public class Secret {
}
/**
+ * Sets the value of the secret
+ *
+ * @return 0 on success, -1 on failure.
+ */
+ public int setValue(byte[] value) throws LibvirtException {
+ int returnValue = libvirt.virSecretSetValue(VSP, value, new NativeLong(value.length), 0);
+ processError();
+ return returnValue;
+ }
+
+ /**
* Undefines, but does not free, the Secret.
*
* @return 0 on success, -1 on failure.
diff --git a/src/main/java/org/libvirt/jna/Libvirt.java b/src/main/java/org/libvirt/jna/Libvirt.java
index 2c8c03d..b1e53a2 100644
--- a/src/main/java/org/libvirt/jna/Libvirt.java
+++ b/src/main/java/org/libvirt/jna/Libvirt.java
@@ -336,6 +336,7 @@ public interface Libvirt extends Library {
public SecretPointer virSecretLookupByUUID(ConnectionPointer virConnectPtr, byte[] uuidBytes);
public SecretPointer virSecretLookupByUUIDString(ConnectionPointer virConnectPtr, String uuidstr);
public int virSecretSetValue(SecretPointer virSecretPtr, String value, NativeLong value_size, int flags);
+ public int virSecretSetValue(SecretPointer virSecretPtr, byte[] value, NativeLong value_size, int flags);
public int virSecretUndefine(SecretPointer virSecretPtr);
//Stream Methods
--
1.7.5.4
12 years, 5 months
[libvirt] Potential deadlock in libvirt lxc driver
by Thomas Hunger
Hi,
I'm running version 0.9.10 on debian [1]. When starting and stopping
containers I see deadlocks every so often. I attached a full backtrace
(see at the end of the log). This seems to happen in conditions
similar to the segfault I wrote about recently. I.e. usually when
destroying domains.
I'm unsure why but it seems to me that lxcMonitorEvent gets called
after a vm has been freed. This happens despite
lxcVmCleanup calling "virEventRemoveHandle(priv->monitorWatch);" to
remove the handle.
best,
Tom
[1]
Linux zap 3.1.0-1-amd64 #1 SMP Tue Jan 10 05:01:58 UTC 2012 x86_64 GNU/Linux
12 years, 5 months
[libvirt] [PATCH] Add support for RAM filesystems for LXC
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Introduce a new syntax for filesystems to allow use of a RAM
filesystem
<filesystem type='ram'>
<source usage='1024'/>
<target dir='/mnt'/>
</filesystem>
The usasge is in KB to limit consumption of host memory.
* docs/formatdomain.html.in: Document new syntax
* docs/schemas/domaincommon.rng: Add new attributes
* src/conf/domain_conf.c: Parsing/formatting of RAM filesystems
* src/lxc/lxc_container.c: Mounting of RAM filesystems
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
docs/formatdomain.html.in | 9 +++++++-
docs/schemas/domaincommon.rng | 13 +++++++++++
src/conf/domain_conf.c | 43 ++++++++++++++++++++----------------
src/lxc/lxc_container.c | 49 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 94 insertions(+), 20 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index e1fe0c4..9d1e02b 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1617,6 +1617,12 @@
format will be autodetected. Only used by LXC driver
<span class="since">(since 0.9.5)</span>.
</dd>
+ <dt><code>type='ram'</code></dt>
+ <dd>
+ An in-memory filesystem, using memory from the host OS.
+ The source element has a single attribute <code>usage</code>
+ which gives the memory usage limit in kilobytes.
+ <span class="since"> (since 0.9.13)</span></dd>
</dl>
The filesystem block has an optional attribute <code>accessmode</code>
@@ -1656,7 +1662,8 @@
The resource on the host that is being accessed in the guest. The
<code>name</code> attribute must be used with
<code>type='template'</code>, and the <code>dir</code> attribute must
- be used with <code>type='mount'</code>
+ be used with <code>type='mount'</code>. The <code>usage</code> attribute
+ is used with <code>type='ram'</code> to set the memory limit in KB.
</dd>
<dt><code>target</code></dt>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 8419ccc..884680a 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1271,6 +1271,19 @@
</element>
</interleave>
</group>
+ <group>
+ <attribute name="type">
+ <value>ram</value>
+ </attribute>
+ <interleave>
+ <element name="source">
+ <attribute name="usage">
+ <ref name="unsignedLong"/>
+ </attribute>
+ <empty/>
+ </element>
+ </interleave>
+ </group>
</choice>
<interleave>
<element name="target">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c82971a..5d692d6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4177,7 +4177,8 @@ virDomainFSDefParseXML(xmlNodePtr node,
def->wrpolicy = VIR_DOMAIN_FS_WRPOLICY_DEFAULT;
}
- if (source == NULL) {
+ if (source == NULL &&
+ def->type != VIR_DOMAIN_FS_TYPE_RAM) {
virDomainReportError(VIR_ERR_NO_SOURCE,
target ? "%s" : NULL, target);
goto error;
@@ -11086,27 +11087,31 @@ virDomainFSDefFormat(virBufferPtr buf,
virBufferAddLit(buf, "/>\n");
}
- if (def->src) {
- switch (def->type) {
- case VIR_DOMAIN_FS_TYPE_MOUNT:
- virBufferEscapeString(buf, " <source dir='%s'/>\n",
- def->src);
- break;
+ switch (def->type) {
+ case VIR_DOMAIN_FS_TYPE_MOUNT:
+ virBufferEscapeString(buf, " <source dir='%s'/>\n",
+ def->src);
+ break;
- case VIR_DOMAIN_FS_TYPE_BLOCK:
- virBufferEscapeString(buf, " <source dev='%s'/>\n",
- def->src);
- break;
+ case VIR_DOMAIN_FS_TYPE_BLOCK:
+ virBufferEscapeString(buf, " <source dev='%s'/>\n",
+ def->src);
+ break;
- case VIR_DOMAIN_FS_TYPE_FILE:
- virBufferEscapeString(buf, " <source file='%s'/>\n",
- def->src);
- break;
+ case VIR_DOMAIN_FS_TYPE_FILE:
+ virBufferEscapeString(buf, " <source file='%s'/>\n",
+ def->src);
+ break;
- case VIR_DOMAIN_FS_TYPE_TEMPLATE:
- virBufferEscapeString(buf, " <source name='%s'/>\n",
- def->src);
- }
+ case VIR_DOMAIN_FS_TYPE_TEMPLATE:
+ virBufferEscapeString(buf, " <source name='%s'/>\n",
+ def->src);
+ break;
+
+ case VIR_DOMAIN_FS_TYPE_RAM:
+ virBufferAsprintf(buf, " <source usage='%lld'/>\n",
+ def->usage);
+ break;
}
virBufferEscapeString(buf, " <target dir='%s'/>\n",
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 0636eab..f35b8f9 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -338,6 +338,8 @@ static int lxcContainerPivotRoot(virDomainFSDefPtr root)
ret = -1;
+ VIR_DEBUG("Pivot via %s", root->src);
+
/* root->parent must be private, so make / private. */
if (mount("", "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) {
virReportSystemError(errno, "%s",
@@ -995,6 +997,47 @@ cleanup:
}
+static int lxcContainerMountFSTmpfs(virDomainFSDefPtr fs)
+{
+ int ret = -1;
+ char *data = NULL;
+
+ if (virAsprintf(&data, "size=%lldk", fs->usage) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (virFileMakePath(fs->dst) < 0) {
+ virReportSystemError(errno,
+ _("Failed to create %s"),
+ fs->dst);
+ goto cleanup;
+ }
+
+ if (mount("tmpfs", fs->dst, "tmpfs", 0, data) < 0) {
+ virReportSystemError(errno,
+ _("Failed to mount directory %s as tmpfs"),
+ fs->dst);
+ goto cleanup;
+ }
+
+ if (fs->readonly) {
+ VIR_DEBUG("Binding %s readonly", fs->dst);
+ if (mount(fs->dst, fs->dst, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
+ virReportSystemError(errno,
+ _("Failed to make directory %s readonly"),
+ fs->dst);
+ }
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(data);
+ return ret;
+}
+
+
static int lxcContainerMountFS(virDomainFSDefPtr fs,
const char *srcprefix)
{
@@ -1007,6 +1050,10 @@ static int lxcContainerMountFS(virDomainFSDefPtr fs,
if (lxcContainerMountFSBlock(fs, srcprefix) < 0)
return -1;
break;
+ case VIR_DOMAIN_FS_TYPE_RAM:
+ if (lxcContainerMountFSTmpfs(fs) < 0)
+ return -1;
+ break;
case VIR_DOMAIN_FS_TYPE_FILE:
lxcError(VIR_ERR_INTERNAL_ERROR,
_("Unexpected filesystem type %s"),
@@ -1196,6 +1243,8 @@ static int lxcContainerResolveSymlinks(virDomainDefPtr vmDef)
for (i = 0 ; i < vmDef->nfss ; i++) {
virDomainFSDefPtr fs = vmDef->fss[i];
+ if (!fs->src)
+ continue;
if (virFileResolveAllLinks(fs->src, &newroot) < 0)
return -1;
--
1.7.10.1
12 years, 5 months
[libvirt] [PATCH] qemu: fix potential dead lock
by Wen Congyang
If we lock the qemu_driver, we should call qemuDomainObjBeginJobWithDriver()
not qemuDomainObjBeginJob().
---
src/qemu/qemu_driver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 39b27b1..3d62aab 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8905,7 +8905,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
goto cleanup;
asyncJob = QEMU_ASYNC_JOB_MIGRATION_OUT;
} else {
- if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
asyncJob = QEMU_ASYNC_JOB_NONE;
}
--
1.7.1
12 years, 5 months
[libvirt] [libvirt-sandbox][PATCH] module lookup and rundir fix
by Radu C.
Hello,
I've been trying to get libvirt-sandbox working on my Gentoo box but I ran into some difficulties. The version I'm using is the latest git one.
The first problem was the following when running virt-sandbox:
"Unable to start sandbox: Error opening file '/tmp/libvirt-sandbox-9ivpRN/9pnet.ko': File exists"
I pinpointed the problem to the following diff in commit [05fb94d2c42abe9cfd86c3663d704c268f325503]:
- gchar *moddirpath = g_strdup_printf("/lib/modules/%s/kernel",
+ gchar *moddirpath = g_strdup_printf("/lib/modules/%s",
The problem is that symlinks are made to the build directory and it finds a module multiple times.
I inserted a printf in the lookup loop so here's what I mean:
dmns libvirt-sandbox # virt-sandbox -c qemu:///system -n test1323 -v
-d /usr/bin/yes
found: /lib/modules/3.4.0-gentoo/kernel/fs/fscache/fscache.ko
found: /lib/modules/3.4.0-gentoo/source/fs/fscache/fscache.ko
found: /lib/modules/3.4.0-gentoo/build/fs/fscache/fscache.ko
found: /lib/modules/3.4.0-gentoo/kernel/net/9p/9pnet.ko
found: /lib/modules/3.4.0-gentoo/source/net/9p/9pnet.ko
found: /lib/modules/3.4.0-gentoo/build/net/9p/9pnet.ko
found: /lib/modules/3.4.0-gentoo/kernel/fs/9p/9p.ko
found: /lib/modules/3.4.0-gentoo/source/fs/9p/9p.ko
found: /lib/modules/3.4.0-gentoo/build/fs/9p/9p.ko
found: /lib/modules/3.4.0-gentoo/kernel/net/9p/9pnet_virtio.ko
found: /lib/modules/3.4.0-gentoo/source/net/9p/9pnet_virtio.ko
found: /lib/modules/3.4.0-gentoo/build/net/9p/9pnet_virtio.ko
The next problem was the following:
dmns libvirt-sandbox # virt-sandbox -c qemu:///system -n test123 -v -d
/usr/bin/yes
Unable to start sandbox: Failed to create domain: internal error
Process exited while reading console log output: char device
redirected to /dev/pts/1
char device redirected to /dev/pts/3
Virtio-9p Failed to initialize fs-driver with id:fsdev-fs1 and export
path:libvirt-sandbox/test123/config
It appears when running as root because of the following line:
./libvirt-sandbox/libvirt-sandbox-context.c: cachedir = (getuid() ? g_get_user_cache_dir() : RUNDIR);
RUNDIR is always "" due to being compiled with -DRUNDIR=\"\" . This is because there's a typo in makefile.am
Both of these are fixed in the diff attachment.
Having these fixes in place everything works fine when using libvirt 0.9.10 but for newer versions I noticed every time I ran virt-sandbox the libvirtd daemon would segfault.
Using git bisect I traced the problem back to commit [1]. So I reverted back to libvirt 0.9.10 but I believe there is a problem both in the commit and somewhere in libvirt-sandbox.
Please have a look and tell me if you need extra info.
[1] http://libvirt.org/git/?p=libvirt.git;a=commit;h=4716138229ae47c5492c1...
Radu Caragea.
12 years, 5 months
[libvirt] [PATCH 0/4] virsh snapshot-info
by Eric Blake
I'm working on a patch series to allow offline disk snapshots,
and in the process, I found that I either don't have enough
information ('virsh snapshot-list' is great for a summary, but not
for an individual snapshot) or too much ('virsh snapshot-dumpxml'
means I have to wade through the XML). This provides an intermediate
view, designed for ease of use.
Eric Blake (4):
snapshot: new query APIs
snapshot: add 'virsh snapshot-info'
snapshot: RPC for new query APIs
snapshot: implement new APIs for qemu, esx, and vbox
include/libvirt/libvirt.h.in | 9 +++
src/driver.h | 10 +++
src/esx/esx_driver.c | 71 ++++++++++++++++++++++++
src/libvirt.c | 85 ++++++++++++++++++++++++++++
src/libvirt_public.syms | 6 ++
src/qemu/qemu_driver.c | 83 ++++++++++++++++++++++++++++
src/remote/remote_driver.c | 2 +
src/remote/remote_protocol.x | 23 +++++++-
src/remote_protocol-structs | 16 +++++
src/vbox/vbox_tmpl.c | 97 ++++++++++++++++++++++++++++++++
tools/virsh.c | 125 ++++++++++++++++++++++++++++++++++++++++++
tools/virsh.pod | 5 ++
12 files changed, 531 insertions(+), 1 deletions(-)
--
1.7.7.6
12 years, 5 months
[libvirt] [PATCH 1/2] Add VSCSI bus type and VSCSI controller type for pseries guest.
by Li Zhang
Now, there is only SCSI bus and controller type in libvirt.
And when configuring VSCSI controller, it needs to configure
the spapr-vio bus address type externally. It's a little
inconvenient to configure the controller type.
This patch is to add VSCSI bus type and VSCSI controller type.
And handle with the problems when VSCSI and SCSI devices
working together, by assign the even number to index of
VSCSI controller and odd number to index of SCSI controller.
And when the VSCSI controller is always assigned as SPAPRVIO
bus address type and SCSI controller will be always assigned
as PCI bus address, which is implemented according to the
controllers' type.
So when one disk is based on VSCSI controller, then assign
the bus as 'vscsi', and one right VSCSI controller will be
selected.
If one disk is based on VSCSI controller, the XML file is
as the following:
<disk type='file' device='disk' >
<driver name='qemu' type='raw'/>
<source file='/path/file'/>
<target dev='sda' bus='vscsi'/>
</disk>
VSCSI controllers' configuration in XML file will be like
this:
<controller type='vscsi' index='0'>
</controller>
If one disk is based on 'vscsi', the 'vscsi' bus should be assigned
externally. Otherwise, it will be set as 'scsi' bus according
to the 'sd' target prefix of the disk.
Signed-off-by: Li Zhang <zhlcindy(a)linux.vnet.ibm.com>
---
src/conf/domain_conf.c | 62 ++++++++++++++++++++++++++++++++++++++++++-----
src/conf/domain_conf.h | 2 ++
src/qemu/qemu_command.c | 11 +++++++--
3 files changed, 67 insertions(+), 8 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 184ff23..99005b7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -177,7 +177,8 @@ VIR_ENUM_IMPL(virDomainDiskBus, VIR_DOMAIN_DISK_BUS_LAST,
"xen",
"usb",
"uml",
- "sata")
+ "sata",
+ "vscsi")
VIR_ENUM_IMPL(virDomainDiskCache, VIR_DOMAIN_DISK_CACHE_LAST,
"default",
@@ -236,7 +237,8 @@ VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
"sata",
"virtio-serial",
"ccid",
- "usb")
+ "usb",
+ "vscsi")
VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
"auto",
@@ -2973,6 +2975,7 @@ virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def)
switch (def->bus) {
case VIR_DOMAIN_DISK_BUS_SCSI:
+ case VIR_DOMAIN_DISK_BUS_VSCSI:
def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
if (caps->hasWideScsiBus) {
@@ -2981,6 +2984,16 @@ virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def)
* Unit 7 is the SCSI controller itself. Therefore unit 7
* cannot be assigned to disks and is skipped.
*/
+
+ /* assign even number to index of vscsi controller,
+ * and odd number to index of scsi controller, which can
+ * make vscsi controller and scsi controller work together.
+ */
+ if (def->bus == VIR_DOMAIN_DISK_BUS_VSCSI)
+ def->info.addr.drive.controller = (idx / 15) * 2;
+ else
+ def->info.addr.drive.controller = (idx / 15) * 2 + 1;
+
def->info.addr.drive.controller = idx / 15;
def->info.addr.drive.bus = 0;
def->info.addr.drive.unit = idx % 15;
@@ -2992,6 +3005,17 @@ virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def)
} else {
/* For a narrow SCSI bus we define the default mapping to be
* 7 units per bus, 1 bus per controller, many controllers */
+
+ /* assign even number to index of vscsi controller,
+ * and odd number to index of scsi controller, which can
+ * make vscsi controller and scsi controller work together.
+ */
+
+ if (def->bus == VIR_DOMAIN_DISK_BUS_VSCSI)
+ def->info.addr.drive.controller = (idx / 7) * 2;
+ else
+ def->info.addr.drive.controller = (idx / 7 ) * 2 + 1;
+
def->info.addr.drive.controller = idx / 7;
def->info.addr.drive.bus = 0;
def->info.addr.drive.unit = idx % 7;
@@ -4061,6 +4085,10 @@ virDomainControllerDefParseXML(xmlNodePtr node,
break;
}
+ case VIR_DOMAIN_CONTROLLER_TYPE_VSCSI:
+ def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
+ break;
+
default:
break;
}
@@ -7606,6 +7634,9 @@ static int virDomainDefMaybeAddController(virDomainDefPtr def,
cont->idx = idx;
cont->model = -1;
+ if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_VSCSI)
+ cont->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
+
if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL) {
cont->opts.vioserial.ports = -1;
cont->opts.vioserial.vectors = -1;
@@ -10133,9 +10164,19 @@ static int virDomainDefAddDiskControllersForType(virDomainDefPtr def,
maxController = def->disks[i]->info.addr.drive.controller;
}
- for (i = 0 ; i <= maxController ; i++) {
- if (virDomainDefMaybeAddController(def, controllerType, i) < 0)
- return -1;
+ /* To make scsi and vscsi can work together correctly,
+ * assign even number to index of vscsi controller
+ * and odd number of scsi controller.*/
+ if (diskBus == VIR_DOMAIN_DISK_BUS_VSCSI) {
+ for (i = 0 ; i * 2 <= maxController ; i ++ ) {
+ if (virDomainDefMaybeAddController(def, controllerType, 2 * i) < 0)
+ return -1;
+ }
+ } else {
+ for (i = 0 ; i * 2 + 1 <= maxController ; i ++ ) {
+ if (virDomainDefMaybeAddController(def, controllerType, 2 * i + 1) < 0)
+ return -1;
+ }
}
return 0;
@@ -10247,6 +10288,11 @@ int virDomainDefAddImplicitControllers(virDomainDefPtr def)
VIR_DOMAIN_DISK_BUS_SATA) < 0)
return -1;
+ if (virDomainDefAddDiskControllersForType(def,
+ VIR_DOMAIN_CONTROLLER_TYPE_VSCSI,
+ VIR_DOMAIN_DISK_BUS_VSCSI) < 0)
+ return -1;
+
if (virDomainDefMaybeAddVirtioSerialController(def) < 0)
return -1;
@@ -13175,7 +13221,11 @@ int virDiskNameToBusDeviceIndex(const virDomainDiskDefPtr disk,
*devIdx = idx % 2;
break;
case VIR_DOMAIN_DISK_BUS_SCSI:
- *busIdx = idx / 7;
+ *busIdx = (idx / 7) * 2 + 1;
+ *devIdx = idx % 7;
+ break;
+ case VIR_DOMAIN_DISK_BUS_VSCSI:
+ *busIdx = (idx / 7) * 2;
*devIdx = idx % 7;
break;
case VIR_DOMAIN_DISK_BUS_FDC:
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 5aa8fc1..0066eba 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -418,6 +418,7 @@ enum virDomainDiskBus {
VIR_DOMAIN_DISK_BUS_USB,
VIR_DOMAIN_DISK_BUS_UML,
VIR_DOMAIN_DISK_BUS_SATA,
+ VIR_DOMAIN_DISK_BUS_VSCSI,
VIR_DOMAIN_DISK_BUS_LAST
};
@@ -597,6 +598,7 @@ enum virDomainControllerType {
VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL,
VIR_DOMAIN_CONTROLLER_TYPE_CCID,
VIR_DOMAIN_CONTROLLER_TYPE_USB,
+ VIR_DOMAIN_CONTROLLER_TYPE_VSCSI,
VIR_DOMAIN_CONTROLLER_TYPE_LAST
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 070d13e..bb3be17 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -57,7 +57,8 @@ VIR_ENUM_IMPL(virDomainDiskQEMUBus, VIR_DOMAIN_DISK_BUS_LAST,
"xen",
"usb",
"uml",
- "sata")
+ "sata",
+ "vscsi")
VIR_ENUM_DECL(qemuDiskCacheV1)
@@ -429,6 +430,7 @@ static int qemuAssignDeviceDiskAliasFixed(virDomainDiskDefPtr disk)
ret = virAsprintf(&dev_name, "ide%d-cd%d", busid, devid);
break;
case VIR_DOMAIN_DISK_BUS_SCSI:
+ case VIR_DOMAIN_DISK_BUS_VSCSI:
if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
ret = virAsprintf(&dev_name, "scsi%d-hd%d", busid, devid);
else
@@ -1836,6 +1838,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
switch (disk->bus) {
case VIR_DOMAIN_DISK_BUS_SCSI:
+ case VIR_DOMAIN_DISK_BUS_VSCSI:
if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("unexpected address type for scsi disk"));
@@ -2223,6 +2226,7 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
disk->info.addr.drive.unit);
break;
case VIR_DOMAIN_DISK_BUS_SCSI:
+ case VIR_DOMAIN_DISK_BUS_VSCSI:
if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_BLOCK)) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
@@ -6447,6 +6451,8 @@ qemuParseCommandLineDisk(virCapsPtr caps,
def->bus = VIR_DOMAIN_DISK_BUS_IDE;
else if (STREQ(values[i], "scsi"))
def->bus = VIR_DOMAIN_DISK_BUS_SCSI;
+ else if (STREQ(values[i], "vscsi"))
+ def->bus = VIR_DOMAIN_DISK_BUS_VSCSI;
else if (STREQ(values[i], "virtio"))
def->bus = VIR_DOMAIN_DISK_BUS_VIRTIO;
else if (STREQ(values[i], "xen"))
@@ -6577,7 +6583,8 @@ qemuParseCommandLineDisk(virCapsPtr caps,
if (def->bus == VIR_DOMAIN_DISK_BUS_IDE) {
def->dst = strdup("hda");
- } else if (def->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
+ } else if (def->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
+ def->bus == VIR_DOMAIN_DISK_BUS_VSCSI) {
def->dst = strdup("sda");
} else if (def->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
def->dst = strdup("vda");
--
1.7.9.5
12 years, 5 months
[libvirt] [PATCH] Add some missing hook functions
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
A core use case of the hook scripts is to be able to do things
to a guest's network configuration. It is possible to hook into
the 'start' operation for a QEMU guest which runs just before
the guest is started. The TAP devices will exist at this point,
but the QEMU process will not. It can be desirable to have a
'started' hook too, which runs once QEMU has started.
If libvirtd is restarted it will re-populate firewall rules,
but there is no QEMU hook to trigger for existing domains.
This is solved with a 'reconnect' hook.
Finally, if attaching to an external QEMU process there needs
to be an 'attach' hook script.
This all also applies to the LXC driver
* docs/hooks.html.in: Document new operations
* src/util/hooks.c, src/util/hooks.c: Add 'started', 'reconnect'
and 'attach' operations for QEMU. Add 'prepare', 'started',
'release' and 'reconnect' operations for LXC
* src/lxc/lxc_driver.c: Add hooks for 'prepare', 'started',
'release' and 'reconnect' operations
* src/qemu/qemu_process.c: Add hooks for 'started', 'reconnect'
and 'reconnect' operations
---
docs/hooks.html.in | 52 +++++++++++++++++++++++---
src/lxc/lxc_driver.c | 94 ++++++++++++++++++++++++++++++++++++++---------
src/qemu/qemu_process.c | 51 +++++++++++++++++++++++++
src/util/hooks.c | 11 +++++-
src/util/hooks.h | 7 ++++
5 files changed, 190 insertions(+), 25 deletions(-)
diff --git a/docs/hooks.html.in b/docs/hooks.html.in
index ab16db2..2d64d42 100644
--- a/docs/hooks.html.in
+++ b/docs/hooks.html.in
@@ -101,7 +101,7 @@
<h5><a name="qemu">/etc/libvirt/hooks/qemu</a></h5>
<ul>
<li>Before a QEMU guest is started, the qemu hook script is
- called in two locations; if either location fails, the guest
+ called in three locations; if either location fails, the guest
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
@@ -110,7 +110,11 @@
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/>
- <pre>/etc/libvirt/hooks/qemu guest_name start begin -</pre></li>
+ <pre>/etc/libvirt/hooks/qemu guest_name start begin -</pre>
+ The third location, <span class="since">0.9.13</span>,
+ occurs after the QEMU process has successfully started up:<br/>
+ <pre>/etc/libvirt/hooks/qemu guest_name started 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
@@ -130,15 +134,51 @@
script returns failure or the output XML is not valid, incoming
migration will be canceled. This hook may be used, e.g., to change
location of disk images for incoming domains.</li>
+ <li><span class="since">Since 0.9.13</span>, the qemu hook script
+ is also called when the libvirtd daemon restarts and reconnects
+ to previously running QEMU processes. If the script fails, the
+ existing QEMU process will be killed off. It is called as:
+ <pre>/etc/libvirt/hooks/qemu guest_name reconnect begin -</pre>
+ </li>
+ <li><span class="since">Since 0.9.13</span>, the qemu hook script
+ is also called when the QEMU driver is told to attach to an
+ externally launched QEMU process. It is called as:
+ <pre>/etc/libvirt/hooks/qemu guest_name attach begin -</pre>
+ </li>
</ul>
<h5><a name="lxc">/etc/libvirt/hooks/lxc</a></h5>
<ul>
- <li>When an LXC guest is started, the lxc hook script is called as:<br/>
- <pre>/etc/libvirt/hooks/lxc guest_name start begin -</pre></li>
+ <li>Before a LXC guest is started, the lxc hook script is
+ called in three locations; if either location fails, the guest
+ is not started. The first location, <span class="since">since
+ 0.9.13</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/>
+ <pre>/etc/libvirt/hooks/lxc 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/>
+ <pre>/etc/libvirt/hooks/lxc guest_name start begin -</pre>
+ The third location, <span class="since">0.9.13</span>,
+ occurs after the LXC process has successfully started up:<br/>
+ <pre>/etc/libvirt/hooks/lxc guest_name started begin -</pre>
+ </li>
<li>When a LXC guest is stopped, the lxc hook script is called
- as:<br/>
- <pre>/etc/libvirt/hooks/lxc guest_name stopped end -</pre></li>
+ 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/>
+ <pre>/etc/libvirt/hooks/lxc 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
+ any additional resource cleanup:<br/>
+ <pre>/etc/libvirt/hooks/lxc guest_name release end -</pre></li>
+ <li><span class="since">Since 0.9.13</span>, the lxc hook script
+ is also called when the libvirtd daemon restarts and reconnects
+ to previously running LXC processes. If the script fails, the
+ existing LXC process will be killed off. It is called as:
+ <pre>/etc/libvirt/hooks/lxc guest_name reconnect begin -</pre>
+ </li>
</ul>
<br/>
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 9aea556..0669c17 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1152,6 +1152,17 @@ static void lxcVmCleanup(lxc_driver_t *driver,
virCgroupFree(&cgroup);
}
+ /* now that we know it's stopped call the hook if present */
+ if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
+ char *xml = virDomainDefFormat(vm->def, 0);
+
+ /* we can't stop the operation even if the script raised an error */
+ virHookCall(VIR_HOOK_DRIVER_LXC, vm->def->name,
+ VIR_HOOK_LXC_OP_RELEASE, VIR_HOOK_SUBOP_END,
+ NULL, xml, NULL);
+ VIR_FREE(xml);
+ }
+
if (vm->newDef) {
virDomainDefFree(vm->def);
vm->def = vm->newDef;
@@ -1625,23 +1636,6 @@ lxcBuildControllerCmd(lxc_driver_t *driver,
virCommandAddArgList(cmd, "--veth", veths[i], NULL);
}
- /* now that we know it is about to start call the hook if present */
- if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
- char *xml = virDomainDefFormat(vm->def, 0);
- int hookret;
-
- hookret = virHookCall(VIR_HOOK_DRIVER_LXC, vm->def->name,
- VIR_HOOK_LXC_OP_START, VIR_HOOK_SUBOP_BEGIN,
- NULL, xml, NULL);
- VIR_FREE(xml);
-
- /*
- * If the script raised an error abort the launch
- */
- if (hookret < 0)
- goto cleanup;
- }
-
virCommandPreserveFD(cmd, handshakefd);
return cmd;
@@ -1803,6 +1797,23 @@ static int lxcVmStart(virConnectPtr conn,
if (virDomainObjSetDefTransient(driver->caps, vm, true) < 0)
goto cleanup;
+ /* Run an early hook to set-up missing devices */
+ if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
+ char *xml = virDomainDefFormat(vm->def, 0);
+ int hookret;
+
+ hookret = virHookCall(VIR_HOOK_DRIVER_LXC, vm->def->name,
+ VIR_HOOK_LXC_OP_PREPARE, VIR_HOOK_SUBOP_BEGIN,
+ NULL, xml, NULL);
+ VIR_FREE(xml);
+
+ /*
+ * If the script raised an error abort the launch
+ */
+ if (hookret < 0)
+ goto cleanup;
+ }
+
/* Here we open all the PTYs we need on the host OS side.
* The LXC controller will open the guest OS side PTYs
* and forward I/O between them.
@@ -1887,6 +1898,23 @@ static int lxcVmStart(virConnectPtr conn,
virCommandSetOutputFD(cmd, &logfd);
virCommandSetErrorFD(cmd, &logfd);
+ /* now that we know it is about to start call the hook if present */
+ if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
+ char *xml = virDomainDefFormat(vm->def, 0);
+ int hookret;
+
+ hookret = virHookCall(VIR_HOOK_DRIVER_LXC, vm->def->name,
+ VIR_HOOK_LXC_OP_START, VIR_HOOK_SUBOP_BEGIN,
+ NULL, xml, NULL);
+ VIR_FREE(xml);
+
+ /*
+ * If the script raised an error abort the launch
+ */
+ if (hookret < 0)
+ goto cleanup;
+ }
+
/* Log timestamp */
if ((timestamp = virTimeStringNow()) == NULL) {
virReportOOMError();
@@ -1965,6 +1993,23 @@ static int lxcVmStart(virConnectPtr conn,
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
goto error;
+ /* finally we can call the 'started' hook script if any */
+ if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
+ char *xml = virDomainDefFormat(vm->def, 0);
+ int hookret;
+
+ hookret = virHookCall(VIR_HOOK_DRIVER_LXC, vm->def->name,
+ VIR_HOOK_LXC_OP_STARTED, VIR_HOOK_SUBOP_BEGIN,
+ NULL, xml, NULL);
+ VIR_FREE(xml);
+
+ /*
+ * If the script raised an error abort the launch
+ */
+ if (hookret < 0)
+ goto error;
+ }
+
rc = 0;
cleanup:
@@ -2512,6 +2557,21 @@ lxcReconnectVM(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
if (virSecurityManagerReserveLabel(driver->securityManager,
vm->def, vm->pid) < 0)
goto error;
+
+ /* now that we know it's reconnected call the hook if present */
+ if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
+ char *xml = virDomainDefFormat(vm->def, 0);
+ int hookret;
+
+ /* we can't stop the operation even if the script raised an error */
+ hookret = virHookCall(VIR_HOOK_DRIVER_LXC, vm->def->name,
+ VIR_HOOK_LXC_OP_RECONNECT, VIR_HOOK_SUBOP_BEGIN,
+ NULL, xml, NULL);
+ VIR_FREE(xml);
+ if (hookret < 0)
+ goto error;
+ }
+
} else {
vm->def->id = -1;
VIR_FORCE_CLOSE(priv->monitor);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 58ba5bf..b79944f 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3108,6 +3108,23 @@ qemuProcessReconnect(void *opaque)
if (virDomainSaveStatus(driver->caps, driver->stateDir, obj) < 0)
goto error;
+ /* Run an hook to allow admins to do some magic */
+ if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
+ char *xml = qemuDomainDefFormatXML(driver, obj->def, 0, false);
+ int hookret;
+
+ hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, obj->def->name,
+ VIR_HOOK_QEMU_OP_RECONNECT, VIR_HOOK_SUBOP_BEGIN,
+ NULL, xml, NULL);
+ VIR_FREE(xml);
+
+ /*
+ * If the script raised an error abort the launch
+ */
+ if (hookret < 0)
+ goto error;
+ }
+
if (obj->def->id >= driver->nextvmid)
driver->nextvmid = obj->def->id + 1;
@@ -3747,6 +3764,23 @@ int qemuProcessStart(virConnectPtr conn,
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
goto cleanup;
+ /* finally we can call the 'started' hook script if any */
+ if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
+ char *xml = qemuDomainDefFormatXML(driver, vm->def, 0, false);
+ int hookret;
+
+ hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
+ VIR_HOOK_QEMU_OP_STARTED, VIR_HOOK_SUBOP_BEGIN,
+ NULL, xml, NULL);
+ VIR_FREE(xml);
+
+ /*
+ * If the script raised an error abort the launch
+ */
+ if (hookret < 0)
+ goto cleanup;
+ }
+
virCommandFree(cmd);
VIR_FORCE_CLOSE(logfile);
@@ -4255,6 +4289,23 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
goto cleanup;
+ /* Run an hook to allow admins to do some magic */
+ if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
+ char *xml = qemuDomainDefFormatXML(driver, vm->def, 0, false);
+ int hookret;
+
+ hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
+ VIR_HOOK_QEMU_OP_ATTACH, VIR_HOOK_SUBOP_BEGIN,
+ NULL, xml, NULL);
+ VIR_FREE(xml);
+
+ /*
+ * If the script raised an error abort the launch
+ */
+ if (hookret < 0)
+ goto cleanup;
+ }
+
VIR_FORCE_CLOSE(logfile);
VIR_FREE(seclabel);
diff --git a/src/util/hooks.c b/src/util/hooks.c
index ce60b43..f89a40f 100644
--- a/src/util/hooks.c
+++ b/src/util/hooks.c
@@ -74,11 +74,18 @@ VIR_ENUM_IMPL(virHookQemuOp, VIR_HOOK_QEMU_OP_LAST,
"stopped",
"prepare",
"release",
- "migrate")
+ "migrate",
+ "started",
+ "reconnect",
+ "attach")
VIR_ENUM_IMPL(virHookLxcOp, VIR_HOOK_LXC_OP_LAST,
"start",
- "stopped")
+ "stopped",
+ "prepare",
+ "release",
+ "started",
+ "reconnect")
static int virHooksFound = -1;
diff --git a/src/util/hooks.h b/src/util/hooks.h
index 7fd29f6..1af7c04 100644
--- a/src/util/hooks.h
+++ b/src/util/hooks.h
@@ -57,6 +57,9 @@ enum virHookQemuOpType {
VIR_HOOK_QEMU_OP_PREPARE, /* domain startup initiated */
VIR_HOOK_QEMU_OP_RELEASE, /* domain destruction is over */
VIR_HOOK_QEMU_OP_MIGRATE, /* domain is being migrated */
+ VIR_HOOK_QEMU_OP_STARTED, /* domain has started */
+ VIR_HOOK_QEMU_OP_RECONNECT, /* domain is being reconnected by libvirt */
+ VIR_HOOK_QEMU_OP_ATTACH, /* domain is being attached to be libvirt */
VIR_HOOK_QEMU_OP_LAST,
};
@@ -64,6 +67,10 @@ enum virHookQemuOpType {
enum virHookLxcOpType {
VIR_HOOK_LXC_OP_START, /* domain is about to start */
VIR_HOOK_LXC_OP_STOPPED, /* domain has stopped */
+ VIR_HOOK_LXC_OP_PREPARE, /* domain startup initiated */
+ VIR_HOOK_LXC_OP_RELEASE, /* domain destruction is over */
+ VIR_HOOK_LXC_OP_STARTED, /* domain has started */
+ VIR_HOOK_LXC_OP_RECONNECT, /* domain is being reconnected by libvirt */
VIR_HOOK_LXC_OP_LAST,
};
--
1.7.10.1
12 years, 5 months