[libvirt] why not shutdown the src vm to avoid split-brain
by zhang bo
In func doPeer2PeerMigrate3(), in the "finish" step, it checks whether domainMigrateFinish3() returns NULL or not.
if it(ddomain) is NULL, it just restarts the guest on the source.
Please consider the scenario that the ddomain has already been running on the dest, but it fails to tell the source
this fact, and ddomain becomes NULL. If we then restart the guest on the source, there will be 2 same guests running
on both sides, and a SPLIT-BRAIN occurs.
It seems much better to stop them both , rather than leaving them both running. At least, when we found the ddomain
is NULL, we should probably check whether the problem is caused by keepAlive failure, if so, kill the guest on the source
rather than restarting it.
How do you think about that?
BTW, it says that: "The lock manager plugins should take care of safety in this scenario" in the comment,
with the commit 2593f9692df0f128b14cde811e18aa49c1cf3e06, I don't quite understand that:
1) If we migrate the guest with the flag VIR_MIGRATE_NON_SHARED_DISK, then nbd server may take care of the data
consistency, But before it starts the cpus on the dest, the nbd server is already stopped. So, at this moment, no
one takes care of this problem.
2) If we migrate the guest with a shared disk, then does it mean that the nfs or other shareing-disk schemas should
prevent split-brain by themselves?
9 years, 9 months
[libvirt] [PATCH 0/3] fsfreeze and fsthaw API testing
by Jincheng Miao
Added guest agent conf to domain xml in order to test API
fsfreeze and fsthaw.
Jincheng Miao (3):
add guest agent configuration to domain xml
Add domain fsfreeze and fsthaw API testing
Add fsfreeze fsthaw test case to linux_domain
cases/linux_domain.conf | 18 +++++
repos/domain/domain_fsfreeze.py | 76 ++++++++++++++++++++
repos/domain/domain_fsthaw.py | 49 +++++++++++++
.../domain/xmls/kvm_linux_guest_install_cdrom.xml | 4 +
repos/domain/xmls/kvm_linux_guest_install_net.xml | 20 +++--
5 files changed, 159 insertions(+), 8 deletions(-)
create mode 100644 repos/domain/domain_fsfreeze.py
create mode 100644 repos/domain/domain_fsthaw.py
9 years, 9 months
[libvirt] Tunnelled post-copy live migration - support of bidirectional communication over the tunnel
by Vojtech Cima
Hello everyone,
we are very interested about the post-copy live migration mechanism in
libvirt [1] using QEMU. Mentioning post-copy in this context means the
setup with the first full iteration of standard pre-copy and then
switching to the post-copy. VIR_MIGRATE_ENABLE_POSTCOPY,
VIR_MIGRATE_POSTCOPY_AFTER_PRECOPY together with VIR_MIGRATE_TUNNELLED flag.
Recently we have noticed the issue that post-copy live migration doesn't
work over the tunnel since since current tunnel implementation in
libvirt supports only uni-directional communication. I spent some time
trying to enable bidirectional communication over the tunnel but still
facing several issues and I would appreciate any hints how to move forward.
The idea is to add a function (probably a callback function) responsible
for handling the traffic in the opposite direction (dest->src) reading
from the virStream and writing to the QEMU [2]. To be able to do so I
replaced the current 'pipe' calls with the 'socketpair' calls to create
bidirectional paths.
Now, trying to use tunnelled post-copy live migration, it gets
initiated, there is some traffic going from source to destination
(obviously the pre-copy phase) but at some point it gets stuck on the
'saferead' function [3] which is now blocking. Can this issue issue be
linked with the default socket blocking policy?
Trying to use standard 'read' function instead of 'saferead' results
that the lower data transfers and it seems it's missing significant part
of information.
Another point is that we suppose that the virStream on its own supports
bidirectional communication, is that correct?
[1] https://github.com/orbitfp7/qemu/tree/wp3-postcopy
[2]
http://libvirt.org/git/?p=libvirt.git;a=blob;f=src/qemu/qemu_migration.c;...
[3]
http://libvirt.org/git/?p=libvirt.git;a=blob;f=src/qemu/qemu_migration.c;...
Thank you very much for any ideas on this topic.
Regards,
Vojtech
9 years, 9 months
[libvirt] [PATCH v2] Comment out variables/functions that are unused.
by Gary R Hook
Avoids complaints when the compiler is configured to "warn-unused".
A few files contain unnecessary code that results in the compiler
erroring out when -Wunused* options are used. Comment out the code
until such time as it is needed.
Signed-off-by: Gary R Hook <gary.hook(a)nimboxx.com>
---
src/libxl/libxl_conf.c | 2 ++
tests/virnetsockettest.c | 8 ++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 0555b91..f8db4d2 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -305,7 +305,9 @@ libxlCapsInitGuests(libxl_ctx *ctx, virCapsPtr caps)
regmatch_t subs[4];
char *saveptr = NULL;
size_t i;
+/*
virArch hostarch = caps->host.arch;
+*/
struct guest_arch guest_archs[32];
int nr_guest_archs = 0;
diff --git a/tests/virnetsockettest.c b/tests/virnetsockettest.c
index 5d91f26..988ab43 100644
--- a/tests/virnetsockettest.c
+++ b/tests/virnetsockettest.c
@@ -333,9 +333,10 @@ static int testSocketUNIXAddrs(const void *data ATTRIBUTE_UNUSED)
return ret;
}
+/*
static int testSocketCommandNormal(const void *data ATTRIBUTE_UNUSED)
{
- virNetSocketPtr csock = NULL; /* Client socket */
+ virNetSocketPtr csock = NULL; / * Client socket * /
char buf[100];
size_t i;
int ret = -1;
@@ -360,10 +361,12 @@ static int testSocketCommandNormal(const void *data ATTRIBUTE_UNUSED)
virObjectUnref(csock);
return ret;
}
+*/
+/*
static int testSocketCommandFail(const void *data ATTRIBUTE_UNUSED)
{
- virNetSocketPtr csock = NULL; /* Client socket */
+ virNetSocketPtr csock = NULL; / * Client socket * /
char buf[100];
int ret = -1;
virCommandPtr cmd = virCommandNewArgList("/bin/cat", "/dev/does-not-exist", NULL);
@@ -383,6 +386,7 @@ static int testSocketCommandFail(const void *data ATTRIBUTE_UNUSED)
virObjectUnref(csock);
return ret;
}
+*/
struct testSSHData {
const char *nodename;
--
1.9.1
9 years, 9 months
[libvirt] [PATCH 0/2] Resolve a couple of Coverity issues
by John Ferlan
One new one and one that I've seen periodically.
John Ferlan (2):
security: Resolve Coverity RESOURCE_LEAK
libxl: Resolve Coverity CHECKED_RETURN
src/libxl/libxl_domain.c | 6 +++++-
src/security/security_manager.c | 17 ++++++++++++-----
2 files changed, 17 insertions(+), 6 deletions(-)
--
2.1.0
9 years, 9 months
[libvirt] [PATCH v2 0/4] attach-interface: Learn net type='direct'
by Michal Privoznik
v2
Michal Privoznik (4):
libvirt_private.syms: Expose virDomainNetTypeFromString
virsh attach-interface: Use enum instead of arbitrary integers
virsh attach-interface: Use virDomainNetType{From,To}String()
virsh attach-interface: Allow macvtap hotplug
src/libvirt_private.syms | 1 +
tools/virsh-domain.c | 36 ++++++++++++++++++++++++++----------
tools/virsh.pod | 14 ++++++++------
3 files changed, 35 insertions(+), 16 deletions(-)
--
2.0.5
9 years, 9 months
[libvirt] [PATCH v3 1/2] security: introduce virSecurityManagerCheckAllLabel function
by Erik Skultety
We do have a check for valid per-domain security model, however we still
do permit an invalid security model for a domain's device (those which
are specified with <source> element).
This patch introduces a new function virSecurityManagerCheckAllLabel
which compares user specified security model against currently
registered security drivers. That being said, it also permits 'none'
being specified as a device security model.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1165485
---
src/libvirt_private.syms | 1 +
src/lxc/lxc_process.c | 3 ++
src/qemu/qemu_process.c | 6 +++
src/security/security_manager.c | 89 +++++++++++++++++++++++++++++++++++++++++
src/security/security_manager.h | 2 +
5 files changed, 101 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 645aef1..e98e813 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -955,6 +955,7 @@ virSecurityDriverLookup;
# security/security_manager.h
+virSecurityManagerCheckAllLabel;
virSecurityManagerClearSocketLabel;
virSecurityManagerGenLabel;
virSecurityManagerGetBaseLabel;
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 19ea7f3..52b7f41 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -1135,6 +1135,9 @@ int virLXCProcessStart(virConnectPtr conn,
vm->def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DEFAULT)
vm->def->seclabels[0]->type = VIR_DOMAIN_SECLABEL_NONE;
+ if (virSecurityManagerCheckAllLabel(driver->securityManager, vm->def) < 0)
+ goto cleanup;
+
if (virSecurityManagerGenLabel(driver->securityManager, vm->def) < 0) {
virDomainAuditSecurityLabel(vm, false);
goto cleanup;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 43a64a1..1d4e957 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4488,6 +4488,10 @@ int qemuProcessStart(virConnectPtr conn,
NULL) < 0)
goto cleanup;
+ VIR_DEBUG("Checking domain and device security labels");
+ if (virSecurityManagerCheckAllLabel(driver->securityManager, vm->def) < 0)
+ goto cleanup;
+
/* If you are using a SecurityDriver with dynamic labelling,
then generate a security label for isolation */
VIR_DEBUG("Generating domain security label (if required)");
@@ -5488,6 +5492,8 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
}
}
+ if (virSecurityManagerCheckAllLabel(driver->securityManager, vm->def) < 0)
+ goto error;
if (virSecurityManagerGenLabel(driver->securityManager, vm->def) < 0)
goto error;
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
index 302f54d..68ed85b 100644
--- a/src/security/security_manager.c
+++ b/src/security/security_manager.c
@@ -703,6 +703,95 @@ virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
}
+static int virSecurityManagerCheckSecurityModel(char *secmodel,
+ void *opaque)
+{
+ size_t i;
+ virSecurityManagerPtr mgr = opaque;
+ virSecurityManagerPtr *sec_managers = NULL;
+
+ if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL)
+ return -1;
+
+ if (STREQ_NULLABLE(secmodel, "none"))
+ return 0;
+
+ for (i = 0; sec_managers[i]; i++) {
+ if (STREQ_NULLABLE(secmodel,
+ sec_managers[i]->drv->name)) {
+ return 0;
+ }
+ }
+
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Unable to find security driver for model %s"),
+ secmodel);
+ return -1;
+}
+
+
+static int
+virSecurityManagerCheckSecurityDiskLabel(virDomainDiskDefPtr disk,
+ void *opaque)
+{
+ size_t i;
+
+ for (i = 0; i < disk->src->nseclabels; i++) {
+ if (virSecurityManagerCheckSecurityModel(disk->src->seclabels[i]->model,
+ opaque) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+virSecurityManagerCheckSecurityChardevLabel(virDomainChrDefPtr dev,
+ void *opaque)
+{
+ size_t i;
+
+ for (i = 0; i < dev->nseclabels; i++) {
+ if (virSecurityManagerCheckSecurityModel(dev->seclabels[i]->model,
+ opaque) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+virSecurityManagerCheckSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainChrDefPtr dev,
+ void *opaque)
+{
+ return virSecurityManagerCheckSecurityChardevLabel(dev, opaque);
+}
+
+
+int virSecurityManagerCheckAllLabel(virSecurityManagerPtr mgr,
+ virDomainDefPtr vm)
+{
+ size_t i;
+
+ for (i = 0; i < vm->ndisks; i++) {
+ if (virSecurityManagerCheckSecurityDiskLabel(vm->disks[i],
+ mgr) < 0)
+ return -1;
+ }
+
+ if (virDomainChrDefForeach(vm,
+ true,
+ virSecurityManagerCheckSecurityChardevCallback,
+ mgr) < 0)
+ return -1;
+
+ return 0;
+}
+
+
int
virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm,
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
index 156f882..13468db 100644
--- a/src/security/security_manager.h
+++ b/src/security/security_manager.h
@@ -111,6 +111,8 @@ int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
pid_t pid);
int virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
virDomainDefPtr sec);
+int virSecurityManagerCheckAllLabel(virSecurityManagerPtr mgr,
+ virDomainDefPtr sec);
int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr sec,
const char *stdin_path);
--
1.9.3
9 years, 9 months
[libvirt] QEMU capabilities vs machine types
by Michal Privoznik
Dear list,
I've ran into the following bug [1]. The problem is, even though we
check whether memory-backend-{ram,file} devices are supported, qemu
fails to start. As I see it, on one hand, qemu lies about supported
devices (when I imitated libvirt capabilities check by hand on the
command line). But on the other hand, libvirt is using '-M none' so even
if qemu is fixed, the domain would be unable to start anyway.
So I believe my question is, does anybody have a bright idea how to fix
this? I don't think we want to extend our capabilities from a list to a
matrix (where a machine type would select a list). Moreover, querying
and creating the matrix would take ages. But then again, machine type is
important. Maybe not so for -x86_64 but for -arm definitely! Or?
Michal
1: https://bugzilla.redhat.com/show_bug.cgi?id=1191567
9 years, 9 months
[libvirt] [PATCH v3] lxc: fix show the wrong xml when guest start failed
by Luyao Huang
https://bugzilla.redhat.com/show_bug.cgi?id=1176503
When guest start failed, libvirt will keep the current vm->def,
this will make a issue that we cannot get a right xml after guest
start failed. And don't call the stop/release hook to do some
other clean work.
Call virLXCProcessCleanup to help us clean the source and call
the hooks if start a vm failed
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
v2: use virLXCProcessCleanup to free the source and call the hook.
v3: rework the patch to suit the virLXCProcessStart code changed.
src/lxc/lxc_process.c | 76 ++++++++++++++++++++++-----------------------------
1 file changed, 32 insertions(+), 44 deletions(-)
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 01da344..1a6cfbb 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -1022,6 +1022,7 @@ int virLXCProcessStart(virConnectPtr conn,
virCgroupPtr selfcgroup;
int status;
char *pidfile = NULL;
+ bool need_stop = false;
if (virCgroupNewSelf(&selfcgroup) < 0)
return -1;
@@ -1259,6 +1260,7 @@ int virLXCProcessStart(virConnectPtr conn,
goto cleanup;
}
+ need_stop = true;
priv->stopReason = VIR_DOMAIN_EVENT_STOPPED_FAILED;
priv->wantReboot = false;
vm->def->id = vm->pid;
@@ -1272,20 +1274,20 @@ int virLXCProcessStart(virConnectPtr conn,
if (VIR_CLOSE(handshakefds[1]) < 0) {
virReportSystemError(errno, "%s", _("could not close handshake fd"));
- goto error;
+ goto cleanup;
}
if (virCommandHandshakeWait(cmd) < 0)
- goto error;
+ goto cleanup;
/* Write domain status to disk for the controller to
* read when it starts */
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
- goto error;
+ goto cleanup;
/* Allow the child to exec the controller */
if (virCommandHandshakeNotify(cmd) < 0)
- goto error;
+ goto cleanup;
if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
driver->inhibitCallback(true, driver->inhibitOpaque);
@@ -1298,7 +1300,7 @@ int virLXCProcessStart(virConnectPtr conn,
_("guest failed to start: %s"), out);
}
- goto error;
+ goto cleanup;
}
/* We know the cgroup must exist by this synchronization
@@ -1310,13 +1312,13 @@ int virLXCProcessStart(virConnectPtr conn,
vm->def->resource->partition :
NULL,
-1, &priv->cgroup) < 0)
- goto error;
+ goto cleanup;
if (!priv->cgroup) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("No valid cgroup for machine %s"),
vm->def->name);
- goto error;
+ goto cleanup;
}
/* And we can get the first monitor connection now too */
@@ -1329,17 +1331,17 @@ int virLXCProcessStart(virConnectPtr conn,
virReportError(VIR_ERR_INTERNAL_ERROR,
_("guest failed to start: %s"), ebuf);
}
- goto error;
+ goto cleanup;
}
if (autoDestroy &&
virCloseCallbacksSet(driver->closeCallbacks, vm,
conn, lxcProcessAutoDestroy) < 0)
- goto error;
+ goto cleanup;
if (virDomainObjSetDefTransient(caps, driver->xmlopt,
vm, false) < 0)
- goto error;
+ goto cleanup;
/* We don't need the temporary NIC names anymore, clear them */
virLXCProcessCleanInterfaces(vm->def);
@@ -1358,47 +1360,38 @@ int virLXCProcessStart(virConnectPtr conn,
* If the script raised an error abort the launch
*/
if (hookret < 0)
- goto error;
+ goto cleanup;
}
rc = 0;
cleanup:
- if (rc != 0 && !err)
- err = virSaveLastError();
- virCommandFree(cmd);
if (VIR_CLOSE(logfd) < 0) {
virReportSystemError(errno, "%s", _("could not close logfile"));
rc = -1;
}
- for (i = 0; i < nveths; i++) {
- if (rc != 0 && veths[i])
- ignore_value(virNetDevVethDelete(veths[i]));
- VIR_FREE(veths[i]);
- }
if (rc != 0) {
- if (vm->newDef) {
- virDomainDefFree(vm->newDef);
- vm->newDef = NULL;
- }
- if (priv->monitor) {
- virObjectUnref(priv->monitor);
- priv->monitor = NULL;
- }
- virDomainConfVMNWFilterTeardown(vm);
-
- virSecurityManagerRestoreAllLabel(driver->securityManager,
- vm->def, false);
- virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
- /* Clear out dynamically assigned labels */
- if (vm->def->nseclabels &&
- vm->def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
- VIR_FREE(vm->def->seclabels[0]->model);
- VIR_FREE(vm->def->seclabels[0]->label);
- VIR_FREE(vm->def->seclabels[0]->imagelabel);
- VIR_DELETE_ELEMENT(vm->def->seclabels, 0, vm->def->nseclabels);
+ err = virSaveLastError();
+ if (need_stop) {
+ virLXCProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED);
+ } else {
+ virSecurityManagerRestoreAllLabel(driver->securityManager,
+ vm->def, false);
+ virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
+ /* Clear out dynamically assigned labels */
+ if (vm->def->nseclabels &&
+ vm->def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
+ VIR_FREE(vm->def->seclabels[0]->model);
+ VIR_FREE(vm->def->seclabels[0]->label);
+ VIR_FREE(vm->def->seclabels[0]->imagelabel);
+ VIR_DELETE_ELEMENT(vm->def->seclabels, 0, vm->def->nseclabels);
+ }
+ virLXCProcessCleanup(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED);
}
}
+ virCommandFree(cmd);
+ for (i = 0; i < nveths; i++)
+ VIR_FREE(veths[i]);
for (i = 0; i < nttyFDs; i++)
VIR_FORCE_CLOSE(ttyFDs[i]);
VIR_FREE(ttyFDs);
@@ -1415,11 +1408,6 @@ int virLXCProcessStart(virConnectPtr conn,
}
return rc;
-
- error:
- err = virSaveLastError();
- virLXCProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED);
- goto cleanup;
}
struct virLXCProcessAutostartData {
--
1.8.3.1
9 years, 9 months