[libvirt] [PATCH] Remove redundant lines in src/qemu/qemu_driver.c
by Tang Chen
maxcpu and hostcpus are defined and calculated in qemudDomainPinVcpuFlags()
and qemudDomainPinEmulator(), but never used. So remove them including nodeinfo.
Signed-off-by: Tang Chen <tangchen(a)cn.fujitsu.com>
---
src/qemu/qemu_driver.c | 18 ------------------
1 file changed, 18 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 12ac15c..ce0f51d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3712,8 +3712,6 @@ qemudDomainPinVcpuFlags(virDomainPtr dom,
virDomainDefPtr persistentDef = NULL;
virCgroupPtr cgroup_dom = NULL;
virCgroupPtr cgroup_vcpu = NULL;
- int maxcpu, hostcpus;
- virNodeInfo nodeinfo;
int ret = -1;
qemuDomainObjPrivatePtr priv;
bool doReset = false;
@@ -3749,13 +3747,6 @@ qemudDomainPinVcpuFlags(virDomainPtr dom,
goto cleanup;
}
- if (nodeGetInfo(dom->conn, &nodeinfo) < 0)
- goto cleanup;
- hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo);
- maxcpu = maplen * 8;
- if (maxcpu > hostcpus)
- maxcpu = hostcpus;
-
pcpumap = virBitmapNewData(cpumap, maplen);
if (!pcpumap)
goto cleanup;
@@ -3995,8 +3986,6 @@ qemudDomainPinEmulator(virDomainPtr dom,
virCgroupPtr cgroup_emulator = NULL;
pid_t pid;
virDomainDefPtr persistentDef = NULL;
- int maxcpu, hostcpus;
- virNodeInfo nodeinfo;
int ret = -1;
qemuDomainObjPrivatePtr priv;
bool doReset = false;
@@ -4025,13 +4014,6 @@ qemudDomainPinEmulator(virDomainPtr dom,
priv = vm->privateData;
- if (nodeGetInfo(dom->conn, &nodeinfo) < 0)
- goto cleanup;
- hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo);
- maxcpu = maplen * 8;
- if (maxcpu > hostcpus)
- maxcpu = hostcpus;
-
pcpumap = virBitmapNewData(cpumap, maplen);
if (!pcpumap)
goto cleanup;
--
1.7.10.1
12 years, 2 months
[libvirt] [PATCH v2] Add a test suite for validating SELinux labelling
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
There are many aspects of the guest XML which result in the
SELinux driver applying file labelling. With the increasing
configuration options it is desirable to test this behaviour.
It is not possible to assume that the test suite has the
ability to set SELinux labels. Most filesystems though will
support extended attributes. Thus for the purpose of testing,
it is possible to extend the existing LD_PRELOAD hack to
override setfilecon() and getfilecon() to simply use the
'user.libvirt.selinux' attribute for the sake of testing.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
Changed in v2:
- Remove stray debug line
- Uncomment VIR_FREE directive
- Add test for turning chardev relabelling on/off
that Rich just added support for
- Opencode the configure.ac check for libattr
---
.gitignore | 1 +
configure.ac | 52 +++++
libvirt.spec.in | 1 +
tests/Makefile.am | 20 +-
tests/securityselinuxhelper.c | 33 +++
tests/securityselinuxlabeldata/chardev.txt | 7 +
tests/securityselinuxlabeldata/chardev.xml | 47 ++++
tests/securityselinuxlabeldata/disks.txt | 5 +
tests/securityselinuxlabeldata/disks.xml | 52 +++++
tests/securityselinuxlabeldata/kernel.txt | 2 +
tests/securityselinuxlabeldata/kernel.xml | 20 ++
tests/securityselinuxlabeltest.c | 340 +++++++++++++++++++++++++++++
12 files changed, 577 insertions(+), 3 deletions(-)
create mode 100644 tests/securityselinuxlabeldata/chardev.txt
create mode 100644 tests/securityselinuxlabeldata/chardev.xml
create mode 100644 tests/securityselinuxlabeldata/disks.txt
create mode 100644 tests/securityselinuxlabeldata/disks.xml
create mode 100644 tests/securityselinuxlabeldata/kernel.txt
create mode 100644 tests/securityselinuxlabeldata/kernel.xml
create mode 100644 tests/securityselinuxlabeltest.c
diff --git a/.gitignore b/.gitignore
index 1cd2d45..58a8f34 100644
--- a/.gitignore
+++ b/.gitignore
@@ -150,6 +150,7 @@
/tests/secaatest
/tests/seclabeltest
/tests/securityselinuxtest
+/tests/securityselinuxlabeltest
/tests/sexpr2xmltest
/tests/shunloadtest
/tests/sockettest
diff --git a/configure.ac b/configure.ac
index 3e90672..2bb52ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1398,6 +1398,53 @@ AM_CONDITIONAL([HAVE_AUDIT], [test "$with_audit" = "yes"])
AC_SUBST([AUDIT_CFLAGS])
AC_SUBST([AUDIT_LIBS])
+
+
+dnl Libattr library
+AC_ARG_WITH([libattr],
+ AC_HELP_STRING([--with-libattr], [use libattr library @<:@default=check@:>@]),
+ [],
+ [with_libattr=check])
+
+LIBATTR_CFLAGS=
+LIBATTR_LIBS=
+if test "$with_libattr" != "no" ; then
+ old_cflags="$CFLAGS"
+ old_libs="$LIBS"
+ if test "$with_libattr" != "check" && test "$with_libattr" != "yes" ; then
+ LIBATTR_CFLAGS="-I$with_libattr/include"
+ LIBATTR_LIBS="-L$with_libattr/lib"
+ fi
+ CFLAGS="$CFLAGS $LIBATTR_CFLAGS"
+ LIBS="$LIBS $LIBATTR_LIBS"
+ fail=0
+ AC_CHECK_HEADER([attr/xattr.h], [], [fail=1])
+ AC_CHECK_LIB([attr], [getxattr], [], [fail=1])
+
+ if test $fail = 1 ; then
+ if test "$with_libattr" = "yes" ; then
+ AC_MSG_ERROR([You must install the Libattr library in order to compile and run libvirt])
+ else
+ with_libattr=no
+ LIBATTR_CFLAGS=
+ LIBATTR_LIBS=
+ fi
+ else
+ with_libattr=yes
+ fi
+
+ if test "$with_libattr" = "yes" ; then
+ LIBATTR_LIBS="$LIBATTR_LIBS -lattr"
+ AC_DEFINE_UNQUOTED([WITH_LIBATTR], 1, [whether liblibattr is available])
+ fi
+
+ CFLAGS="$old_cflags"
+ LIBS="$old_libs"
+fi
+AM_CONDITIONAL([WITH_LIBATTR], [test "$with_libattr" = "yes"])
+AC_SUBST([LIBATTR_CFLAGS])
+AC_SUBST([LIBATTR_LIBS])
+
dnl UUCP style file locks for PTY consoles
if test "$with_console_lock_files" != "no"; then
case $with_console_lock_files in
@@ -3133,6 +3180,11 @@ AC_MSG_NOTICE([ audit: $AUDIT_CFLAGS $AUDIT_LIBS])
else
AC_MSG_NOTICE([ audit: no])
fi
+if test "$with_libattr" = "yes" ; then
+AC_MSG_NOTICE([ libattr: $LIBATTR_CFLAGS $LIBATTR_LIBS])
+else
+AC_MSG_NOTICE([ libattr: no])
+fi
if test "$with_selinux" = "yes" ; then
AC_MSG_NOTICE([ selinux: $SELINUX_CFLAGS $SELINUX_LIBS])
else
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 1192739..dc5347c 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -385,6 +385,7 @@ BuildRequires: ncurses-devel
BuildRequires: gettext
BuildRequires: libtasn1-devel
BuildRequires: gnutls-devel
+BuildRequires: libattr-devel
%if 0%{?fedora} >= 12 || 0%{?rhel} >= 6
# for augparse, optionally used in testing
BuildRequires: augeas
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8dbad97..d715291 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -68,6 +68,7 @@ EXTRA_DIST = \
qemuxml2argvdata \
qemuxml2xmloutdata \
qemuxmlnsdata \
+ securityselinuxlabeldata \
schematestutils.sh \
sexpr2xmldata \
storagepoolschematest \
@@ -97,6 +98,9 @@ test_programs = virshtest sockettest \
if WITH_SECDRIVER_SELINUX
test_programs += securityselinuxtest
+if WITH_LIBATTR
+test_programs += securityselinuxlabeltest
+endif
endif
if WITH_DRIVER_MODULES
@@ -573,10 +577,20 @@ securityselinuxtest_SOURCES = \
securityselinuxtest.c testutils.h testutils.c
securityselinuxtest_CFLAGS = -Dabs_builddir="\"$(abs_builddir)\"" $(AM_CFLAGS)
securityselinuxtest_LDADD = $(LDADDS)
-securityselinuxtest_DEPENDENCIES = libsecurityselinuxhelper.la
-else
-EXTRA_DIST += securityselinuxtest.c securityselinuxhelper.c
+securityselinuxtest_DEPENDENCIES = libsecurityselinuxhelper.la ../src/libvirt.la
+
+if WITH_QEMU
+if WITH_LIBATTR
+securityselinuxlabeltest_SOURCES = \
+ securityselinuxlabeltest.c testutils.h testutils.c \
+ testutilsqemu.h testutilsqemu.c
+securityselinuxlabeltest_CFLAGS = -Dabs_builddir="\"$(abs_builddir)\"" $(AM_CFLAGS)
+securityselinuxlabeltest_LDADD = $(qemu_LDADDS)
+securityselinuxlabeltest_DEPENDENCIES = libsecurityselinuxhelper.la ../src/libvirt.la
+endif
+endif
endif
+EXTRA_DIST += securityselinuxtest.c securityselinuxlabeltest.c securityselinuxhelper.c
virbuftest_SOURCES = \
virbuftest.c testutils.h testutils.c
diff --git a/tests/securityselinuxhelper.c b/tests/securityselinuxhelper.c
index 43676de..d4e50ba 100644
--- a/tests/securityselinuxhelper.c
+++ b/tests/securityselinuxhelper.c
@@ -24,6 +24,9 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
+#include <attr/xattr.h>
+
+
/*
* The kernel policy will not allow us to arbitrarily change
* test process context. This helper is used as an LD_PRELOAD
@@ -64,3 +67,33 @@ int setcon(security_context_t context)
{
return setenv("FAKE_CONTEXT", context, 1);
}
+
+
+#if WITH_LIBATTR
+int setfilecon(const char *path, security_context_t con)
+{
+ const char *constr = con;
+ return setxattr(path, "user.libvirt.selinux",
+ constr, strlen(constr), 0);
+}
+
+
+int getfilecon(const char *path, security_context_t *con)
+{
+ char *constr = NULL;
+ ssize_t len = getxattr(path, "user.libvirt.selinux",
+ NULL, 0);
+ if (len < 0)
+ return -1;
+ if (!(constr = malloc(len+1)))
+ return -1;
+ memset(constr, 0, len);
+ if (getxattr(path, "user.libvirt.selinux", constr, len) < 0) {
+ free(constr);
+ return -1;
+ }
+ *con = constr;
+ constr[len] = '\0';
+ return 0;
+}
+#endif
diff --git a/tests/securityselinuxlabeldata/chardev.txt b/tests/securityselinuxlabeldata/chardev.txt
new file mode 100644
index 0000000..3f4b630
--- /dev/null
+++ b/tests/securityselinuxlabeldata/chardev.txt
@@ -0,0 +1,7 @@
+/plain.txt;system_u:object_r:svirt_image_t:s0:c41,c264
+/plain.dev;system_u:object_r:svirt_image_t:s0:c41,c264
+/plain.fifo;system_u:object_r:svirt_image_t:s0:c41,c264
+/nolabel.sock;
+/plain.sock;
+/yeslabel.sock;system_u:object_r:svirt_image_t:s0:c41,c264
+/altlabel.sock;system_u:object_r:svirt_image_custom_t:s0:c41,c264
diff --git a/tests/securityselinuxlabeldata/chardev.xml b/tests/securityselinuxlabeldata/chardev.xml
new file mode 100644
index 0000000..64b6b5f
--- /dev/null
+++ b/tests/securityselinuxlabeldata/chardev.xml
@@ -0,0 +1,47 @@
+<domain type='kvm'>
+ <name>vm1</name>
+ <uuid>c7b3edbd-edaf-9455-926a-d65c16db1800</uuid>
+ <memory unit='KiB'>219200</memory>
+ <os>
+ <type arch='i686' machine='pc-1.0'>hvm</type>
+ <boot dev='cdrom'/>
+ </os>
+ <devices>
+ <serial type='file'>
+ <source path='/plain.txt'/>
+ </serial>
+ <serial type='pipe'>
+ <source path='/plain.fifo'/>
+ </serial>
+ <serial type='dev'>
+ <source path='/plain.dev'/>
+ </serial>
+ <serial type='unix'>
+ <source mode='bind' path='/plain.sock'/>
+ </serial>
+ <serial type='unix'>
+ <source mode='connect' path='/nolabel.sock'>
+ <seclabel relabel='no' model='selinux'/>
+ </source>
+ </serial>
+ <serial type='unix'>
+ <source mode='connect' path='/yeslabel.sock'>
+ </source>
+ </serial>
+ <serial type='unix'>
+ <source mode='connect' path='/altlabel.sock'>
+ <seclabel relabel='yes' model='selinux'>
+ <label>system_u:object_r:svirt_image_custom_t:s0:c41,c264</label>
+ </seclabel>
+ </source>
+ </serial>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>
+ <listen type='address' address='0.0.0.0'/>
+ </graphics>
+ </devices>
+ <seclabel model="selinux" type="dynamic" relabel="yes">
+ <label>system_u:system_r:svirt_t:s0:c41,c264</label>
+ <imagelabel>system_u:object_r:svirt_image_t:s0:c41,c264</imagelabel>
+ </seclabel>
+</domain>
diff --git a/tests/securityselinuxlabeldata/disks.txt b/tests/securityselinuxlabeldata/disks.txt
new file mode 100644
index 0000000..2573d99
--- /dev/null
+++ b/tests/securityselinuxlabeldata/disks.txt
@@ -0,0 +1,5 @@
+/plain.raw;system_u:object_r:svirt_image_t:s0:c41,c264
+/shared.raw;system_u:object_r:svirt_image_t:s0
+/readonly.raw;system_u:object_r:virt_content_t:s0
+/nolabel.raw;
+/altlabel.raw;system_u:object_r:svirt_image_custom_t:s0:c41,c264
diff --git a/tests/securityselinuxlabeldata/disks.xml b/tests/securityselinuxlabeldata/disks.xml
new file mode 100644
index 0000000..33e8763
--- /dev/null
+++ b/tests/securityselinuxlabeldata/disks.xml
@@ -0,0 +1,52 @@
+<domain type='kvm'>
+ <name>vm1</name>
+ <uuid>c7b3edbd-edaf-9455-926a-d65c16db1800</uuid>
+ <memory unit='KiB'>219200</memory>
+ <os>
+ <type arch='i686' machine='pc-1.0'>hvm</type>
+ <boot dev='cdrom'/>
+ </os>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/plain.raw'/>
+ <target dev='vda' bus='virtio'/>
+ </disk>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/shared.raw'/>
+ <shareable/>
+ <target dev='vdb' bus='virtio'/>
+ </disk>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/readonly.raw'/>
+ <readonly/>
+ <target dev='vdc' bus='virtio'/>
+ </disk>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/nolabel.raw'>
+ <seclabel model='selinux' relabel='no'/>
+ </source>
+ <target dev='vdd' bus='virtio'/>
+ </disk>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/altlabel.raw'>
+ <seclabel model='selinux' relabel='yes'>
+ <label>system_u:object_r:svirt_image_custom_t:s0:c41,c264</label>
+ </seclabel>
+ </source>
+ <target dev='vde' bus='virtio'/>
+ </disk>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>
+ <listen type='address' address='0.0.0.0'/>
+ </graphics>
+ </devices>
+ <seclabel model="selinux" type="dynamic" relabel="yes">
+ <label>system_u:system_r:svirt_t:s0:c41,c264</label>
+ <imagelabel>system_u:object_r:svirt_image_t:s0:c41,c264</imagelabel>
+ </seclabel>
+</domain>
diff --git a/tests/securityselinuxlabeldata/kernel.txt b/tests/securityselinuxlabeldata/kernel.txt
new file mode 100644
index 0000000..87063fd
--- /dev/null
+++ b/tests/securityselinuxlabeldata/kernel.txt
@@ -0,0 +1,2 @@
+/vmlinuz.raw;system_u:object_r:virt_content_t:s0
+/initrd.raw;system_u:object_r:virt_content_t:s0
diff --git a/tests/securityselinuxlabeldata/kernel.xml b/tests/securityselinuxlabeldata/kernel.xml
new file mode 100644
index 0000000..0fd551d
--- /dev/null
+++ b/tests/securityselinuxlabeldata/kernel.xml
@@ -0,0 +1,20 @@
+<domain type='kvm'>
+ <name>vm1</name>
+ <uuid>c7b3edbd-edaf-9455-926a-d65c16db1800</uuid>
+ <memory unit='KiB'>219200</memory>
+ <os>
+ <type arch='i686' machine='pc-1.0'>hvm</type>
+ <kernel>/vmlinuz.raw</kernel>
+ <initrd>/initrd.raw</initrd>
+ </os>
+ <devices>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>
+ <listen type='address' address='0.0.0.0'/>
+ </graphics>
+ </devices>
+ <seclabel model="selinux" type="dynamic" relabel="yes">
+ <label>system_u:system_r:svirt_t:s0:c41,c264</label>
+ <imagelabel>system_u:object_r:svirt_image_t:s0:c41,c264</imagelabel>
+ </seclabel>
+</domain>
diff --git a/tests/securityselinuxlabeltest.c b/tests/securityselinuxlabeltest.c
new file mode 100644
index 0000000..f25c6bf
--- /dev/null
+++ b/tests/securityselinuxlabeltest.c
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2011-2012 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
+ * License along with this library; If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <selinux/selinux.h>
+#include <selinux/context.h>
+
+#include "internal.h"
+#include "testutils.h"
+#include "testutilsqemu.h"
+#include "qemu/qemu_domain.h"
+#include "memory.h"
+#include "virfile.h"
+#include "util.h"
+#include "logging.h"
+#include "virterror_internal.h"
+#include "security/security_manager.h"
+
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+static virCapsPtr caps;
+
+static virSecurityManagerPtr mgr;
+
+typedef struct testSELinuxFile testSELinuxFile;
+
+struct testSELinuxFile {
+ char *file;
+ char *context;
+};
+
+
+static int
+testSELinuxMungePath(char **path)
+{
+ char *tmp;
+
+ if (virAsprintf(&tmp, "%s/securityselinuxlabeldata%s",
+ abs_srcdir, *path) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ VIR_FREE(*path);
+ *path = tmp;
+ return 0;
+}
+
+static int
+testSELinuxLoadFileList(const char *testname,
+ testSELinuxFile **files,
+ size_t *nfiles)
+{
+ int ret = -1;
+ char *path = NULL;
+ FILE *fp = NULL;
+
+ *files = NULL;
+ *nfiles = 0;
+
+ if (virAsprintf(&path, "%s/securityselinuxlabeldata/%s.txt",
+ abs_srcdir, testname) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (!(fp = fopen(path, "r"))) {
+ goto cleanup;
+ }
+
+ while (!feof(fp)) {
+ char *line;
+ char *file, *context;
+ if (VIR_ALLOC_N(line, 1024) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ if (!fgets(line, 1024, fp)) {
+ if (!feof(fp))
+ goto cleanup;
+ break;
+ }
+
+ char *tmp = strchr(line, ';');
+ *tmp = '\0';
+ tmp++;
+
+ if (virAsprintf(&file, "%s/securityselinuxlabeldata%s", abs_builddir, line) < 0) {
+ VIR_FREE(line);
+ virReportOOMError();
+ goto cleanup;
+ }
+ if (*tmp != '\0' && *tmp != '\n') {
+ if (!(context = strdup(tmp))) {
+ VIR_FREE(line);
+ VIR_FREE(file);
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ tmp = strchr(context, '\n');
+ *tmp = '\0';
+ } else {
+ context = NULL;
+ }
+
+ if (VIR_EXPAND_N(*files, *nfiles, 1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ (*files)[(*nfiles)-1].file = file;
+ (*files)[(*nfiles)-1].context = context;
+ }
+
+ ret = 0;
+
+cleanup:
+ if (fp)
+ fclose(fp);
+ VIR_FREE(path);
+ return ret;
+}
+
+
+static virDomainDefPtr
+testSELinuxLoadDef(const char *testname)
+{
+ char *xmlfile = NULL;
+ char *xmlstr = NULL;
+ virDomainDefPtr def = NULL;
+ size_t i;
+
+ if (virAsprintf(&xmlfile, "%s/securityselinuxlabeldata/%s.xml",
+ abs_srcdir, testname) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (virFileReadAll(xmlfile, 1024*1024, &xmlstr) < 0) {
+ goto cleanup;
+ }
+
+ if (!(def = virDomainDefParseString(caps, xmlstr,
+ QEMU_EXPECTED_VIRT_TYPES,
+ 0)))
+ goto cleanup;
+
+ for (i = 0 ; i < def->ndisks ; i++) {
+ if (def->disks[i]->type != VIR_DOMAIN_DISK_TYPE_FILE &&
+ def->disks[i]->type != VIR_DOMAIN_DISK_TYPE_BLOCK)
+ continue;
+
+ if (testSELinuxMungePath(&def->disks[i]->src) < 0)
+ goto cleanup;
+ }
+
+ for (i = 0 ; i < def->nserials ; i++) {
+ if (def->serials[i]->source.type != VIR_DOMAIN_CHR_TYPE_FILE &&
+ def->serials[i]->source.type != VIR_DOMAIN_CHR_TYPE_PIPE &&
+ def->serials[i]->source.type != VIR_DOMAIN_CHR_TYPE_DEV &&
+ def->serials[i]->source.type != VIR_DOMAIN_CHR_TYPE_UNIX)
+ continue;
+
+ if (def->serials[i]->source.type == VIR_DOMAIN_CHR_TYPE_UNIX) {
+ if (testSELinuxMungePath(&def->serials[i]->source.data.nix.path) < 0)
+ goto cleanup;
+ } else {
+ if (testSELinuxMungePath(&def->serials[i]->source.data.file.path) < 0)
+ goto cleanup;
+ }
+ }
+
+ if (def->os.kernel &&
+ testSELinuxMungePath(&def->os.kernel) < 0)
+ goto cleanup;
+ if (def->os.initrd &&
+ testSELinuxMungePath(&def->os.initrd) < 0)
+ goto cleanup;
+
+cleanup:
+ VIR_FREE(xmlfile);
+ VIR_FREE(xmlstr);
+ return def;
+}
+
+
+static int
+testSELinuxCreateDisks(testSELinuxFile *files, size_t nfiles)
+{
+ size_t i;
+
+ if (virFileMakePath(abs_builddir "/securityselinuxlabeldata") < 0)
+ return -1;
+
+ for (i = 0 ; i < nfiles ; i++) {
+ if (virFileTouch(files[i].file, 0600) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static int
+testSELinuxDeleteDisks(testSELinuxFile *files, size_t nfiles)
+{
+ size_t i;
+
+ for (i = 0 ; i < nfiles ; i++) {
+ if (unlink(files[i].file) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static int
+testSELinuxCheckLabels(testSELinuxFile *files, size_t nfiles)
+{
+ size_t i;
+ security_context_t ctx;
+
+ for (i = 0 ; i < nfiles ; i++) {
+ if (getfilecon(files[i].file, &ctx) < 0) {
+ if (errno == ENODATA) {
+ ctx = NULL;
+ } else {
+ virReportSystemError(errno,
+ "Cannot read label on %s",
+ files[i].file);
+ return -1;
+ }
+ }
+ if (!STREQ_NULLABLE(files[i].context, ctx)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "File %s context '%s' did not match epected '%s'",
+ files[i].file, ctx, files[i].context);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
+testSELinuxLabeling(const void *opaque)
+{
+ const char *testname = opaque;
+ int ret = -1;
+ testSELinuxFile *files = NULL;
+ size_t nfiles = 0;
+ size_t i;
+ virDomainDefPtr def = NULL;
+
+ if (testSELinuxLoadFileList(testname, &files, &nfiles) < 0)
+ goto cleanup;
+
+ if (testSELinuxCreateDisks(files, nfiles) < 0)
+ goto cleanup;
+
+ if (!(def = testSELinuxLoadDef(testname)))
+ goto cleanup;
+
+ if (virSecurityManagerSetAllLabel(mgr, def, NULL) < 0)
+ goto cleanup;
+
+ if (testSELinuxCheckLabels(files, nfiles) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+cleanup:
+ if (testSELinuxDeleteDisks(files, nfiles) < 0)
+ goto cleanup;
+
+ virDomainDefFree(def);
+ for (i = 0 ; i < nfiles; i++) {
+ VIR_FREE(files[i].file);
+ VIR_FREE(files[i].context);
+ }
+ VIR_FREE(files);
+ return ret;
+}
+
+
+
+static int
+mymain(void)
+{
+ int ret = 0;
+
+ if (!(mgr = virSecurityManagerNew("selinux", "QEMU", false, true, false))) {
+ virErrorPtr err = virGetLastError();
+ if (err->code == VIR_ERR_CONFIG_UNSUPPORTED)
+ exit(EXIT_AM_SKIP);
+
+ fprintf(stderr, "Unable to initialize security driver: %s\n",
+ err->message);
+ exit(EXIT_FAILURE);
+ }
+
+ if ((caps = testQemuCapsInit()) == NULL)
+ exit(EXIT_FAILURE);
+
+#define DO_TEST_LABELING(name) \
+ if (virtTestRun("Labelling " # name, 1, testSELinuxLabeling, name) < 0) \
+ ret = -1; \
+
+ setcon((security_context_t)"system_r:system_u:libvirtd_t:s0:c0.c1023");
+
+ DO_TEST_LABELING("disks");
+ DO_TEST_LABELING("kernel");
+ DO_TEST_LABELING("chardev");
+
+ return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/libsecurityselinuxhelper.so")
--
1.7.11.4
12 years, 2 months
[libvirt] [PATCH 00/29] Add selinux test & refactor configure.ac
by Daniel P. Berrange
This is an expanded version of this series which added a new
SELinux test case
https://www.redhat.com/archives/libvir-list/2012-September/msg01381.html
The change here is to fix some bugs in the previous autoconf
macros, and dramatically expand their usage, removing ~700
lines of code from configure.ac
.gitignore | 1
configure.ac | 726 +----------------------------
daemon/Makefile.am | 2
daemon/libvirtd-config.c | 4
daemon/libvirtd.c | 4
daemon/libvirtd.h | 6
daemon/remote.c | 2
docs/hacking.html.in | 2
libvirt.spec.in | 1
m4/virt-apparmor.m4 | 19
m4/virt-audit.m4 | 9
m4/virt-avahi.m4 | 9
m4/virt-capng.m4 | 9
m4/virt-dbus.m4 | 19
m4/virt-hal.m4 | 9
m4/virt-lib.m4 | 273 ++++++++++
m4/virt-libattr.m4 | 9
m4/virt-libblkid.m4 | 9
m4/virt-netcf.m4 | 23
m4/virt-numactl.m4 | 9
m4/virt-pciaccess.m4 | 9
m4/virt-result.m4 | 9
m4/virt-sanlock.m4 | 9
m4/virt-sasl.m4 | 12
m4/virt-selinux.m4 | 33 +
m4/virt-udev.m4 | 15
m4/virt-yajl.m4 | 34 +
src/Makefile.am | 22
src/lxc/lxc_container.c | 14
src/lxc/lxc_controller.c | 8
src/node_device/node_device_driver.c | 8
src/node_device/node_device_driver.h | 4
src/nodeinfo.c | 10
src/nwfilter/nwfilter_driver.c | 4
src/qemu/qemu_capabilities.c | 2
src/qemu/qemu_driver.c | 4
src/qemu/qemu_process.c | 4
src/remote/remote_driver.c | 8
src/rpc/virnetclient.c | 10
src/rpc/virnetclient.h | 4
src/rpc/virnetserverclient.c | 12
src/rpc/virnetserverclient.h | 2
src/rpc/virnetservermdns.c | 12
src/rpc/virnetsocket.c | 16
src/rpc/virnetsocket.h | 4
src/storage/storage_backend.c | 6
src/storage/storage_backend_fs.c | 8
src/storage/storage_backend_scsi.c | 4
src/util/command.c | 4
src/util/json.c | 14
src/util/storage_file.c | 2
src/util/util.c | 2
src/util/viraudit.c | 14
src/util/virdbus.c | 6
src/util/virdbus.h | 2
tests/Makefile.am | 22
tests/libvirtdconftest.c | 2
tests/qemuhelptest.c | 2
tests/securityselinuxhelper.c | 33 +
tests/securityselinuxlabeldata/chardev.txt | 5
tests/securityselinuxlabeldata/chardev.xml | 34 +
tests/securityselinuxlabeldata/disks.txt | 5
tests/securityselinuxlabeldata/disks.xml | 52 ++
tests/securityselinuxlabeldata/kernel.txt | 2
tests/securityselinuxlabeldata/kernel.xml | 20
tests/securityselinuxlabeltest.c | 341 +++++++++++++
tools/Makefile.am | 4
67 files changed, 1184 insertions(+), 814 deletions(-)
12 years, 2 months
[libvirt] [PATCH] Don't use O_TRUNC when opening QEMU logfiles
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
SELinux wants all log files opened with O_APPEND. When
running non-root though, libvirtd likes to use O_TRUNC
to avoid log files growing in size indefinitely. Instead
of using O_TRUNC though, we can use O_APPEND and then
call ftruncate() which keeps SELinux happier.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/qemu/qemu_domain.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 0ae30b7..e67c247 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1446,12 +1446,22 @@ qemuDomainOpenLogHelper(struct qemud_driver *driver,
{
char *logfile;
int fd = -1;
+ bool trunc = false;
if (virAsprintf(&logfile, "%s/%s.log", driver->logDir, vm->def->name) < 0) {
virReportOOMError();
return -1;
}
+ /* To make SELinux happy we always need to open in append mode.
+ * So we fake O_TRUNC by calling ftruncate after open instead
+ */
+ if (oflags & O_TRUNC) {
+ oflags &= ~O_TRUNC;
+ oflags |= O_APPEND;
+ trunc = true;
+ }
+
if ((fd = open(logfile, oflags, mode)) < 0) {
virReportSystemError(errno, _("failed to create logfile %s"),
logfile);
@@ -1463,6 +1473,13 @@ qemuDomainOpenLogHelper(struct qemud_driver *driver,
VIR_FORCE_CLOSE(fd);
goto cleanup;
}
+ if (trunc &&
+ ftruncate(fd, 0) < 0) {
+ virReportSystemError(errno, _("failed to truncate %s"),
+ logfile);
+ VIR_FORCE_CLOSE(fd);
+ goto cleanup;
+ }
cleanup:
VIR_FREE(logfile);
--
1.7.11.2
12 years, 2 months
[libvirt] [PATCH v4 0/2] Add <seclabel> to character devices.
by Richard W.M. Jones
The updates compared to the previous version:
- All style issues fixed, except for a few long lines where it's just
not possible to split the lines and keep the code looking
reasonable.
- Added RNG.
- Fixed the potential segfault on the error path in
virSecurityDeviceLabelDefParseXML
- Simplified the changes to virSecurityDeviceLabelDefParseXML by using
local variables to store the returned values until just before we
return, when we assign them to the final '_rtn' parameters.
Rich.
12 years, 2 months
[libvirt] [PATCH] qemu: Fix failure path in disk hotplug
by Jiri Denemark
Disk hotplug is a two phase action: qemuMonitorAddDrive followed by
qemuMonitorAddDevice. When the first part succeeds but the second one
fails, we need to rollback the drive addition.
---
src/qemu/qemu_hotplug.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 7dc88ba..5934f77 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -250,14 +250,20 @@ int qemuDomainAttachPciDiskDevice(virConnectPtr conn,
if (qemuCapsGet(priv->caps, QEMU_CAPS_DEVICE)) {
ret = qemuMonitorAddDrive(priv->mon, drivestr);
if (ret == 0) {
ret = qemuMonitorAddDevice(priv->mon, devstr);
if (ret < 0) {
- VIR_WARN("qemuMonitorAddDevice failed on %s (%s)",
- drivestr, devstr);
- /* XXX should call 'drive_del' on error but this does not
- exist yet */
+ virErrorPtr orig_err = virSaveLastError();
+ if (qemuMonitorDriveDel(priv->mon, drivestr) < 0) {
+ VIR_WARN("Unable to remove drive %s (%s) after failed "
+ "qemuMonitorAddDevice",
+ drivestr, devstr);
+ }
+ if (orig_err) {
+ virSetError(orig_err);
+ virFreeError(orig_err);
+ }
}
}
} else {
virDevicePCIAddress guestAddr = disk->info.addr.pci;
ret = qemuMonitorAddPCIDisk(priv->mon,
--
1.7.12
12 years, 2 months
[libvirt] [PATCH] locking: Remove README file in favor of locking.html
by Jiri Denemark
The README file seems to be a leftover from some previous version of
locking driver. It is not consistent with what the code does nor is it
consistent with existing documentation in locking.html.
---
src/locking/README | 165 -----------------------------------------------------
1 file changed, 165 deletions(-)
delete mode 100644 src/locking/README
diff --git a/src/locking/README b/src/locking/README
deleted file mode 100644
index da2a8f8..0000000
--- a/src/locking/README
+++ /dev/null
@@ -1,165 +0,0 @@
- Using the Lock Manager APIs
- ===========================
-
-This file describes how to use the lock manager APIs.
-All the guest lifecycle sequences here have higher
-level wrappers provided by the 'domain_lock.h' API,
-which simplify thue usage
-
-At libvirtd startup:
-
- plugin = virLockManagerPluginLoad("sync-manager");
-
-
-At libvirtd shtudown:
-
- virLockManagerPluginUnload(plugin)
-
-
-At guest startup:
-
- manager = virLockManagerNew(plugin,
- VIR_LOCK_MANAGER_OBJECT_DOMAIN,
- 0);
-
- virLockManagerSetParameter(manager, "id", id);
- virLockManagerSetParameter(manager, "uuid", uuid);
- virLockManagerSetParameter(manager, "name", name);
-
- foreach disk
- virLockManagerRegisterResource(manager,
- VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
- disk.path,
- ..flags...);
-
- if (!virLockManagerAcquireObject(manager))
- abort..
-
- run QEMU
-
-
-At guest shutdown:
-
- ...send QEMU 'quit' monitor command, and/or kill(qemupid)...
-
- if (!virLockManagerShutdown(manager))
- kill(supervisorpid); /* XXX or leave it running ??? */
-
- virLockManagerFree(manager);
-
-
-
-At libvirtd restart with running guests:
-
- foreach still running guest
- manager = virLockManagerNew(driver,
- VIR_LOCK_MANAGER_START_DOMAIN,
- VIR_LOCK_MANAGER_NEW_ATTACH);
- virLockManagerSetParameter(manager, "id", id);
- virLockManagerSetParameter(manager, "uuid", uuid);
- virLockManagerSetParameter(manager, "name", name);
-
- if (!virLockManagerGetChild(manager, &qemupid))
- kill(supervisorpid); /* XXX or leave it running ??? */
-
-
-
-With disk hotplug:
-
- if (virLockManagerAcquireResource(manager,
- VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
- disk.path
- ..flags..))
- ...abort hotplug attempt ...
-
- ...hotplug the device...
-
-
-
-With disk unhotplug:
-
- ...hotunplug the device...
-
- if (virLockManagerReleaseResource(manager,
- VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
- disk.path
- ..flags..))
- ...log warning ...
-
-
-
-During migration:
-
- 1. On source host
-
- if (!virLockManagerPrepareMigrate(manager, hosturi))
- ..don't start migration..
-
- 2. On dest host
-
- manager = virLockManagerNew(driver,
- VIR_LOCK_MANAGER_START_DOMAIN,
- VIR_LOCK_MANAGER_NEW_MIGRATE);
- virLockManagerSetParameter(manager, "id", id);
- virLockManagerSetParameter(manager, "uuid", uuid);
- virLockManagerSetParameter(manager, "name", name);
-
- foreach disk
- virLockManagerRegisterResource(manager,
- VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
- disk.path,
- ..flags...);
-
- char **supervisorargv;
- int supervisorargc;
-
- supervisor = virLockManagerGetSupervisorPath(manager);
- virLockManagerGetSupervisorArgs(&argv, &argc);
-
- cmd = qemuBuildCommandLine(supervisor, supervisorargv, supervisorargv);
-
- supervisorpid = virCommandExec(cmd);
-
- if (!virLockManagerGetChild(manager, &qemupid))
- kill(supervisorpid); /* XXX or leave it running ??? */
-
- 3. Initiate migration in QEMU on source and wait for completion
-
- 4a. On failure
-
- 4a1 On target
-
- virLockManagerCompleteMigrateIn(manager,
- VIR_LOCK_MANAGER_MIGRATE_CANCEL);
- virLockManagerShutdown(manager);
- virLockManagerFree(manager);
-
- 4a2 On source
-
- virLockManagerCompleteMigrateIn(manager,
- VIR_LOCK_MANAGER_MIGRATE_CANCEL);
-
- 4b. On succcess
-
-
- 4b1 On target
-
- virLockManagerCompleteMigrateIn(manager, 0);
-
- 42 On source
-
- virLockManagerCompleteMigrateIn(manager, 0);
- virLockManagerShutdown(manager);
- virLockManagerFree(manager);
-
-
-Notes:
-
- - If a lock manager impl does just VM level leases, it can
- ignore all the resource paths at startup.
-
- - If a lock manager impl does not support migrate
- it can return an error from all migrate calls
-
- - If a lock manger impl does not support hotplug
- it can return an error from all resource acquire/release calls
--
1.7.12
12 years, 2 months
[libvirt] [PATCH v3 0/2] Add <seclabel> to character devices.
by Richard W.M. Jones
Previous discussion:
https://www.redhat.com/archives/libvir-list/2012-September/thread.html#01037
This adds <seclabel> to character devices' <source/> elements,
like this:
<serial type="unix">
<source mode="connect" path="/tmp/console.sock">
<seclabel model="selinux" relabel="no"/>
</source>
<target port="0"/>
</serial>
I tested it by controlling the labelling of the libguestfs console
socket (when unlabelled, SELinux prevents libguestfs from starting),
and it appears to work.
By the way, I could only get this to work by explicitly adding the
model="selinux" attribute. Looking at the code, it seems the same
would be true for disk-specific seclabels too, so the documentation is
wrong.
Rich.
12 years, 2 months
[libvirt] [PATCH v8] support offline migration
by liguang
original migration did not aware of offline case
so, add code to support offline migration quietly
(did not disturb original migration) by pass
VIR_MIGRATE_OFFLINE flag to migration APIs if only
the domain is really inactive, and
migration process will not puzzled by domain
offline and exit unexpectedly.
these changes did not take care of disk images the
domain required, for them could be transferred by
other APIs as suggested, then VIR_MIGRATE_OFFLINE
should not combined with VIR_MIGRATE_NON_SHARED_*.
so, this migration result is just make domain
definition alive at target side.
Signed-off-by: liguang <lig.fnst(a)cn.fujitsu.com>
---
include/libvirt/libvirt.h.in | 1 +
src/qemu/qemu_driver.c | 15 ++++++++++++
src/qemu/qemu_migration.c | 52 ++++++++++++++++++++++++++++++++++++-----
src/qemu/qemu_migration.h | 3 +-
tools/virsh-domain.c | 6 +++++
5 files changed, 69 insertions(+), 8 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index cfe5047..77df2ab 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -995,6 +995,7 @@ typedef enum {
* whole migration process; this will be used automatically
* when supported */
VIR_MIGRATE_UNSAFE = (1 << 9), /* force migration even if it is considered unsafe */
+ VIR_MIGRATE_OFFLINE = (1 << 10), /* offline migrate */
} virDomainMigrateFlags;
/* Domain migration. */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b12d9bc..2380ccc 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9641,6 +9641,15 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
}
if (!virDomainObjIsActive(vm)) {
+ if (flags & VIR_MIGRATE_OFFLINE) {
+ if (flags & (VIR_MIGRATE_NON_SHARED_DISK|
+ VIR_MIGRATE_NON_SHARED_INC)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("migrating storage handled by volume APIs"));
+ goto endjob;
+ }
+ goto offline;
+ }
virReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
goto endjob;
@@ -9653,6 +9662,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
if (qemuDomainCheckEjectableMedia(driver, vm, asyncJob) < 0)
goto endjob;
+offline:
if (!(xml = qemuMigrationBegin(driver, vm, xmlin, dname,
cookieout, cookieoutlen,
flags)))
@@ -9888,6 +9898,11 @@ qemuDomainMigrateConfirm3(virDomainPtr domain,
goto cleanup;
}
+ if (flags & VIR_MIGRATE_OFFLINE) {
+ ret = 0;
+ goto cleanup;
+ }
+
if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_OUT))
goto cleanup;
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 1b21ef6..cb63264 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -70,6 +70,7 @@ enum qemuMigrationCookieFlags {
QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS,
QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE,
QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT,
+ QEMU_MIGRATION_COOKIE_FLAG_OFFLINE,
QEMU_MIGRATION_COOKIE_FLAG_LAST
};
@@ -77,12 +78,13 @@ enum qemuMigrationCookieFlags {
VIR_ENUM_DECL(qemuMigrationCookieFlag);
VIR_ENUM_IMPL(qemuMigrationCookieFlag,
QEMU_MIGRATION_COOKIE_FLAG_LAST,
- "graphics", "lockstate", "persistent");
+ "graphics", "lockstate", "persistent", "offline");
enum qemuMigrationCookieFeatures {
QEMU_MIGRATION_COOKIE_GRAPHICS = (1 << QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS),
QEMU_MIGRATION_COOKIE_LOCKSTATE = (1 << QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE),
QEMU_MIGRATION_COOKIE_PERSISTENT = (1 << QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT),
+ QEMU_MIGRATION_COOKIE_OFFLINE = (1 << QEMU_MIGRATION_COOKIE_FLAG_OFFLINE),
};
typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics;
@@ -439,6 +441,9 @@ qemuMigrationCookieXMLFormat(struct qemud_driver *driver,
virBufferAdjustIndent(buf, -2);
}
+ if (mig->flags & QEMU_MIGRATION_COOKIE_OFFLINE)
+ virBufferAsprintf(buf, " <offline/>\n");
+
virBufferAddLit(buf, "</qemu-migration>\n");
return 0;
}
@@ -662,6 +667,11 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
VIR_FREE(nodes);
}
+ if ((flags & QEMU_MIGRATION_COOKIE_OFFLINE)) {
+ if (virXPathBoolean("count(./offline) > 0", ctxt))
+ mig->flags |= QEMU_MIGRATION_COOKIE_OFFLINE;
+ }
+
return 0;
error:
@@ -721,6 +731,10 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
qemuMigrationCookieAddPersistent(mig, dom) < 0)
return -1;
+ if (flags & QEMU_MIGRATION_COOKIE_OFFLINE) {
+ mig->flags |= QEMU_MIGRATION_COOKIE_OFFLINE;
+ }
+
if (!(*cookieout = qemuMigrationCookieXMLFormatStr(driver, mig)))
return -1;
@@ -1151,6 +1165,13 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
QEMU_MIGRATION_COOKIE_LOCKSTATE) < 0)
goto cleanup;
+ if (flags & VIR_MIGRATE_OFFLINE) {
+ if (qemuMigrationBakeCookie(mig, driver, vm,
+ cookieout, cookieoutlen,
+ QEMU_MIGRATION_COOKIE_OFFLINE) < 0)
+ goto cleanup;
+ }
+
if (xmlin) {
if (!(def = virDomainDefParseString(driver->caps, xmlin,
QEMU_EXPECTED_VIRT_TYPES,
@@ -1314,6 +1335,15 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
goto endjob;
}
+ if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
+ QEMU_MIGRATION_COOKIE_OFFLINE)))
+ return ret;
+
+ if (mig->flags & QEMU_MIGRATION_COOKIE_OFFLINE) {
+ ret = 0;
+ goto cleanup;
+ }
+
/* Start the QEMU daemon, with the same command-line arguments plus
* -incoming $migrateFrom
*/
@@ -1856,7 +1886,8 @@ qemuMigrationRun(struct qemud_driver *driver,
virLockManagerPluginGetName(driver->lockManager));
return -1;
}
-
+ if (flags & VIR_MIGRATE_OFFLINE)
+ return 0;
if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
QEMU_MIGRATION_COOKIE_GRAPHICS)))
goto cleanup;
@@ -2372,6 +2403,8 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver,
qemuDomainObjExitRemoteWithDriver(driver, vm);
}
VIR_FREE(dom_xml);
+ if (flags & VIR_MIGRATE_OFFLINE)
+ goto cleanup;
if (ret == -1)
goto cleanup;
@@ -2477,7 +2510,7 @@ finish:
vm->def->name);
cleanup:
- if (ddomain) {
+ if (ddomain || (flags & VIR_MIGRATE_OFFLINE)) {
virObjectUnref(ddomain);
ret = 0;
} else {
@@ -2554,7 +2587,7 @@ static int doPeer2PeerMigrate(struct qemud_driver *driver,
}
/* domain may have been stopped while we were talking to remote daemon */
- if (!virDomainObjIsActive(vm)) {
+ if (!virDomainObjIsActive(vm) && !(flags & VIR_MIGRATE_OFFLINE)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("guest unexpectedly quit"));
goto cleanup;
@@ -2617,7 +2650,7 @@ qemuMigrationPerformJob(struct qemud_driver *driver,
if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup;
- if (!virDomainObjIsActive(vm)) {
+ if (!virDomainObjIsActive(vm) && !(flags & VIR_MIGRATE_OFFLINE)) {
virReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
goto endjob;
@@ -2941,6 +2974,8 @@ qemuMigrationFinish(struct qemud_driver *driver,
*/
if (retcode == 0) {
if (!virDomainObjIsActive(vm)) {
+ if (flags & VIR_MIGRATE_OFFLINE)
+ goto offline;
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("guest unexpectedly quit"));
goto endjob;
@@ -3038,7 +3073,7 @@ qemuMigrationFinish(struct qemud_driver *driver,
goto endjob;
}
}
-
+ offline:
dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
event = virDomainEventNewFromObj(vm,
@@ -3120,7 +3155,10 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen, 0)))
return -1;
-
+ if (flags & VIR_MIGRATE_OFFLINE) {
+ rv = 0;
+ goto cleanup;
+ }
/* Did the migration go as planned? If yes, kill off the
* domain object, but if no, resume CPUs
*/
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index 1740204..2bcaea0 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -36,7 +36,8 @@
VIR_MIGRATE_NON_SHARED_DISK | \
VIR_MIGRATE_NON_SHARED_INC | \
VIR_MIGRATE_CHANGE_PROTECTION | \
- VIR_MIGRATE_UNSAFE)
+ VIR_MIGRATE_UNSAFE | \
+ VIR_MIGRATE_OFFLINE)
enum qemuMigrationJobPhase {
QEMU_MIGRATION_PHASE_NONE = 0,
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 4684466..ec25043 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -6525,6 +6525,7 @@ static const vshCmdOptDef opts_migrate[] = {
{"dname", VSH_OT_DATA, 0, N_("rename to new name during migration (if supported)")},
{"timeout", VSH_OT_INT, 0, N_("force guest to suspend if live migration exceeds timeout (in seconds)")},
{"xml", VSH_OT_STRING, 0, N_("filename containing updated XML for the target")},
+ {"offline", VSH_OT_BOOL, 0, N_("for offline migration")},
{NULL, 0, 0, NULL}
};
@@ -6591,6 +6592,11 @@ doMigrate(void *opaque)
if (vshCommandOptBool(cmd, "unsafe"))
flags |= VIR_MIGRATE_UNSAFE;
+ if (vshCommandOptBool(cmd, "offline")) {
+ if (!virDomainIsActive(dom))
+ flags |= VIR_MIGRATE_OFFLINE;
+ }
+
if (xmlfile &&
virFileReadAll(xmlfile, 8192, &xml) < 0) {
vshError(ctl, _("file '%s' doesn't exist"), xmlfile);
--
1.7.2.5
12 years, 2 months
[libvirt] [PATCH] Fix crash accessing a NULL URI when looking up auth credentials
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
When auto-probing hypervisor drivers, the conn->uri field will
initially be NULL. Care must be taken not to access members
when doing auth lookups in the config file
---
src/remote/remote_driver.c | 2 +-
src/util/virauth.c | 2 +-
src/util/viruri.h | 2 ++
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index cf1f079..8c6c807 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -3281,7 +3281,7 @@ static int remoteAuthFillFromConfig(virConnectPtr conn,
if (virAuthConfigLookup(state->config,
"libvirt",
- conn->uri->server,
+ VIR_URI_SERVER(conn->uri),
credname,
&value) < 0)
goto cleanup;
diff --git a/src/util/virauth.c b/src/util/virauth.c
index 5539c3c..ff8d0d4 100644
--- a/src/util/virauth.c
+++ b/src/util/virauth.c
@@ -130,7 +130,7 @@ virAuthGetCredential(virConnectPtr conn,
if (virAuthConfigLookup(config,
servicename,
- conn->uri->server,
+ VIR_URI_SERVER(conn->uri),
credname,
&tmp) < 0)
goto cleanup;
diff --git a/src/util/viruri.h b/src/util/viruri.h
index 571bf3c..de927fa 100644
--- a/src/util/viruri.h
+++ b/src/util/viruri.h
@@ -60,4 +60,6 @@ char *virURIFormatParams(virURIPtr uri);
void virURIFree(virURIPtr uri);
+#define VIR_URI_SERVER(uri) ((uri) && (uri)->server ? (uri)->server : "localhost")
+
#endif /* __VIR_URI_H__ */
--
1.7.11.4
12 years, 2 months