[libvirt] [PATCHv2 0/2] macvtap: don't use netlink to save/set mac for macvtap+passthrough+802.1Qbh
by Laine Stump
These two patches are the v2 of a single patch that I sent last
week:
https://www.redhat.com/archives/libvir-list/2015-August/msg00889.html
At the time I sent that patch, I had no hardware to test it on, but
was operating on a misunderstood assumption - someone in the know had
told me that libvirt didn't need to save/restore the MAC address of
VFs for 802.1Qbh macvtap passthrough, and I extrapolated from there
that we didn't need to *set* the MAC address of the VF either. This
makes sense, since that is what happens for 802.1Qbh *device*
passthrough, but based on my own tests the 802.1Qbh "associate" fails
unless libvirt sets the VF's MAC address prior to associate.
So this patch takes a different approach from V1 - instead of
completely skipping the save/set/restore of MAC address for VFs that
are using 802.1Qbh, it still does it, but uses the "old" method of
ioctl(SIOCGIFHWADDR) and ioctl(SIOCSIFHWADDR).
I *did* have the proper hardware to test this time, and it works (both
for a Cisco VMFEX card using 802.1Qbh and for an Intel 82576 card with
straight macvtap passthrough).
Laine Stump (2):
util: make virNetDev(Replace|Restore)MacAddress public functions
util: don't use netlink to save/set mac for
macvtap+passthrough+802.1Qbh
src/libvirt_private.syms | 2 +
src/util/virnetdev.c | 172 ++++++++++++++++++++++----------------------
src/util/virnetdev.h | 10 +++
src/util/virnetdevmacvlan.c | 26 +++++--
4 files changed, 121 insertions(+), 89 deletions(-)
--
2.1.0
9 years, 3 months
[libvirt] [PATCH] virsh: Enhance the detailed output of domblklist for networked source
by Lin Ma
Format & Output more detailed information about networked source
e.g: The output without the patch:
$ virsh domblklist $DOMAIN --details
Type Device Target Source
------------------------------------------------
network disk vda test-pool/image
network disk vdb iqn.2015-08.org.example:sn01/0
network disk vdc /image.raw
network disk vdd -
network disk vde -
network disk vdf image1
network disk vdg test-volume/image.raw
The output with the patch:
$ virsh domblklist $DOMAIN --details
Type Device Target Source
------------------------------------------------
network disk vda rbd://monitor1.example.org:6321/test-pool/image
network disk vdb iscsi://192.168.124.200:3260/iqn.2015-08.org.example:sn01/0
network disk vdc http://192.168.124.200:80/image.raw
network disk vdd nbd+unix:///var/run/nbdsock
network disk vde nbd://192.168.124.200:12345
network disk vdf sheepdog://192.168.124.200:6000/image1
network disk vdg gluster://192.168.124.200/test-volume/image.raw
Signed-off-by: Lin Ma <lma(a)suse.com>
---
tools/virsh-domain-monitor.c | 60 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 55 insertions(+), 5 deletions(-)
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 340a8e2..9188b42 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -518,6 +518,12 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
for (i = 0; i < ndisks; i++) {
char *type = NULL;
char *device = NULL;
+ char *protocol = NULL;
+ char *transport = NULL;
+ char *host_name = NULL;
+ char *host_port = NULL;
+ char *socket = NULL;
+ char *name = NULL;
char *target;
char *source;
@@ -541,11 +547,55 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
VIR_FREE(device);
goto cleanup;
}
- source = virXPathString("string(./source/@file"
- "|./source/@dev"
- "|./source/@dir"
- "|./source/@name"
- "|./source/@volume)", ctxt);
+ if (type && STREQ(type, "network")) {
+ protocol = virXPathString("string(./source/@protocol)", ctxt);
+ name = virXPathString("string(./source/@name)", ctxt);
+ transport = virXPathString("string(./source/host/@transport)", ctxt);
+ socket = virXPathString("string(./source/host/@socket)", ctxt);
+ host_name = virXPathString("string(./source/host/@name)", ctxt);
+ host_port = virXPathString("string(./source/host/@port)", ctxt);
+ if (VIR_STRDUP(source, protocol) < 0)
+ goto cleanup;
+ VIR_FREE(protocol);
+ if(transport) {
+ if(virAsprintf(&source, "%s+%s", source, transport) < 0)
+ goto cleanup;
+ VIR_FREE(transport);
+ }
+ if(virAsprintf(&source, "%s://", source) < 0)
+ goto cleanup;
+ if(host_name) {
+ if(virAsprintf(&source, "%s%s", source, host_name) < 0)
+ goto cleanup;
+ VIR_FREE(host_name);
+ if(host_port) {
+ if(virAsprintf(&source, "%s:%s", source, host_port) < 0)
+ goto cleanup;
+ VIR_FREE(host_port);
+ }
+ }
+ if(name) {
+ if(!STRPREFIX(name, "/"))
+ if(virAsprintf(&source, "%s/", source) < 0)
+ goto cleanup;
+ if(virAsprintf(&source, "%s%s", source, name) < 0)
+ goto cleanup;
+ VIR_FREE(name);
+ } else if(socket) {
+ if(!STRPREFIX(socket, "/"))
+ if(virAsprintf(&source, "%s/", source) < 0)
+ goto cleanup;
+ if(virAsprintf(&source, "%s%s", source, socket) < 0)
+ goto cleanup;
+ VIR_FREE(socket);
+ }
+ } else {
+ source = virXPathString("string(./source/@file"
+ "|./source/@dev"
+ "|./source/@dir"
+ "|./source/@name"
+ "|./source/@volume)", ctxt);
+ }
if (details) {
vshPrint(ctl, "%-10s %-10s %-10s %s\n", type, device,
target, source ? source : "-");
--
2.1.4
9 years, 3 months
[libvirt] [PATCH v2 0/9] admin API: Introduce server listing API
by Erik Skultety
v2:
- tab replacing patch now also includes files Martin added in his keepalive
series (trivial, ready to be pushed)
- admin_server now marked as renamed instead of deleted and formated with -M
- introduction of virAdmServe structure split to a separate patch
- resolved server naming issues from review (added fallback data)
- refactored lock_daemon a little not to store duplicate reference to a
server, since we now have daemon structure
- tweaked virnetdaemontest and included new data for it
virt-admin still missing in this series, because first we need to handle proper
connecting to daemons, i.e. discuss the URI format and then we can add
individual commands, so I postponed it in this series and will look at the
connect routine first.
Erik Skultety (9):
test: Replace tabs with spaces in virnetdaemondata json files
test:
s/{in,out}put-data-admin-nomdns/{in,out}put-data-admin-nomdns-nonames
locking: Remove redundant 'srv' element from virLockDaemon
rpc: Introduce new elements 'id' and 'name' to virnetserver structure
virnetdaemon: Add post exec restart support for multiple servers
admin: Move admin_server.{h,c} to admin.{h,c}
admin: Introduce virAdmServer structure
admin: Introduce adminDaemonConnectListServers API
admin: Usage example of the new server listing API (not to be pushed)
.gitignore | 1 +
Makefile.am | 2 +-
configure.ac | 1 +
daemon/Makefile.am | 6 +-
daemon/admin.c | 174 +++++++++++++++
daemon/admin.h | 36 ++++
daemon/admin_server.c | 103 +++------
daemon/admin_server.h | 23 +-
daemon/libvirtd.c | 10 +-
examples/admin/Makefile.am | 25 +++
examples/admin/listservers.c | 65 ++++++
include/libvirt/libvirt-admin.h | 12 ++
po/POTFILES.in | 2 +-
src/admin/admin_protocol.x | 27 ++-
src/admin_protocol-structs | 16 ++
src/datatypes.c | 35 +++
src/datatypes.h | 36 ++++
src/libvirt-admin.c | 171 +++++++++++++++
src/libvirt_admin_private.syms | 5 +
src/libvirt_admin_public.syms | 4 +
src/libvirt_remote.syms | 3 +-
src/locking/lock_daemon.c | 42 ++--
src/lxc/lxc_controller.c | 2 +-
src/rpc/virnetdaemon.c | 111 +++++++---
src/rpc/virnetdaemon.h | 30 ++-
src/rpc/virnetserver.c | 46 +++-
src/rpc/virnetserver.h | 5 +
.../input-data-admin-nomdns-names.json | 128 +++++++++++
.../input-data-admin-nomdns-nonames.json | 126 +++++++++++
.../virnetdaemondata/input-data-admin-nomdns.json | 126 -----------
.../input-data-no-keepalive-required.json | 240 ++++++++++-----------
.../output-data-admin-nomdns-names.json | 128 +++++++++++
....json => output-data-admin-nomdns-nonames.json} | 2 +
.../virnetdaemondata/output-data-anon-clients.json | 1 +
.../output-data-initial-nomdns.json | 1 +
tests/virnetdaemondata/output-data-initial.json | 1 +
.../output-data-no-keepalive-required.json | 240 ++++++++++-----------
tests/virnetdaemontest.c | 52 ++---
38 files changed, 1492 insertions(+), 546 deletions(-)
create mode 100644 daemon/admin.c
create mode 100644 daemon/admin.h
create mode 100644 examples/admin/Makefile.am
create mode 100644 examples/admin/listservers.c
create mode 100644 tests/virnetdaemondata/input-data-admin-nomdns-names.json
create mode 100644 tests/virnetdaemondata/input-data-admin-nomdns-nonames.json
delete mode 100644 tests/virnetdaemondata/input-data-admin-nomdns.json
create mode 100644 tests/virnetdaemondata/output-data-admin-nomdns-names.json
rename tests/virnetdaemondata/{output-data-admin-nomdns.json => output-data-admin-nomdns-nonames.json} (98%)
--
2.4.3
9 years, 3 months
[libvirt] [PATCH v2 0/2] qemu: Default to virtio-net where available
by Andrea Bolognani
This new version of the patch addresses Martin's comments
by using capabilities to detect whether virtio-net can be
used, and if that is the case, does so on all architectures.
Plus, the commit messages are slightly less terse this time
around :)
Cheers.
Andrea Bolognani (2):
qemu: Introduce QEMU_CAPS_DEVICE_VIRTIO_NET capability
qemu: Default to virtio-net where available
src/qemu/qemu_capabilities.c | 7 ++++++-
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_domain.c | 19 ++++++++++++++-----
tests/qemucapabilitiesdata/caps_1.2.2-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.3.1-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.4.2-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.5.3-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.6.0-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.6.50-1.caps | 1 +
tests/qemucapabilitiesdata/caps_2.1.1-1.caps | 1 +
tests/qemuhelptest.c | 18 ++++++++++++------
11 files changed, 40 insertions(+), 12 deletions(-)
--
2.4.3
9 years, 3 months
[libvirt] [PATCH 0/4] Resolve a few NFS root-squash related issues
by John Ferlan
The following series of patches resolve a few issues found within
and because of an NFS root-squash environment.
Patch 1: No real change - mostly to get data on which path was failing
Patch 2: Create a virFileUnlink() API which will essentially follow the
code that virFileCreateAs[Forked] and virDirCreate[NoFork] have taken
with respect to running the 'unlink' in a fork'd process under the uid/gid
used to create the volume.
Patch 3: Commit id '7c2d65dde2' used the default mode to create a file
when "vol->target.perms->mode" was set rather than checking it against
-1 in virStorageBackendCreateRaw when calling virFileOpenAs. The logic
was change to follow other changes which check "->mode == -1", then use
default, else use "->mode" value.
Patch 4: Commit id '155ca616' added a check and call to a storage driver
'refreshVol' API. Unfortunately if it failed, proper cleanup wasn't done
leaving 'voldef' set and already in the pool list. The cleanup path would
then delete the memory eventually leading to a crash or corruption for an
ensuing refresh or list pool. For an NFS root squash environment with
incorrect XML to create the file (either wrong uid/gid or mode value),
the refreshVol would fail since it tried to run as root. On such a failure,
it was possible that the volume remained in the NFS pool when it should
have been deleted (unless root could delete the file).
The last 3 patches are very much so related and intertwined. Fortunately
it's a very limited environment.
John Ferlan (4):
virfile: Add error for root squash change mode failure
virfile: Introduce virFileUnlink
storage: Correct the 'mode' check
storage: Handle failure from refreshVol
src/libvirt_private.syms | 1 +
src/storage/storage_backend.c | 8 +--
src/storage/storage_backend_fs.c | 3 +-
src/storage/storage_driver.c | 6 ++-
src/util/virfile.c | 113 ++++++++++++++++++++++++++++++++++++++-
src/util/virfile.h | 1 +
6 files changed, 126 insertions(+), 6 deletions(-)
--
2.1.0
9 years, 3 months
[libvirt] [PATCH] lxc: fuse mount for /proc/cpuinfo
by Cédric Bosdonnat
We already have a fuse mount to reflect the cgroup memory restrictions
in the container. This commit adds the same for the number of available
CPUs. Only the CPUs listed by virProcessGetAffinity are shown in the
container's cpuinfo.
---
src/lxc/lxc_container.c | 42 ++++++++++++-------
src/lxc/lxc_fuse.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 136 insertions(+), 15 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index a433552..7ae13a8 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -1055,24 +1055,38 @@ static int lxcContainerMountProcFuse(virDomainDefPtr def,
const char *stateDir)
{
int ret;
- char *meminfo_path = NULL;
+ char *src_path = NULL;
+ char *dst_path = NULL;
+ const char *paths[] = {"meminfo", "cpuinfo"};
+ size_t i;
- VIR_DEBUG("Mount /proc/meminfo stateDir=%s", stateDir);
+ for (i = 0; i < 2; i++) {
+ VIR_DEBUG("Mount /proc/%s stateDir=%s", paths[i], stateDir);
+
+ if ((ret = virAsprintf(&src_path,
+ "/.oldroot/%s/%s.fuse/%s",
+ stateDir,
+ def->name,
+ paths[i])) < 0)
+ return ret;
+
+ if ((ret = virAsprintf(&dst_path,
+ "/proc/%s",
+ paths[i])) < 0) {
+ VIR_FREE(src_path);
+ return ret;
+ }
- if ((ret = virAsprintf(&meminfo_path,
- "/.oldroot/%s/%s.fuse/meminfo",
- stateDir,
- def->name)) < 0)
- return ret;
+ if ((ret = mount(src_path, dst_path,
+ NULL, MS_BIND, NULL)) < 0) {
+ virReportSystemError(errno,
+ _("Failed to mount %s on %s"),
+ src_path, dst_path);
+ }
- if ((ret = mount(meminfo_path, "/proc/meminfo",
- NULL, MS_BIND, NULL)) < 0) {
- virReportSystemError(errno,
- _("Failed to mount %s on /proc/meminfo"),
- meminfo_path);
+ VIR_FREE(src_path);
+ VIR_FREE(dst_path);
}
-
- VIR_FREE(meminfo_path);
return ret;
}
#else
diff --git a/src/lxc/lxc_fuse.c b/src/lxc/lxc_fuse.c
index 34a69cc..9c88147 100644
--- a/src/lxc/lxc_fuse.c
+++ b/src/lxc/lxc_fuse.c
@@ -42,6 +42,61 @@
#if WITH_FUSE
static const char *fuse_meminfo_path = "/meminfo";
+static const char *fuse_cpuinfo_path = "/cpuinfo";
+
+static virBufferPtr lxcProcComputeCpuinfo() {
+ FILE *fd = NULL;
+ char *line = NULL;
+ size_t n;
+ bool writeProc = false;
+ virBuffer buffer = VIR_BUFFER_INITIALIZER;
+ virBufferPtr new_cpuinfo = &buffer;
+ pid_t pid;
+ virBitmapPtr cpuAffinity = NULL;
+
+ fd = fopen("/proc/cpuinfo", "r");
+ if (fd == NULL) {
+ virReportSystemError(errno, _("%s"), "Cannot open /proc/cpuinfo");
+ goto error;
+ }
+
+ pid = getpid();
+ if (!(cpuAffinity = virProcessGetAffinity(pid)))
+ goto error;
+
+ while (getline(&line, &n, fd) > 0) {
+ if (STRPREFIX(line, "processor\t:")) {
+ unsigned long cpuid = 0;
+ char *suffix = NULL;
+ if (virStrToLong_ul(line + 12, &suffix, 10, &cpuid) < 0) {
+ goto error;
+ }
+
+ if (virBitmapGetBit(cpuAffinity, cpuid, &writeProc) < 0) {
+ goto error;
+ }
+ }
+
+ if (writeProc) {
+ virBufferAdd(new_cpuinfo, line, -1);
+
+ if (virBufferCheckError(new_cpuinfo) < 0) {
+ goto error;
+ }
+ }
+ }
+
+ cleanup:
+ VIR_FREE(line);
+ VIR_FORCE_FCLOSE(fd);
+ virBitmapFree(cpuAffinity);
+ return new_cpuinfo;
+
+ error:
+ virBufferFreeAndReset(new_cpuinfo);
+ new_cpuinfo = NULL;
+ goto cleanup;
+}
static int lxcProcGetattr(const char *path, struct stat *stbuf)
{
@@ -50,6 +105,7 @@ static int lxcProcGetattr(const char *path, struct stat *stbuf)
struct stat sb;
struct fuse_context *context = fuse_get_context();
virDomainDefPtr def = (virDomainDefPtr)context->private_data;
+ virBufferPtr cpuinfo = NULL;
memset(stbuf, 0, sizeof(struct stat));
if (virAsprintf(&mempath, "/proc/%s", path) < 0)
@@ -76,12 +132,36 @@ static int lxcProcGetattr(const char *path, struct stat *stbuf)
stbuf->st_atime = sb.st_atime;
stbuf->st_ctime = sb.st_ctime;
stbuf->st_mtime = sb.st_mtime;
+ } else if (STREQ(path, fuse_cpuinfo_path)) {
+ if (!(cpuinfo = lxcProcComputeCpuinfo())) {
+ res = -EIO;
+ goto cleanup;
+ }
+
+ if (stat(mempath, &sb) < 0) {
+ res = -errno;
+ goto cleanup;
+ }
+
+ stbuf->st_uid = def->idmap.uidmap ? def->idmap.uidmap[0].target : 0;
+ stbuf->st_gid = def->idmap.gidmap ? def->idmap.gidmap[0].target : 0;
+ stbuf->st_mode = sb.st_mode;
+ stbuf->st_nlink = 1;
+ stbuf->st_blksize = sb.st_blksize;
+ stbuf->st_size = virBufferUse(cpuinfo);
+ stbuf->st_blocks = stbuf->st_size / 512;
+ if (stbuf->st_size % 512 != 0)
+ stbuf->st_blocks++;
+ stbuf->st_atime = sb.st_atime;
+ stbuf->st_ctime = sb.st_ctime;
+ stbuf->st_mtime = sb.st_mtime;
} else {
res = -ENOENT;
}
cleanup:
VIR_FREE(mempath);
+ virBufferFreeAndReset(cpuinfo);
return res;
}
@@ -96,6 +176,7 @@ static int lxcProcReaddir(const char *path, void *buf,
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
filler(buf, fuse_meminfo_path + 1, NULL, 0);
+ filler(buf, fuse_cpuinfo_path + 1, NULL, 0);
return 0;
}
@@ -103,7 +184,8 @@ static int lxcProcReaddir(const char *path, void *buf,
static int lxcProcOpen(const char *path ATTRIBUTE_UNUSED,
struct fuse_file_info *fi ATTRIBUTE_UNUSED)
{
- if (!STREQ(path, fuse_meminfo_path))
+ if (!STREQ(path, fuse_meminfo_path) &&
+ !STREQ(path, fuse_cpuinfo_path))
return -ENOENT;
if ((fi->flags & 3) != O_RDONLY)
@@ -234,6 +316,28 @@ static int lxcProcReadMeminfo(char *hostpath, virDomainDefPtr def,
return res;
}
+static int lxcProcReadCpuinfo(char *buf, size_t size, off_t offset)
+{
+ virBufferPtr new_cpuinfo = lxcProcComputeCpuinfo();
+ int new_size = -1;
+ int copied = -1;
+
+ if (!new_cpuinfo)
+ goto error;
+
+ copied = size;
+ new_size = virBufferUse(new_cpuinfo);
+
+ if ((new_size - offset) < size)
+ copied = new_size - offset;
+
+ memcpy(buf, virBufferCurrentContent(new_cpuinfo) + offset, copied);
+
+ error:
+ virBufferFreeAndReset(new_cpuinfo);
+ return copied;
+}
+
static int lxcProcRead(const char *path ATTRIBUTE_UNUSED,
char *buf ATTRIBUTE_UNUSED,
size_t size ATTRIBUTE_UNUSED,
@@ -254,6 +358,9 @@ static int lxcProcRead(const char *path ATTRIBUTE_UNUSED,
if (STREQ(path, fuse_meminfo_path)) {
if ((res = lxcProcReadMeminfo(hostpath, def, buf, size, offset)) < 0)
res = lxcProcHostRead(hostpath, buf, size, offset);
+ } else if (STREQ(path, fuse_cpuinfo_path)) {
+ if ((res = lxcProcReadCpuinfo(buf, size, offset)) < 0)
+ res = lxcProcHostRead(hostpath, buf, size, offset);
}
VIR_FREE(hostpath);
--
2.1.4
9 years, 3 months
[libvirt] [PATCH] qemu: Need to check for machine.os when using ADDRESS_TYPE_CCW
by John Ferlan
https://bugzilla.redhat.com/show_bug.cgi?id=1258361
When attaching a disk or rng when providing an address type ccw, we need
to ensure the machine.os is valid for the target guest. Checks are made
when the address type is not provided, but if provided the os.machine
check is bypassed.
For an inactive guest, an addition followed by a start would cause the
startup to fail after qemu_command builds the command line and attempts
to start the guest. For an active guest, libvirtd would crash.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
NOTE:
For 'rng' in qemu_command - rather than change each of the if..else if..
conditions to have the {}, I just made the check up front.
Also while I could separate these into disk and rng - since it's the same
fix for the same problem it just seem "proper" to include both in same patch
src/qemu/qemu_command.c | 15 +++++++++++++++
src/qemu/qemu_hotplug.c | 21 ++++++++++++++++++---
2 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index abc57d7..ecdec2c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4296,6 +4296,13 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
case VIR_DOMAIN_DISK_BUS_VIRTIO:
if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
+ if (!STREQLEN(def->os.machine, "s390-ccw", 8)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("cannot use CCW address type for disk target "
+ "'%s' using machine type '%s'"),
+ disk->dst, def->os.machine);
+ goto error;
+ }
virBufferAddLit(&opt, "virtio-blk-ccw");
if (disk->iothread)
virBufferAsprintf(&opt, ",iothread=iothread%u", disk->iothread);
@@ -6874,6 +6881,14 @@ qemuBuildRNGDevStr(virDomainDefPtr def,
goto error;
}
+ if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
+ !STREQLEN(def->os.machine, "s390-ccw", 8)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("cannot use CCW address type for rng device "
+ "using machine type '%s'"),
+ def->os.machine);
+ goto error;
+ }
if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
virBufferAsprintf(&buf, "virtio-rng-ccw,rng=obj%s,id=%s",
dev->info.alias, dev->info.alias);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index e71a204..154539c 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -319,6 +319,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
int ret = -1;
const char* type = virDomainDiskBusTypeToString(disk->bus);
qemuDomainObjPrivatePtr priv = vm->privateData;
+ bool is_s390_ccw = STREQLEN(vm->def->os.machine, "s390-ccw", 8);
char *devstr = NULL;
char *drivestr = NULL;
bool releaseaddr = false;
@@ -326,8 +327,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
const char *src = virDomainDiskGetSource(disk);
if (!disk->info.type) {
- if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
- virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW))
+ if (is_s390_ccw && virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW))
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390))
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390;
@@ -346,6 +346,13 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
+ if (!is_s390_ccw) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("cannot use CCW address type for disk target "
+ "'%s' using machine type '%s'"),
+ disk->dst, vm->def->os.machine);
+ return -1;
+ }
if (virDomainCCWAddressAssign(&disk->info, priv->ccwaddrs,
!disk->info.addr.ccw.assigned) < 0)
goto error;
@@ -1642,6 +1649,7 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
virDomainRNGDefPtr rng)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
+ bool is_s390_ccw = STRPREFIX(vm->def->os.machine, "s390-ccw");
char *devstr = NULL;
char *charAlias = NULL;
char *objAlias = NULL;
@@ -1657,7 +1665,7 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
return -1;
if (rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
- if (STRPREFIX(vm->def->os.machine, "s390-ccw") &&
+ if (is_s390_ccw &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
rng->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
} else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390)) {
@@ -1670,6 +1678,13 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, &rng->info) < 0)
return -1;
} else if (rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
+ if (!is_s390_ccw) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("cannot use CCW address type for rng device "
+ "using machine type '%s'"),
+ vm->def->os.machine);
+ return -1;
+ }
if (virDomainCCWAddressAssign(&rng->info, priv->ccwaddrs,
!rng->info.addr.ccw.assigned) < 0)
return -1;
--
2.1.0
9 years, 3 months
[libvirt] [PATCH] Close the source fd if the destination qemu exits during tunnelled migration
by Shivaprasad G Bhat
Tunnelled migration can hang if the destination qemu exits despite all the
ABI checks. This happens whenever the destination qemu exits before the
complete transfer. The savevm state checks at runtime can fail at
destination qemu and error out. The source qemu cant notice it as the
EPIPE is not propogated to qemu. The qemuMigrationIOFunc() notices
the stream being broken from virStreamSend() and it cleans up the stream alone.
The qemuMigrationWaitForCompletion() would never get to 100% transfer
completion. The qemuMigrationWaitForCompletion() never breaks out as well since
the ssh connection to destination is healthy, and the source qemu also thinks
the migration is ongoing as the Fd to which it transfers, is never
closed or broken. So, the migration will hang forever. Even Ctrl-C on the
virsh migrate wouldn't be honoured. Close the source side FD when there is
an error in the stream. That way, the source qemu updates itself and
qemuMigrationWaitForCompletion() notices the failure.
Close the FD for all kinds of errors to be sure. The error message is not
copied for EPIPE so that the destination error is copied instead later.
Note:
Reproducible with repeated migrations between Power hosts running in different
subcores-per-core modes.
Signed-off-by: Shivaprasad G Bhat <sbhat(a)linux.vnet.ibm.com>
---
src/qemu/qemu_migration.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index ff89ab5..4f9aced 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -4029,7 +4029,11 @@ static void qemuMigrationIOFunc(void *arg)
}
error:
- virCopyLastError(&data->err);
+ /* Let the source qemu know that the transfer can't continue anymore.
+ * Don't copy the error for EPIPE as destination has the actual error */
+ VIR_FORCE_CLOSE(data->sock);
+ if (!virLastErrorIsSystemErrno(EPIPE))
+ virCopyLastError(&data->err);
virResetLastError();
VIR_FREE(buffer);
}
9 years, 3 months
[libvirt] [PATCH v3 0/5] vz: add migration support
by nshirokovskiy@virtuozzo.com
NOTE that minimal command to migrate vz domain is like next:
virsh -c vz:///system migrate --direct 200 shiny0 --migrateuri vz+ssh://shiny0/system
--live --persistent --compressed
==Difference from v1:
1. Patch is quite different. First patchset implements migration thru managed
migration scheme. This one goes thru p2p scheme. I belive this is a better
approach. Vz migration is done via vz sdk and first patchset uses 5 phased
migration only to get a token from destination on prepare phase which is kind a
misuse. This patch just adds vz specific function to driver interface
to archive the same goal.
2. Offline migration is supported as there is no more dependency on current
flow of managed migration scheme.
==Difference from v2:
1. Implement thru direct migration instead of p2p. p2p is just managed
5-staged migration when managing is done on daemon side. Vz migration stages
are all hidden in vz sdk and thus it would be more consistent to use direct
scheme.
2. Use existing driver function for prepare migration phase to pass session
uuid from destination to source instead of new one. As vz migration is direct
one we will not use prepare phase function in a straight forward manner
anyway.
src/libvirt-domain.c | 3 +-
src/vz/vz_driver.c | 315 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/vz/vz_sdk.c | 86 ++++++++++++---
src/vz/vz_sdk.h | 6 +
src/vz/vz_utils.h | 4 +-
5 files changed, 398 insertions(+), 16 deletions(-)
9 years, 3 months
[libvirt] libvirtlight problem with Xen
by Eric
I'm trying to use virt-manager with Xen. My Dom0 is Debian 8. When I
create a DomU (Ubuntu Trusty) as a PV guest, the boot fails with an
error saying that libvirtlight failed to connect.
The opinion from the virt-manager list group is that the problem is
libvirt, not virt-manager.
I've googled around, and have seen old posts about this, but these seem
to claim that the problem has resolved.
Solution?
Thanks
Eric
9 years, 3 months