[libvirt] [PATCH 0/6] storage: fs: tweak dir perms handling on build
by Cole Robinson
Consider the following issue
- Using virt-manager with qemu:///session
- User adds a storage pool pointing at /tmp. No explicit permissions are
requested in the XML
- virt-manager calls PoolDefine, then PoolBuild
- libvirt tries to unconditionally chmod 755 /tmp. This fails because my
user doesn't own root. Pool build fails, virt-manager reports failure
Yes there's a couple ways we could avoid this specific case in
virt-manager, but I think it makes more sense to have pool.build on
a directory be a no-op in this case. The following patches address this.
- Patch 1 is an error reporting tweak
- Patch 2 is a feature, but implementing it simplifies later patches
- Patch 3 makes pool.build not even attempt mkdir if the dir already exists.
- Patch 4 makes pool.build skip dir chown'ing unless user explicitly
requested uid or gid via the XML
- Patch 5-6 make pool.build skip dir chmod unless the user explicitly
requested <mode> via the XML. If a mode is required for mkdir, continue
to use the previous default.
Cole Robinson (6):
storage: fs: Don't overwrite virDirCreate error
storage: fs: Fill in permissions on pool refresh
storage: fs: Don't attempt directory creation if it already exists
storage: fs: Don't try to chown directory unless user requested
storage: conf: Don't set any default <mode> in the XML
storage: fs: Only force directory permissions if required
docs/schemas/storagecommon.rng | 5 +-
src/conf/storage_conf.c | 42 +++++------
src/storage/storage_backend.c | 20 ++++--
src/storage/storage_backend.h | 3 +
src/storage/storage_backend_fs.c | 81 ++++++++++++++++------
src/storage/storage_backend_logical.c | 4 +-
src/util/virfile.c | 47 ++++++++-----
tests/storagepoolxml2xmlin/pool-dir.xml | 2 +-
tests/storagepoolxml2xmlout/pool-dir.xml | 2 +-
tests/storagepoolxml2xmlout/pool-netfs-gluster.xml | 2 +-
tests/storagevolxml2xmlin/vol-file.xml | 6 +-
tests/storagevolxml2xmlout/vol-file.xml | 6 +-
tests/storagevolxml2xmlout/vol-gluster-dir.xml | 2 +-
tests/storagevolxml2xmlout/vol-sheepdog.xml | 2 +-
14 files changed, 147 insertions(+), 77 deletions(-)
--
2.3.6
9 years, 5 months
[libvirt] [PATCH] Document that virNodeGetInfo can return mhz == 0.
by Richard W.M. Jones
On the s/390x architecture, libvirt may already return 0 in the
node_info->mhz field (see src/nodeinfo.c:linuxNodeInfoCPUPopulate).
We may also want to return this on aarch64 in future, because
calculating the proper value requires SMBIOS, which is not available
on non-server-class systems (specifically on systems which don't
adhere to the SBSA standard).
Therefore this change documents the existing behaviour and provides a
valid path for aarch64.
Signed-off-by: Richard W.M. Jones <rjones(a)redhat.com>
Bug-URL: https://bugzilla.redhat.com/1206353
---
include/libvirt/libvirt-host.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h
index 953366b..070550b 100644
--- a/include/libvirt/libvirt-host.h
+++ b/include/libvirt/libvirt-host.h
@@ -354,7 +354,8 @@ struct _virNodeInfo {
char model[32]; /* string indicating the CPU model */
unsigned long memory; /* memory size in kilobytes */
unsigned int cpus; /* the number of active CPUs */
- unsigned int mhz; /* expected CPU frequency */
+ unsigned int mhz; /* expected CPU frequency, 0 if not known or
+ on unusual architectures */
unsigned int nodes; /* the number of NUMA cell, 1 for unusual NUMA
topologies or uniform memory access; check
capabilities XML for the actual NUMA topology */
--
2.3.1
9 years, 5 months
[libvirt] [java] [PATCH 0/6] Fix JNA wrapping, fix memory leaks and wrap security model / label function
by Claudio Bley
Hi.
First and foremost, this series fixes a few mistakes in the wrapping
code found by inspecting the org.libvirt.jna.Libvirt interface and the
corresponding C types of the XML API file.
The last two patches add two missing functions introduced in libvirt
0.6.1.
At the end of the day, this means libvirt-java has gained full
coverage of the libvirt functions up to and including version
0.8.5. Yay!
Claudio Bley (6):
JNA: fix wrong return type void vs. int
JNA: add CString class and fix memory leaks
JNA: simplify freeing memory for C strings
Use the CString class for Arrays of CStrings too
Implement Domain.getSecurityLabel and add SecurityLabel class
Implement Connect.getSecurityModel and add SecurityModel class
src/main/java/org/libvirt/Connect.java | 74 +++++++++--------
src/main/java/org/libvirt/Device.java | 9 +-
src/main/java/org/libvirt/Domain.java | 57 ++++++-------
src/main/java/org/libvirt/DomainSnapshot.java | 8 +-
src/main/java/org/libvirt/Interface.java | 7 +-
src/main/java/org/libvirt/Library.java | 44 +++-------
src/main/java/org/libvirt/Network.java | 14 +---
src/main/java/org/libvirt/NetworkFilter.java | 2 +-
src/main/java/org/libvirt/Secret.java | 2 +-
src/main/java/org/libvirt/SecurityLabel.java | 49 +++++++++++
src/main/java/org/libvirt/SecurityModel.java | 37 +++++++++
src/main/java/org/libvirt/StoragePool.java | 9 +-
src/main/java/org/libvirt/StorageVol.java | 16 +---
src/main/java/org/libvirt/jna/CString.java | 85 +++++++++++++++++++
src/main/java/org/libvirt/jna/Libvirt.java | 114 +++++++++++++++++---------
15 files changed, 343 insertions(+), 184 deletions(-)
create mode 100644 src/main/java/org/libvirt/SecurityLabel.java
create mode 100644 src/main/java/org/libvirt/SecurityModel.java
create mode 100644 src/main/java/org/libvirt/jna/CString.java
--
2.2.2
9 years, 5 months
[libvirt] [PATCH V2] libxl: support domainReset
by Jim Fehlig
Currently, libxl does not provide a reset function, but domainReset
can be implemented in the libxl driver by forcibly destroying the
domain and starting it again.
Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
This is essentially a V2 of a patch submitted quite some time ago
https://www.redhat.com/archives/libvir-list/2014-August/msg00077.html
The idea of implmenting domainReset in the libxl driver by forcibly
destroying the domain and starting it again was ACK'ed in principle
by Ian Campbell
https://www.redhat.com/archives/libvir-list/2014-August/msg00109.html
I never pushed the patch since it was not ACK'ed by a libvirt
maintainer and stumbled across it while cleaning up some of my
old branches. The only change here is rebase against current
libvirt.git master.
src/libxl/libxl_driver.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 12be816..671d336 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -1237,6 +1237,64 @@ libxlDomainReboot(virDomainPtr dom, unsigned int flags)
}
static int
+libxlDomainReset(virDomainPtr dom, unsigned int flags)
+{
+ libxlDriverPrivatePtr driver = dom->conn->privateData;
+ libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
+ virDomainObjPtr vm;
+ int ret = -1;
+
+ virCheckFlags(0, -1);
+
+ if (!(vm = libxlDomObjFromDomain(dom)))
+ goto cleanup;
+
+ if (virDomainResetEnsureACL(dom->conn, vm->def) < 0)
+ goto cleanup;
+
+ if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("Domain is not running"));
+ goto endjob;
+ }
+
+ /*
+ * The semantics of reset can be achieved by forcibly destroying
+ * the domain and starting it again.
+ */
+ if (libxl_domain_destroy(cfg->ctx, vm->def->id, NULL) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to destroy domain '%d' before reset"),
+ vm->def->id);
+ goto endjob;
+ }
+
+ libxlDomainCleanup(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED);
+
+ if (libxlDomainStart(driver, vm, false, -1) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to start domain '%d' after reset"),
+ vm->def->id);
+ goto endjob;
+ }
+
+ ret = 0;
+
+ endjob:
+ if (!libxlDomainObjEndJob(driver, vm))
+ vm = NULL;
+
+ cleanup:
+ if (vm)
+ virObjectUnlock(vm);
+ virObjectUnref(cfg);
+ return ret;
+}
+
+static int
libxlDomainDestroyFlags(virDomainPtr dom,
unsigned int flags)
{
@@ -5066,6 +5124,7 @@ static virHypervisorDriver libxlHypervisorDriver = {
.domainShutdown = libxlDomainShutdown, /* 0.9.0 */
.domainShutdownFlags = libxlDomainShutdownFlags, /* 0.9.10 */
.domainReboot = libxlDomainReboot, /* 0.9.0 */
+ .domainReset = libxlDomainReset, /* 1.2.8 */
.domainDestroy = libxlDomainDestroy, /* 0.9.0 */
.domainDestroyFlags = libxlDomainDestroyFlags, /* 0.9.4 */
.domainGetOSType = libxlDomainGetOSType, /* 0.9.0 */
--
2.3.7
9 years, 6 months
[libvirt] Socket files in virt-aa-helper
by Michał Dubiel
Hi guys,
I have got a question. I need to add apparmor support for vhost-user socket
files used to communicate with the vhost-user server app. Those ones
defined with something like:
<interface type='vhostuser'>
<mac address='02:ed:f3:5d:de:f3'/>
<source type='unix' path='/var/run/vrouter/uvh_vif_tapa8396c51-2a'
mode='client'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03'
function='0x0'/>
</interface>
I added something like this into get_files() function in virt-aa-helper.c:
for (i = 0; i < ctl->def->nnets; i++) {
if (ctl->def->nets[i] &&
ctl->def->nets[i]->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER &&
ctl->def->nets[i]->data.vhostuser) {
virDomainChrSourceDefPtr vhu =
ctl->def->nets[i]->data.vhostuser;
if (vah_add_file_chardev(&buf, vhu->data.nix.path, "rw",
vhu->type) != 0)
goto cleanup;
}
}
However, there is a restriction for the socket file types in valid_path()
function:
switch (sb.st_mode & S_IFMT) {
case S_IFSOCK:
return 1;
break;
default:
break;
}
That prevents this from working.
May I ask why the socket file types are restricted? Vhost-user uses sockets
so if I want to use apparmor virt-aa-helper has to be able to add the line
for the socket file into /etc/apparmor.d/libvirt/libvirt-UUID.files.
Regards,
Michal
9 years, 6 months
[libvirt] [PATCH v3 0/9] Selective block device migration implementation
by Michal Privoznik
I've taken Pavel's patches, reworked them a bit, added something and sending
v3. The original patches can be found here:
https://www.redhat.com/archives/libvir-list/2015-May/msg00697.html
Michal Privoznik (3):
virDomainDiskGetSource: Mark passed disk as 'const'
qemuMigrationBeginPhase: Fix function header indentation
qemuMigrationDriveMirror: Pass disk format to qemu
Pavel Boldin (6):
util: multi-value virTypedParameter
util: multi-value parameters in virTypedParamsAdd*
util: virTypedParams{Filter,PickStrings}
util: add virTypedParamsAddStringList
qemu: migration: selective block device migration
virsh: selective block device migration
include/libvirt/libvirt-domain.h | 9 ++
include/libvirt/libvirt-host.h | 17 +++
src/conf/domain_conf.c | 2 +-
src/conf/domain_conf.h | 2 +-
src/libvirt_public.syms | 3 +
src/qemu/qemu_driver.c | 72 +++++++---
src/qemu/qemu_migration.c | 267 +++++++++++++++++++++++++----------
src/qemu/qemu_migration.h | 24 ++--
src/util/virtypedparam.c | 269 ++++++++++++++++++++++++++++-------
src/util/virtypedparam.h | 10 ++
tests/Makefile.am | 6 +
tests/virtypedparamtest.c | 294 +++++++++++++++++++++++++++++++++++++++
tools/virsh-domain.c | 23 +++
tools/virsh.pod | 21 +--
14 files changed, 854 insertions(+), 165 deletions(-)
create mode 100644 tests/virtypedparamtest.c
--
2.3.6
9 years, 6 months
[libvirt] [libvirt-glib] gconfig: Fix small leak in test-domain-create
by Christophe Fergeau
The object returned by gvir_config_domain_disk_get_driver() must be
unref'ed when no longer used.
---
libvirt-gconfig/tests/test-domain-create.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/libvirt-gconfig/tests/test-domain-create.c b/libvirt-gconfig/tests/test-domain-create.c
index eb4b945..417d3d0 100644
--- a/libvirt-gconfig/tests/test-domain-create.c
+++ b/libvirt-gconfig/tests/test-domain-create.c
@@ -284,6 +284,7 @@ int main(int argc, char **argv)
g_assert(gvir_config_domain_disk_driver_get_copy_on_read(driver));
g_assert(gvir_config_domain_disk_get_target_bus(disk) == GVIR_CONFIG_DOMAIN_DISK_BUS_IDE);
g_str_const_check(gvir_config_domain_disk_get_target_dev(disk), "hda");
+ g_object_unref(driver);
/* network interfaces node */
--
2.3.5
9 years, 6 months
Re: [libvirt] [CFT][PATCH 00/10] Making new mounts of proc and sysfs as safe as bind mounts (take 2)
by Richard Weinberger
[CC'ing libvirt-lxc folks]
Am 28.05.2015 um 23:32 schrieb Eric W. Biederman:
> Richard Weinberger <richard(a)nod.at> writes:
>
>> Am 28.05.2015 um 21:57 schrieb Eric W. Biederman:
>>>> FWIW, it breaks also libvirt-lxc:
>>>> Error: internal error: guest failed to start: Failed to re-mount /proc/sys on /proc/sys flags=1021: Operation not permitted
>>>
>>> Interesting. I had not anticipated a failure there? And it is failing
>>> in remount? Oh that is interesting.
>>>
>>> That implies that there is some flag of the original mount of /proc that
>>> the remount of /proc/sys is clearing, and that previously
>>>
>>> The flags specified are current rdonly,remount,bind so I expect there
>>> are some other flags on proc that libvirt-lxc is clearing by accident
>>> and we did not fail before because the kernel was not enforcing things.
>>
>> Please see:
>> http://libvirt.org/git/?p=libvirt.git;a=blob;f=src/lxc/lxc_container.c;h=...
>> lxcContainerMountBasicFS()
>>
>> and:
>> http://libvirt.org/git/?p=libvirt.git;a=blob;f=src/lxc/lxc_container.c;h=...
>> lxcBasicMounts
>>
>>> What are the mount flags in a working libvirt-lxc?
>>
>> See:
>> test1:~ # cat /proc/self/mountinfo
>> 149 147 0:56 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
>> 150 149 0:56 /sys /proc/sys ro,nodev,relatime - proc proc rw
>
>> If you need more info, please let me know. :-)
>
> Oh interesting I had not realized libvirt-lxc had grown an unprivileged
> mode using user namespaces.
>
> This does appear to be a classic remount bug, where you are not
> preserving the permissions. It appears the fact that the code
> failed to enforce locked permissions on the fresh mount of proc
> was hiding this bug until now.
>
> I expect what you actually want is the code below:
>
> diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
> index 9a9ae5c2aaf0..f008a7484bfe 100644
> --- a/src/lxc/lxc_container.c
> +++ b/src/lxc/lxc_container.c
> @@ -850,7 +850,7 @@ typedef struct {
>
> static const virLXCBasicMountInfo lxcBasicMounts[] = {
> { "proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, false, false, false },
> - { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_RDONLY, false, false, false },
> + { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, false, false, false },
> { "/.oldroot/proc/sys/net/ipv4", "/proc/sys/net/ipv4", NULL, MS_BIND, false, false, true },
> { "/.oldroot/proc/sys/net/ipv6", "/proc/sys/net/ipv6", NULL, MS_BIND, false, false, true },
> { "sysfs", "/sys", "sysfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, false, false, false },
>
> Or possibly just:
>
> diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
> index 9a9ae5c2aaf0..a60ccbd12bfc 100644
> --- a/src/lxc/lxc_container.c
> +++ b/src/lxc/lxc_container.c
> @@ -850,7 +850,7 @@ typedef struct {
>
> static const virLXCBasicMountInfo lxcBasicMounts[] = {
> { "proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, false, false, false },
> - { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_RDONLY, false, false, false },
> + { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_RDONLY, true, false, false },
> { "/.oldroot/proc/sys/net/ipv4", "/proc/sys/net/ipv4", NULL, MS_BIND, false, false, true },
> { "/.oldroot/proc/sys/net/ipv6", "/proc/sys/net/ipv6", NULL, MS_BIND, false, false, true },
> { "sysfs", "/sys", "sysfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, false, false, false },
>
> As the there is little point in making /proc/sys read-only in a
> user-namespace, as the permission checks are uid based and no-one should
> have the global uid 0 in your container. Making mounting /proc/sys
> read-only rather pointless.
Eric, using the patch below I was able to spawn a user-namespace enabled container
using libvirt-lxc. :-)
I had to:
1. Disable the read-only mount of /proc/sys which is anyway useless in the user-namespace case.
2. Disable the /proc/sys/net/ipv{4,6} bind mounts, this ugly hack is only needed for the non user-namespace case.
3. Remove MS_RDONLY from the sysfs mount (For the non user-namespace case we'd have to keep this, though).
Daniel, I'd take this as a chance to disable all the MS_RDONLY games if user-namespace are configured.
With Eric's fixes they hurt us. And as I wrote many times before if root within the user-namespace
is able to do nasty things in /sys and /proc that's a plain kernel bug which needs fixing. There is no
point in mounting these read-only. Except for the case then no user-namespace is used.
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 9a9ae5c..497e05f 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -850,10 +850,10 @@ typedef struct {
static const virLXCBasicMountInfo lxcBasicMounts[] = {
{ "proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, false, false, false },
- { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_RDONLY, false, false, false },
- { "/.oldroot/proc/sys/net/ipv4", "/proc/sys/net/ipv4", NULL, MS_BIND, false, false, true },
- { "/.oldroot/proc/sys/net/ipv6", "/proc/sys/net/ipv6", NULL, MS_BIND, false, false, true },
- { "sysfs", "/sys", "sysfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, false, false, false },
+ { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_RDONLY, true, false, false },
+ { "/.oldroot/proc/sys/net/ipv4", "/proc/sys/net/ipv4", NULL, MS_BIND, true, false, true },
+ { "/.oldroot/proc/sys/net/ipv6", "/proc/sys/net/ipv6", NULL, MS_BIND, true, false, true },
+ { "sysfs", "/sys", "sysfs", MS_NOSUID|MS_NOEXEC|MS_NODEV, false, false, false },
{ "securityfs", "/sys/kernel/security", "securityfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, true, true, false },
#if WITH_SELINUX
{ SELINUX_MOUNT, SELINUX_MOUNT, "selinuxfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, true, true, false },
Thanks,
//richard
9 years, 6 months
[libvirt] [libvirt-php][PATCH 00/10] Couple of PHP fixes
by Michal Privoznik
Even though this project is not actively developed, it does not
mean we can't make some things better in it. After this patchset,
distcheck works, targets are not built everytime, only when
necessary, and so on.
Michal Privoznik (10):
Update .gitignore
Update autotools generated files
get_next_free_numeric_value: Use correct format for sscanf()
tools: Cleanup Makefile
configure.ac: Check for libtool
src: Clean up Makefile
tests: Clean up Makefile.am
tests: Update qemu path
tests: run under distcheck
Install libvirt-php.ini more wisely
.gitignore | 28 ++
INSTALL | 8 +-
Makefile.am | 4 +-
configure.ac | 8 +-
install-sh | 14 +-
missing | 412 ++++++++++-----------------
src/Makefile.am | 64 +++--
src/libvirt-php.c | 2 +-
tests/Makefile.am | 37 ++-
tests/data/example-qcow2-disk.xml | 2 +-
tests/{functions.phpt => functions.phpt.in} | 4 +-
tests/php.ini | 2 +-
tests/runtests.sh | 4 +-
tests/test-domain-create-and-coredump.phpt | 3 +-
tests/test-domain-create-and-get-xpath.phpt | 3 +-
tests/test-domain-create-get-metadata.phpt | 3 +-
tests/test-domain-create.phpt | 3 +-
tests/test-domain-define-create-destroy.phpt | 3 +-
tests/test-domain-define-undefine.phpt | 3 +-
tests/test-domain-snapshot.phpt | 3 +-
tools/Makefile.am | 29 +-
21 files changed, 309 insertions(+), 330 deletions(-)
rename tests/{functions.phpt => functions.phpt.in} (91%)
--
2.3.6
9 years, 6 months
[libvirt] [PATCHv2] qemu: add a check for slot and base when build dimm address
by Luyao Huang
When hot-plug a memory device, we don't check if there
is a memory device have the same address with the memory device
we want hot-pluged. Qemu forbid use/hot-plug 2 memory device
with same slot or the same base(qemu side this elemnt named addr).
Introduce a address check when build memory device qemu command line.
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
v2:
move the check to qemuBuildMemoryDeviceStr() to check the dimm address
when start/hot-plug a memory device.
src/qemu/qemu_command.c | 77 ++++++++++++++++++++++++++++++++++++-------------
1 file changed, 57 insertions(+), 20 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d8ce511..0380a3b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4955,6 +4955,61 @@ qemuBuildMemoryDimmBackendStr(virDomainMemoryDefPtr mem,
}
+static int
+qemuBuildMemoryDeviceAddr(virBuffer *buf,
+ virDomainDefPtr def,
+ virDomainMemoryDefPtr mem)
+{
+ ssize_t i;
+
+ if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+ return 0;
+
+ if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("only 'dimm' addresses are supported for the "
+ "pc-dimm device"));
+ return -1;
+ }
+
+ if (mem->info.addr.dimm.slot >= def->mem.memory_slots) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("memory device slot '%u' exceeds slots count '%u'"),
+ mem->info.addr.dimm.slot, def->mem.memory_slots);
+ return -1;
+ }
+
+ for (i = 0; i < def->nmems; i++) {
+ virDomainMemoryDefPtr tmp = def->mems[i];
+
+ if (tmp == mem ||
+ tmp->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM)
+ continue;
+
+ if (mem->info.addr.dimm.slot == tmp->info.addr.dimm.slot) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("memory device slot '%u' already been"
+ " used by other memory device"),
+ mem->info.addr.dimm.slot);
+ return -1;
+ }
+
+ if (mem->info.addr.dimm.base != 0 && tmp->info.addr.dimm.base != 0 &&
+ mem->info.addr.dimm.base == tmp->info.addr.dimm.base) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("memory device base '0x%llx' already been"
+ " used by other memory device"),
+ mem->info.addr.dimm.base);
+ return -1;
+ }
+ }
+
+ virBufferAsprintf(buf, ",slot=%d", mem->info.addr.dimm.slot);
+ virBufferAsprintf(buf, ",addr=%llu", mem->info.addr.dimm.base);
+
+ return 0;
+}
+
char *
qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem,
virDomainDefPtr def,
@@ -4976,29 +5031,11 @@ qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem,
return NULL;
}
- if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM &&
- mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("only 'dimm' addresses are supported for the "
- "pc-dimm device"));
- return NULL;
- }
-
- if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM &&
- mem->info.addr.dimm.slot >= def->mem.memory_slots) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("memory device slot '%u' exceeds slots count '%u'"),
- mem->info.addr.dimm.slot, def->mem.memory_slots);
- return NULL;
- }
-
virBufferAsprintf(&buf, "pc-dimm,node=%d,memdev=mem%s,id=%s",
mem->targetNode, mem->info.alias, mem->info.alias);
- if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) {
- virBufferAsprintf(&buf, ",slot=%d", mem->info.addr.dimm.slot);
- virBufferAsprintf(&buf, ",addr=%llu", mem->info.addr.dimm.base);
- }
+ if (qemuBuildMemoryDeviceAddr(&buf, def, mem) < 0)
+ return NULL;
break;
--
1.8.3.1
9 years, 6 months