[libvirt] [PATCH v5] Introduce --without-pm-utils to get rid of pm-is-supported dependency
by Cédric Bosdonnat
This uses the dbus api of systemd to check the power management
capabilities of the node.
---
Difference with v4:
* Removed left-over debug bits
* Rebased
* Cleaned up the spurious white space change
configure.ac | 22 +++++++++
libvirt.spec.in | 9 ++++
src/libvirt_private.syms | 3 ++
src/util/virnodesuspend.c | 75 ++++++++++++++++++++++------
src/util/virsystemd.c | 59 ++++++++++++++++++++++
src/util/virsystemd.h | 6 +++
tests/virsystemdtest.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 279 insertions(+), 16 deletions(-)
diff --git a/configure.ac b/configure.ac
index 52c50df..ea85851 100644
--- a/configure.ac
+++ b/configure.ac
@@ -563,6 +563,10 @@ AC_ARG_WITH([chrdev-lock-files],
[location for UUCP style lock files for character devices
(use auto for default paths on some platforms) @<:@default=auto@:>@])])
m4_divert_text([DEFAULTS], [with_chrdev_lock_files=auto])
+AC_ARG_WITH([pm-utils],
+ [AS_HELP_STRING([--with-pm-utils],
+ [use pm-utils for power management @<:@default=yes@:>@])])
+m4_divert_text([DEFAULTS], [with_pm_utils=check])
dnl
dnl in case someone want to build static binaries
@@ -1621,6 +1625,23 @@ fi
AM_CONDITIONAL([WITH_PHYP],[test "$with_phyp" = "yes"])
+dnl
+dnl Should we build with pm-utils support?
+dnl
+if test "$with_pm_utils" = "check"; then
+ with_pm_utils=yes
+ if test "$with_dbus" = "yes"; then
+ if test "$init_systemd" = "yes"; then
+ with_pm_utils=no
+ fi
+ fi
+fi
+
+if test "$with_pm_utils" = "yes"; then
+ AC_DEFINE_UNQUOTED([WITH_PM_UTILS], 1, [whether to use pm-utils])
+fi
+AM_CONDITIONAL([WITH_PM_UTILS], [test "$with_pm_utils" = "yes"])
+
dnl virsh libraries
VIRSH_LIBS="$VIRSH_LIBS $READLINE_LIBS"
AC_SUBST([VIRSH_LIBS])
@@ -2853,6 +2874,7 @@ AC_MSG_NOTICE([ rbd: $LIBRBD_LIBS])
else
AC_MSG_NOTICE([ rbd: no])
fi
+AC_MSG_NOTICE([pm-utils: $with_pm_utils])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Test suite])
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 8e83fb3..b61ef8d 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -132,6 +132,7 @@
%define with_libssh2 0%{!?_without_libssh2:0}
%define with_wireshark 0%{!?_without_wireshark:0}
%define with_systemd_daemon 0%{!?_without_systemd_daemon:0}
+%define with_pm_utils 1
# Non-server/HV driver defaults which are always enabled
%define with_sasl 0%{!?_without_sasl:1}
@@ -182,6 +183,7 @@
%if 0%{?fedora} >= 17 || 0%{?rhel} >= 7
%define with_systemd 1
%define with_systemd_daemon 1
+ %define with_pm_utils 0
%endif
# Fedora 18 / RHEL-7 are first where firewalld support is enabled
@@ -1138,8 +1140,10 @@ Requires: nc
Requires: gettext
# Needed by virt-pki-validate script.
Requires: gnutls-utils
+%if %{with_pm_utils}
# Needed for probing the power management features of the host.
Requires: pm-utils
+%{endif}
%if %{with_sasl}
Requires: cyrus-sasl
# Not technically required, but makes 'out-of-box' config
@@ -1395,6 +1399,10 @@ driver
%define _without_systemd_daemon --without-systemd-daemon
%endif
+%if ! %{with_pm_utils}
+ %define _without_pm_utils --without-pm-utils
+%endif
+
%define when %(date +"%%F-%%T")
%define where %(hostname)
%define who %{?packager}%{!?packager:Unknown}
@@ -1471,6 +1479,7 @@ rm -f po/stamp-po
%{?_with_firewalld} \
%{?_without_wireshark} \
%{?_without_systemd_daemon} \
+ %{?_without_pm_utils} \
%{with_packager} \
%{with_packager_version} \
--with-qemu-user=%{qemu_user} \
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index cd43335..6e807c4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1888,6 +1888,9 @@ virSysinfoSetup;
# util/virsystemd.h
+virSystemdCanHibernate;
+virSystemdCanHybridSleep;
+virSystemdCanSuspend;
virSystemdCreateMachine;
virSystemdMakeMachineName;
virSystemdMakeScopeName;
diff --git a/src/util/virnodesuspend.c b/src/util/virnodesuspend.c
index 08c47aa..70ede2a 100644
--- a/src/util/virnodesuspend.c
+++ b/src/util/virnodesuspend.c
@@ -22,6 +22,7 @@
#include <config.h>
#include "virnodesuspend.h"
+# include "virsystemd.h"
#include "vircommand.h"
#include "virthread.h"
#include "datatypes.h"
@@ -228,23 +229,9 @@ int nodeSuspendForDuration(unsigned int target,
return ret;
}
-
-/**
- * virNodeSuspendSupportsTarget:
- * @target: The power management target to check whether it is supported
- * by the host. Values could be:
- * VIR_NODE_SUSPEND_TARGET_MEM
- * VIR_NODE_SUSPEND_TARGET_DISK
- * VIR_NODE_SUSPEND_TARGET_HYBRID
- * @supported: set to true if supported, false otherwise
- *
- * Run the script 'pm-is-supported' (from the pm-utils package)
- * to find out if @target is supported by the host.
- *
- * Returns 0 if the query was successful, -1 on failure.
- */
+#ifdef WITH_PM_UTILS
static int
-virNodeSuspendSupportsTarget(unsigned int target, bool *supported)
+virNodeSuspendSupportsTargetPMUtils(unsigned int target, bool *supported)
{
virCommandPtr cmd;
int status;
@@ -280,6 +267,62 @@ virNodeSuspendSupportsTarget(unsigned int target, bool *supported)
virCommandFree(cmd);
return ret;
}
+#endif
+
+static int
+virNodeSuspendSupportsTargetSystemd(unsigned int target, bool *supported)
+{
+ int ret = -1;
+
+ if (virNodeSuspendInitialize() < 0)
+ return -1;
+
+ *supported = false;
+
+ switch (target) {
+ case VIR_NODE_SUSPEND_TARGET_MEM:
+ ret = virSystemdCanSuspend(supported);
+ break;
+ case VIR_NODE_SUSPEND_TARGET_DISK:
+ ret = virSystemdCanHibernate(supported);
+ break;
+ case VIR_NODE_SUSPEND_TARGET_HYBRID:
+ ret = virSystemdCanHybridSleep(supported);
+ break;
+ default:
+ return ret;
+ }
+
+ return ret;
+}
+
+/**
+ * virNodeSuspendSupportsTarget:
+ * @target: The power management target to check whether it is supported
+ * by the host. Values could be:
+ * VIR_NODE_SUSPEND_TARGET_MEM
+ * VIR_NODE_SUSPEND_TARGET_DISK
+ * VIR_NODE_SUSPEND_TARGET_HYBRID
+ * @supported: set to true if supported, false otherwise
+ *
+ * Run the script 'pm-is-supported' (from the pm-utils package)
+ * to find out if @target is supported by the host.
+ *
+ * Returns 0 if the query was successful, -1 on failure.
+ */
+static int
+virNodeSuspendSupportsTarget(unsigned int target, bool *supported)
+{
+ int ret;
+
+ ret = virNodeSuspendSupportsTargetSystemd(target, supported);
+#ifdef WITH_PM_UTILS
+ if (ret < 0)
+ ret = virNodeSuspendSupportsTargetPMUtils(target, supported);
+#endif
+
+ return ret;
+}
/**
* virNodeSuspendGetTargetMask:
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
index 93b3f9c..e9ca564 100644
--- a/src/util/virsystemd.c
+++ b/src/util/virsystemd.c
@@ -325,3 +325,62 @@ virSystemdNotifyStartup(void)
sd_notify(0, "READY=1");
#endif
}
+
+static int
+virSystemdPMSupportTarget(const char *methodName, bool *result)
+{
+ int ret;
+ DBusConnection *conn;
+ DBusMessage *message = NULL;
+ char *response;
+
+ ret = virDBusIsServiceEnabled("org.freedesktop.login1");
+ if (ret < 0)
+ return ret;
+
+ if ((ret = virDBusIsServiceRegistered("org.freedesktop.login1")) < 0)
+ return ret;
+
+ if (!(conn = virDBusGetSystemBus()))
+ return -1;
+
+ ret = -1;
+
+ if (virDBusCallMethod(conn,
+ &message,
+ NULL,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ methodName,
+ NULL) < 0)
+ return ret;
+
+ if ((ret = virDBusMessageRead(message, "s", &response)) < 0)
+ goto cleanup;
+
+ *result = STREQ("yes", response) || STREQ("challenge", response);
+
+ ret = 0;
+
+ cleanup:
+ dbus_message_unref(message);
+ VIR_FREE(response);
+
+ return ret;
+}
+
+int virSystemdCanSuspend(bool *result)
+{
+ return virSystemdPMSupportTarget("CanSuspend", result);
+}
+
+int virSystemdCanHibernate(bool *result)
+{
+ return virSystemdPMSupportTarget("CanHibernate", result);
+}
+
+int virSystemdCanHybridSleep(bool *result)
+{
+ return virSystemdPMSupportTarget("CanHybridSleep", result);
+}
diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h
index 7fed456..491c9b7 100644
--- a/src/util/virsystemd.h
+++ b/src/util/virsystemd.h
@@ -48,4 +48,10 @@ int virSystemdTerminateMachine(const char *name,
void virSystemdNotifyStartup(void);
+int virSystemdCanSuspend(bool *result);
+
+int virSystemdCanHibernate(bool *result);
+
+int virSystemdCanHybridSleep(bool *result);
+
#endif /* __VIR_SYSTEMD_H__ */
diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c
index 2b014cc..86d717f 100644
--- a/tests/virsystemdtest.c
+++ b/tests/virsystemdtest.c
@@ -55,10 +55,21 @@ VIR_MOCK_IMPL_RET_ARGS(dbus_connection_send_with_reply_and_block,
} else {
reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
}
+ } else if (STREQ(service, "org.freedesktop.login1")) {
+ char *supported = getenv("RESULT_SUPPORT");
+ DBusMessageIter iter;
+ reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
+ dbus_message_iter_init_append(reply, &iter);
+
+ if (!dbus_message_iter_append_basic(&iter,
+ DBUS_TYPE_STRING,
+ &supported))
+ goto error;
} else if (STREQ(service, "org.freedesktop.DBus") &&
STREQ(member, "ListActivatableNames")) {
const char *svc1 = "org.foo.bar.wizz";
const char *svc2 = "org.freedesktop.machine1";
+ const char *svc3 = "org.freedesktop.login1";
DBusMessageIter iter;
DBusMessageIter sub;
reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
@@ -75,11 +86,17 @@ VIR_MOCK_IMPL_RET_ARGS(dbus_connection_send_with_reply_and_block,
DBUS_TYPE_STRING,
&svc2))
goto error;
+ if (!getenv("FAIL_NO_SERVICE") &&
+ !dbus_message_iter_append_basic(&sub,
+ DBUS_TYPE_STRING,
+ &svc3))
+ goto error;
dbus_message_iter_close_container(&iter, &sub);
} else if (STREQ(service, "org.freedesktop.DBus") &&
STREQ(member, "ListNames")) {
const char *svc1 = "org.foo.bar.wizz";
const char *svc2 = "org.freedesktop.systemd1";
+ const char *svc3 = "org.freedesktop.login1";
DBusMessageIter iter;
DBusMessageIter sub;
reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
@@ -96,6 +113,11 @@ VIR_MOCK_IMPL_RET_ARGS(dbus_connection_send_with_reply_and_block,
DBUS_TYPE_STRING,
&svc2))
goto error;
+ if ((!getenv("FAIL_NO_SERVICE") && !getenv("FAIL_NOT_REGISTERED")) &&
+ !dbus_message_iter_append_basic(&sub,
+ DBUS_TYPE_STRING,
+ &svc3))
+ goto error;
dbus_message_iter_close_container(&iter, &sub);
} else {
reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
@@ -313,6 +335,86 @@ testScopeName(const void *opaque)
return ret;
}
+typedef int (*virSystemdCanHelper)(bool * result);
+struct testPMSupportData {
+ virSystemdCanHelper tested;
+};
+
+static int testPMSupportHelper(const void *opaque)
+{
+ int rv;
+ bool result;
+ size_t i;
+ const char *results[4] = {"yes", "no", "na", "challenge"};
+ int expected[4] = {1, 0, 0, 1};
+ const struct testPMSupportData *data = opaque;
+
+ for (i = 0; i < 4; i++) {
+ setenv("RESULT_SUPPORT", results[i], 1);
+ if ((rv = data->tested(&result)) < 0) {
+ fprintf(stderr, "%s", "Unexpected canSuspend error\n");
+ return -1;
+ }
+
+ if (result != expected[i]) {
+ fprintf(stderr, "Unexpected result for answer '%s'\n", results[i]);
+ goto error;
+ }
+ unsetenv("RESULT_SUPPORT");
+ }
+
+ return 0;
+error:
+ unsetenv("RESULT_SUPPORT");
+ return -1;
+}
+
+static int testPMSupportHelperNoSystemd(const void *opaque)
+{
+ int rv;
+ bool result;
+ const struct testPMSupportData *data = opaque;
+
+ setenv("FAIL_NO_SERVICE", "1", 1);
+
+ if ((rv = data->tested(&result)) == 0) {
+ unsetenv("FAIL_NO_SERVICE");
+ fprintf(stderr, "%s", "Unexpected canSuspend success\n");
+ return -1;
+ }
+ unsetenv("FAIL_NO_SERVICE");
+
+ if (rv != -2) {
+ fprintf(stderr, "%s", "Unexpected canSuspend error\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int testPMSupportSystemdNotRunning(const void *opaque)
+{
+ int rv;
+ bool result;
+ const struct testPMSupportData *data = opaque;
+
+ setenv("FAIL_NOT_REGISTERED", "1", 1);
+
+ if ((rv = data->tested(&result)) == 0) {
+ unsetenv("FAIL_NOT_REGISTERED");
+ fprintf(stderr, "%s", "Unexpected canSuspend success\n");
+ return -1;
+ }
+ unsetenv("FAIL_NOT_REGISTERED");
+
+ if (rv != -2) {
+ fprintf(stderr, "%s", "Unexpected canSuspend error\n");
+ return -1;
+ }
+
+ return 0;
+}
+
static int
mymain(void)
{
@@ -351,6 +453,25 @@ mymain(void)
TEST_SCOPE("demo", "/machine/eng-dept/testing!stuff",
"machine-eng\\x2ddept-testing\\x21stuff-lxc\\x2ddemo.scope");
+# define TESTS_PM_SUPPORT_HELPER(name, function) \
+ do { \
+ struct testPMSupportData data = { \
+ function \
+ }; \
+ if (virtTestRun("Test " name " ", testPMSupportHelper, &data) < 0) \
+ ret = -1; \
+ if (virtTestRun("Test " name " no systemd ", \
+ testPMSupportHelperNoSystemd, &data) < 0) \
+ ret = -1; \
+ if (virtTestRun("Test systemd " name " not running ", \
+ testPMSupportSystemdNotRunning, &data) < 0) \
+ ret = -1; \
+ } while (0)
+
+ TESTS_PM_SUPPORT_HELPER("canSuspend", &virSystemdCanSuspend);
+ TESTS_PM_SUPPORT_HELPER("canHibernate", &virSystemdCanHibernate);
+ TESTS_PM_SUPPORT_HELPER("canHybridSleep", &virSystemdCanHybridSleep);
+
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
1.8.4.5
10 years, 7 months
[libvirt] [PATCH] tests: drop dead code from argv2xml and xml2xml
by Eric Blake
Noticed while tweaking the RelaxNG grammar for <disk> elements.
* tests/qemuxml2xmloutdata/qemuxml2xmlout-numad-static-vcpu-no-numatune.xml:
* tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-cdrom-empty.xml:
Drop unused files.
* tests/qemuargv2xmltest.c (testInfo, DO_TEST_FULL): Drop unused
field.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Pushing under the trivial rule.
tests/qemuargv2xmltest.c | 16 +++++------
.../qemuxml2xmlout-disk-cdrom-empty.xml | 32 ----------------------
...emuxml2xmlout-numad-static-vcpu-no-numatune.xml | 29 --------------------
3 files changed, 7 insertions(+), 70 deletions(-)
delete mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-cdrom-empty.xml
delete mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-numad-static-vcpu-no-numatune.xml
diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
index 4cc3749..0fc9fcb 100644
--- a/tests/qemuargv2xmltest.c
+++ b/tests/qemuargv2xmltest.c
@@ -95,7 +95,6 @@ static int testCompareXMLToArgvFiles(const char *xml,
struct testInfo {
const char *name;
unsigned long long extraFlags;
- const char *migrateFrom;
};
static int
@@ -137,16 +136,16 @@ mymain(void)
if (!(driver.xmlopt = virQEMUDriverCreateXMLConf(&driver)))
return EXIT_FAILURE;
-# define DO_TEST_FULL(name, extraFlags, migrateFrom) \
+# define DO_TEST_FULL(name, extraFlags) \
do { \
- const struct testInfo info = { name, extraFlags, migrateFrom }; \
+ const struct testInfo info = { name, extraFlags }; \
if (virtTestRun("QEMU ARGV-2-XML " name, \
testCompareXMLToArgvHelper, &info) < 0) \
ret = -1; \
} while (0)
# define DO_TEST(name) \
- DO_TEST_FULL(name, 0, NULL)
+ DO_TEST_FULL(name, 0)
setenv("PATH", "/bin", 1);
setenv("USER", "test", 1);
@@ -264,12 +263,11 @@ mymain(void)
DO_TEST("nosharepages");
- DO_TEST_FULL("restore-v1", 0, "stdio");
- DO_TEST_FULL("restore-v2", 0, "stdio");
- DO_TEST_FULL("restore-v2", 0, "exec:cat");
- DO_TEST_FULL("migrate", 0, "tcp:10.0.0.1:5000");
+ DO_TEST("restore-v1");
+ DO_TEST("restore-v2");
+ DO_TEST("migrate");
- DO_TEST_FULL("qemu-ns-no-env", 1, NULL);
+ DO_TEST_FULL("qemu-ns-no-env", 1);
virObjectUnref(driver.config);
virObjectUnref(driver.caps);
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-cdrom-empty.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-cdrom-empty.xml
deleted file mode 100644
index 2c5a81a..0000000
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-cdrom-empty.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<domain type='qemu'>
- <name>QEMUGuest1</name>
- <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
- <memory unit='KiB'>219100</memory>
- <currentMemory unit='KiB'>219100</currentMemory>
- <vcpu placement='static'>1</vcpu>
- <os>
- <type arch='i686' machine='pc'>hvm</type>
- <boot dev='hd'/>
- </os>
- <clock offset='utc'/>
- <on_poweroff>destroy</on_poweroff>
- <on_reboot>restart</on_reboot>
- <on_crash>destroy</on_crash>
- <devices>
- <emulator>/usr/bin/qemu</emulator>
- <disk type='block' device='disk'>
- <source dev='/dev/HostVG/QEMUGuest1'/>
- <target dev='hda' bus='ide'/>
- <address type='drive' controller='0' bus='0' target='0' unit='0'/>
- </disk>
- <disk type='file' device='cdrom'>
- <target dev='hdc' bus='ide'/>
- <source startupPolicy='optional'/>
- <readonly/>
- <address type='drive' controller='0' bus='1' target='0' unit='0'/>
- </disk>
- <controller type='usb' index='0'/>
- <controller type='ide' index='0'/>
- <memballoon model='virtio'/>
- </devices>
-</domain>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-numad-static-vcpu-no-numatune.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-numad-static-vcpu-no-numatune.xml
deleted file mode 100644
index 71c1497..0000000
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-numad-static-vcpu-no-numatune.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<domain type='qemu'>
- <name>QEMUGuest1</name>
- <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
- <memory unit='KiB'>219136</memory>
- <currentMemory unit='KiB'>219136</currentMemory>
- <vcpu placement='static'>2</vcpu>
- <os>
- <type arch='i686' machine='pc'>hvm</type>
- <boot dev='hd'/>
- </os>
- <cpu>
- <topology sockets='2' cores='1' threads='1'/>
- </cpu>
- <clock offset='utc'/>
- <on_poweroff>destroy</on_poweroff>
- <on_reboot>restart</on_reboot>
- <on_crash>destroy</on_crash>
- <devices>
- <emulator>/usr/bin/qemu</emulator>
- <disk type='block' device='disk'>
- <source dev='/dev/HostVG/QEMUGuest1'/>
- <target dev='hda' bus='ide'/>
- <address type='drive' controller='0' bus='0' target='0' unit='0'/>
- </disk>
- <controller type='ide' index='0'/>
- <controller type='usb' index='0'/>
- <memballoon model='virtio'/>
- </devices>
-</domain>
--
1.9.0
10 years, 7 months
[libvirt] [PATCH 0/2] bhyve: enhance domain management
by Wojciech Macek
Two small changes:
1. Inside domainDestroy, forget about domain if it is not persistent.
2. Add domainCreateXML call
Wojciech Macek (2):
bhyve: fix domain management
bhyve: domainCreateXML
src/bhyve/bhyve_driver.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 78 insertions(+), 2 deletions(-)
--
1.9.0
10 years, 7 months
[libvirt] API calls to get interfaces and block devices
by Ruben Kerkhof
Hi all,
I have a few python scripts which use the libvirt api to get interface and block device statistics.
What has been bugging me for a while now that is that there’s no high level api to get a list of all interfaces or block devices for a vm.
The list can be retrieved from the xml with a bit of Xpath magic, but this seems to me to break the nice abstraction layer libvirt provides.
Ideally, I don’t have to do anything with xml, and add dependencies on xml parsers to my code.
I’ve seen examples of code doing this, for example the collectd libvirt plugin, but there must be many others.
Can I kindly ask for such an API? Unfortunately I don’t have the skills to code this up myself.
Kind regards,
Ruben Kerkhof
10 years, 7 months
[libvirt] [PATCH] virsh: Add one blank line after output of dompmsuspend/dompmwakeup
by Shanzhi Yu
There should be include one blank line after result of dompmsuspend
and dompmwakeup
---
tools/virsh-domain.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 73414f8..3aca1e7 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -2830,7 +2830,7 @@ cmdDomPMSuspend(vshControl *ctl, const vshCmd *cmd)
goto cleanup;
}
- vshPrint(ctl, _("Domain %s successfully suspended"),
+ vshPrint(ctl, _("Domain %s successfully suspended\n"),
virDomainGetName(dom));
ret = true;
@@ -2881,7 +2881,7 @@ cmdDomPMWakeup(vshControl *ctl, const vshCmd *cmd)
goto cleanup;
}
- vshPrint(ctl, _("Domain %s successfully woken up"),
+ vshPrint(ctl, _("Domain %s successfully woken up\n"),
virDomainGetName(dom));
ret = true;
--
1.8.3.1
10 years, 7 months
[libvirt] [PATCH] cpu: Properly check input parameters
by Jiri Denemark
Most of the APIs in CPU driver do not expect to get NULL for input
parameters. Let's mark them with ATTRIBUTE_NONNULL and also check for
some members of virCPUDef when the APIs expect them have some specific
values.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/cpu/cpu.c | 48 +++++++++++++++++++++++++++++++++++++-----------
src/cpu/cpu.h | 36 ++++++++++++++++++++++++------------
2 files changed, 61 insertions(+), 23 deletions(-)
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 9cd2300..528e1a7 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -108,12 +108,6 @@ cpuCompareXML(virCPUDefPtr host,
if (cpu == NULL)
goto cleanup;
- if (!cpu->model) {
- virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("no CPU model specified"));
- goto cleanup;
- }
-
ret = cpuCompare(host, cpu);
cleanup:
@@ -146,6 +140,12 @@ cpuCompare(virCPUDefPtr host,
VIR_DEBUG("host=%p, cpu=%p", host, cpu);
+ if (!cpu->model) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("no guest CPU model specified"));
+ return VIR_CPU_COMPARE_ERROR;
+ }
+
if ((driver = cpuGetSubDriver(host->arch)) == NULL)
return VIR_CPU_COMPARE_ERROR;
@@ -203,14 +203,15 @@ cpuDecode(virCPUDefPtr cpu,
}
if (models == NULL && nmodels != 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("nonzero nmodels doesn't match with NULL models"));
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("nonzero nmodels doesn't match with NULL models"));
return -1;
}
- if (cpu == NULL) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("invalid CPU definition"));
+ if (cpu->type > VIR_CPU_TYPE_GUEST ||
+ cpu->mode != VIR_CPU_MODE_CUSTOM) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("invalid CPU definition stub"));
return -1;
}
@@ -264,6 +265,12 @@ cpuEncode(virArch arch,
virArchToString(arch), cpu, forced, required,
optional, disabled, forbidden, vendor);
+ if (!cpu->model) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("no guest CPU model specified"));
+ return -1;
+ }
+
if ((driver = cpuGetSubDriver(arch)) == NULL)
return -1;
@@ -367,6 +374,12 @@ cpuGuestData(virCPUDefPtr host,
VIR_DEBUG("host=%p, guest=%p, data=%p, msg=%p", host, guest, data, msg);
+ if (!guest->model) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("no guest CPU model specified"));
+ return VIR_CPU_COMPARE_ERROR;
+ }
+
if ((driver = cpuGetSubDriver(host->arch)) == NULL)
return VIR_CPU_COMPARE_ERROR;
@@ -529,6 +542,19 @@ cpuBaseline(virCPUDefPtr *cpus,
return NULL;
}
+ for (i = 0; i < ncpus; i++) {
+ if (!cpus[i]) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("invalid CPU definition at index %zu"), i);
+ return NULL;
+ }
+ if (!cpus[i]->model) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("no CPU model specified at index %zu"), i);
+ return NULL;
+ }
+ }
+
if (models == NULL && nmodels != 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("nonzero nmodels doesn't match with NULL models"));
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 27169fe..e9f2713 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -119,18 +119,21 @@ struct cpuArchDriver {
extern virCPUCompareResult
cpuCompareXML(virCPUDefPtr host,
- const char *xml);
+ const char *xml)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
extern virCPUCompareResult
cpuCompare (virCPUDefPtr host,
- virCPUDefPtr cpu);
+ virCPUDefPtr cpu)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
extern int
cpuDecode (virCPUDefPtr cpu,
const virCPUData *data,
const char **models,
unsigned int nmodels,
- const char *preferred);
+ const char *preferred)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
extern int
cpuEncode (virArch arch,
@@ -140,7 +143,8 @@ cpuEncode (virArch arch,
virCPUDataPtr *optional,
virCPUDataPtr *disabled,
virCPUDataPtr *forbidden,
- virCPUDataPtr *vendor);
+ virCPUDataPtr *vendor)
+ ATTRIBUTE_NONNULL(2);
extern void
cpuDataFree (virCPUDataPtr data);
@@ -152,7 +156,8 @@ extern virCPUCompareResult
cpuGuestData(virCPUDefPtr host,
virCPUDefPtr guest,
virCPUDataPtr *data,
- char **msg);
+ char **msg)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
extern char *
cpuBaselineXML(const char **xmlCPUs,
@@ -166,30 +171,37 @@ cpuBaseline (virCPUDefPtr *cpus,
unsigned int ncpus,
const char **models,
unsigned int nmodels,
- unsigned int flags);
+ unsigned int flags)
+ ATTRIBUTE_NONNULL(1);
extern int
cpuUpdate (virCPUDefPtr guest,
- const virCPUDef *host);
+ const virCPUDef *host)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
extern int
cpuHasFeature(const virCPUData *data,
- const char *feature);
+ const char *feature)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
bool
cpuModelIsAllowed(const char *model,
const char **models,
- unsigned int nmodels);
+ unsigned int nmodels)
+ ATTRIBUTE_NONNULL(1);
extern int
-cpuGetModels(const char *arch, char ***models);
+cpuGetModels(const char *arch, char ***models)
+ ATTRIBUTE_NONNULL(1);
/* cpuDataFormat and cpuDataParse are implemented for unit tests only and
* have no real-life usage
*/
-char *cpuDataFormat(const virCPUData *data);
+char *cpuDataFormat(const virCPUData *data)
+ ATTRIBUTE_NONNULL(1);
virCPUDataPtr cpuDataParse(virArch arch,
- const char *xmlStr);
+ const char *xmlStr)
+ ATTRIBUTE_NONNULL(2);
#endif /* __VIR_CPU_H__ */
--
1.9.1
10 years, 7 months
[libvirt] [PATCH] cpu: Add documentation for CPU driver APIs
by Jiri Denemark
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/cpu/cpu.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 202 insertions(+)
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index e91f5bb..9cd2300 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -77,6 +77,19 @@ cpuGetSubDriver(virArch arch)
}
+/**
+ * cpuCompareXML:
+ *
+ * @host: host CPU definition
+ * @xml: XML description of either guest or host CPU to be compared with @host
+ *
+ * Compares the CPU described by @xml with @host CPU.
+ *
+ * Returns VIR_CPU_COMPARE_ERROR on error, VIR_CPU_COMPARE_INCOMPATIBLE when
+ * the two CPUs are incompatible, VIR_CPU_COMPARE_IDENTICAL when the two CPUs
+ * are identical, VIR_CPU_COMPARE_SUPERSET when the @xml CPU is a superset of
+ * the @host CPU.
+ */
virCPUCompareResult
cpuCompareXML(virCPUDefPtr host,
const char *xml)
@@ -112,6 +125,19 @@ cpuCompareXML(virCPUDefPtr host,
}
+/**
+ * cpuCompare:
+ *
+ * @host: host CPU definition
+ * @cpu: either guest or host CPU to be compared with @host
+ *
+ * Compares the CPU described by @cpu with @host CPU.
+ *
+ * Returns VIR_CPU_COMPARE_ERROR on error, VIR_CPU_COMPARE_INCOMPATIBLE when
+ * the two CPUs are incompatible, VIR_CPU_COMPARE_IDENTICAL when the two CPUs
+ * are identical, VIR_CPU_COMPARE_SUPERSET when the @cpu CPU is a superset of
+ * the @host CPU.
+ */
virCPUCompareResult
cpuCompare(virCPUDefPtr host,
virCPUDefPtr cpu)
@@ -134,6 +160,31 @@ cpuCompare(virCPUDefPtr host,
}
+/**
+ * cpuDecode:
+ *
+ * @cpu: CPU definition stub to be filled in
+ * @data: internal CPU data to be decoded into @cpu definition
+ * @models: list of CPU models that can be considered when decoding @data
+ * @nmodels: number of CPU models in @models
+ * @preferred: CPU models that should be used if possible
+ *
+ * Decodes internal CPU data into a CPU definition consisting of a CPU model
+ * and a list of CPU features. The @cpu model stub is supposed to have arch,
+ * type, match and fallback members set, this function will add the rest. If
+ * @models list is NULL, all models supported by libvirt will be considered
+ * when decoding the data. In general, this function will select the model
+ * closest to the CPU specified by @data unless @preferred is non-NULL, in
+ * which case the @preferred model will be used as long as it is compatible
+ * with @data.
+ *
+ * For VIR_ARCH_I686 and VIR_ARCH_X86_64 architectures this means the computed
+ * CPU definition will have the shortest possible list of additional features.
+ * When @preferred is non-NULL, the @preferred model will be used even if
+ * other models would result in a shorter list of additional features.
+ *
+ * Returns 0 on success, -1 on error.
+ */
int
cpuDecode(virCPUDefPtr cpu,
const virCPUData *data,
@@ -177,6 +228,25 @@ cpuDecode(virCPUDefPtr cpu,
}
+/**
+ * cpuEncode:
+ *
+ * @arch: CPU architecture
+ * @cpu: CPU definition to be encoded into internal CPU driver representation
+ * @forced: where to store CPU data corresponding to forced features
+ * @required: where to store CPU data corresponding to required features
+ * @optional: where to store CPU data corresponding to optional features
+ * @disabled: where to store CPU data corresponding to disabled features
+ * @forbidden: where to store CPU data corresponding to forbidden features
+ * @vendor: where to store CPU data corresponding to CPU vendor
+ *
+ * Encode CPU definition from @cpu into internal CPU driver representation.
+ * Any of @forced, @required, @optional, @disabled, @forbidden and @vendor
+ * arguments can be NULL in case the caller is not interested in the
+ * corresponding data.
+ *
+ * Returns 0 on success, -1 on error.
+ */
int
cpuEncode(virArch arch,
const virCPUDef *cpu,
@@ -209,6 +279,15 @@ cpuEncode(virArch arch,
}
+/**
+ * cpuDataFree:
+ *
+ * @data: CPU data structure to be freed
+ *
+ * Free internal CPU data.
+ *
+ * Returns nothing.
+ */
void
cpuDataFree(virCPUDataPtr data)
{
@@ -233,6 +312,13 @@ cpuDataFree(virCPUDataPtr data)
}
+/**
+ * cpuNodeData:
+ *
+ * @arch: CPU architecture
+ *
+ * Returns CPU data for host CPU or NULL on error.
+ */
virCPUDataPtr
cpuNodeData(virArch arch)
{
@@ -254,6 +340,23 @@ cpuNodeData(virArch arch)
}
+/**
+ * cpuGuestData:
+ *
+ * @host: host CPU definition
+ * @guest: guest CPU definition
+ * @data: computed guest CPU data
+ * @msg: error message describing why the @guest and @host CPUs are considered
+ * incompatible
+ *
+ * Computes guest CPU data for the @guest CPU definition when run on the @host
+ * CPU.
+ *
+ * Returns VIR_CPU_COMPARE_ERROR on error, VIR_CPU_COMPARE_INCOMPATIBLE when
+ * the two CPUs are incompatible (@msg will describe the incompatibility),
+ * VIR_CPU_COMPARE_IDENTICAL when the two CPUs are identical,
+ * VIR_CPU_COMPARE_SUPERSET when the @guest CPU is a superset of the @host CPU.
+ */
virCPUCompareResult
cpuGuestData(virCPUDefPtr host,
virCPUDefPtr guest,
@@ -278,6 +381,27 @@ cpuGuestData(virCPUDefPtr host,
}
+/**
+ * cpuBaselineXML:
+ *
+ * @xmlCPUs: list of host CPU XML descriptions
+ * @ncpus: number of CPUs in @xmlCPUs
+ * @models: list of CPU models that can be considered for the baseline CPU
+ * @nmodels: number of CPU models in @models
+ * @flags: bitwise-OR of virConnectBaselineCPUFlags
+ *
+ * Computes the most feature-rich CPU which is compatible with all given
+ * host CPUs. If @models array is NULL, all models supported by libvirt will
+ * be considered when computing the baseline CPU model, otherwise the baseline
+ * CPU model will be one of the provided CPU @models.
+ *
+ * If @flags includes VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES then libvirt
+ * will explicitly list all CPU features that are part of the host CPU,
+ * without this flag features that are part of the CPU model will not be
+ * listed.
+ *
+ * Returns XML description of the baseline CPU or NULL on error.
+ */
char *
cpuBaselineXML(const char **xmlCPUs,
unsigned int ncpus,
@@ -353,6 +477,27 @@ cpuBaselineXML(const char **xmlCPUs,
}
+/**
+ * cpuBaseline:
+ *
+ * @cpus: list of host CPU definitions
+ * @ncpus: number of CPUs in @cpus
+ * @models: list of CPU models that can be considered for the baseline CPU
+ * @nmodels: number of CPU models in @models
+ * @flags: bitwise-OR of virConnectBaselineCPUFlags
+ *
+ * Computes the most feature-rich CPU which is compatible with all given
+ * host CPUs. If @models array is NULL, all models supported by libvirt will
+ * be considered when computing the baseline CPU model, otherwise the baseline
+ * CPU model will be one of the provided CPU @models.
+ *
+ * If @flags includes VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES then libvirt
+ * will explicitly list all CPU features that are part of the host CPU,
+ * without this flag features that are part of the CPU model will not be
+ * listed.
+ *
+ * Returns baseline CPU definition or NULL on error.
+ */
virCPUDefPtr
cpuBaseline(virCPUDefPtr *cpus,
unsigned int ncpus,
@@ -404,6 +549,20 @@ cpuBaseline(virCPUDefPtr *cpus,
}
+/**
+ * cpuUpdate:
+ *
+ * @guest: guest CPU definition
+ * @host: host CPU definition
+ *
+ * Updates @guest CPU definition according to @host CPU. This is required to
+ * support guest CPU definition which are relative to host CPU, such as CPUs
+ * with VIR_CPU_MODE_CUSTOM and optional features or VIR_CPU_MATCH_MINIMUM, or
+ * CPUs with non-custom mode (VIR_CPU_MODE_HOST_MODEL,
+ * VIR_CPU_MODE_HOST_PASSTHROUGH).
+ *
+ * Returns 0 on success, -1 on error.
+ */
int
cpuUpdate(virCPUDefPtr guest,
const virCPUDef *host)
@@ -425,6 +584,18 @@ cpuUpdate(virCPUDefPtr guest,
return driver->update(guest, host);
}
+
+/**
+ * cpuHasFeature:
+ *
+ * @data: internal CPU representation
+ * @feature: feature to be checked for
+ *
+ * Checks whether @feature is supported by the CPU described by @data.
+ *
+ * Returns 1 if the feature is supported, 0 if it's not supported, or
+ * -1 on error.
+ */
int
cpuHasFeature(const virCPUData *data,
const char *feature)
@@ -446,6 +617,16 @@ cpuHasFeature(const virCPUData *data,
return driver->hasFeature(data, feature);
}
+
+/**
+ * cpuDataFormat:
+ *
+ * @data: internal CPU representation
+ *
+ * Formats @data into XML for test purposes.
+ *
+ * Returns string representation of the XML describing @data or NULL on error.
+ */
char *
cpuDataFormat(const virCPUData *data)
{
@@ -466,6 +647,17 @@ cpuDataFormat(const virCPUData *data)
return driver->dataFormat(data);
}
+
+/**
+ * cpuDataParse:
+ *
+ * @arch: CPU architecture
+ * @xmlStr: XML string produced by cpuDataFormat
+ *
+ * Parses XML representation of virCPUData structure for test purposes.
+ *
+ * Returns internal CPU data structure parsed from the XML or NULL on error.
+ */
virCPUDataPtr
cpuDataParse(virArch arch,
const char *xmlStr)
@@ -541,6 +733,16 @@ cpuGetArchModels(const char *arch, struct cpuGetModelsData *data)
}
+/**
+ * cpuGetModels:
+ *
+ * @archName: CPU architecture string
+ * @models: where to store the list of supported models
+ *
+ * Fetches all CPU models supported by libvirt on @archName.
+ *
+ * Returns number of supported CPU models or -1 on error.
+ */
int
cpuGetModels(const char *archName, char ***models)
{
--
1.9.1
10 years, 7 months
[libvirt] [PATCH] tests: Fix systemd test with --without-driver-modules
by Jiri Denemark
Every test that makes use of virmock.h (only virsystemdtest as of now)
needs to be linked with -export-dynamic to make sure the LD_PRELOADed
mock library can access it's wrap_* symbols. Normally,
DRIVER_MODULE_LDFLAGS variable contains -export-dynamic but when
--without-driver-modules configure option is used, DRIVER_MODULE_LDFLAGS
is empty.
This patch turns on -export-dynamic for all tests unconditionally
regardless on --without-driver-modules. This fixes virsystemdtest and
all future users of virmock.h.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
tests/Makefile.am | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c5346d1..1e63b86 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -43,6 +43,9 @@ AM_CFLAGS = \
$(COVERAGE_CFLAGS) \
$(WARN_CFLAGS)
+AM_LDFLAGS = \
+ -export-dynamic
+
if WITH_DRIVER_MODULES
INCLUDES += \
-DTEST_DRIVER_DIR=\"$(top_builddir)/src/.libs\"
@@ -921,7 +924,6 @@ virsystemdtest_SOURCES = \
virsystemdtest.c testutils.h testutils.c
virsystemdtest_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
virsystemdtest_LDADD = $(LDADDS)
-virsystemdtest_LDFLAGS = $(DRIVER_MODULE_LDFLAGS)
else ! WITH_DBUS
EXTRA_DIST += virdbustest.c virmockdbus.c virsystemdtest.c
--
1.9.2
10 years, 7 months
[libvirt] [PATCH] virsh: Add a white line into secret-get-value output
by liyang
From: Li Yang <liyang.fnst(a)cn.fujitsu.com>
Commonly there is a whilt line at the end of the virsh
command output, for example:
[root@localhost /]# virsh list --name --all
virt-tests-vm1
[root@localhost /]#
For now the output of secret-get-value like this:
[root@localhost /]# virsh secret-get-value b7811f0f-7fcb-d6b0-c12c-2d8807814b33
00111111001111110011111100111111
[root@localhost /]
So modify the codes, make output like this:
[root@localhost /]# virsh secret-get-value b7811f0f-7fcb-d6b0-c12c-2d8807814b33
00111111001111110011111100111111
[root@localhost /]
Signed-off-by: Li Yang <liyang.fnst(a)cn.fujitsu.com>
---
tools/virsh-secret.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/virsh-secret.c b/tools/virsh-secret.c
index b5acfda..784fd3f 100644
--- a/tools/virsh-secret.c
+++ b/tools/virsh-secret.c
@@ -284,7 +284,7 @@ cmdSecretGetValue(vshControl *ctl, const vshCmd *cmd)
vshError(ctl, "%s", _("Failed to allocate memory"));
goto cleanup;
}
- vshPrint(ctl, "%s", base64);
+ vshPrint(ctl, "%s\n", base64);
memset(base64, 0, strlen(base64));
VIR_FREE(base64);
ret = true;
--
1.7.1
10 years, 7 months