[libvirt] [PATCH 0/2] Only free compiled regex when regcomp() succeeds
by Jim Fehlig
During a recent discussion about calling regfree() when regcomp() fails,
we decided it was best to not call regfree() when compilation fails.
https://www.redhat.com/archives/libvir-list/2013-September/msg00262.html
The first patch fixes existing infractions throughout the code. I split
the second patch out since there were other issues beyond simply removing
a call to regfree().
Jim Fehlig (2):
Don't call regfree() if regcomp() fails
libxl: Compile regular expression where it is used
src/libxl/libxl_conf.c | 29 +++++++++++++++--------------
src/storage/storage_backend.c | 2 +-
src/storage/storage_backend_logical.c | 1 -
src/xen/xen_hypervisor.c | 3 ---
4 files changed, 16 insertions(+), 19 deletions(-)
--
1.8.1.4
11 years, 2 months
[libvirt] [PATCH] storage: new backend: btrfs subvolumes
by Oskari Saarenmaa
This commit adds a new storage pool driver, btrfs, which can be used to
manage btrfs subvolumes on an existing btrfs filesystem. The driver can
create new blank subvolumes and snapshots of existing subvolumes as well
as delete existing subvolumes.
The subvolumes created are automatically made visible on the host side
and can be attached to domains using the <filesystem> tags as defined in
'format domain' documentation.
Libvirt volumes do not implement quotas at the moment because the current
(btrfs-progs-0.20.rc1.20130501git7854c8b-4.fc20.x86_64) support for quota
management in btrfs-progs is lacking the necessary features, for example
it's not possible to see the quota assigned to a certain subvolume and
usage information is only updated on syncfs(2). Quota support will be
implemented once the tools gain the necessary features.
Signed-off-by: Oskari Saarenmaa <os(a)ohmu.fi>
---
configure.ac | 23 +-
docs/drivers.html.in | 1 +
docs/schemas/storagepool.rng | 11 +
docs/storage.html.in | 60 +++++
include/libvirt/libvirt.h.in | 1 +
libvirt.spec.in | 2 +
src/Makefile.am | 8 +
src/conf/storage_conf.c | 12 +-
src/conf/storage_conf.h | 1 +
src/storage/storage_backend.c | 6 +
src/storage/storage_backend_btrfs.c | 284 ++++++++++++++++++++++
src/storage/storage_backend_btrfs.h | 30 +++
tests/storagepoolxml2xmlin/pool-btrfs.xml | 7 +
tests/storagepoolxml2xmlout/pool-btrfs.xml | 17 ++
tests/storagepoolxml2xmltest.c | 1 +
tests/storagevolxml2xmlin/vol-btrfs-snapshot.xml | 11 +
tests/storagevolxml2xmlin/vol-btrfs.xml | 8 +
tests/storagevolxml2xmlout/vol-btrfs-snapshot.xml | 26 ++
tests/storagevolxml2xmlout/vol-btrfs.xml | 17 ++
tests/storagevolxml2xmltest.c | 2 +
20 files changed, 525 insertions(+), 3 deletions(-)
create mode 100644 src/storage/storage_backend_btrfs.c
create mode 100644 src/storage/storage_backend_btrfs.h
create mode 100644 tests/storagepoolxml2xmlin/pool-btrfs.xml
create mode 100644 tests/storagepoolxml2xmlout/pool-btrfs.xml
create mode 100644 tests/storagevolxml2xmlin/vol-btrfs-snapshot.xml
create mode 100644 tests/storagevolxml2xmlin/vol-btrfs.xml
create mode 100644 tests/storagevolxml2xmlout/vol-btrfs-snapshot.xml
create mode 100644 tests/storagevolxml2xmlout/vol-btrfs.xml
diff --git a/configure.ac b/configure.ac
index f853e03..100c87d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1562,6 +1562,8 @@ AC_ARG_WITH([storage-rbd],
AC_HELP_STRING([--with-storage-rbd], [with RADOS Block Device backend for the storage driver @<:@default=check@:>@]),[],[with_storage_rbd=check])
AC_ARG_WITH([storage-sheepdog],
AC_HELP_STRING([--with-storage-sheepdog], [with Sheepdog backend for the storage driver @<:@default=check@:>@]),[],[with_storage_sheepdog=check])
+AC_ARG_WITH([storage-btrfs],
+ AC_HELP_STRING([--with-storage-btrfs], [with Btrfs backend for the storage driver @<:@default=check@:>@]),[],[with_storage_btrfs=check])
if test "$with_libvirtd" = "no"; then
with_storage_dir=no
@@ -1774,6 +1776,24 @@ fi
AM_CONDITIONAL([WITH_STORAGE_SHEEPDOG],
[test "$with_storage_sheepdog" = "yes"])
+if test "$with_storage_btrfs" = "yes" || test "$with_storage_btrfs" = "check"; then
+ AC_PATH_PROG([BTRFS], [btrfs], [], [$PATH:/sbin:/usr/sbin])
+
+ if test "$with_storage_btrfs" = "yes" ; then
+ if test -z "$BTRFS" ; then AC_MSG_ERROR([We need btrfs -command for btrfs storage driver]) ; fi
+ else
+ if test -z "$BTRFS" ; then with_storage_btrfs=no ; fi
+ if test "$with_storage_btrfs" = "check" ; then with_storage_btrfs=yes ; fi
+ fi
+
+ if test "$with_storage_btrfs" = "yes" ; then
+ AC_DEFINE_UNQUOTED([WITH_STORAGE_BTRFS], 1, [whether Btrfs backend for storage driver is enabled])
+ AC_DEFINE_UNQUOTED([BTRFS],["$BTRFS"],[Location of btrfs program])
+ fi
+fi
+AM_CONDITIONAL([WITH_STORAGE_BTRFS], [test "$with_storage_btrfs" = "yes"])
+
+
LIBPARTED_CFLAGS=
LIBPARTED_LIBS=
@@ -1861,7 +1881,7 @@ AC_SUBST([DEVMAPPER_CFLAGS])
AC_SUBST([DEVMAPPER_LIBS])
with_storage=no
-for backend in dir fs lvm iscsi scsi mpath rbd disk; do
+for backend in dir fs lvm iscsi scsi mpath rbd disk btrfs; do
if eval test \$with_storage_$backend = yes; then
with_storage=yes
break
@@ -2573,6 +2593,7 @@ AC_MSG_NOTICE([ mpath: $with_storage_mpath])
AC_MSG_NOTICE([ Disk: $with_storage_disk])
AC_MSG_NOTICE([ RBD: $with_storage_rbd])
AC_MSG_NOTICE([Sheepdog: $with_storage_sheepdog])
+AC_MSG_NOTICE([ Btrfs: $with_storage_btrfs])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Security Drivers])
AC_MSG_NOTICE([])
diff --git a/docs/drivers.html.in b/docs/drivers.html.in
index 7aa44f3..d9eb6d7 100644
--- a/docs/drivers.html.in
+++ b/docs/drivers.html.in
@@ -48,6 +48,7 @@
<li><strong><a href="storage.html#StorageBackendMultipath">Multipath backend</a></strong></li>
<li><strong><a href="storage.html#StorageBackendRBD">RBD (RADOS Block Device) backend</a></strong></li>
<li><strong><a href="storage.html#StorageBackendSheepdog">Sheepdog backend</a></strong></li>
+ <li><strong><a href="storage.html#StorageBackendBtrfs">Btrfs subvolume backend</a></strong></li>
</ul>
</body>
</html>
diff --git a/docs/schemas/storagepool.rng b/docs/schemas/storagepool.rng
index a4ef5af..6435566 100644
--- a/docs/schemas/storagepool.rng
+++ b/docs/schemas/storagepool.rng
@@ -21,6 +21,7 @@
<ref name='poolmpath'/>
<ref name='poolrbd'/>
<ref name='poolsheepdog'/>
+ <ref name='poolbtrfs'/>
</choice>
</element>
</define>
@@ -125,6 +126,16 @@
<ref name='sourcesheepdog'/>
</define>
+ <define name='poolbtrfs'>
+ <attribute name='type'>
+ <value>btrfs</value>
+ </attribute>
+ <ref name='commonmetadata'/>
+ <ref name='sizing'/>
+ <ref name='sourcedir'/>
+ <ref name='target'/>
+ </define>
+
<define name='sourceinfovendor'>
<optional>
<element name='vendor'>
diff --git a/docs/storage.html.in b/docs/storage.html.in
index 1181444..4d4690c 100644
--- a/docs/storage.html.in
+++ b/docs/storage.html.in
@@ -114,6 +114,9 @@
<li>
<a href="#StorageBackendSheepdog">Sheepdog backend</a>
</li>
+ <li>
+ <a href="#StorageBackendBtrfs">Btrfs subvolume backend</a>
+ </li>
</ul>
<h2><a name="StorageBackendDir">Directory pool</a></h2>
@@ -647,5 +650,62 @@
The Sheepdog pool does not use the volume format type element.
</p>
+ <h2><a name="StorageBackendBtrfs">Btrfs subolume pools</a></h2>
+ <p>
+ This provides a pool based on a Btrfs filesystem using subvolumes and
+ optionally their snapshots. Btrfs subvolume pool can be used to create
+ subvolumes ans snapshots on the host side and the created volumes can
+ be attached as filesystems to LXC domains.
+
+ The btrfs filesystem must already be formatted and mounted. Subvolume
+ quotas are not supported at the moment.
+
+ <span class="since">Since 1.1.3</span>
+ </p>
+
+ <h3>Example pool input</h3>
+ <pre>
+ <pool type="btrfs">
+ <name>lxcdomains</name>
+ <target>
+ <path>/lxc</path>
+ </target>
+ </pool></pre>
+
+ <h3>Example volume output</h3>
+ <pre>
+ <volume>
+ <name>vanilla</name>
+ <key>/lxc/vanilla</key>
+ <source>
+ </source>
+ <capacity unit='bytes'>0</capacity>
+ <allocation unit='bytes'>0</allocation>
+ <target>
+ <path>/lxc/vanilla</path>
+ <permissions>
+ <mode>00</mode>
+ <owner>0</owner>
+ <group>0</group>
+ </permissions>
+ </target>
+ </volume></pre>
+
+ <h3>Example filesystem attachment</h3>
+ <p>Btrfs volumes can be attached to LXC guests. Information about
+ attaching a filesystem to a guest can be found at the
+ <a href="formatdomain.html#elementsFilesystems">format domain</a>
+ page.</p>
+
+ <h3>Valid pool format types</h3>
+ <p>
+ The Btrfs pool does not use the pool format type element.
+ </p>
+
+ <h3>Valid volume format types</h3>
+ <p>
+ The Btrfs pool does not use the volume format type element.
+ </p>
+
</body>
</html>
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index a47e33c..6106ad5 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -3028,6 +3028,7 @@ typedef enum {
VIR_CONNECT_LIST_STORAGE_POOLS_MPATH = 1 << 13,
VIR_CONNECT_LIST_STORAGE_POOLS_RBD = 1 << 14,
VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG = 1 << 15,
+ VIR_CONNECT_LIST_STORAGE_POOLS_BTRFS = 1 << 16,
} virConnectListAllStoragePoolsFlags;
int virConnectListAllStoragePools(virConnectPtr conn,
diff --git a/libvirt.spec.in b/libvirt.spec.in
index e94901a..3867b99 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -730,6 +730,8 @@ Requires: device-mapper
Requires: device-mapper
%endif
%if %{with_storage_sheepdog}
+# For Btrfs storage
+Requires: btrfs-progs
# For Sheepdog support
Requires: sheepdog
%endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 636bcbc..cdcda36 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -789,6 +789,9 @@ STORAGE_DRIVER_RBD_SOURCES = \
STORAGE_DRIVER_SHEEPDOG_SOURCES = \
storage/storage_backend_sheepdog.h storage/storage_backend_sheepdog.c
+STORAGE_DRIVER_BTRFS_SOURCES = \
+ storage/storage_backend_btrfs.h storage/storage_backend_btrfs.c
+
STORAGE_HELPER_DISK_SOURCES = \
storage/parthelper.c
@@ -1402,6 +1405,10 @@ if WITH_STORAGE_SHEEPDOG
libvirt_driver_storage_impl_la_SOURCES += $(STORAGE_DRIVER_SHEEPDOG_SOURCES)
endif
+if WITH_STORAGE_BTRFS
+libvirt_driver_storage_impl_la_SOURCES += $(STORAGE_DRIVER_BTRFS_SOURCES)
+endif
+
if WITH_NODE_DEVICES
# Needed to keep automake quiet about conditionals
if WITH_DRIVER_MODULES
@@ -1594,6 +1601,7 @@ EXTRA_DIST += \
$(STORAGE_DRIVER_DISK_SOURCES) \
$(STORAGE_DRIVER_RBD_SOURCES) \
$(STORAGE_DRIVER_SHEEPDOG_SOURCES) \
+ $(STORAGE_DRIVER_BTRFS_SOURCES) \
$(NODE_DEVICE_DRIVER_SOURCES) \
$(NODE_DEVICE_DRIVER_HAL_SOURCES) \
$(NODE_DEVICE_DRIVER_UDEV_SOURCES) \
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 002663f..ce7c999 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -55,7 +55,8 @@ VIR_ENUM_IMPL(virStoragePool,
VIR_STORAGE_POOL_LAST,
"dir", "fs", "netfs",
"logical", "disk", "iscsi",
- "scsi", "mpath", "rbd", "sheepdog")
+ "scsi", "mpath", "rbd", "sheepdog",
+ "btrfs")
VIR_ENUM_IMPL(virStoragePoolFormatFileSystem,
VIR_STORAGE_POOL_FS_LAST,
@@ -261,6 +262,11 @@ static virStoragePoolTypeInfo poolTypeInfo[] = {
.formatFromString = virStorageVolFormatDiskTypeFromString,
.formatToString = virStorageVolFormatDiskTypeToString,
},
+ },
+ {.poolType = VIR_STORAGE_POOL_BTRFS,
+ .volOptions = {
+ .formatToString = virStoragePoolFormatDiskTypeToString,
+ }
}
};
@@ -2189,7 +2195,9 @@ virStoragePoolMatch(virStoragePoolObjPtr poolobj,
(MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_RBD) &&
(poolobj->def->type == VIR_STORAGE_POOL_RBD)) ||
(MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG) &&
- (poolobj->def->type == VIR_STORAGE_POOL_SHEEPDOG))))
+ (poolobj->def->type == VIR_STORAGE_POOL_SHEEPDOG)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_BTRFS) &&
+ (poolobj->def->type == VIR_STORAGE_POOL_BTRFS))))
return false;
}
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index 62ff1fd..3d02c2a 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -128,6 +128,7 @@ enum virStoragePoolType {
VIR_STORAGE_POOL_MPATH, /* Multipath devices */
VIR_STORAGE_POOL_RBD, /* RADOS Block Device */
VIR_STORAGE_POOL_SHEEPDOG, /* Sheepdog device */
+ VIR_STORAGE_POOL_BTRFS, /* btrfs subvolumes / snapshots */
VIR_STORAGE_POOL_LAST,
};
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 4ebe11b..1518dec 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -80,6 +80,9 @@
#if WITH_STORAGE_SHEEPDOG
# include "storage_backend_sheepdog.h"
#endif
+#if WITH_STORAGE_BTRFS
+# include "storage_backend_btrfs.h"
+#endif
#define VIR_FROM_THIS VIR_FROM_STORAGE
@@ -112,6 +115,9 @@ static virStorageBackendPtr backends[] = {
#if WITH_STORAGE_SHEEPDOG
&virStorageBackendSheepdog,
#endif
+#if WITH_STORAGE_BTRFS
+ &virStorageBackendBtrfs,
+#endif
NULL
};
diff --git a/src/storage/storage_backend_btrfs.c b/src/storage/storage_backend_btrfs.c
new file mode 100644
index 0000000..f0b7563
--- /dev/null
+++ b/src/storage/storage_backend_btrfs.c
@@ -0,0 +1,284 @@
+/*
+ * storage_backend_btrfs.c: btrfs subvolume / snapshot backed storage
+ *
+ * Copyright (C) 2007-2012 Red Hat, Inc.
+ * Copyright (C) 2013 Oskari Saarenmaa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Oskari Saarenmaa <os(a)ohmu.fi>
+ */
+
+#include <config.h>
+
+#include <sys/statvfs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "storage_backend.h"
+#include "viralloc.h"
+#include "virfile.h"
+#include "virstring.h"
+
+#define VIR_FROM_THIS VIR_FROM_STORAGE
+
+static char *
+btrfsPoolVolPath(virStoragePoolObjPtr pool,
+ const char *name)
+{
+ char *res = NULL;
+ int rc = -1;
+ if (STREQLEN(name, pool->def->target.path,
+ strlen(pool->def->target.path))) {
+ rc = VIR_STRDUP(res, name);
+ } else {
+ rc = virAsprintf(&res, "%s/%s", pool->def->target.path, name);
+ }
+ return (rc < 0) ? NULL : res;
+}
+
+static int
+btrfsPoolCheck(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolObjPtr pool,
+ bool *isActive)
+{
+ *isActive = (access(pool->def->target.path, R_OK | X_OK) == 0);
+ return 0;
+}
+
+struct btrfsVolS {
+ int count;
+ struct {
+ char *name;
+ char *uuid;
+ } *vols;
+};
+
+static int
+btrfsPoolFindVols(virStoragePoolObjPtr pool,
+ char **const groups,
+ void *data)
+{
+ struct btrfsVolS *bvols = data;
+ virStorageVolDefPtr vol = NULL;
+ int idx, ret = -1;
+
+ if (VIR_ALLOC(vol) < 0)
+ goto cleanup;
+
+ if (VIR_STRDUP(vol->name, groups[2]) < 0)
+ goto cleanup;
+
+ vol->type = VIR_STORAGE_VOL_DIR;
+ if (virAsprintf(&vol->target.path, "%s/%s",
+ pool->def->target.path,
+ vol->name) == -1)
+ goto cleanup;
+
+ if (VIR_STRDUP(vol->key, vol->target.path) < 0)
+ goto cleanup;
+
+ /* Store uuid and name in case a snapshot targets this volume */
+ if (VIR_REALLOC_N(bvols->vols, bvols->count+1) < 0)
+ goto cleanup;
+ idx = bvols->count++;
+ bvols->vols[idx].name = NULL;
+ bvols->vols[idx].uuid = NULL;
+ if (VIR_STRDUP(bvols->vols[idx].name, groups[2]) < 0 ||
+ VIR_STRDUP(bvols->vols[idx].uuid, groups[1]) < 0)
+ goto cleanup;
+
+ /* Is this a snapshot? */
+ if (STRNEQ(groups[0], "-")) {
+ for (idx = 0; idx < bvols->count; idx++) {
+ if (STREQ(bvols->vols[idx].uuid, groups[0])) {
+ vol->backingStore.path = btrfsPoolVolPath(pool, bvols->vols[idx].name);
+ if (vol->backingStore.path == NULL)
+ goto cleanup;
+ break;
+ }
+ }
+ }
+
+ if (VIR_REALLOC_N(pool->volumes.objs,
+ pool->volumes.count+1) < 0)
+ goto cleanup;
+
+ pool->volumes.objs[pool->volumes.count++] = vol;
+ vol = NULL;
+ ret = 0;
+
+cleanup:
+ virStorageVolDefFree(vol);
+ return ret;
+}
+
+static int
+btrfsPoolRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolObjPtr pool)
+{
+ struct statvfs sb;
+ struct btrfsVolS bvols;
+ int idx, vars[] = {3};
+ const char *regexes[] = {
+ "^ID [0-9]+ gen [0-9]+ top level [0-9]+ "
+ "parent_uuid ([-a-f0-9]+) uuid ([-a-f0-9]+) path (\\S+)$"};
+ virCommandPtr cmd = virCommandNewArgList(
+ "btrfs", "subvolume", "list", "-uq", pool->def->target.path, NULL);
+
+ bvols.count = 0;
+ bvols.vols = NULL;
+ if (virStorageBackendRunProgRegex(pool, cmd, 1, regexes, vars,
+ btrfsPoolFindVols, &bvols, NULL) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to parse btrfs subvolume list"));
+ goto cleanup;
+ }
+
+ if (statvfs(pool->def->target.path, &sb) < 0) {
+ virReportSystemError(errno,
+ _("cannot statvfs path '%s'"),
+ pool->def->target.path);
+ goto cleanup;
+ }
+ pool->def->capacity = ((unsigned long long)sb.f_frsize *
+ (unsigned long long)sb.f_blocks);
+ pool->def->available = ((unsigned long long)sb.f_bfree *
+ (unsigned long long)sb.f_frsize);
+ pool->def->allocation = pool->def->capacity - pool->def->available;
+
+ return 0;
+
+cleanup:
+ virStoragePoolObjClearVols(pool);
+ for (idx = 0; idx < bvols.count; idx++) {
+ VIR_FREE(bvols.vols[idx].name);
+ VIR_FREE(bvols.vols[idx].uuid);
+ }
+ VIR_FREE(bvols.vols);
+
+ return -1;
+}
+
+static int
+btrfsPoolVolCreate(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolObjPtr pool,
+ virStorageVolDefPtr vol)
+{
+ vol->type = VIR_STORAGE_VOL_DIR;
+
+ VIR_FREE(vol->target.path);
+ vol->target.path = btrfsPoolVolPath(pool, vol->name);
+ if (vol->target.path == NULL)
+ return -1;
+
+ if (virFileExists(vol->target.path)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("volume target path '%s' already exists"),
+ vol->target.path);
+ return -1;
+ }
+
+ VIR_FREE(vol->key);
+ return VIR_STRDUP(vol->key, vol->target.path);
+}
+
+static int
+btrfsPoolVolBuild(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolObjPtr pool,
+ virStorageVolDefPtr vol,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ int ret = -1;
+ char *target_volume = NULL, *snapshot_source = NULL;
+ virCommandPtr cmd = virCommandNew("btrfs");
+ struct stat st;
+
+ if (!cmd)
+ goto cleanup;
+
+ target_volume = btrfsPoolVolPath(pool, vol->target.path);
+ if (target_volume == NULL)
+ goto cleanup;
+
+ if (vol->backingStore.path == NULL) {
+ virCommandAddArgList(cmd, "subvolume", "create", target_volume, NULL);
+ } else {
+ int accessRetCode = -1;
+ snapshot_source = btrfsPoolVolPath(pool, vol->backingStore.path);
+ if (snapshot_source == NULL)
+ goto cleanup;
+
+ accessRetCode = access(snapshot_source, R_OK | X_OK);
+ if (accessRetCode != 0) {
+ virReportSystemError(errno,
+ _("inaccessible backing store volume %s"),
+ vol->backingStore.path);
+ goto cleanup;
+ }
+
+ virCommandAddArgList(cmd, "subvolume", "snapshot", snapshot_source,
+ target_volume, NULL);
+ }
+
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+ if (stat(target_volume, &st) < 0) {
+ virReportSystemError(errno,
+ _("failed to create %s"), vol->target.path);
+ goto cleanup;
+ }
+ ret = 0;
+
+cleanup:
+ VIR_FREE(target_volume);
+ VIR_FREE(snapshot_source);
+ virCommandFree(cmd);
+ return ret;
+}
+
+static int
+btrfsPoolVolDelete(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolObjPtr pool,
+ virStorageVolDefPtr vol,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ int ret = -1;
+ char *target_volume = btrfsPoolVolPath(pool, vol->target.path);
+ virCommandPtr cmd = virCommandNewArgList("btrfs", "subvolume",
+ "delete", target_volume, NULL);
+ if (target_volume == NULL || cmd == NULL)
+ goto cleanup;
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+ ret = 0;
+
+cleanup:
+ VIR_FREE(target_volume);
+ virCommandFree(cmd);
+ return ret;
+}
+
+virStorageBackend virStorageBackendBtrfs = {
+ .type = VIR_STORAGE_POOL_BTRFS,
+
+ .checkPool = btrfsPoolCheck,
+ .refreshPool = btrfsPoolRefresh,
+
+ .buildVol = btrfsPoolVolBuild,
+ .createVol = btrfsPoolVolCreate,
+ .deleteVol = btrfsPoolVolDelete,
+};
diff --git a/src/storage/storage_backend_btrfs.h b/src/storage/storage_backend_btrfs.h
new file mode 100644
index 0000000..7d65f58
--- /dev/null
+++ b/src/storage/storage_backend_btrfs.h
@@ -0,0 +1,30 @@
+/*
+ * storage_backend_btrfs.c: btrfs subvolume / snapshot backed storage
+ *
+ * Copyright (C) 2013 Oskari Saarenmaa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Oskari Saarenmaa <os(a)ohmu.fi>
+ */
+
+#ifndef __VIR_STORAGE_BACKEND_BTRFS_H__
+# define __VIR_STORAGE_BACKEND_BTRFS_H__
+
+# include "storage_backend.h"
+
+extern virStorageBackend virStorageBackendBtrfs;
+
+#endif /* __VIR_STORAGE_BACKEND_BTRFS_H__ */
diff --git a/tests/storagepoolxml2xmlin/pool-btrfs.xml b/tests/storagepoolxml2xmlin/pool-btrfs.xml
new file mode 100644
index 0000000..c9e0626
--- /dev/null
+++ b/tests/storagepoolxml2xmlin/pool-btrfs.xml
@@ -0,0 +1,7 @@
+<pool type='btrfs'>
+ <name>lxc</name>
+ <uuid>96a73758-5481-4e79-b557-e130b81adf4c</uuid>
+ <target>
+ <path>/lxc</path>
+ </target>
+</pool>
diff --git a/tests/storagepoolxml2xmlout/pool-btrfs.xml b/tests/storagepoolxml2xmlout/pool-btrfs.xml
new file mode 100644
index 0000000..c2cdec9
--- /dev/null
+++ b/tests/storagepoolxml2xmlout/pool-btrfs.xml
@@ -0,0 +1,17 @@
+<pool type='btrfs'>
+ <name>lxc</name>
+ <uuid>96a73758-5481-4e79-b557-e130b81adf4c</uuid>
+ <capacity unit='bytes'>0</capacity>
+ <allocation unit='bytes'>0</allocation>
+ <available unit='bytes'>0</available>
+ <source>
+ </source>
+ <target>
+ <path>/lxc</path>
+ <permissions>
+ <mode>0755</mode>
+ <owner>-1</owner>
+ <group>-1</group>
+ </permissions>
+ </target>
+</pool>
diff --git a/tests/storagepoolxml2xmltest.c b/tests/storagepoolxml2xmltest.c
index d59cff9..cf61d24 100644
--- a/tests/storagepoolxml2xmltest.c
+++ b/tests/storagepoolxml2xmltest.c
@@ -100,6 +100,7 @@ mymain(void)
DO_TEST("pool-iscsi-multiiqn");
DO_TEST("pool-iscsi-vendor-product");
DO_TEST("pool-sheepdog");
+ DO_TEST("pool-btrfs");
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/tests/storagevolxml2xmlin/vol-btrfs-snapshot.xml b/tests/storagevolxml2xmlin/vol-btrfs-snapshot.xml
new file mode 100644
index 0000000..f412e44
--- /dev/null
+++ b/tests/storagevolxml2xmlin/vol-btrfs-snapshot.xml
@@ -0,0 +1,11 @@
+<volume>
+ <name>clone</name>
+ <capacity unit="bytes">0</capacity>
+ <allocation unit="bytes">0</allocation>
+ <target>
+ <path>/lxc/clone</path>
+ </target>
+ <backingStore>
+ <path>/lxc/vanilla</path>
+ </backingStore>
+</volume>
diff --git a/tests/storagevolxml2xmlin/vol-btrfs.xml b/tests/storagevolxml2xmlin/vol-btrfs.xml
new file mode 100644
index 0000000..9522029
--- /dev/null
+++ b/tests/storagevolxml2xmlin/vol-btrfs.xml
@@ -0,0 +1,8 @@
+<volume>
+ <name>vanilla</name>
+ <capacity unit="bytes">0</capacity>
+ <allocation unit="bytes">0</allocation>
+ <target>
+ <path>/lxc/vanilla</path>
+ </target>
+</volume>
diff --git a/tests/storagevolxml2xmlout/vol-btrfs-snapshot.xml b/tests/storagevolxml2xmlout/vol-btrfs-snapshot.xml
new file mode 100644
index 0000000..b96b5f0
--- /dev/null
+++ b/tests/storagevolxml2xmlout/vol-btrfs-snapshot.xml
@@ -0,0 +1,26 @@
+<volume>
+ <name>clone</name>
+ <key>(null)</key>
+ <source>
+ </source>
+ <capacity unit='bytes'>0</capacity>
+ <allocation unit='bytes'>0</allocation>
+ <target>
+ <path>/lxc/clone</path>
+ <format type='unknown'/>
+ <permissions>
+ <mode>0600</mode>
+ <owner>4294967295</owner>
+ <group>4294967295</group>
+ </permissions>
+ </target>
+ <backingStore>
+ <path>/lxc/vanilla</path>
+ <format type='unknown'/>
+ <permissions>
+ <mode>0600</mode>
+ <owner>4294967295</owner>
+ <group>4294967295</group>
+ </permissions>
+ </backingStore>
+</volume>
diff --git a/tests/storagevolxml2xmlout/vol-btrfs.xml b/tests/storagevolxml2xmlout/vol-btrfs.xml
new file mode 100644
index 0000000..bef5a1a
--- /dev/null
+++ b/tests/storagevolxml2xmlout/vol-btrfs.xml
@@ -0,0 +1,17 @@
+<volume>
+ <name>vanilla</name>
+ <key>(null)</key>
+ <source>
+ </source>
+ <capacity unit='bytes'>0</capacity>
+ <allocation unit='bytes'>0</allocation>
+ <target>
+ <path>/lxc/vanilla</path>
+ <format type='unknown'/>
+ <permissions>
+ <mode>0600</mode>
+ <owner>4294967295</owner>
+ <group>4294967295</group>
+ </permissions>
+ </target>
+</volume>
diff --git a/tests/storagevolxml2xmltest.c b/tests/storagevolxml2xmltest.c
index 5b0a60b..fdfcc55 100644
--- a/tests/storagevolxml2xmltest.c
+++ b/tests/storagevolxml2xmltest.c
@@ -120,6 +120,8 @@ mymain(void)
DO_TEST("pool-logical", "vol-logical");
DO_TEST("pool-logical", "vol-logical-backing");
DO_TEST("pool-sheepdog", "vol-sheepdog");
+ DO_TEST("pool-btrfs", "vol-btrfs");
+ DO_TEST("pool-btrfs", "vol-btrfs-snapshot");
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
1.8.3.1
11 years, 2 months
[libvirt] [PATCH 1/n] spec: fix rpm build when lxc disabled
by Eric Blake
'make rpm' failed if ~/.rpmmacros contains '%_without_lxc 1',
which simulates the case of not having lxc available.
RPM build errors:
File not found: /home/eblake/rpmbuild/BUILDROOT/libvirt-1.1.1-1.fc19.x86_64/etc/libvirt/virt-login-shell.conf
File not found by glob: /home/eblake/rpmbuild/BUILDROOT/libvirt-1.1.1-1.fc19.x86_64/usr/share/man/man1/virt-login-shell.1*
File not found: /home/eblake/rpmbuild/BUILDROOT/libvirt-1.1.1-1.fc19.x86_64/usr/bin/virt-login-shell
make: *** [rpm] Error 1
Reported by Dan Berrange.
* libvirt.spec.in: Mark virt-login-shell as conditional on lxc.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
I'm working on a couple more that I spotted while in the area:
we still unconditionally build vbox even though we recently
moved it into libvirtd for licensing reasons, which means a
client_only build will probably fall over on that; but while
testing my hypothesis, I discoverd that a client_only build
fails even earlier with:
TEST: fdstreamtest
1) Stream read blocking ... OK
2) Stream read non-blocking ... Unexpected EOF block 0 want 128
FAILED
3) Stream write blocking ... OK
4) Stream write non-blocking ... Failed to finish stream: internal error: libvirt: error : cannot execute binary /home/eblake/rpmbuild/BUILD/libvirt-1.1.1/tests/../src/libvirt_iohelper: No such file or directory
libvirt.spec.in | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index e94901a..affd2ec 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -2014,17 +2014,23 @@ fi
%doc AUTHORS ChangeLog.gz NEWS README COPYING COPYING.LESSER TODO
%config(noreplace) %{_sysconfdir}/libvirt/libvirt.conf
+%if %{with_lxc}
%config(noreplace) %{_sysconfdir}/libvirt/virt-login-shell.conf
+%endif
%{_mandir}/man1/virsh.1*
%{_mandir}/man1/virt-xml-validate.1*
%{_mandir}/man1/virt-pki-validate.1*
%{_mandir}/man1/virt-host-validate.1*
+%if %{with_lxc}
%{_mandir}/man1/virt-login-shell.1*
+%endif
%{_bindir}/virsh
%{_bindir}/virt-xml-validate
%{_bindir}/virt-pki-validate
%{_bindir}/virt-host-validate
+%if %{with_lxc}
%attr(4755, root, root) %{_bindir}/virt-login-shell
+%endif
%{_libdir}/lib*.so.*
%if %{with_dtrace}
--
1.8.3.1
11 years, 2 months
[libvirt] [PATCH] libxl: Check for regcomp failure
by Jim Fehlig
Change libxlGetAutoballoonConf() function to return an int
for success/failure, and fail if regcomp fails.
Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
src/libxl/libxl_conf.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index fcb278b..a634476 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -1014,21 +1014,28 @@ error:
return -1;
}
-static bool
-libxlGetAutoballoonConf(libxlDriverConfigPtr cfg)
+static int
+libxlGetAutoballoonConf(libxlDriverConfigPtr cfg, bool *autoballoon)
{
regex_t regex;
- int ret;
+ int res;
+
+ if ((res = regcomp(®ex,
+ "(^| )dom0_mem=((|min:|max:)[0-9]+[bBkKmMgG]?,?)+($| )",
+ REG_NOSUB | REG_EXTENDED)) != 0) {
+ char error[100];
+ regerror(res, ®ex, error, sizeof(error));
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to compile regex %s"),
+ error);
- ret = regcomp(®ex,
- "(^| )dom0_mem=((|min:|max:)[0-9]+[bBkKmMgG]?,?)+($| )",
- REG_NOSUB | REG_EXTENDED);
- if (ret)
- return true;
+ return -1;
+ }
- ret = regexec(®ex, cfg->verInfo->commandline, 0, NULL, 0);
+ res = regexec(®ex, cfg->verInfo->commandline, 0, NULL, 0);
regfree(®ex);
- return ret == REG_NOMATCH;
+ *autoballoon = res == REG_NOMATCH;
+ return 0;
}
libxlDriverConfigPtr
@@ -1098,7 +1105,8 @@ libxlDriverConfigNew(void)
}
/* setup autoballoon */
- cfg->autoballoon = libxlGetAutoballoonConf(cfg);
+ if (libxlGetAutoballoonConf(cfg, &cfg->autoballoon) < 0)
+ goto error;
return cfg;
--
1.8.1.4
11 years, 2 months
[libvirt] [PATCH] Add '<nat>' element to '<forward>' network schemas
by Ján Tomko
Commits 905629f4 and 1716e7a6 have added support for specifying
an IPv4 range and a port range to be used by NAT:
<forward mode='nat'>
<nat>
<address start='10.20.30.40' end='10.20.30.44'/>
<port start='60000' end='65432'/>
</nat>
</forward>
https://bugzilla.redhat.com/show_bug.cgi?id=1004364
---
docs/schemas/network.rng | 26 +++++++++++++++++++++
docs/schemas/networkcommon.rng | 7 ++++++
.../nat-network-forward-nat-address.xml | 26 +++++++++++++++++++++
.../nat-network-forward-nat-address.xml | 27 ++++++++++++++++++++++
tests/networkxml2xmltest.c | 1 +
5 files changed, 87 insertions(+)
create mode 100644 tests/networkxml2xmlin/nat-network-forward-nat-address.xml
create mode 100644 tests/networkxml2xmlout/nat-network-forward-nat-address.xml
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index ab183f1..d7edb09 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -160,6 +160,32 @@
<empty/>
</element>
</optional>
+ <optional>
+ <element name='nat'>
+ <interleave>
+ <optional>
+ <element name='address'>
+ <attribute name='start'>
+ <ref name='ipv4Addr'/>
+ </attribute>
+ <attribute name='end'>
+ <ref name='ipv4Addr'/>
+ </attribute>
+ </element>
+ </optional>
+ <optional>
+ <element name='port'>
+ <attribute name='start'>
+ <ref name='port'/>
+ </attribute>
+ <attribute name='end'>
+ <ref name='port'/>
+ </attribute>
+ </element>
+ </optional>
+ </interleave>
+ </element>
+ </optional>
</interleave>
</element>
</optional>
diff --git a/docs/schemas/networkcommon.rng b/docs/schemas/networkcommon.rng
index e60f1fc..e26b7f3 100644
--- a/docs/schemas/networkcommon.rng
+++ b/docs/schemas/networkcommon.rng
@@ -217,4 +217,11 @@
</oneOrMore>
</element>
</define>
+
+ <define name='port'>
+ <data type='integer'>
+ <param name='minInclusive'>1</param>
+ <param name='maxInclusive'>65535</param>
+ </data>
+ </define>
</grammar>
diff --git a/tests/networkxml2xmlin/nat-network-forward-nat-address.xml b/tests/networkxml2xmlin/nat-network-forward-nat-address.xml
new file mode 100644
index 0000000..403d058
--- /dev/null
+++ b/tests/networkxml2xmlin/nat-network-forward-nat-address.xml
@@ -0,0 +1,26 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <bridge name="virbr0"/>
+ <forward mode="nat" dev="eth1">
+ <nat>
+ <address start='10.20.30.40' end='10.20.30.44'/>
+ <port start='60000' end='65432'/>
+ </nat>
+ </forward>
+ <ip address="192.168.122.1" netmask="255.255.255.0">
+ <dhcp>
+ <range start="192.168.122.2" end="192.168.122.254"/>
+ <host mac="00:16:3e:77:e2:ed" name="a.example.com" ip="192.168.122.10"/>
+ <host mac="00:16:3e:3e:a9:1a" name="b.example.com" ip="192.168.122.11"/>
+ </dhcp>
+ </ip>
+ <ip family="ipv4" address="192.168.123.1" netmask="255.255.255.0">
+ </ip>
+ <ip family="ipv6" address="2001:db8:ac10:fe01::1" prefix="64">
+ </ip>
+ <ip family="ipv6" address="2001:db8:ac10:fd01::1" prefix="64">
+ </ip>
+ <ip family="ipv4" address="10.24.10.1">
+ </ip>
+</network>
diff --git a/tests/networkxml2xmlout/nat-network-forward-nat-address.xml b/tests/networkxml2xmlout/nat-network-forward-nat-address.xml
new file mode 100644
index 0000000..faeba24
--- /dev/null
+++ b/tests/networkxml2xmlout/nat-network-forward-nat-address.xml
@@ -0,0 +1,27 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'>
+ <nat>
+ <address start='10.20.30.40' end='10.20.30.44'/>
+ <port start='60000' end='65432'/>
+ </nat>
+ <interface dev='eth1'/>
+ </forward>
+ <bridge name='virbr0' stp='on' delay='0'/>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <range start='192.168.122.2' end='192.168.122.254'/>
+ <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10'/>
+ <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11'/>
+ </dhcp>
+ </ip>
+ <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+ </ip>
+ <ip family='ipv4' address='10.24.10.1'>
+ </ip>
+</network>
diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c
index 675a862..d04039d 100644
--- a/tests/networkxml2xmltest.c
+++ b/tests/networkxml2xmltest.c
@@ -108,6 +108,7 @@ mymain(void)
DO_TEST("nat-network-dns-srv-record-minimal");
DO_TEST("nat-network-dns-hosts");
DO_TEST("nat-network-dns-forward-plain");
+ DO_TEST("nat-network-forward-nat-address");
DO_TEST("8021Qbh-net");
DO_TEST("direct-net");
DO_TEST("host-bridge-net");
--
1.8.1.5
11 years, 2 months
[libvirt] [PATCH] Fix a typo in network XML docs
by Ján Tomko
---
Pushed as trivial.
docs/formatnetwork.html.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index e1482db..36c381a 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -155,7 +155,7 @@
</forward>
...</pre>
<p>
- An singe IPv4 address can be set by setting
+ A single IPv4 address can be set by setting
<code>start</code> and <code>end</code> attributes to
the same value.
</p>
--
1.8.1.5
11 years, 2 months
[libvirt] [PATCH] Change 'shortforward' to bool.
by Ján Tomko
---
Pushed as trivial.
src/conf/network_conf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index d54f2aa..654919e 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -2552,7 +2552,7 @@ virNetworkDefFormatInternal(virBufferPtr buf,
unsigned char *uuid;
char uuidstr[VIR_UUID_STRING_BUFLEN];
size_t i;
- int shortforward;
+ bool shortforward;
virBufferAddLit(buf, "<network");
if (!(flags & VIR_NETWORK_XML_INACTIVE) && (def->connections > 0)) {
--
1.8.1.5
11 years, 2 months
[libvirt] [PATCH] LXC: Don't mount securityfs when user namespace enabled
by Gao feng
Right now, securityfs is disallowed to be mounted in
un init user namespace, we should avoid to mount securityfs
in the container which enables user namespace.
Signed-off-by: Gao feng <gaofeng(a)cn.fujitsu.com>
---
src/lxc/lxc_container.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 8abaea0..c41ab40 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -750,7 +750,7 @@ err:
}
-static int lxcContainerMountBasicFS(void)
+static int lxcContainerMountBasicFS(bool userns_enabled)
{
const struct {
const char *src;
@@ -801,6 +801,9 @@ static int lxcContainerMountBasicFS(void)
continue;
#endif
+ if (STREQ(mnts[i].src, "securityfs") && userns_enabled)
+ continue;
+
if (virFileMakePath(mnts[i].dst) < 0) {
virReportSystemError(errno,
_("Failed to mkdir %s"),
@@ -1530,7 +1533,7 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
goto cleanup;
/* Mounts the core /proc, /sys, etc filesystems */
- if (lxcContainerMountBasicFS() < 0)
+ if (lxcContainerMountBasicFS(vmDef->idmap.nuidmap) < 0)
goto cleanup;
/* Mounts /proc/meminfo etc sysinfo */
--
1.8.3.1
11 years, 2 months
[libvirt] [PATCH] [RFC] docs: Add OpenStack into references
by Martin Kletzander
diff --git a/docs/apps.html.in b/docs/apps.html.in
index 46e5dca..9f22df8 100644
--- a/docs/apps.html.in
+++ b/docs/apps.html.in
@@ -244,6 +244,15 @@
integrates libvirt for VM monitoring, live migration, and life-cycle
management.
</dd>
+
+ <dt><a href="http://www.openstack.org">OpenStack</a></dt>
+ <dd>
+ OpenStack is a "cloud operating system" usable for both public
+ and private clouds. Its various parts take care of compute,
+ storage and networking resources and iterface with the user
+ using a dashboard. Compute part uses libvirt to manage VM
+ life-cycle, monitoring and so on.
+ </dd>
</dl>
<h2><a name="libraries">Libraries</a></h2>
--
1.8.3.2
11 years, 2 months
[libvirt] [PATCH] conf: Don't deref NULL actual network in virDomainNetGetActualHostdev()
by Peter Krempa
In commit 991270db99690 I've used virDomainNetGetActualHostdev() to get
the actual hostdev from a network when removing the network from the
list to avoid leaving the hostdev in the list. I didn't notice that this
function doesn't check if the actual network is allocated and
dereferences it. This crashes the daemon when cleaning up a domain
object in early startup phases when the actual network definition isn't
allocated. When the actual definition isn't present, the hostdev that
might correspond to it won't be present anyways so it's safe to return
NULL.
Thanks to Cole Robinson for noticing this problem.
---
src/conf/domain_conf.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cef4cf9..276c6ba 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -17875,6 +17875,7 @@ virDomainNetGetActualHostdev(virDomainNetDefPtr iface)
if (iface->type == VIR_DOMAIN_NET_TYPE_HOSTDEV)
return &iface->data.hostdev.def;
if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
+ iface->data.network.actual &&
iface->data.network.actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
return &iface->data.network.actual->data.hostdev.def;
}
--
1.8.3.2
11 years, 2 months