[libvirt] [PATCH] Using qemu with sheepdog pool
by joel SIMOES
From: Joel SIMOES <joel.simoes(a)laposte.net>
---
src/qemu/qemu_conf.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 65 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index ac53f6d..dfafcdc 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1185,6 +1185,56 @@ int qemuDriverAllocateID(virQEMUDriverPtr driver)
return virAtomicIntInc(&driver->nextvmid);
}
+
+static int
+qemuAddSheepPoolSourceHost(virDomainDiskDefPtr def,
+ virStoragePoolDefPtr pooldef)
+{
+ int ret = -1;
+ char **tokens = NULL;
+
+ /* Only support one host */
+ if (pooldef->source.nhost != 1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Expected exactly 1 host for the storage pool"));
+ goto cleanup;
+ }
+
+ /* iscsi pool only supports one host */
+ def->nhosts = 1;
+
+ if (VIR_ALLOC_N(def->hosts, def->nhosts) < 0)
+ goto cleanup;
+
+ if (VIR_STRDUP(def->hosts[0].name, pooldef->source.hosts[0].name) < 0)
+ goto cleanup;
+
+ if (virAsprintf(&def->hosts[0].port, "%d",
+ pooldef->source.hosts[0].port ?
+ pooldef->source.hosts[0].port :
+ 7000) < 0)
+ goto cleanup;
+
+
+
+
+
+ /* Storage pool have not supported these 2 attributes yet,
+ * use the defaults.
+ */
+ def->hosts[0].transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP;
+ def->hosts[0].socket = NULL;
+
+
+ def->protocol = VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG;
+
+ ret = 0;
+
+cleanup:
+ virStringFreeList(tokens);
+ return ret;
+}
+
static int
qemuAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
virStoragePoolDefPtr pooldef)
@@ -1352,14 +1402,15 @@ qemuTranslateDiskSourcePool(virConnectPtr conn,
def->srcpool->pooltype = pooldef->type;
def->srcpool->voltype = info.type;
-
- if (def->srcpool->mode && pooldef->type != VIR_STORAGE_POOL_ISCSI) {
+
+ if (def->srcpool->mode && pooldef->type != VIR_STORAGE_POOL_ISCSI && !(def->srcpool->mode == VIR_DOMAIN_DISK_SOURCE_POOL_MODE_DIRECT && pooldef->type == VIR_STORAGE_POOL_SHEEPDOG) ) {
+
virReportError(VIR_ERR_XML_ERROR, "%s",
_("disk source mode is only valid when "
- "storage pool is of iscsi type"));
+ "storage pool is of iscsi type or only direct for sheepdog "));
goto cleanup;
}
-
+
VIR_FREE(def->src);
virDomainDiskHostDefFree(def->nhosts, def->hosts);
virDomainDiskAuthClear(def);
@@ -1439,9 +1490,17 @@ qemuTranslateDiskSourcePool(virConnectPtr conn,
}
break;
- case VIR_STORAGE_POOL_MPATH:
- case VIR_STORAGE_POOL_RBD:
case VIR_STORAGE_POOL_SHEEPDOG:
+ def->srcpool->actualtype = VIR_DOMAIN_DISK_TYPE_NETWORK;
+ // force direct mode
+ def->srcpool->mode = VIR_DOMAIN_DISK_SOURCE_POOL_MODE_DIRECT;
+ def->protocol = VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG;
+ def->src = virStorageVolGetPath(vol);
+
+ qemuAddSheepPoolSourceHost(def, pooldef);
+ break;
+ case VIR_STORAGE_POOL_MPATH:
+ case VIR_STORAGE_POOL_RBD:
case VIR_STORAGE_POOL_GLUSTER:
case VIR_STORAGE_POOL_LAST:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
--
1.8.3.2
10 years, 11 months
[libvirt] [PATCH v2] Block info query: Add check for transient domain
by John Ferlan
Currently the qemuDomainGetBlockInfo will return allocation == physical
for most backing stores. For a qcow2 block backed device it's possible
to return the highest lv extent allocated from qemu for an active guest.
That is a value where allocation != physical and one would hope be less.
However, if the guest is not running, then the code falls back to returning
allocation == physical. This turns out to be problematic for rhev which
monitors the size of the backing store. During a migration, before the
VM has been started on the target and while it is deemed inactive on the
source, there's a small window of time where the allocation is returned
as physical triggering the code to extend the file unnecessarily.
Since rhev uses transient domains and this is edge condition for a transient
domain, rather than returning good status and allocation == physical when
this "window of opportunity" exists, this patch will check for a transient
(or non persistent) domain and return a failure to the caller rather than
returning the defaults. For a persistent domain, the defaults will be
returned. The description for the virDomainGetBlockInfo has been updated
to describe the phenomena.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
The v1 of this patch is at:
https://www.redhat.com/archives/libvir-list/2013-December/msg00984.html
There is a bz associated as well:
https://bugzilla.redhat.com/show_bug.cgi?id=1040507
I've read, reread, changed the text for the function so many times. I'm
open to any suggestions for adjustments! It's not easy to describe the
issues without getting into too much detail.
include/libvirt/libvirt.h.in | 8 ++++---
src/libvirt.c | 53 ++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_driver.c | 29 +++++++++++++++++++-----
3 files changed, 82 insertions(+), 8 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 47a896b..b3ce000 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2140,7 +2140,8 @@ int virDomainBlockResize (virDomainPtr dom,
/** virDomainBlockInfo:
*
- * This struct provides information about the size of a block device backing store
+ * This struct provides information about the size of a block device
+ * backing store
*
* Examples:
*
@@ -2153,11 +2154,12 @@ int virDomainBlockResize (virDomainPtr dom,
*
* - qcow2 file in filesystem
* * capacity: logical size from qcow2 header
- * * allocation, physical: logical size of the file / highest qcow extent (identical)
+ * * allocation, physical: logical size of the file /
+ * highest qcow extent (identical)
*
* - qcow2 file in a block device
* * capacity: logical size from qcow2 header
- * * allocation: highest qcow extent written
+ * * allocation: highest qcow extent written for an active domain
* * physical: size of the block device container
*/
typedef struct _virDomainBlockInfo virDomainBlockInfo;
diff --git a/src/libvirt.c b/src/libvirt.c
index c15e29a..9cc5b1c 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -8403,6 +8403,59 @@ error:
* can be found by calling virDomainGetXMLDesc() and inspecting
* elements within //domain/devices/disk.
*
+ * For QEMU domains, the allocation and physical virDomainBlockInfo
+ * values returned will generally be the same, except when using a
+ * non raw, block backing device, such as qcow2 for an active domain.
+ * When the persistent domain is not active, QEMU will return the
+ * default which is the same value for allocation and physical.
+ *
+ * Active QEMU domains can return an allocation value which is more
+ * representative of the currently used blocks by the device compared
+ * to the physical size of the device. Applications can use/monitor
+ * the allocation value with the understanding that if the domain
+ * becomes inactive during an attempt to get the value, the default
+ * values will be returned. Thus, the application should check
+ * after the call for the domain being inactive if the values are
+ * the same. Optionally, the application could be watching for a
+ * shutdown event and then ignore any values received afterwards.
+ * This can be an issue when a domain is being migrated and the
+ * exact timing of the domain being made inactive and check of
+ * the allocation value results the default being returned. For
+ * a transient domain in the similar situation, this call will return
+ * -1 and an error message indicating the "domain is not running".
+ *
+ * The following is some pseudo code illustrating the call sequence:
+ *
+ * ...
+ * virDomainPtr dom;
+ * virDomainBlockInfo info;
+ * char *device;
+ * ...
+ * // Either get a list of all domains or a specific domain
+ * // via a virDomainLookupBy*() call.
+ * //
+ * // It's also required to fill in the device pointer, but that's
+ * // specific to the implementation. For the purposes of this example
+ * // a qcow2 backed device name string would need to be provided.
+ * ...
+ * // If the following call is made on a persistent domain with a
+ * // qcow2 block backed block device, then it's possible the returned
+ * // allocation equals the physical value. In that case, the domain
+ * // that may have been active prior to calling has become inactive,
+ * // such as is the case during a domain migration. Thus once we
+ * // get data returned, check for active domain when the values are
+ * // the same.
+ * if (virDomainGetBlockInfo(dom, device, &info, 0) < 0)
+ * goto failure;
+ * if (info.allocation == info.physical) {
+ * // If the domain is no longer active,
+ * // then the defaults are being returned.
+ * if (!virDomainIsActive())
+ * goto ignore_return;
+ * }
+ * // Do something with the allocation and physical values
+ * ...
+ *
* Returns 0 in case of success and -1 in case of failure.
*/
int
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6e21267..699cbf5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10166,6 +10166,7 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
struct stat sb;
int idx;
int format;
+ int activeFail = false;
virQEMUDriverConfigPtr cfg = NULL;
char *alias = NULL;
@@ -10265,15 +10266,23 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
/* Set default value .. */
info->allocation = info->physical;
- /* ..but if guest is running & not using raw
- disk format and on a block device, then query
- highest allocated extent from QEMU */
+ /* ..but if guest is not using raw disk format and on a block device,
+ * then query highest allocated extent from QEMU
+ */
if (disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK &&
format != VIR_STORAGE_FILE_RAW &&
- S_ISBLK(sb.st_mode) &&
- virDomainObjIsActive(vm)) {
+ S_ISBLK(sb.st_mode)) {
qemuDomainObjPrivatePtr priv = vm->privateData;
+ /* If the guest is not running, then success/failure return
+ * depends on whether domain is persistent
+ */
+ if (!virDomainObjIsActive(vm)) {
+ activeFail = true;
+ ret = 0;
+ goto cleanup;
+ }
+
if (VIR_STRDUP(alias, disk->info.alias) < 0)
goto cleanup;
@@ -10287,6 +10296,7 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
&info->allocation);
qemuDomainObjExitMonitor(driver, vm);
} else {
+ activeFail = true;
ret = 0;
}
@@ -10300,6 +10310,15 @@ cleanup:
VIR_FREE(alias);
virStorageFileFreeMetadata(meta);
VIR_FORCE_CLOSE(fd);
+
+ /* If we failed to get data from a domain because it's inactive and
+ * it's not a persisent domain, then force failure.
+ */
+ if (activeFail && vm && !vm->persistent) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain is not running"));
+ ret = -1;
+ }
if (vm)
virObjectUnlock(vm);
virObjectUnref(cfg);
--
1.8.4.2
10 years, 11 months
[libvirt] [PATCH] [PATCH]Correct syntax-check Using qemu with sheepdog pool
by joel SIMOES
From: Joel SIMOES <joel.simoes(a)laposte.net>
---
src/qemu/qemu_conf.c | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index dfafcdc..954542a 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1215,17 +1215,13 @@ qemuAddSheepPoolSourceHost(virDomainDiskDefPtr def,
7000) < 0)
goto cleanup;
-
-
-
-
/* Storage pool have not supported these 2 attributes yet,
* use the defaults.
*/
def->hosts[0].transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP;
def->hosts[0].socket = NULL;
-
+
def->protocol = VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG;
ret = 0;
@@ -1402,15 +1398,14 @@ qemuTranslateDiskSourcePool(virConnectPtr conn,
def->srcpool->pooltype = pooldef->type;
def->srcpool->voltype = info.type;
-
- if (def->srcpool->mode && pooldef->type != VIR_STORAGE_POOL_ISCSI && !(def->srcpool->mode == VIR_DOMAIN_DISK_SOURCE_POOL_MODE_DIRECT && pooldef->type == VIR_STORAGE_POOL_SHEEPDOG) ) {
-
+
+ if (def->srcpool->mode && pooldef->type != VIR_STORAGE_POOL_ISCSI && !(def->srcpool->mode == VIR_DOMAIN_DISK_SOURCE_POOL_MODE_DIRECT && pooldef->type == VIR_STORAGE_POOL_SHEEPDOG)) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("disk source mode is only valid when "
"storage pool is of iscsi type or only direct for sheepdog "));
goto cleanup;
}
-
+
VIR_FREE(def->src);
virDomainDiskHostDefFree(def->nhosts, def->hosts);
virDomainDiskAuthClear(def);
@@ -1496,11 +1491,10 @@ qemuTranslateDiskSourcePool(virConnectPtr conn,
def->srcpool->mode = VIR_DOMAIN_DISK_SOURCE_POOL_MODE_DIRECT;
def->protocol = VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG;
def->src = virStorageVolGetPath(vol);
-
qemuAddSheepPoolSourceHost(def, pooldef);
break;
case VIR_STORAGE_POOL_MPATH:
- case VIR_STORAGE_POOL_RBD:
+ case VIR_STORAGE_POOL_RBD:
case VIR_STORAGE_POOL_GLUSTER:
case VIR_STORAGE_POOL_LAST:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
--
1.8.3.2
10 years, 11 months
[libvirt] [question]Is there a good way to get the mac of guest interface after I attached it to a guest
by Sheldon
Now I working on a new KVM management tool base on html5 and libvirt
we will support a REST API for detach and attach guest interface.
we want to use mac as the identifier of the network interface.
That meas we should get the mac after the user create a interface.
also other people may be doing the exact same thing at the exact same
time to create a interface.
Here are the demo codes:
dom = self._get_vm(vm)
xml = """
<interface type='network'>
<source network='default'/>
</interface>
"""
dom.attachDeviceFlags(xml, libvirt.VIR_DOMAIN_AFFECT_CURRENT)
# now I want to get the mac, how to get it?
I have check libvirt use this code to generate a mac address.
does libvirt can gurantee that the MAC address generated is unique?
void virMacAddrGenerate(const unsigned char prefix[VIR_MAC_PREFIX_BUFLEN],
virMacAddrPtr addr)
{
addr->addr[0] = prefix[0];
addr->addr[1] = prefix[1];
addr->addr[2] = prefix[2];
addr->addr[3] = virRandomBits(8);
addr->addr[4] = virRandomBits(8);
addr->addr[5] = virRandomBits(8);
}
libvirt also use the KVM prefix as default as it's in the privately
administered range:
52:54:00:XX:XX:XX
--
Thanks and best regards!
Sheldon Feng(冯少合)<shaohef(a)linux.vnet.ibm.com>
IBM Linux Technology Center
10 years, 11 months
[libvirt] [PATCH 00/16] lxc driver connectDomainXMLFromNative
by Cédric Bosdonnat
The aim of these patches is to provide users a way to easily convert existing LXC
containers into libvirt LXC domains. This conversion is mostly based on the use
of connectDomainXMLFromNative implementation, but there are small bits that will
still need to be manually tweaked, like creating a VLAN interface on the host or
precise the rootfs format for image files.
Cédric Bosdonnat (16):
LXC driver: started implementing connectDomainXMLFromNative
LXC from native: import rootfs
LXC from native: migrate fstab and lxc.mount.entry
LXC from native: implement no network conversion
LXC from native: migrate veth network configuration
LXC from native: convert phys network types to net hostdev devices
LXC from native: convert lxc.tty to console devices
LXC from native: convert macvlan network configuration
LXC from native: convert lxc.id_map into <idmap>
LXC from native: migrate memory tuning
LXC from native: map lxc.cgroup.cpu.*
LXC from native: map lxc.cgroup.cpuset.*
LXC from native: add lxc.cgroup.blkio.* mapping
LXC from native: map lxc.arch to /domain/os/type@arch
LXC from native: map block filesystems
LXC from native: map vlan network type
.gitignore | 1 +
po/POTFILES.in | 1 +
src/Makefile.am | 1 +
src/lxc/lxc_container.c | 2 +-
src/lxc/lxc_container.h | 2 +
src/lxc/lxc_driver.c | 36 +-
src/lxc/lxc_native.c | 1027 ++++++++++++++++++++
src/lxc/lxc_native.h | 34 +
tests/Makefile.am | 7 +-
tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config | 9 +
tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml | 44 +
.../lxcconf2xmldata/lxcconf2xml-cpusettune.config | 8 +
tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml | 36 +
tests/lxcconf2xmldata/lxcconf2xml-cputune.config | 9 +
tests/lxcconf2xmldata/lxcconf2xml-cputune.xml | 38 +
tests/lxcconf2xmldata/lxcconf2xml-idmap.config | 6 +
tests/lxcconf2xmldata/lxcconf2xml-idmap.xml | 32 +
.../lxcconf2xml-macvlannetwork.config | 14 +
.../lxcconf2xmldata/lxcconf2xml-macvlannetwork.xml | 30 +
tests/lxcconf2xmldata/lxcconf2xml-memtune.config | 12 +
tests/lxcconf2xmldata/lxcconf2xml-memtune.xml | 38 +
tests/lxcconf2xmldata/lxcconf2xml-nonetwork.config | 5 +
tests/lxcconf2xmldata/lxcconf2xml-nonetwork.xml | 33 +
.../lxcconf2xmldata/lxcconf2xml-physnetwork.config | 8 +
tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml | 35 +
tests/lxcconf2xmldata/lxcconf2xml-simple.config | 39 +
tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 41 +
.../lxcconf2xmldata/lxcconf2xml-vlannetwork.config | 13 +
tests/lxcconf2xmldata/lxcconf2xml-vlannetwork.xml | 30 +
tests/lxcconf2xmldata/lxcconf2xml.fstab | 3 +
tests/lxcconf2xmltest.c | 133 +++
31 files changed, 1724 insertions(+), 3 deletions(-)
create mode 100644 src/lxc/lxc_native.c
create mode 100644 src/lxc/lxc_native.h
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cpusettune.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cputune.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cputune.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-idmap.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-idmap.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-macvlannetwork.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-macvlannetwork.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-memtune.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-memtune.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-nonetwork.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-nonetwork.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-simple.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-simple.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-vlannetwork.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-vlannetwork.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml.fstab
create mode 100644 tests/lxcconf2xmltest.c
--
1.8.5.2
10 years, 11 months
[libvirt] [PATCH] qemu: Use virtio network device for aarch64/virt
by Oleg Strikov
This patch changes network device type used by default from rtl8139
to virtio when architecture type is aarch64 and machine type is virt.
Qemu doesn't support any other machine types for aarch64 right now and
we can't make any other aarch64-specific tuning in this function yet.
Signed-off-by: Oleg Strikov <oleg.strikov(a)canonical.com>
---
src/qemu/qemu_domain.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index c947e2e..a0e9a33 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -795,11 +795,12 @@ qemuDomainDefaultNetModel(const virDomainDef *def)
{
if (def->os.arch == VIR_ARCH_S390 ||
def->os.arch == VIR_ARCH_S390X)
return "virtio";
- if (def->os.arch == VIR_ARCH_ARMV7L) {
+ if (def->os.arch == VIR_ARCH_ARMV7L ||
+ def->os.arch == VIR_ARCH_AARCH64) {
if (STREQ(def->os.machine, "versatilepb"))
return "smc91c111";
if (STREQ(def->os.machine, "virt"))
return "virtio";
--
1.7.9.5
10 years, 11 months
[libvirt] [libvirt-sandbox PATCH v3] Add filter support.
by Ian Main
This patch adds two new classes, filterref and filterref-parameter.
Network interfaces can now have an associated filter reference with any
number of filterref parameters. Also added filter= option to
virt-sandbox tool.
---
V2:
- Changed set_filter to set_name and get_filter to get_name.
V3:
- Added type checks on all public methods.
- Call setters on property set.
- Fix install_property flags.
- Remove unneeded HANDLE defines.
- Add missing g_list_free().
- Add missing unref().
- Fixed names in copyright notices.
- Change order of files in Makefile.am
libvirt-sandbox/Makefile.am | 4 +
.../libvirt-sandbox-builder-container.c | 36 ++++
libvirt-sandbox/libvirt-sandbox-builder-machine.c | 36 ++++
...rt-sandbox-config-network-filterref-parameter.c | 208 ++++++++++++++++++++
...rt-sandbox-config-network-filterref-parameter.h | 73 +++++++
.../libvirt-sandbox-config-network-filterref.c | 218 +++++++++++++++++++++
.../libvirt-sandbox-config-network-filterref.h | 74 +++++++
libvirt-sandbox/libvirt-sandbox-config-network.c | 42 ++++
libvirt-sandbox/libvirt-sandbox-config-network.h | 4 +
libvirt-sandbox/libvirt-sandbox-config.c | 39 ++++
libvirt-sandbox/libvirt-sandbox.h | 3 +
libvirt-sandbox/libvirt-sandbox.sym | 16 ++
12 files changed, 753 insertions(+)
create mode 100644 libvirt-sandbox/libvirt-sandbox-config-network-filterref-parameter.c
create mode 100644 libvirt-sandbox/libvirt-sandbox-config-network-filterref-parameter.h
create mode 100644 libvirt-sandbox/libvirt-sandbox-config-network-filterref.c
create mode 100644 libvirt-sandbox/libvirt-sandbox-config-network-filterref.h
diff --git a/libvirt-sandbox/Makefile.am b/libvirt-sandbox/Makefile.am
index 0882490..720bb06 100644
--- a/libvirt-sandbox/Makefile.am
+++ b/libvirt-sandbox/Makefile.am
@@ -57,6 +57,8 @@ SANDBOX_HEADER_FILES = \
libvirt-sandbox-config.h \
libvirt-sandbox-config-network.h \
libvirt-sandbox-config-network-address.h \
+ libvirt-sandbox-config-network-filterref-parameter.h \
+ libvirt-sandbox-config-network-filterref.h \
libvirt-sandbox-config-network-route.h \
libvirt-sandbox-config-mount.h \
libvirt-sandbox-config-mount-file.h \
@@ -85,6 +87,8 @@ SANDBOX_SOURCE_FILES = \
libvirt-sandbox-config.c \
libvirt-sandbox-config-network.c \
libvirt-sandbox-config-network-address.c \
+ libvirt-sandbox-config-network-filterref.c \
+ libvirt-sandbox-config-network-filterref-parameter.c \
libvirt-sandbox-config-network-route.c \
libvirt-sandbox-config-mount.c \
libvirt-sandbox-config-mount-file.c \
diff --git a/libvirt-sandbox/libvirt-sandbox-builder-container.c b/libvirt-sandbox/libvirt-sandbox-builder-container.c
index 43ee5ef..bac8c70 100644
--- a/libvirt-sandbox/libvirt-sandbox-builder-container.c
+++ b/libvirt-sandbox/libvirt-sandbox-builder-container.c
@@ -324,6 +324,8 @@ static gboolean gvir_sandbox_builder_container_construct_devices(GVirSandboxBuil
while (tmp) {
const gchar *source, *mac;
GVirSandboxConfigNetwork *network = GVIR_SANDBOX_CONFIG_NETWORK(tmp->data);
+ GVirSandboxConfigNetworkFilterref *filterref;
+ GVirConfigDomainInterfaceFilterref *glib_fref;
iface = gvir_config_domain_interface_network_new();
source = gvir_sandbox_config_network_get_source(network);
@@ -339,6 +341,40 @@ static gboolean gvir_sandbox_builder_container_construct_devices(GVirSandboxBuil
gvir_config_domain_add_device(domain,
GVIR_CONFIG_DOMAIN_DEVICE(iface));
+
+ filterref = gvir_sandbox_config_network_get_filterref(network);
+ if (filterref) {
+ GList *param_iter, *parameters;
+ const gchar *fref_name = gvir_sandbox_config_network_filterref_get_name(filterref);
+ glib_fref = gvir_config_domain_interface_filterref_new();
+ gvir_config_domain_interface_filterref_set_name(glib_fref, fref_name);
+ param_iter = parameters = gvir_sandbox_config_network_filterref_get_parameters(filterref);
+ while (param_iter) {
+ const gchar *name;
+ const gchar *value;
+ GVirSandboxConfigNetworkFilterrefParameter *param = GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER(param_iter->data);
+ GVirConfigDomainInterfaceFilterrefParameter *glib_param;
+
+ name = gvir_sandbox_config_network_filterref_parameter_get_name(param);
+ value = gvir_sandbox_config_network_filterref_parameter_get_value(param);
+
+ glib_param = gvir_config_domain_interface_filterref_parameter_new();
+ gvir_config_domain_interface_filterref_parameter_set_name(glib_param, name);
+ gvir_config_domain_interface_filterref_parameter_set_value(glib_param, value);
+
+ gvir_config_domain_interface_filterref_add_parameter(glib_fref, glib_param);
+ g_object_unref(glib_param);
+
+ param_iter = param_iter->next;
+ }
+
+ g_list_foreach(parameters, (GFunc)g_object_unref, NULL);
+ g_list_free(parameters);
+
+ gvir_config_domain_interface_set_filterref(GVIR_CONFIG_DOMAIN_INTERFACE(iface), glib_fref);
+ g_object_unref(glib_fref);
+ }
+
g_object_unref(iface);
tmp = tmp->next;
diff --git a/libvirt-sandbox/libvirt-sandbox-builder-machine.c b/libvirt-sandbox/libvirt-sandbox-builder-machine.c
index 131b376..542663c 100644
--- a/libvirt-sandbox/libvirt-sandbox-builder-machine.c
+++ b/libvirt-sandbox/libvirt-sandbox-builder-machine.c
@@ -581,6 +581,8 @@ static gboolean gvir_sandbox_builder_machine_construct_devices(GVirSandboxBuilde
while (tmp) {
const gchar *source, *mac;
GVirSandboxConfigNetwork *network = GVIR_SANDBOX_CONFIG_NETWORK(tmp->data);
+ GVirSandboxConfigNetworkFilterref *filterref;
+ GVirConfigDomainInterfaceFilterref *glib_fref;
source = gvir_sandbox_config_network_get_source(network);
if (source) {
@@ -600,6 +602,40 @@ static gboolean gvir_sandbox_builder_machine_construct_devices(GVirSandboxBuilde
gvir_config_domain_add_device(domain,
GVIR_CONFIG_DOMAIN_DEVICE(iface));
+
+ filterref = gvir_sandbox_config_network_get_filterref(network);
+ if (filterref) {
+ GList *param_iter, *parameters;
+ const gchar *fref_name = gvir_sandbox_config_network_filterref_get_name(filterref);
+ glib_fref = gvir_config_domain_interface_filterref_new();
+ gvir_config_domain_interface_filterref_set_name(glib_fref, fref_name);
+ param_iter = parameters = gvir_sandbox_config_network_filterref_get_parameters(filterref);
+ while (param_iter) {
+ const gchar *name;
+ const gchar *value;
+ GVirSandboxConfigNetworkFilterrefParameter *param = GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER(param_iter->data);
+ GVirConfigDomainInterfaceFilterrefParameter *glib_param;
+
+ name = gvir_sandbox_config_network_filterref_parameter_get_name(param);
+ value = gvir_sandbox_config_network_filterref_parameter_get_value(param);
+
+ glib_param = gvir_config_domain_interface_filterref_parameter_new();
+ gvir_config_domain_interface_filterref_parameter_set_name(glib_param, name);
+ gvir_config_domain_interface_filterref_parameter_set_value(glib_param, value);
+
+ gvir_config_domain_interface_filterref_add_parameter(glib_fref, glib_param);
+ g_object_unref(glib_param);
+
+ param_iter = param_iter->next;
+ }
+
+ g_list_foreach(parameters, (GFunc)g_object_unref, NULL);
+ g_list_free(parameters);
+
+ gvir_config_domain_interface_set_filterref(iface, glib_fref);
+ g_object_unref(glib_fref);
+ }
+
g_object_unref(iface);
tmp = tmp->next;
diff --git a/libvirt-sandbox/libvirt-sandbox-config-network-filterref-parameter.c b/libvirt-sandbox/libvirt-sandbox-config-network-filterref-parameter.c
new file mode 100644
index 0000000..fabed90
--- /dev/null
+++ b/libvirt-sandbox/libvirt-sandbox-config-network-filterref-parameter.c
@@ -0,0 +1,208 @@
+/*
+ * libvirt-sandbox-config-network-filterref-parameter.c: libvirt sandbox configuration
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ian Main <imain(a)redhat.com>
+ */
+
+#include <config.h>
+#include <string.h>
+
+#include "libvirt-sandbox/libvirt-sandbox.h"
+
+/**
+ * SECTION: libvirt-sandbox-config-network-filterref-parameter
+ * @short_description: Set parameters for a filter reference.
+ * @include: libvirt-sandbox/libvirt-sandbox.h
+ *
+ * Provides an object to store filter parameter name and value.
+ *
+ * The GVirSandboxConfigNetworkFilterrefParameter object stores a
+ * name and value required to set a single parameter of a filter reference.
+ */
+
+#define GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF_PARAMETER, GVirSandboxConfigNetworkFilterrefParameterPrivate))
+
+struct _GVirSandboxConfigNetworkFilterrefParameterPrivate
+{
+ gchar *name;
+ gchar *value;
+};
+
+G_DEFINE_TYPE(GVirSandboxConfigNetworkFilterrefParameter, gvir_sandbox_config_network_filterref_parameter, G_TYPE_OBJECT);
+
+
+enum {
+ PROP_0,
+ PROP_NAME,
+ PROP_VALUE,
+};
+
+enum {
+ LAST_SIGNAL
+};
+
+//static gint signals[LAST_SIGNAL];
+
+
+static void gvir_sandbox_config_network_filterref_parameter_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GVirSandboxConfigNetworkFilterrefParameter *config = GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER(object);
+ GVirSandboxConfigNetworkFilterrefParameterPrivate *priv = config->priv;
+
+ switch (prop_id) {
+ case PROP_NAME:
+ g_value_set_string(value, priv->name);
+ break;
+
+ case PROP_VALUE:
+ g_value_set_string(value, priv->value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+
+static void gvir_sandbox_config_network_filterref_parameter_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GVirSandboxConfigNetworkFilterrefParameter *filter = GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER(object);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ gvir_sandbox_config_network_filterref_parameter_set_name(filter, g_value_get_string(value));
+ break;
+
+ case PROP_VALUE:
+ gvir_sandbox_config_network_filterref_parameter_set_value(filter, g_value_get_string(value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+
+static void gvir_sandbox_config_network_filterref_parameter_finalize(GObject *object)
+{
+ GVirSandboxConfigNetworkFilterrefParameter *config = GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER(object);
+ GVirSandboxConfigNetworkFilterrefParameterPrivate *priv = config->priv;
+
+ g_free(priv->name);
+ g_free(priv->value);
+
+ G_OBJECT_CLASS(gvir_sandbox_config_network_filterref_parameter_parent_class)->finalize(object);
+}
+
+
+static void gvir_sandbox_config_network_filterref_parameter_class_init(GVirSandboxConfigNetworkFilterrefParameterClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+ object_class->finalize = gvir_sandbox_config_network_filterref_parameter_finalize;
+ object_class->get_property = gvir_sandbox_config_network_filterref_parameter_get_property;
+ object_class->set_property = gvir_sandbox_config_network_filterref_parameter_set_property;
+
+ g_object_class_install_property(object_class,
+ PROP_NAME,
+ g_param_spec_string("name",
+ "Name",
+ "Name of parameter",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property(object_class,
+ PROP_VALUE,
+ g_param_spec_string("value",
+ "Value",
+ "Value of parameter",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_type_class_add_private(klass, sizeof(GVirSandboxConfigNetworkFilterrefParameterPrivate));
+}
+
+
+static void gvir_sandbox_config_network_filterref_parameter_init(GVirSandboxConfigNetworkFilterrefParameter *param)
+{
+ param->priv = GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER_GET_PRIVATE(param);
+}
+
+
+/**
+ * gvir_sandbox_config_network_filterref_parameter_new:
+ *
+ * Create a new network config with DHCP enabled
+ *
+ * Returns: (transfer full): a new sandbox network object
+ */
+GVirSandboxConfigNetworkFilterrefParameter *gvir_sandbox_config_network_filterref_parameter_new(void)
+{
+ return GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER(g_object_new(GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF_PARAMETER,
+ NULL));
+}
+
+void gvir_sandbox_config_network_filterref_parameter_set_name(GVirSandboxConfigNetworkFilterrefParameter *param,
+ const gchar *name)
+{
+ GVirSandboxConfigNetworkFilterrefParameterPrivate *priv;
+
+ g_return_if_fail(GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF_PARAMETER(param));
+ priv = param->priv;
+ g_free(priv->name);
+ priv->name = g_strdup(name);
+}
+
+const gchar *gvir_sandbox_config_network_filterref_parameter_get_name(GVirSandboxConfigNetworkFilterrefParameter *param)
+{
+ GVirSandboxConfigNetworkFilterrefParameterPrivate *priv;
+
+ g_return_val_if_fail(GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF_PARAMETER(param), NULL);
+ priv = param->priv;
+ return priv->name;
+}
+
+void gvir_sandbox_config_network_filterref_parameter_set_value(GVirSandboxConfigNetworkFilterrefParameter *param,
+ const gchar *value)
+{
+ GVirSandboxConfigNetworkFilterrefParameterPrivate *priv;
+
+ g_return_if_fail(GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF_PARAMETER(param));
+ priv = param->priv;
+ g_free(priv->value);
+ priv->value = g_strdup(value);
+}
+
+const gchar *gvir_sandbox_config_network_filterref_parameter_get_value(GVirSandboxConfigNetworkFilterrefParameter *param)
+{
+ GVirSandboxConfigNetworkFilterrefParameterPrivate *priv;
+
+ g_return_val_if_fail(GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF_PARAMETER(param), NULL);
+ priv = param->priv;
+ return priv->value;
+}
diff --git a/libvirt-sandbox/libvirt-sandbox-config-network-filterref-parameter.h b/libvirt-sandbox/libvirt-sandbox-config-network-filterref-parameter.h
new file mode 100644
index 0000000..9544539
--- /dev/null
+++ b/libvirt-sandbox/libvirt-sandbox-config-network-filterref-parameter.h
@@ -0,0 +1,73 @@
+/*
+ * libvirt-sandbox-config-network-filterref-parameter.h: libvirt sandbox configuration
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ian Main <imain(a)redhat.com>
+ */
+
+#if !defined(__LIBVIRT_SANDBOX_H__) && !defined(LIBVIRT_SANDBOX_BUILD)
+#error "Only <libvirt-sandbox/libvirt-sandbox.h> can be included directly."
+#endif
+
+#ifndef __LIBVIRT_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER_H__
+#define __LIBVIRT_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER_H__
+
+G_BEGIN_DECLS
+
+#define GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF_PARAMETER (gvir_sandbox_config_network_filterref_parameter_get_type ())
+#define GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF_PARAMETER, GVirSandboxConfigNetworkFilterrefParameter))
+#define GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF_PARAMETER, GVirSandboxConfigNetworkFilterrefParameterClass))
+#define GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF_PARAMETER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF_PARAMETER))
+#define GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF_PARAMETER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF_PARAMETER))
+#define GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF_PARAMETER, GVirSandboxConfigNetworkFilterrefParameterClass))
+
+typedef struct _GVirSandboxConfigNetworkFilterrefParameter GVirSandboxConfigNetworkFilterrefParameter;
+typedef struct _GVirSandboxConfigNetworkFilterrefParameterPrivate GVirSandboxConfigNetworkFilterrefParameterPrivate;
+typedef struct _GVirSandboxConfigNetworkFilterrefParameterClass GVirSandboxConfigNetworkFilterrefParameterClass;
+
+struct _GVirSandboxConfigNetworkFilterrefParameter
+{
+ GObject parent;
+
+ GVirSandboxConfigNetworkFilterrefParameterPrivate *priv;
+
+ /* Do not add fields to this struct */
+};
+
+struct _GVirSandboxConfigNetworkFilterrefParameterClass
+{
+ GObjectClass parent_class;
+
+ gpointer padding[LIBVIRT_SANDBOX_CLASS_PADDING];
+};
+
+GType gvir_sandbox_config_network_filterref_parameter_get_type(void);
+
+GVirSandboxConfigNetworkFilterrefParameter *gvir_sandbox_config_network_filterref_parameter_new(void);
+
+void gvir_sandbox_config_network_filterref_parameter_set_name(GVirSandboxConfigNetworkFilterrefParameter *param,
+ const gchar *name);
+const gchar *gvir_sandbox_config_network_filterref_parameter_get_name(GVirSandboxConfigNetworkFilterrefParameter *param);
+
+void gvir_sandbox_config_network_filterref_parameter_set_value(GVirSandboxConfigNetworkFilterrefParameter *param,
+ const gchar *value);
+const gchar *gvir_sandbox_config_network_filterref_parameter_get_value(GVirSandboxConfigNetworkFilterrefParameter *param);
+
+G_END_DECLS
+
+#endif /* __LIBVIRT_SANDBOX_CONFIG_NETWORK_FILTERREF_PARAMETER_H__ */
diff --git a/libvirt-sandbox/libvirt-sandbox-config-network-filterref.c b/libvirt-sandbox/libvirt-sandbox-config-network-filterref.c
new file mode 100644
index 0000000..85b41ae
--- /dev/null
+++ b/libvirt-sandbox/libvirt-sandbox-config-network-filterref.c
@@ -0,0 +1,218 @@
+/*
+ * libvirt-sandbox-config-network-filterref.c: libvirt sandbox filterr reference
+ * configuration
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ian Main <imain(a)redhat.com>
+ */
+
+#include <config.h>
+#include <string.h>
+
+#include "libvirt-sandbox/libvirt-sandbox.h"
+
+/**
+ * SECTION: libvirt-sandbox-config-network-filterref
+ * @short_description: Add a network filter to a network interface.
+ * @include: libvirt-sandbox/libvirt-sandbox.h
+ * @see_aloso: #GVirSandboxConfig
+ *
+ * Provides an object to store the name of the filter reference.
+ *
+ * The GVirSandboxConfigNetworkFilterref object stores the name of the filter
+ * references associated with a network interface.
+ */
+
+#define GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF, GVirSandboxConfigNetworkFilterrefPrivate))
+
+struct _GVirSandboxConfigNetworkFilterrefPrivate
+{
+ gchar *filter;
+ GList *parameters;
+};
+
+G_DEFINE_TYPE(GVirSandboxConfigNetworkFilterref, gvir_sandbox_config_network_filterref, G_TYPE_OBJECT);
+
+
+enum {
+ PROP_0,
+ PROP_FILTER
+};
+
+enum {
+ LAST_SIGNAL
+};
+
+//static gint signals[LAST_SIGNAL];
+
+static void gvir_sandbox_config_network_filterref_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GVirSandboxConfigNetworkFilterref *config = GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF(object);
+ GVirSandboxConfigNetworkFilterrefPrivate *priv = config->priv;
+
+ switch (prop_id) {
+ case PROP_FILTER:
+ g_value_set_string(value, priv->filter);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+
+static void gvir_sandbox_config_network_filterref_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GVirSandboxConfigNetworkFilterref *filterref = GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF(object);
+
+ switch (prop_id) {
+ case PROP_FILTER:
+ gvir_sandbox_config_network_filterref_set_name(filterref, g_value_get_string(value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+
+
+static void gvir_sandbox_config_network_filterref_finalize(GObject *object)
+{
+ GVirSandboxConfigNetworkFilterref *config = GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF(object);
+ GVirSandboxConfigNetworkFilterrefPrivate *priv = config->priv;
+
+ g_free(priv->filter);
+ g_list_foreach(priv->parameters, (GFunc)g_object_unref, NULL);
+ g_list_free(priv->parameters);
+
+ G_OBJECT_CLASS(gvir_sandbox_config_network_filterref_parent_class)->finalize(object);
+}
+
+
+static void gvir_sandbox_config_network_filterref_class_init(GVirSandboxConfigNetworkFilterrefClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+ object_class->finalize = gvir_sandbox_config_network_filterref_finalize;
+ object_class->get_property = gvir_sandbox_config_network_filterref_get_property;
+ object_class->set_property = gvir_sandbox_config_network_filterref_set_property;
+
+ g_object_class_install_property(object_class,
+ PROP_FILTER,
+ g_param_spec_string("filter",
+ "Filter name",
+ "The filter reference name",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_type_class_add_private(klass, sizeof(GVirSandboxConfigNetworkFilterrefPrivate));
+}
+
+/**
+ * gvir_sandbox_config_network_filterref_new:
+ *
+ * Create a new network filterref config.
+ *
+ * Returns: (transfer full): a new sandbox network_filterref object
+ */
+GVirSandboxConfigNetworkFilterref *gvir_sandbox_config_network_filterref_new(void)
+{
+ return GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF(g_object_new(GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF,
+ NULL));
+}
+
+
+static void gvir_sandbox_config_network_filterref_init(GVirSandboxConfigNetworkFilterref *config)
+{
+ config->priv = GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_GET_PRIVATE(config);
+}
+
+
+/**
+ * gvir_sandbox_config_network_filterref_get_name:
+ * @config: (transfer none): the network filter reference name
+ *
+ * Retrieves the network filter reference name.
+ *
+ * Returns: (transfer none): the network filter reference name.
+ */
+const gchar *gvir_sandbox_config_network_filterref_get_name(GVirSandboxConfigNetworkFilterref *filterref)
+{
+ GVirSandboxConfigNetworkFilterrefPrivate *priv;
+
+ g_return_val_if_fail(GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF(filterref), NULL);
+ priv = filterref->priv;
+ return priv->filter;
+}
+
+void gvir_sandbox_config_network_filterref_set_name(GVirSandboxConfigNetworkFilterref *filterref,
+ const gchar *name)
+{
+ GVirSandboxConfigNetworkFilterrefPrivate *priv;
+
+ g_return_if_fail(GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF(filterref));
+ priv = filterref->priv;
+ g_free(priv->filter);
+ priv->filter = g_strdup(name);
+}
+
+/**
+ * gvir_sandbox_config_network_filterref_add_parameter:
+ * @filter: (transfer none): the network filter reference.
+ * @param: (transfer none): the filter parameter
+ *
+ * Add a parameter to a network filter reference.
+ */
+void gvir_sandbox_config_network_filterref_add_parameter(GVirSandboxConfigNetworkFilterref *filter,
+ GVirSandboxConfigNetworkFilterrefParameter *param)
+{
+ GVirSandboxConfigNetworkFilterrefPrivate *priv;
+
+ g_return_if_fail(GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF(filter));
+ g_return_if_fail(GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF_PARAMETER(param));
+ priv = filter->priv;
+ priv->parameters = g_list_append(priv->parameters, g_object_ref(param));
+}
+
+
+/**
+ * gvir_sandbox_config_network_filterref_get_parameters:
+ * @filter: (transfer none): the filter reference configuration
+ *
+ * Retrieve the list of parameters associated with a network filter reference
+ *
+ * Returns: (transfer full)(element-type GVirSandboxConfigNetworkFilterrefParameter): the parameter list
+ */
+GList *gvir_sandbox_config_network_filterref_get_parameters(GVirSandboxConfigNetworkFilterref *filter)
+{
+ GVirSandboxConfigNetworkFilterrefPrivate *priv;
+
+ g_return_val_if_fail(GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF(filter), NULL);
+ priv = filter->priv;
+ g_list_foreach(priv->parameters, (GFunc)g_object_ref, NULL);
+ return g_list_copy(priv->parameters);
+}
diff --git a/libvirt-sandbox/libvirt-sandbox-config-network-filterref.h b/libvirt-sandbox/libvirt-sandbox-config-network-filterref.h
new file mode 100644
index 0000000..e036a93
--- /dev/null
+++ b/libvirt-sandbox/libvirt-sandbox-config-network-filterref.h
@@ -0,0 +1,74 @@
+/*
+ * libvirt-sandbox-config-network-filterref.h: libvirt sandbox filter reference
+ * configuration
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ian Main <imain(a)redhat.com>
+ */
+
+#if !defined(__LIBVIRT_SANDBOX_H__) && !defined(LIBVIRT_SANDBOX_BUILD)
+#error "Only <libvirt-sandbox/libvirt-sandbox.h> can be included directly."
+#endif
+
+#ifndef __LIBVIRT_SANDBOX_CONFIG_NETWORK_FILTERREF_H__
+#define __LIBVIRT_SANDBOX_CONFIG_NETWORK_FILTERREF_H__
+
+G_BEGIN_DECLS
+
+#define GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF (gvir_sandbox_config_network_filterref_get_type ())
+#define GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF, GVirSandboxConfigNetworkFilterref))
+#define GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF, GVirSandboxConfigNetworkFilterrefClass))
+#define GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF))
+#define GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF))
+#define GVIR_SANDBOX_CONFIG_NETWORK_FILTERREF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GVIR_SANDBOX_TYPE_CONFIG_NETWORK_FILTERREF, GVirSandboxConfigNetworkFilterrefClass))
+
+typedef struct _GVirSandboxConfigNetworkFilterref GVirSandboxConfigNetworkFilterref;
+typedef struct _GVirSandboxConfigNetworkFilterrefPrivate GVirSandboxConfigNetworkFilterrefPrivate;
+typedef struct _GVirSandboxConfigNetworkFilterrefClass GVirSandboxConfigNetworkFilterrefClass;
+
+struct _GVirSandboxConfigNetworkFilterref
+{
+ GObject parent;
+
+ GVirSandboxConfigNetworkFilterrefPrivate *priv;
+
+ /* Do not add fields to this struct */
+};
+
+struct _GVirSandboxConfigNetworkFilterrefClass
+{
+ GObjectClass parent_class;
+
+ gpointer padding[LIBVIRT_SANDBOX_CLASS_PADDING];
+};
+
+GType gvir_sandbox_config_network_filterref_get_type(void);
+
+GVirSandboxConfigNetworkFilterref *gvir_sandbox_config_network_filterref_new(void);
+
+const gchar *gvir_sandbox_config_network_filterref_get_name(GVirSandboxConfigNetworkFilterref *config);
+void gvir_sandbox_config_network_filterref_set_name(GVirSandboxConfigNetworkFilterref *filter, const gchar *name);
+
+void gvir_sandbox_config_network_filterref_add_parameter(GVirSandboxConfigNetworkFilterref *filter,
+ GVirSandboxConfigNetworkFilterrefParameter *param);
+GList *gvir_sandbox_config_network_filterref_get_parameters(GVirSandboxConfigNetworkFilterref *filter);
+
+
+G_END_DECLS
+
+#endif /* __LIBVIRT_SANDBOX_CONFIG_NETWORK_FILTERREF_H__ */
diff --git a/libvirt-sandbox/libvirt-sandbox-config-network.c b/libvirt-sandbox/libvirt-sandbox-config-network.c
index f04cf4c..2bb55bf 100644
--- a/libvirt-sandbox/libvirt-sandbox-config-network.c
+++ b/libvirt-sandbox/libvirt-sandbox-config-network.c
@@ -47,6 +47,7 @@ struct _GVirSandboxConfigNetworkPrivate
gchar *mac;
GList *routes;
GList *addrs;
+ GVirSandboxConfigNetworkFilterref *filterref;
};
G_DEFINE_TYPE(GVirSandboxConfigNetwork, gvir_sandbox_config_network, G_TYPE_OBJECT);
@@ -133,6 +134,8 @@ static void gvir_sandbox_config_network_finalize(GObject *object)
g_list_free(priv->addrs);
g_list_foreach(priv->routes, (GFunc)g_object_unref, NULL);
g_list_free(priv->routes);
+ if (priv->filterref)
+ g_object_unref(priv->filterref);
G_OBJECT_CLASS(gvir_sandbox_config_network_parent_class)->finalize(object);
}
@@ -287,6 +290,45 @@ GList *gvir_sandbox_config_network_get_addresses(GVirSandboxConfigNetwork *confi
}
/**
+ * gvir_sandbox_config_network_set_filterref:
+ * @config: (transfer none): the sandbox network configuration
+ * @ref: (transfer none): the network filterref
+ *
+ * Set a network filterref for the given network.
+ */
+void gvir_sandbox_config_network_set_filterref(GVirSandboxConfigNetwork *config,
+ GVirSandboxConfigNetworkFilterref *filterref)
+{
+ GVirSandboxConfigNetworkPrivate *priv;
+
+ g_return_if_fail(GVIR_SANDBOX_IS_CONFIG_NETWORK(config));
+ g_return_if_fail(GVIR_SANDBOX_IS_CONFIG_NETWORK_FILTERREF(filterref));
+ priv = config->priv;
+ if (priv->filterref)
+ g_object_unref(priv->filterref);
+ priv->filterref = g_object_ref(filterref);
+}
+
+
+/**
+ * gvir_sandbox_config_network_get_filterref:
+ * @config: (transfer none): the sandbox network configuration
+ *
+ * Retrieve the associated filter reference.
+ *
+ * Returns: (transfer none): The associated filter reference.
+ */
+GVirSandboxConfigNetworkFilterref *gvir_sandbox_config_network_get_filterref(GVirSandboxConfigNetwork *config)
+{
+ GVirSandboxConfigNetworkPrivate *priv;
+
+ g_return_val_if_fail(GVIR_SANDBOX_IS_CONFIG_NETWORK(config), NULL);
+ priv = config->priv;
+ return priv->filterref;
+}
+
+
+/**
* gvir_sandbox_config_network_add_route:
* @config: (transfer none): the sandbox network configuration
* @addr: (transfer none): the network route
diff --git a/libvirt-sandbox/libvirt-sandbox-config-network.h b/libvirt-sandbox/libvirt-sandbox-config-network.h
index d926fd1..4a52221 100644
--- a/libvirt-sandbox/libvirt-sandbox-config-network.h
+++ b/libvirt-sandbox/libvirt-sandbox-config-network.h
@@ -78,6 +78,10 @@ void gvir_sandbox_config_network_add_address(GVirSandboxConfigNetwork *config,
GVirSandboxConfigNetworkAddress *addr);
GList *gvir_sandbox_config_network_get_addresses(GVirSandboxConfigNetwork *config);
+void gvir_sandbox_config_network_set_filterref(GVirSandboxConfigNetwork *config,
+ GVirSandboxConfigNetworkFilterref *ref);
+GVirSandboxConfigNetworkFilterref *gvir_sandbox_config_network_get_filterref(GVirSandboxConfigNetwork *config);
+
void gvir_sandbox_config_network_add_route(GVirSandboxConfigNetwork *config,
GVirSandboxConfigNetworkRoute *addr);
GList *gvir_sandbox_config_network_get_routes(GVirSandboxConfigNetwork *config);
diff --git a/libvirt-sandbox/libvirt-sandbox-config.c b/libvirt-sandbox/libvirt-sandbox-config.c
index b1525a1..f996ea5 100644
--- a/libvirt-sandbox/libvirt-sandbox-config.c
+++ b/libvirt-sandbox/libvirt-sandbox-config.c
@@ -911,6 +911,8 @@ gboolean gvir_sandbox_config_add_network_strv(GVirSandboxConfig *config,
* source=private,address=192.168.122.1/24%192.168.122.255,
* address=192.168.122.1/24%192.168.122.255,address=2001:212::204:2/64
* route=192.168.122.255/24%192.168.1.1
+ * filter=clean-traffic
+ * filter.ip=192.168.122.1
*/
gboolean gvir_sandbox_config_add_network_opts(GVirSandboxConfig *config,
const gchar *network,
@@ -924,8 +926,10 @@ gboolean gvir_sandbox_config_add_network_opts(GVirSandboxConfig *config,
gchar **params = g_strsplit(network, ",", 50);
gsize j = 0;
GVirSandboxConfigNetwork *net;
+ GVirSandboxConfigNetworkFilterref *filter;
net = gvir_sandbox_config_network_new();
+ filter = gvir_sandbox_config_network_filterref_new();
gvir_sandbox_config_network_set_dhcp(net, FALSE);
while (params && params[j]) {
@@ -947,6 +951,40 @@ gboolean gvir_sandbox_config_add_network_opts(GVirSandboxConfig *config,
} else if (g_str_has_prefix(param, "mac=")) {
gvir_sandbox_config_network_set_mac(net,
param + strlen("mac="));
+ } else if (g_str_has_prefix(param, "filter.")) {
+ GVirSandboxConfigNetworkFilterrefParameter *filter_param;
+ gchar *tail = g_strdup(param + strlen("filter."));
+ gchar *equ = g_strrstr(tail, "=");
+ gchar *name, *name_up, *value;
+
+ if (equ == NULL) {
+ g_free(tail);
+ g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0,
+ _("No assignment in filter parameter configuration"));
+ g_object_unref(net);
+ goto cleanup;
+ }
+
+ name = g_strndup(tail, equ - tail);
+ value = g_strdup(equ + 1);
+ /* Convert to upcase for convenience. */
+ name_up = g_ascii_strup(name, -1);
+ g_free(name);
+
+ filter_param = gvir_sandbox_config_network_filterref_parameter_new();
+ gvir_sandbox_config_network_filterref_parameter_set_name(filter_param, name_up);
+ gvir_sandbox_config_network_filterref_parameter_set_value(filter_param, value);
+ gvir_sandbox_config_network_filterref_add_parameter(filter, filter_param);
+
+ g_free(tail);
+ g_free(name_up);
+ g_free(value);
+ } else if (g_str_has_prefix(param, "filter=")) {
+ gchar *name = g_strdup(param + strlen("filter="));
+
+ gvir_sandbox_config_network_filterref_set_name(filter, name);
+ gvir_sandbox_config_network_set_filterref(net, filter);
+ g_free(name);
} else if (g_str_has_prefix(param, "address=")) {
GVirSandboxConfigNetworkAddress *addr;
GInetAddress *primaryaddr;
@@ -1090,6 +1128,7 @@ gboolean gvir_sandbox_config_add_network_opts(GVirSandboxConfig *config,
ret = TRUE;
cleanup:
+ g_object_unref(filter);
return ret;
}
diff --git a/libvirt-sandbox/libvirt-sandbox.h b/libvirt-sandbox/libvirt-sandbox.h
index a3f0b2c..adb21a1 100644
--- a/libvirt-sandbox/libvirt-sandbox.h
+++ b/libvirt-sandbox/libvirt-sandbox.h
@@ -25,6 +25,7 @@
/* External includes */
#include <libvirt-gobject/libvirt-gobject.h>
+#include <locale.h>
/* Local includes */
#include <libvirt-sandbox/libvirt-sandbox-main.h>
@@ -37,6 +38,8 @@
#include <libvirt-sandbox/libvirt-sandbox-config-mount-guest-bind.h>
#include <libvirt-sandbox/libvirt-sandbox-config-mount-ram.h>
#include <libvirt-sandbox/libvirt-sandbox-config-network-address.h>
+#include <libvirt-sandbox/libvirt-sandbox-config-network-filterref-parameter.h>
+#include <libvirt-sandbox/libvirt-sandbox-config-network-filterref.h>
#include <libvirt-sandbox/libvirt-sandbox-config-network-route.h>
#include <libvirt-sandbox/libvirt-sandbox-config-network.h>
#include <libvirt-sandbox/libvirt-sandbox-config.h>
diff --git a/libvirt-sandbox/libvirt-sandbox.sym b/libvirt-sandbox/libvirt-sandbox.sym
index 7b7c8be..7afef53 100644
--- a/libvirt-sandbox/libvirt-sandbox.sym
+++ b/libvirt-sandbox/libvirt-sandbox.sym
@@ -44,6 +44,7 @@ LIBVIRT_SANDBOX_0.2.1 {
gvir_sandbox_config_mount_ram_set_usage;
gvir_sandbox_config_network_add_address;
+ gvir_sandbox_config_network_set_filterref;
gvir_sandbox_config_network_add_route;
gvir_sandbox_config_network_get_type;
gvir_sandbox_config_network_get_dhcp;
@@ -51,6 +52,7 @@ LIBVIRT_SANDBOX_0.2.1 {
gvir_sandbox_config_network_get_source;
gvir_sandbox_config_network_get_routes;
gvir_sandbox_config_network_get_addresses;
+ gvir_sandbox_config_network_get_filterref;
gvir_sandbox_config_network_new;
gvir_sandbox_config_network_set_dhcp;
gvir_sandbox_config_network_set_mac;
@@ -65,6 +67,20 @@ LIBVIRT_SANDBOX_0.2.1 {
gvir_sandbox_config_network_address_set_primary;
gvir_sandbox_config_network_address_set_prefix;
+ gvir_sandbox_config_network_filterref_get_type;
+ gvir_sandbox_config_network_filterref_new;
+ gvir_sandbox_config_network_filterref_get_name;
+ gvir_sandbox_config_network_filterref_set_name;
+ gvir_sandbox_config_network_filterref_add_parameter;
+ gvir_sandbox_config_network_filterref_get_parameters;
+
+ gvir_sandbox_config_network_filterref_parameter_get_type;
+ gvir_sandbox_config_network_filterref_parameter_new;
+ gvir_sandbox_config_network_filterref_parameter_get_name;
+ gvir_sandbox_config_network_filterref_parameter_set_name;
+ gvir_sandbox_config_network_filterref_parameter_get_value;
+ gvir_sandbox_config_network_filterref_parameter_set_value;
+
gvir_sandbox_config_network_route_get_type;
gvir_sandbox_config_network_route_get_prefix;
gvir_sandbox_config_network_route_get_gateway;
--
1.8.1.4
10 years, 11 months
[libvirt] [PATCH v3] qemu: Don't fail if the SCSI host device is shareable between domains
by Osier Yang
It doesn't make sense to fail if the SCSI host device is specified
as "shareable" explicitly between domains (NB, it works if and only
if the device is specified as "shareable" for *all* domains,
otherwise it fails).
To fix the problem, this patch introduces an array for virSCSIDevice
struct, which records all the names of domain which are using the
device (note that the recorded domains must specifiy the device as
shareable). And the change on the data struct brings on many
subsequent changes in the code.
Since prior to this patch, the "shareable" tag didn't work as expected,
it actually work like "non-shareable". If there was a live domain using
the SCSI device with "shareable" specified, then after upgrading
(assuming the live domain keep running during upgrading) the older
libvirt (without this patch) to newer libvirt (with this patch), it may
cause some confusion when user tries to start later domains as
"shareable". So this patch also added notes in formatdomain.html to
declare the fact.
* src/util/virscsi.h:
- Remove virSCSIDeviceGetUsedBy
- Change definition of virSCSIDeviceGetUsedBy and virSCSIDeviceListDel
- Add virSCSIDeviceIsAvailable
* src/util/virscsi.c:
- struct virSCSIDevice: Change "used_by" to be an array; Add
"n_used_by" as the array count
- virSCSIDeviceGetUsedBy: Removed
- virSCSIDeviceFree: frees the "used_by" array
- virSCSIDeviceSetUsedBy: Copy the domain name to avoid potential
memory corruption
- virSCSIDeviceIsAvailable: New
- virSCSIDeviceListDel: Change the logic, for device which is already
in the list, just remove the corresponding entry in "used_by". And
since it's only used in one place, we can safely removing the code
to find out the dev in the list first.
- Copyright updating
* src/libvirt_private.sys:
- virSCSIDeviceGetUsedBy: Remove
- virSCSIDeviceIsAvailable: New
* src/qemu/qemu_hostdev.c:
- qemuUpdateActiveScsiHostdevs: Check if the device existing before
adding it to the list;
- qemuPrepareHostdevSCSIDevices: Error out if the not all domains
use the device as "shareable"; Also don't try to add the device
to the activeScsiHostdevs list if it already there; And make
more sensible error w.r.t the current "shareable" value in
driver->activeScsiHostdevs.
- qemuDomainReAttachHostScsiDevices: Change the logic according
to the changes on helpers.
---
docs/formatdomain.html.in | 6 ++++
src/libvirt_private.syms | 2 +-
src/qemu/qemu_hostdev.c | 77 ++++++++++++++++++++++++++---------------------
src/util/virscsi.c | 45 +++++++++++++++++++++------
src/util/virscsi.h | 7 +++--
5 files changed, 90 insertions(+), 47 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index ff50214..18bfad1 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2798,6 +2798,12 @@
between domains (assuming the hypervisor and OS support this).
Only supported by SCSI host device.
<span class="since">Since 1.0.6</span>
+ <p>
+ Note: though <code>shareable</shareable> was introduced
+ <span class="since">since 1.0.6</span>, but it doesn't work as
+ as expected (actually works like non-shareable) until
+ <span class="since">1.2.2</span>.
+ </p>
</dd>
</dl>
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 13caf93..0f30292 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1686,7 +1686,7 @@ virSCSIDeviceGetSgName;
virSCSIDeviceGetShareable;
virSCSIDeviceGetTarget;
virSCSIDeviceGetUnit;
-virSCSIDeviceGetUsedBy;
+virSCSIDeviceIsAvailable;
virSCSIDeviceListAdd;
virSCSIDeviceListCount;
virSCSIDeviceListDel;
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 86a463a..2b9d274 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -250,13 +250,14 @@ qemuUpdateActiveScsiHostdevs(virQEMUDriverPtr driver,
virDomainHostdevDefPtr hostdev = NULL;
size_t i;
int ret = -1;
+ virSCSIDevicePtr scsi = NULL;
+ virSCSIDevicePtr tmp = NULL;
if (!def->nhostdevs)
return 0;
virObjectLock(driver->activeScsiHostdevs);
for (i = 0; i < def->nhostdevs; i++) {
- virSCSIDevicePtr scsi = NULL;
hostdev = def->hostdevs[i];
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
@@ -271,11 +272,18 @@ qemuUpdateActiveScsiHostdevs(virQEMUDriverPtr driver,
hostdev->shareable)))
goto cleanup;
- virSCSIDeviceSetUsedBy(scsi, def->name);
-
- if (virSCSIDeviceListAdd(driver->activeScsiHostdevs, scsi) < 0) {
+ if ((tmp = virSCSIDeviceListFind(driver->activeScsiHostdevs, scsi))) {
+ if (virSCSIDeviceSetUsedBy(tmp, def->name) < 0) {
+ virSCSIDeviceFree(scsi);
+ goto cleanup;
+ }
virSCSIDeviceFree(scsi);
- goto cleanup;
+ } else {
+ if (virSCSIDeviceSetUsedBy(scsi, def->name) < 0 ||
+ virSCSIDeviceListAdd(driver->activeScsiHostdevs, scsi) < 0) {
+ virSCSIDeviceFree(scsi);
+ goto cleanup;
+ }
}
}
ret = 0;
@@ -1118,24 +1126,29 @@ qemuPrepareHostdevSCSIDevices(virQEMUDriverPtr driver,
for (i = 0; i < count; i++) {
virSCSIDevicePtr scsi = virSCSIDeviceListGet(list, i);
if ((tmp = virSCSIDeviceListFind(driver->activeScsiHostdevs, scsi))) {
- const char *other_name = virSCSIDeviceGetUsedBy(tmp);
+ bool scsi_shareable = virSCSIDeviceGetShareable(scsi);
+ bool tmp_shareable = virSCSIDeviceGetShareable(tmp);
- if (other_name)
- virReportError(VIR_ERR_OPERATION_INVALID,
- _("SCSI device %s is in use by domain %s"),
- virSCSIDeviceGetName(tmp), other_name);
- else
+ if (!(scsi_shareable && tmp_shareable)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- _("SCSI device %s is already in use"),
+ _("SCSI device %s is already in use by "
+ "other domain(s) as '%s'"),
+ tmp_shareable ? "shareable" : "non-shareable",
virSCSIDeviceGetName(tmp));
- goto error;
- }
+ goto error;
+ }
- virSCSIDeviceSetUsedBy(scsi, name);
- VIR_DEBUG("Adding %s to activeScsiHostdevs", virSCSIDeviceGetName(scsi));
+ if (virSCSIDeviceSetUsedBy(tmp, name) < 0)
+ goto error;
+ } else {
+ if (virSCSIDeviceSetUsedBy(scsi, name) < 0)
+ goto error;
- if (virSCSIDeviceListAdd(driver->activeScsiHostdevs, scsi) < 0)
- goto error;
+ VIR_DEBUG("Adding %s to activeScsiHostdevs", virSCSIDeviceGetName(scsi));
+
+ if (virSCSIDeviceListAdd(driver->activeScsiHostdevs, scsi) < 0)
+ goto error;
+ }
}
virObjectUnlock(driver->activeScsiHostdevs);
@@ -1380,8 +1393,8 @@ qemuDomainReAttachHostScsiDevices(virQEMUDriverPtr driver,
virObjectLock(driver->activeScsiHostdevs);
for (i = 0; i < nhostdevs; i++) {
virDomainHostdevDefPtr hostdev = hostdevs[i];
- virSCSIDevicePtr scsi, tmp;
- const char *used_by = NULL;
+ virSCSIDevicePtr scsi;
+ virSCSIDevicePtr tmp;
virDomainDeviceDef dev;
dev.type = VIR_DOMAIN_DEVICE_HOSTDEV;
@@ -1411,30 +1424,26 @@ qemuDomainReAttachHostScsiDevices(virQEMUDriverPtr driver,
/* Only delete the devices which are marked as being used by @name,
* because qemuProcessStart could fail on the half way. */
- tmp = virSCSIDeviceListFind(driver->activeScsiHostdevs, scsi);
- virSCSIDeviceFree(scsi);
-
- if (!tmp) {
+ if (!(tmp = virSCSIDeviceListFind(driver->activeScsiHostdevs, scsi))) {
VIR_WARN("Unable to find device %s:%d:%d:%d "
"in list of active SCSI devices",
hostdev->source.subsys.u.scsi.adapter,
hostdev->source.subsys.u.scsi.bus,
hostdev->source.subsys.u.scsi.target,
hostdev->source.subsys.u.scsi.unit);
+ virSCSIDeviceFree(scsi);
continue;
}
- used_by = virSCSIDeviceGetUsedBy(tmp);
- if (STREQ_NULLABLE(used_by, name)) {
- VIR_DEBUG("Removing %s:%d:%d:%d dom=%s from activeScsiHostdevs",
- hostdev->source.subsys.u.scsi.adapter,
- hostdev->source.subsys.u.scsi.bus,
- hostdev->source.subsys.u.scsi.target,
- hostdev->source.subsys.u.scsi.unit,
- name);
+ VIR_DEBUG("Removing %s:%d:%d:%d dom=%s from activeScsiHostdevs",
+ hostdev->source.subsys.u.scsi.adapter,
+ hostdev->source.subsys.u.scsi.bus,
+ hostdev->source.subsys.u.scsi.target,
+ hostdev->source.subsys.u.scsi.unit,
+ name);
- virSCSIDeviceListDel(driver->activeScsiHostdevs, tmp);
- }
+ virSCSIDeviceListDel(driver->activeScsiHostdevs, tmp, name);
+ virSCSIDeviceFree(scsi);
}
virObjectUnlock(driver->activeScsiHostdevs);
}
diff --git a/src/util/virscsi.c b/src/util/virscsi.c
index 58d9e25..2c6d865 100644
--- a/src/util/virscsi.c
+++ b/src/util/virscsi.c
@@ -1,6 +1,7 @@
/*
* virscsi.c: helper APIs for managing host SCSI devices
*
+ * Copyright (C) 2013 - 2014 Red Hat, Inc.
* Copyright (C) 2013 Fujitsu, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -55,7 +56,8 @@ struct _virSCSIDevice {
char *name; /* adapter:bus:target:unit */
char *id; /* model:vendor */
char *sg_path; /* e.g. /dev/sg2 */
- const char *used_by; /* name of the domain using this dev */
+ char **used_by; /* name of the domains using this dev */
+ size_t n_used_by; /* how many domains are using this dev */
bool readonly;
bool shareable;
@@ -256,26 +258,37 @@ cleanup:
void
virSCSIDeviceFree(virSCSIDevicePtr dev)
{
+ size_t i;
+
if (!dev)
return;
VIR_FREE(dev->id);
VIR_FREE(dev->name);
VIR_FREE(dev->sg_path);
+ for (i = 0; i < dev->n_used_by; i++) {
+ VIR_FREE(dev->used_by[i]);
+ }
+ VIR_FREE(dev->used_by);
VIR_FREE(dev);
}
-void
+int
virSCSIDeviceSetUsedBy(virSCSIDevicePtr dev,
const char *name)
{
- dev->used_by = name;
+ char *copy = NULL;
+
+ if (VIR_STRDUP(copy, name) < 0)
+ return -1;
+
+ return VIR_APPEND_ELEMENT(dev->used_by, dev->n_used_by, copy);
}
-const char *
-virSCSIDeviceGetUsedBy(virSCSIDevicePtr dev)
+bool
+virSCSIDeviceIsAvailable(virSCSIDevicePtr dev)
{
- return dev->used_by;
+ return dev->n_used_by == 0;
}
const char *
@@ -406,10 +419,24 @@ virSCSIDeviceListSteal(virSCSIDeviceListPtr list,
void
virSCSIDeviceListDel(virSCSIDeviceListPtr list,
- virSCSIDevicePtr dev)
+ virSCSIDevicePtr dev,
+ const char *name)
{
- virSCSIDevicePtr ret = virSCSIDeviceListSteal(list, dev);
- virSCSIDeviceFree(ret);
+ virSCSIDevicePtr ret = NULL;
+ size_t i;
+
+ for (i = 0; i < ret->n_used_by; i++) {
+ if (STREQ_NULLABLE(ret->used_by[i], name)) {
+ if (ret->n_used_by > 1) {
+ VIR_DELETE_ELEMENT(ret->used_by, i, ret->n_used_by);
+ } else {
+ ret = virSCSIDeviceListSteal(list, dev);
+ virSCSIDeviceFree(ret);
+ }
+
+ break;
+ }
+ }
}
virSCSIDevicePtr
diff --git a/src/util/virscsi.h b/src/util/virscsi.h
index b2e98ca..aff7e5a 100644
--- a/src/util/virscsi.h
+++ b/src/util/virscsi.h
@@ -50,8 +50,8 @@ virSCSIDevicePtr virSCSIDeviceNew(const char *adapter,
bool shareable);
void virSCSIDeviceFree(virSCSIDevicePtr dev);
-void virSCSIDeviceSetUsedBy(virSCSIDevicePtr dev, const char *name);
-const char *virSCSIDeviceGetUsedBy(virSCSIDevicePtr dev);
+int virSCSIDeviceSetUsedBy(virSCSIDevicePtr dev, const char *name);
+bool virSCSIDeviceIsAvailable(virSCSIDevicePtr dev);
const char *virSCSIDeviceGetName(virSCSIDevicePtr dev);
unsigned int virSCSIDeviceGetAdapter(virSCSIDevicePtr dev);
unsigned int virSCSIDeviceGetBus(virSCSIDevicePtr dev);
@@ -83,7 +83,8 @@ size_t virSCSIDeviceListCount(virSCSIDeviceListPtr list);
virSCSIDevicePtr virSCSIDeviceListSteal(virSCSIDeviceListPtr list,
virSCSIDevicePtr dev);
void virSCSIDeviceListDel(virSCSIDeviceListPtr list,
- virSCSIDevicePtr dev);
+ virSCSIDevicePtr dev,
+ const char *name);
virSCSIDevicePtr virSCSIDeviceListFind(virSCSIDeviceListPtr list,
virSCSIDevicePtr dev);
--
1.8.1.4
10 years, 11 months
[libvirt] [PATCH] wireshark: Fix VPATH build
by Jiri Denemark
config-post.h included indirectly from packet-libvirt.c stays in
$(top_srcdir) rather than $(top_builddir) which is added automatically.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
tools/wireshark/src/Makefile.am | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/wireshark/src/Makefile.am b/tools/wireshark/src/Makefile.am
index 81e7041..afe9975 100644
--- a/tools/wireshark/src/Makefile.am
+++ b/tools/wireshark/src/Makefile.am
@@ -17,6 +17,9 @@
# <http://www.gnu.org/licenses/>.
#
# Author: Yuto KAWAMURA(kawamuray)
+
+INCLUDES = -I$(top_srcdir)
+
ws_plugin_LTLIBRARIES = libvirt.la
libvirt_la_SOURCES = packet-libvirt.c plugin.c
libvirt_la_CPPFLAGS = $(WS_DISSECTOR_CPPFLAGS)
--
1.8.5.3
10 years, 11 months
[libvirt] [PATCH] maint: update to latest gnulib, for mingw improvements
by Eric Blake
On Fedora 20, mingw-headers has switched over to winpthreads as
the provider for its <pthread.h>. winpthreads is notorious for
providing a less-than-stellar header, and needs several workarounds
before it can be used in a project assuming POSIX semantics. While
we still use Windows primitives rather than pthread when compiling
for mingw, this update will make it possible to switch to mingw
pthreads.
* .gnulib: Update to latest, for mingw fixes.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
We're in between releases, so I'm pushing this under the
gnulib/trivial rule.
* .gnulib d18d1b8...d5fec6c (15):
> pthread: work around winpthread header pollution on mingw
> qacl: check for fchmod
> Fix typo in ChangeLog.
> fdopen-tests: port to Tru64
> stdalign: port to HP-UX compilers
> strtoimax: port to platforms lacking 'long long'
> update from texinfo
> relocatable-maint.texi: escape braces
> maint: remove duplicate ChangeLog entry
> maint.mk: adapt openat.h-include-without-use test
> relocatable-perl: like relocatable-script, but for Perl scripts
> relocatable-shell: Update suggested usage in maintainer documentation.
> tests: fix export bug in previous patch
> tests: simplify porting to Solaris 10 /bin/sh
> update from texinfo
.gnulib | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.gnulib b/.gnulib
index d18d1b8..d5fec6c 160000
--- a/.gnulib
+++ b/.gnulib
@@ -1 +1 @@
-Subproject commit d18d1b8023822220bb8f0a079c7312a1adffdce0
+Subproject commit d5fec6c22f03c6a73d62260c9ce091c10c0a9cbd
--
1.8.5.3
10 years, 11 months