Devel
Threads by month
- ----- 2026 -----
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- 18 participants
- 40170 discussions
The name libvirt-qpid is probably not as descriptive of the project as
it could be. If we want to change the name then now is our best
opportunity to do so, as part of the process to convert it to QMFv2 and
make it a matahari agent - potentially breaking backward compatibility
with existing consoles.
As this project is still remaining outside of the matahari project, how
do folks feel about changing the name to libvirt-qmf?
regards,
Zane.
2
1
[libvirt] [PATCH] util: Avoid duplicating virFileOpenAsNoFork in virFileOpenAs
by Jiri Denemark 14 Jul '11
by Jiri Denemark 14 Jul '11
14 Jul '11
In 2f4d2496a88055a8343b3efca618522da8715d92 I didn't notice that one
part of virFileOpenAs doesn't actually call to virFileOpenAsNoFork but
rather includes a copy of the code from there.
---
src/util/util.c | 35 +++++------------------------------
1 files changed, 5 insertions(+), 30 deletions(-)
diff --git a/src/util/util.c b/src/util/util.c
index 62e0152..0afb7a2 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -754,7 +754,6 @@ int
virFileOpenAs(const char *path, int openflags, mode_t mode,
uid_t uid, gid_t gid, unsigned int flags)
{
- struct stat st;
pid_t pid;
int waitret, status, ret = 0;
int fd = -1;
@@ -821,6 +820,7 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
/* fall back to the simpler method, which works better in
* some cases */
VIR_FORCE_CLOSE(fd);
+ flags &= ~VIR_FILE_OPEN_AS_UID;
return virFileOpenAsNoFork(path, openflags, mode, uid, gid, flags);
}
if (!ret)
@@ -845,36 +845,11 @@ parenterror:
ret = -errno;
goto childerror;
}
- if ((fd = open(path, openflags, mode)) < 0) {
- ret = -errno;
- if (ret != -EACCES) {
- /* in case of EACCES, the parent will retry */
- virReportSystemError(errno,
- _("child failed to create file '%s'"),
- path);
- }
- goto childerror;
- }
- if (fstat(fd, &st) == -1) {
- ret = -errno;
- virReportSystemError(errno, _("stat of '%s' failed"), path);
- goto childerror;
- }
- if ((st.st_gid != gid)
- && (fchown(fd, -1, gid) < 0)) {
- ret = -errno;
- virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"),
- path, (unsigned int) uid, (unsigned int) gid);
- goto childerror;
- }
- if ((flags & VIR_FILE_OPEN_FORCE_PERMS)
- && (fchmod(fd, mode) < 0)) {
- ret = -errno;
- virReportSystemError(errno,
- _("cannot set mode of '%s' to %04o"),
- path, mode);
+
+ ret = virFileOpenAsNoFork(path, openflags, mode, uid, gid, flags);
+ if (ret < 0)
goto childerror;
- }
+ fd = ret;
do {
ret = sendfd(pair[1], fd);
--
1.7.6
3
2
qemuDomainModifyDeviceFlags: Changing "ret" to "0", but don't
reset it to "-1" on failure, it's not good idea to change the value
of "ret" in the codes to do some condition checking. This patch
fix it.
---
src/qemu/qemu_driver.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0a6b48e..ae11c68 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4892,10 +4892,10 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
_("unknown domain modify action %d"), action);
break;
}
- } else
- ret = 0;
+ }
- if (!ret && (flags & VIR_DOMAIN_AFFECT_LIVE)) {
+ if (!(flags & VIR_DOMAIN_AFFECT_CONFIG) &&
+ (flags & VIR_DOMAIN_AFFECT_LIVE)) {
/* If dev exists it was created to modify the domain config. Free it. */
virDomainDeviceDefFree(dev);
dev = virDomainDeviceDefParse(driver->caps, vm->def, xml,
--
1.7.6
3
3
Domain listing, basic information retrieval and domain life cycle
management is implemented. But currently the domian XML output
lacks the complete devices section.
The driver uses OpenWSMAN to directly communicate with an Hyper-V
server over its WS-Management interface exposed via Microsoft WinRM.
Just like the ESX driver this driver includes a generator that
generates the type definitions for the Hyper-V API that are feed
to OpenWSMAN.
Currently there are some sections in the code that are disabled
because of bugs in OpenWSMAN <= 2.2.6. Patches for those problems
have been posted upstream.
The driver is based on the work of Michael Sievers. This started in
the same master program project group at the University of Paderborn
as the ESX driver.
See Michael's blog for details: http://hyperv4libvirt.wordpress.com/
---
cfg.mk | 1 +
configure.ac | 38 +
docs/drivers.html.in | 1 +
docs/drvhyperv.html.in | 103 +++
docs/index.html.in | 3 +
docs/sitemap.html.in | 4 +
include/libvirt/virterror.h | 1 +
libvirt.spec.in | 9 +
po/POTFILES.in | 3 +
src/Makefile.am | 52 ++
src/README | 3 +-
src/driver.h | 1 +
src/hyperv/.gitignore | 1 +
src/hyperv/hyperv_device_monitor.c | 77 ++
src/hyperv/hyperv_device_monitor.h | 29 +
src/hyperv/hyperv_driver.c | 1275 +++++++++++++++++++++++++++++++++
src/hyperv/hyperv_driver.h | 29 +
src/hyperv/hyperv_interface_driver.c | 77 ++
src/hyperv/hyperv_interface_driver.h | 29 +
src/hyperv/hyperv_network_driver.c | 80 ++
src/hyperv/hyperv_network_driver.h | 29 +
src/hyperv/hyperv_nwfilter_driver.c | 77 ++
src/hyperv/hyperv_nwfilter_driver.h | 29 +
src/hyperv/hyperv_private.h | 43 ++
src/hyperv/hyperv_secret_driver.c | 77 ++
src/hyperv/hyperv_secret_driver.h | 29 +
src/hyperv/hyperv_storage_driver.c | 79 ++
src/hyperv/hyperv_storage_driver.h | 29 +
src/hyperv/hyperv_util.c | 129 ++++
src/hyperv/hyperv_util.h | 39 +
src/hyperv/hyperv_wmi.c | 692 ++++++++++++++++++
src/hyperv/hyperv_wmi.h | 119 +++
src/hyperv/hyperv_wmi_classes.c | 37 +
src/hyperv/hyperv_wmi_classes.h | 94 +++
src/hyperv/hyperv_wmi_generator.input | 294 ++++++++
src/hyperv/hyperv_wmi_generator.py | 309 ++++++++
src/hyperv/openwsman.h | 47 ++
src/libvirt.c | 12 +
src/util/virterror.c | 3 +
39 files changed, 3982 insertions(+), 1 deletions(-)
create mode 100644 docs/drvhyperv.html.in
create mode 100644 src/hyperv/.gitignore
create mode 100644 src/hyperv/hyperv_device_monitor.c
create mode 100644 src/hyperv/hyperv_device_monitor.h
create mode 100644 src/hyperv/hyperv_driver.c
create mode 100644 src/hyperv/hyperv_driver.h
create mode 100644 src/hyperv/hyperv_interface_driver.c
create mode 100644 src/hyperv/hyperv_interface_driver.h
create mode 100644 src/hyperv/hyperv_network_driver.c
create mode 100644 src/hyperv/hyperv_network_driver.h
create mode 100644 src/hyperv/hyperv_nwfilter_driver.c
create mode 100644 src/hyperv/hyperv_nwfilter_driver.h
create mode 100644 src/hyperv/hyperv_private.h
create mode 100644 src/hyperv/hyperv_secret_driver.c
create mode 100644 src/hyperv/hyperv_secret_driver.h
create mode 100644 src/hyperv/hyperv_storage_driver.c
create mode 100644 src/hyperv/hyperv_storage_driver.h
create mode 100644 src/hyperv/hyperv_util.c
create mode 100644 src/hyperv/hyperv_util.h
create mode 100644 src/hyperv/hyperv_wmi.c
create mode 100644 src/hyperv/hyperv_wmi.h
create mode 100644 src/hyperv/hyperv_wmi_classes.c
create mode 100644 src/hyperv/hyperv_wmi_classes.h
create mode 100644 src/hyperv/hyperv_wmi_generator.input
create mode 100755 src/hyperv/hyperv_wmi_generator.py
create mode 100644 src/hyperv/openwsman.h
diff --git a/cfg.mk b/cfg.mk
index b00cda3..c20b8c9 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -411,6 +411,7 @@ sc_prohibit_xmlGetProp:
msg_gen_function =
msg_gen_function += ESX_ERROR
msg_gen_function += ESX_VI_ERROR
+msg_gen_function += HYPERV_ERROR
msg_gen_function += PHYP_ERROR
msg_gen_function += VIR_ERROR
msg_gen_function += VMX_ERROR
diff --git a/configure.ac b/configure.ac
index e9d5be4..d7ebe79 100644
--- a/configure.ac
+++ b/configure.ac
@@ -66,6 +66,7 @@ XMLRPC_REQUIRED=1.14.0
HAL_REQUIRED=0.5.0
DEVMAPPER_REQUIRED=1.0.0
LIBCURL_REQUIRED="7.18.0"
+OPENWSMAN_REQUIRED="2.2.6"
LIBPCAP_REQUIRED="1.0.0"
LIBNL_REQUIRED="1.1"
LIBSSH2_REQUIRED="1.0"
@@ -275,6 +276,8 @@ AC_ARG_WITH([lxc],
AC_HELP_STRING([--with-lxc], [add Linux Container support @<:@default=check@:>@]),[],[with_lxc=check])
AC_ARG_WITH([esx],
AC_HELP_STRING([--with-esx], [add ESX support @<:@default=check@:>@]),[],[with_esx=check])
+AC_ARG_WITH([hyperv],
+ AC_HELP_STRING([--with-hyperv], [add Hyper-V support @<:@default=check@:>@]),[],[with_hyperv=check])
AC_ARG_WITH([test],
AC_HELP_STRING([--with-test], [add test driver support @<:@default=yes@:>@]),[],[with_test=yes])
AC_ARG_WITH([remote],
@@ -1912,6 +1915,35 @@ LIBCURL_CFLAGS="-DCURL_DISABLE_TYPECHECK $LIBCURL_CFLAGS"
AC_SUBST([LIBCURL_CFLAGS])
AC_SUBST([LIBCURL_LIBS])
+
+dnl
+dnl check for openwsman (Hyper-V)
+dnl
+
+OPENWSMAN_CFLAGS=""
+OPENWSMAN_LIBS=""
+
+if test "$with_hyperv" = "yes" || test "$with_hyperv" = "check"; then
+ PKG_CHECK_MODULES(OPENWSMAN, openwsman >= $OPENWSMAN_REQUIRED, [
+ if test "$with_hyperv" = "check"; then
+ with_hyperv=yes
+ fi
+ ], [
+ if test "$with_hyperv" = "check"; then
+ with_hyperv=no
+ AC_MSG_NOTICE([openwsman is required for the Hyper-V driver, disabling it])
+ elif test "$with_hyperv" = "yes"; then
+ AC_MSG_ERROR([openwsman >= $OPENWSMAN_REQUIRED is required for the Hyper-V driver])
+ fi
+ ])
+fi
+
+if test "$with_hyperv" = "yes" ; then
+ AC_DEFINE_UNQUOTED([WITH_HYPERV], 1, [whether Hyper-V driver is enabled])
+fi
+AM_CONDITIONAL([WITH_HYPERV], [test "$with_hyperv" = "yes"])
+
+
dnl
dnl check for python
dnl
@@ -2414,6 +2446,7 @@ AC_MSG_NOTICE([xenlight: $with_libxl])
AC_MSG_NOTICE([ LXC: $with_lxc])
AC_MSG_NOTICE([ PHYP: $with_phyp])
AC_MSG_NOTICE([ ESX: $with_esx])
+AC_MSG_NOTICE([ Hyper-V: $with_hyperv])
AC_MSG_NOTICE([ Test: $with_test])
AC_MSG_NOTICE([ Remote: $with_remote])
AC_MSG_NOTICE([ Network: $with_network])
@@ -2455,6 +2488,11 @@ AC_MSG_NOTICE([ libcurl: $LIBCURL_CFLAGS $LIBCURL_LIBS])
else
AC_MSG_NOTICE([ libcurl: no])
fi
+if test "$with_hyperv" = "yes" ; then
+AC_MSG_NOTICE([openwsman: $OPENWSMAN_CFLAGS $OPENWSMAN_LIBS])
+else
+AC_MSG_NOTICE([openwsman: no])
+fi
if test "$with_libssh2" != "no" ; then
AC_MSG_NOTICE([ libssh2: $LIBSSH2_CFLAGS $LIBSSH2_LIBS])
else
diff --git a/docs/drivers.html.in b/docs/drivers.html.in
index 0428870..75038fc 100644
--- a/docs/drivers.html.in
+++ b/docs/drivers.html.in
@@ -28,6 +28,7 @@
<li><strong><a href="drvesx.html">VMware ESX</a></strong></li>
<li><strong><a href="drvvmware.html">VMware Workstation/Player</a></strong></li>
<li><strong><a href="drvxen.html">Xen</a></strong></li>
+ <li><strong><a href="drvhyperv.html">Microsoft Hyper-V</a></strong></li>
</ul>
<h2><a name="stroage">Storage drivers</a></h2>
diff --git a/docs/drvhyperv.html.in b/docs/drvhyperv.html.in
new file mode 100644
index 0000000..dec5969
--- /dev/null
+++ b/docs/drvhyperv.html.in
@@ -0,0 +1,103 @@
+<html><body>
+ <h1>Microsoft Hyper-V hypervisor driver</h1>
+ <ul id="toc"></ul>
+ <p>
+ The libvirt Microsoft Hyper-V driver can manage Hyper-V 2008 R2.
+ </p>
+
+
+ <h2><a name="uri">Connections to the Microsoft Hyper-V driver</a></h2>
+ <p>
+ Some example remote connection URIs for the driver are:
+ </p>
+<pre>
+hyperv://example-hyperv.com (over HTTPS)
+hyperv://example-hyperv.com/?transport=http (over HTTP)
+</pre>
+ <p>
+ <strong>Note</strong>: In contrast to other drivers, the Hyper-V driver
+ is a client-side-only driver. It connects to the Hyper-V server using
+ WS-Management over HTTP(S). Therefore, the
+ <a href="remote.html">remote transport mechanism</a> provided by the
+ remote driver and libvirtd will not work, and you cannot use URIs like
+ <code>hyperv+ssh://example.com</code>.
+ </p>
+
+
+ <h3><a name="uriformat">URI Format</a></h3>
+ <p>
+ URIs have this general form (<code>[...]</code> marks an optional part).
+ </p>
+<pre>
+hyperv://[username@]hostname[:port]/[?extraparameters]
+</pre>
+ <p>
+ The default HTTPS ports is 5986. If the port parameter is given, it
+ overrides the default port.
+ </p>
+
+
+ <h4><a name="extraparams">Extra parameters</a></h4>
+ <p>
+ Extra parameters can be added to a URI as part of the query string
+ (the part following <code>?</code>). A single parameter is formed by a
+ <code>name=value</code> pair. Multiple parameters are separated by
+ <code>&</code>.
+ </p>
+<pre>
+?transport=http
+</pre>
+ <p>
+ The driver understands the extra parameters shown below.
+ </p>
+ <table class="top_table">
+ <tr>
+ <th>Name</th>
+ <th>Values</th>
+ <th>Meaning</th>
+ </tr>
+ <tr>
+ <td>
+ <code>transport</code>
+ </td>
+ <td>
+ <code>http</code> or <code>https</code>
+ </td>
+ <td>
+ Overrides the default HTTPS transport. The default HTTP port
+ is 5985.
+ </td>
+ </tr>
+ </table>
+
+
+ <h3><a name="auth">Authentication</a></h3>
+ <p>
+ In order to perform any useful operation the driver needs to log into
+ the Hyper-V server. Therefore, only <code>virConnectOpenAuth</code> can
+ be used to connect to an Hyper-V server, <code>virConnectOpen</code> and
+ <code>virConnectOpenReadOnly</code> don't work.
+ To log into an Hyper-V server the driver will request credentials using
+ the callback passed to the <code>virConnectOpenAuth</code> function.
+ The driver passes the hostname as challenge parameter to the callback.
+ </p>
+ <p>
+ <strong>Note</strong>: Currently only <code>Basic</code> authentication
+ is supported by libvirt. This method is disabled by default on the
+ Hyper-V server and can be enabled via the WinRM commandline tool.
+ </p>
+<pre>
+winrm set winrm/config/service/auth @{Basic="true"}
+</pre>
+ <p>
+ To allow <code>Basic</code> authentication with HTTP transport WinRM
+ needs to allow unencrypted communication. This can be enabled via the
+ WinRM commandline tool. Although this is not the recommended
+ communication mode.
+ </p>
+<pre>
+winrm set winrm/config/service @{AllowUnencrypted="true"}
+</pre>
+
+
+</body></html>
diff --git a/docs/index.html.in b/docs/index.html.in
index 64eb84d..73c2bf8 100644
--- a/docs/index.html.in
+++ b/docs/index.html.in
@@ -63,6 +63,9 @@
The <a href="http://www.vmware.com/">VMware Workstation and Player</a> hypervisors
</li>
<li>
+ The <a href="http://www.microsoft.com/hyper-v-server/">Microsoft Hyper-V</a> hypervisor
+ </li>
+ <li>
Storage on IDE/SCSI/USB disks, FibreChannel, LVM, iSCSI, NFS and filesystems
</li>
</ul>
diff --git a/docs/sitemap.html.in b/docs/sitemap.html.in
index 897ee94..2c71763 100644
--- a/docs/sitemap.html.in
+++ b/docs/sitemap.html.in
@@ -202,6 +202,10 @@
<a href="drvvmware.html">VMware Workstation / Player</a>
<span>Driver for VMware Workstation / Player</span>
</li>
+ <li>
+ <a href="drvhyperv.html">Microsoft Hyper-V</a>
+ <span>Driver for Microsoft Hyper-V</span>
+ </li>
</ul>
</li>
<li>
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index efa4796..bd64eb4 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -82,6 +82,7 @@ typedef enum {
VIR_FROM_EVENT = 40, /* Error from event loop impl */
VIR_FROM_LIBXL = 41, /* Error from libxenlight driver */
VIR_FROM_LOCKING = 42, /* Error from lock manager */
+ VIR_FROM_HYPERV = 43, /* Error from Hyper-V driver */
} virErrorDomain;
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 230237e..c971681 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -50,6 +50,7 @@
# Then the hypervisor drivers that talk a native remote protocol
%define with_phyp 0%{!?_without_phyp:1}
%define with_esx 0%{!?_without_esx:1}
+%define with_hyperv 0%{!?_without_hyperv:1}
%define with_xenapi 0%{!?_without_xenapi:1}
# Then the secondary host drivers
@@ -437,6 +438,9 @@ BuildRequires: libcurl-devel
BuildRequires: curl-devel
%endif
%endif
+%if %{with_hyperv}
+BuildRequires: openwsman-devel >= 2.2.6
+%endif
%if %{with_audit}
BuildRequires: audit-libs-devel
%endif
@@ -569,6 +573,10 @@ of recent versions of Linux (and other OSes).
%define _without_esx --without-esx
%endif
+%if ! %{with_hyperv}
+%define _without_hyperv --without-hyperv
+%endif
+
%if ! %{with_vmware}
%define _without_vmware --without-vmware
%endif
@@ -687,6 +695,7 @@ of recent versions of Linux (and other OSes).
%{?_without_one} \
%{?_without_phyp} \
%{?_without_esx} \
+ %{?_without_hyperv} \
%{?_without_vmware} \
%{?_without_network} \
%{?_with_rhel5_api} \
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5782cbf..809ace6 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -28,6 +28,9 @@ src/esx/esx_vi.c
src/esx/esx_vi_methods.c
src/esx/esx_vi_types.c
src/fdstream.c
+src/hyperv/hyperv_driver.c
+src/hyperv/hyperv_util.c
+src/hyperv/hyperv_wmi.c
src/interface/netcf_driver.c
src/internal.h
src/libvirt.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 39f0cf8..7b7a959 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -379,6 +379,32 @@ ESX_DRIVER_EXTRA_DIST = \
esx/esx_vi_generator.py \
$(ESX_DRIVER_GENERATED)
+HYPERV_DRIVER_SOURCES = \
+ hyperv/hyperv_private.h \
+ hyperv/hyperv_driver.c hyperv/hyperv_driver.h \
+ hyperv/hyperv_interface_driver.c hyperv/hyperv_interface_driver.h \
+ hyperv/hyperv_network_driver.c hyperv/hyperv_network_driver.h \
+ hyperv/hyperv_storage_driver.c hyperv/hyperv_storage_driver.h \
+ hyperv/hyperv_device_monitor.c hyperv/hyperv_device_monitor.h \
+ hyperv/hyperv_secret_driver.c hyperv/hyperv_secret_driver.h \
+ hyperv/hyperv_nwfilter_driver.c hyperv/hyperv_nwfilter_driver.h \
+ hyperv/hyperv_util.c hyperv/hyperv_util.h \
+ hyperv/hyperv_wmi.c hyperv/hyperv_wmi.h \
+ hyperv/hyperv_wmi_classes.c hyperv/hyperv_wmi_classes.h \
+ hyperv/openwsman.h
+
+HYPERV_DRIVER_GENERATED = \
+ hyperv/hyperv_wmi.generated.c \
+ hyperv/hyperv_wmi.generated.h \
+ hyperv/hyperv_wmi_classes.generated.c \
+ hyperv/hyperv_wmi_classes.generated.h \
+ hyperv/hyperv_wmi_classes.generated.typedef
+
+HYPERV_DRIVER_EXTRA_DIST = \
+ hyperv/hyperv_wmi_generator.input \
+ hyperv/hyperv_wmi_generator.py \
+ $(HYPERV_DRIVER_GENERATED)
+
NETWORK_DRIVER_SOURCES = \
network/bridge_driver.h network/bridge_driver.c
@@ -809,6 +835,31 @@ libvirt_driver_esx_la_SOURCES = $(ESX_DRIVER_SOURCES)
libvirt_driver_esx_la_DEPENDENCIES = $(ESX_DRIVER_GENERATED)
endif
+
+BUILT_SOURCES += $(HYPERV_DRIVER_GENERATED)
+
+$(HYPERV_DRIVER_GENERATED): $(srcdir)/hyperv/hyperv_wmi_generator.input \
+ $(srcdir)/hyperv/hyperv_wmi_generator.py
+ $(AM_V_GEN)srcdir=$(srcdir) $(srcdir)/hyperv/hyperv_wmi_generator.py
+
+if WITH_HYPERV
+if WITH_DRIVER_MODULES
+mod_LTLIBRARIES += libvirt_driver_hyperv.la
+else
+noinst_LTLIBRARIES += libvirt_driver_hyperv.la
+libvirt_la_BUILT_LIBADD += libvirt_driver_hyperv.la
+endif
+libvirt_driver_hyperv_la_CFLAGS = $(OPENWSMAN_CFLAGS) \
+ -I@top_srcdir@/src/conf -I@top_srcdir@/src/vmx $(AM_CFLAGS)
+libvirt_driver_hyperv_la_LDFLAGS = $(AM_LDFLAGS)
+libvirt_driver_hyperv_la_LIBADD = $(OPENWSMAN_LIBS)
+if WITH_DRIVER_MODULES
+libvirt_driver_hyperv_la_LIBADD += ../gnulib/lib/libgnu.la
+libvirt_driver_hyperv_la_LDFLAGS += -module -avoid-version
+endif
+libvirt_driver_hyperv_la_SOURCES = $(HYPERV_DRIVER_SOURCES)
+endif
+
if WITH_NETWORK
if WITH_DRIVER_MODULES
mod_LTLIBRARIES += libvirt_driver_network.la
@@ -1000,6 +1051,7 @@ EXTRA_DIST += \
$(LIBXL_DRIVER_SOURCES) \
$(ESX_DRIVER_SOURCES) \
$(ESX_DRIVER_EXTRA_DIST) \
+ $(HYPERV_DRIVER_SOURCES) \
$(NETWORK_DRIVER_SOURCES) \
$(INTERFACE_DRIVER_SOURCES) \
$(STORAGE_DRIVER_SOURCES) \
diff --git a/src/README b/src/README
index f95a8b7..00d11d1 100644
--- a/src/README
+++ b/src/README
@@ -26,6 +26,7 @@ There are two core shared modules to be aware of:
Then there are the hypervisor implementations:
* esx/ - VMware ESX and GSX support using vSphere API over SOAP
+ * hyperv/ - Microsoft Hyper-V support using WinRM
* lxc/ - Linux Native Containers
* openvz/ - OpenVZ containers using cli tools
* phyp/ - IBM Power Hypervisor using CLI tools over SSH
@@ -41,7 +42,7 @@ Then there are the hypervisor implementations:
Finally some secondary drivers that are shared for several HVs.
Currently these are used by LXC, OpenVZ, QEMU, UML and Xen drivers.
-The ESX, Power Hypervisor, Remote, Test & VirtualBox drivers all
+The ESX, Hyper-V, Power Hypervisor, Remote, Test & VirtualBox drivers all
implement the secondary drivers directly
* cpu/ - CPU feature management
diff --git a/src/driver.h b/src/driver.h
index 70ea4c2..589f232 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -29,6 +29,7 @@ typedef enum {
VIR_DRV_XENAPI = 12,
VIR_DRV_VMWARE = 13,
VIR_DRV_LIBXL = 14,
+ VIR_DRV_HYPERV = 15,
} virDrvNo;
diff --git a/src/hyperv/.gitignore b/src/hyperv/.gitignore
new file mode 100644
index 0000000..29e1d48
--- /dev/null
+++ b/src/hyperv/.gitignore
@@ -0,0 +1 @@
+*.generated.*
diff --git a/src/hyperv/hyperv_device_monitor.c b/src/hyperv/hyperv_device_monitor.c
new file mode 100644
index 0000000..2bf1eb6
--- /dev/null
+++ b/src/hyperv/hyperv_device_monitor.c
@@ -0,0 +1,77 @@
+
+/*
+ * hyperv_device_monitor.c: device monitor functions for managing
+ * Microsoft Hyper-V host devices
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#include "internal.h"
+#include "datatypes.h"
+#include "util.h"
+#include "memory.h"
+#include "logging.h"
+#include "uuid.h"
+#include "hyperv_private.h"
+#include "hyperv_device_monitor.h"
+
+#define VIR_FROM_THIS VIR_FROM_HYPERV
+
+
+
+static virDrvOpenStatus
+hypervDeviceOpen(virConnectPtr conn,
+ virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ if (conn->driver->no != VIR_DRV_HYPERV) {
+ return VIR_DRV_OPEN_DECLINED;
+ }
+
+ conn->devMonPrivateData = conn->privateData;
+
+ return VIR_DRV_OPEN_SUCCESS;
+}
+
+
+
+static int
+hypervDeviceClose(virConnectPtr conn)
+{
+ conn->devMonPrivateData = NULL;
+
+ return 0;
+}
+
+
+
+static virDeviceMonitor hypervDeviceMonitor = {
+ "Hyper-V",
+ .open = hypervDeviceOpen, /* 0.9.4 */
+ .close = hypervDeviceClose, /* 0.9.4 */
+};
+
+
+
+int
+hypervDeviceRegister(void)
+{
+ return virRegisterDeviceMonitor(&hypervDeviceMonitor);
+}
diff --git a/src/hyperv/hyperv_device_monitor.h b/src/hyperv/hyperv_device_monitor.h
new file mode 100644
index 0000000..864e8af
--- /dev/null
+++ b/src/hyperv/hyperv_device_monitor.h
@@ -0,0 +1,29 @@
+
+/*
+ * hyperv_device_monitor.h: device monitor functions for managing
+ * Microsoft Hyper-V host devices
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __HYPERV_DEVICE_MONITOR_H__
+# define __HYPERV_DEVICE_MONITOR_H__
+
+int hypervDeviceRegister(void);
+
+#endif /* __HYPERV_DEVICE_MONITOR_H__ */
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
new file mode 100644
index 0000000..a1d56a5
--- /dev/null
+++ b/src/hyperv/hyperv_driver.c
@@ -0,0 +1,1275 @@
+
+/*
+ * hyperv_driver.c: core driver functions for managing Microsoft Hyper-V hosts
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ * Copyright (C) 2009 Michael Sievers <msievers83(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#include "internal.h"
+#include "datatypes.h"
+#include "domain_conf.h"
+#include "authhelper.h"
+#include "util.h"
+#include "memory.h"
+#include "logging.h"
+#include "uuid.h"
+#include "hyperv_driver.h"
+#include "hyperv_interface_driver.h"
+#include "hyperv_network_driver.h"
+#include "hyperv_storage_driver.h"
+#include "hyperv_device_monitor.h"
+#include "hyperv_secret_driver.h"
+#include "hyperv_nwfilter_driver.h"
+#include "hyperv_private.h"
+#include "hyperv_util.h"
+#include "hyperv_wmi.h"
+#include "openwsman.h"
+
+#define VIR_FROM_THIS VIR_FROM_HYPERV
+
+
+
+static void
+hypervFreePrivate(hypervPrivate **priv)
+{
+ if (priv == NULL || *priv == NULL) {
+ return;
+ }
+
+ if ((*priv)->client != NULL) {
+ /* FIXME: This leaks memory due to bugs in openwsman <= 2.2.6 */
+ wsmc_release((*priv)->client);
+ }
+
+ hypervFreeParsedUri(&(*priv)->parsedUri);
+ VIR_FREE(*priv);
+}
+
+
+
+static virDrvOpenStatus
+hypervOpen(virConnectPtr conn, virConnectAuthPtr auth,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ virDrvOpenStatus result = VIR_DRV_OPEN_ERROR;
+ hypervPrivate *priv = NULL;
+ char *username = NULL;
+ char *password = NULL;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_ComputerSystem *computerSystem = NULL;
+
+ /* Decline if the URI is NULL or the scheme is not hyperv */
+ if (conn->uri == NULL || conn->uri->scheme == NULL ||
+ STRCASENEQ(conn->uri->scheme, "hyperv")) {
+ return VIR_DRV_OPEN_DECLINED;
+ }
+
+ /* Require server part */
+ if (conn->uri->server == NULL) {
+ HYPERV_ERROR(VIR_ERR_INVALID_ARG, "%s",
+ _("URI is missing the server part"));
+ return VIR_DRV_OPEN_ERROR;
+ }
+
+ /* Require auth */
+ if (auth == NULL || auth->cb == NULL) {
+ HYPERV_ERROR(VIR_ERR_INVALID_ARG, "%s",
+ _("Missing or invalid auth pointer"));
+ return VIR_DRV_OPEN_ERROR;
+ }
+
+ /* Allocate per-connection private data */
+ if (VIR_ALLOC(priv) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (hypervParseUri(&priv->parsedUri, conn->uri) < 0) {
+ goto cleanup;
+ }
+
+ /* Set the port dependent on the transport protocol if no port is
+ * specified. This allows us to rely on the port parameter being
+ * correctly set when building URIs later on, without the need to
+ * distinguish between the situations port == 0 and port != 0 */
+ if (conn->uri->port == 0) {
+ if (STRCASEEQ(priv->parsedUri->transport, "https")) {
+ conn->uri->port = 5986;
+ } else {
+ conn->uri->port = 5985;
+ }
+ }
+
+ /* Request credentials */
+ if (conn->uri->user != NULL) {
+ username = strdup(conn->uri->user);
+
+ if (username == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ } else {
+ username = virRequestUsername(auth, "administrator", conn->uri->server);
+
+ if (username == NULL) {
+ HYPERV_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed"));
+ goto cleanup;
+ }
+ }
+
+ password = virRequestPassword(auth, username, conn->uri->server);
+
+ if (password == NULL) {
+ HYPERV_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed"));
+ goto cleanup;
+ }
+
+ /* Initialize the openwsman connection */
+ priv->client = wsmc_create(conn->uri->server, conn->uri->port, "/wsman",
+ priv->parsedUri->transport, username, password);
+
+ if (priv->client == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not create openwsman client"));
+ goto cleanup;
+ }
+
+ if (wsmc_transport_init(priv->client, NULL) != 0) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not initialize openwsman transport"));
+ goto cleanup;
+ }
+
+ /* FIXME: Currently only basic authentication is supported */
+ wsman_transport_set_auth_method(priv->client, "basic");
+
+ /* Check if the connection can be established and if the server has the
+ * Hyper-V role installed. If the call to hypervGetMsvmComputerSystemList
+ * succeeds than the connection has be established. If the returned list
+ * is empty than the server isn't a Hyper-V server. */
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+ virBufferAddLit(&query, "where ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_PHYSICAL);
+
+ if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ if (computerSystem == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("%s is not a Hyper-V server"), conn->uri->server);
+ goto cleanup;
+ }
+
+ conn->privateData = priv;
+
+ result = VIR_DRV_OPEN_SUCCESS;
+
+ cleanup:
+ if (result == VIR_DRV_OPEN_ERROR) {
+ hypervFreePrivate(&priv);
+ }
+
+ VIR_FREE(username);
+ VIR_FREE(password);
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return result;
+}
+
+
+
+static int
+hypervClose(virConnectPtr conn)
+{
+ hypervPrivate *priv = conn->privateData;
+
+ hypervFreePrivate(&priv);
+
+ conn->privateData = NULL;
+
+ return 0;
+}
+
+
+
+static const char *
+hypervGetType(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+ return "Hyper-V";
+}
+
+
+
+static char *
+hypervGetHostname(virConnectPtr conn)
+{
+ char *hostname = NULL;
+ hypervPrivate *priv = conn->privateData;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Win32_ComputerSystem *computerSystem = NULL;
+
+ virBufferAddLit(&query, WIN32_COMPUTERSYSTEM_WQL_SELECT);
+
+ if (hypervGetWin32ComputerSystemList(priv, &query, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ if (computerSystem == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup %s"),
+ "Win32_ComputerSystem");
+ goto cleanup;
+ }
+
+ hostname = strdup(computerSystem->data->DNSHostName);
+
+ if (hostname == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return hostname;
+}
+
+
+
+static int
+hypervNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
+{
+ int result = -1;
+ hypervPrivate *priv = conn->privateData;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Win32_ComputerSystem *computerSystem = NULL;
+ Win32_Processor *processorList = NULL;
+ Win32_Processor *processor = NULL;
+ char *tmp;
+
+ memset(info, 0, sizeof (*info));
+
+ virBufferAddLit(&query, WIN32_COMPUTERSYSTEM_WQL_SELECT);
+
+ /* Get Win32_ComputerSystem */
+ if (hypervGetWin32ComputerSystemList(priv, &query, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ if (computerSystem == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup %s"),
+ "Win32_ComputerSystem");
+ goto cleanup;
+ }
+
+ /* Get Win32_Processor list */
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Win32_ComputerSystem.Name=\"%s\"} "
+ "where AssocClass = Win32_ComputerSystemProcessor "
+ "ResultClass = Win32_Processor",
+ computerSystem->data->Name);
+
+ if (hypervGetWin32ProcessorList(priv, &query, &processorList) < 0) {
+ goto cleanup;
+ }
+
+ if (processorList == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup %s"),
+ "Win32_Processor");
+ goto cleanup;
+ }
+
+ /* Strip the string to fit more relevant information in 32 chars */
+ tmp = processorList->data->Name;
+
+ while (*tmp != '\0') {
+ if (STRPREFIX(tmp, " ")) {
+ memmove(tmp, tmp + 1, strlen(tmp + 1) + 1);
+ continue;
+ } else if (STRPREFIX(tmp, "(R)") || STRPREFIX(tmp, "(C)")) {
+ memmove(tmp, tmp + 3, strlen(tmp + 3) + 1);
+ continue;
+ } else if (STRPREFIX(tmp, "(TM)")) {
+ memmove(tmp, tmp + 4, strlen(tmp + 4) + 1);
+ continue;
+ }
+
+ ++tmp;
+ }
+
+ /* Fill struct */
+ if (virStrncpy(info->model, processorList->data->Name,
+ sizeof (info->model) - 1, sizeof (info->model)) == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("CPU model %s too long for destination"),
+ processorList->data->Name);
+ goto cleanup;
+ }
+
+ info->memory = computerSystem->data->TotalPhysicalMemory / 1024; /* byte to kilobyte */
+ info->mhz = processorList->data->MaxClockSpeed;
+ info->nodes = 1;
+ info->sockets = 0;
+
+ for (processor = processorList; processor != NULL;
+ processor = processor->next) {
+ ++info->sockets;
+ }
+
+ info->cores = processorList->data->NumberOfCores;
+ info->threads = info->cores / processorList->data->NumberOfLogicalProcessors;
+ info->cpus = info->sockets * info->cores;
+
+ result = 0;
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+ hypervFreeObject(priv, (hypervObject *)processorList);
+
+ return result;
+}
+
+
+
+static int
+hypervListDomains(virConnectPtr conn, int *ids, int maxids)
+{
+ bool success = false;
+ hypervPrivate *priv = conn->privateData;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_ComputerSystem *computerSystemList = NULL;
+ Msvm_ComputerSystem *computerSystem = NULL;
+ int count = 0;
+
+ if (maxids == 0) {
+ return 0;
+ }
+
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+ virBufferAddLit(&query, "where ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL);
+ virBufferAddLit(&query, "and ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_ACTIVE);
+
+ if (hypervGetMsvmComputerSystemList(priv, &query,
+ &computerSystemList) < 0) {
+ goto cleanup;
+ }
+
+ for (computerSystem = computerSystemList; computerSystem != NULL;
+ computerSystem = computerSystem->next) {
+ ids[count++] = computerSystem->data->ProcessID;
+
+ if (count >= maxids) {
+ break;
+ }
+ }
+
+ success = true;
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystemList);
+
+ return success ? count : -1;
+}
+
+
+
+static int
+hypervNumberOfDomains(virConnectPtr conn)
+{
+ bool success = false;
+ hypervPrivate *priv = conn->privateData;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_ComputerSystem *computerSystemList = NULL;
+ Msvm_ComputerSystem *computerSystem = NULL;
+ int count = 0;
+
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+ virBufferAddLit(&query, "where ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL);
+ virBufferAddLit(&query, "and ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_ACTIVE);
+
+ if (hypervGetMsvmComputerSystemList(priv, &query,
+ &computerSystemList) < 0) {
+ goto cleanup;
+ }
+
+ for (computerSystem = computerSystemList; computerSystem != NULL;
+ computerSystem = computerSystem->next) {
+ ++count;
+ }
+
+ success = true;
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystemList);
+
+ return success ? count : -1;
+}
+
+
+
+static virDomainPtr
+hypervDomainLookupByID(virConnectPtr conn, int id)
+{
+ virDomainPtr domain = NULL;
+ hypervPrivate *priv = conn->privateData;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_ComputerSystem *computerSystem = NULL;
+
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+ virBufferAddLit(&query, "where ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL);
+ virBufferAsprintf(&query, "and ProcessID = %d", id);
+
+ if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ if (computerSystem == NULL) {
+ HYPERV_ERROR(VIR_ERR_NO_DOMAIN, _("No domain with ID %d"), id);
+ goto cleanup;
+ }
+
+ hypervMsvmComputerSystemToDomain(conn, computerSystem, &domain);
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return domain;
+}
+
+
+
+static virDomainPtr
+hypervDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
+{
+ virDomainPtr domain = NULL;
+ hypervPrivate *priv = conn->privateData;
+ char uuid_string[VIR_UUID_STRING_BUFLEN];
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_ComputerSystem *computerSystem = NULL;
+
+ virUUIDFormat(uuid, uuid_string);
+
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+ virBufferAddLit(&query, "where ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL);
+ virBufferAsprintf(&query, "and Name = \"%s\"", uuid_string);
+
+ if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ if (computerSystem == NULL) {
+ HYPERV_ERROR(VIR_ERR_NO_DOMAIN,
+ _("No domain with UUID %s"), uuid_string);
+ goto cleanup;
+ }
+
+ hypervMsvmComputerSystemToDomain(conn, computerSystem, &domain);
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return domain;
+}
+
+
+
+static virDomainPtr
+hypervDomainLookupByName(virConnectPtr conn, const char *name)
+{
+ virDomainPtr domain = NULL;
+ hypervPrivate *priv = conn->privateData;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_ComputerSystem *computerSystem = NULL;
+
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+ virBufferAddLit(&query, "where ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL);
+ virBufferAsprintf(&query, "and ElementName = \"%s\"", name);
+
+ if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ if (computerSystem == NULL) {
+ HYPERV_ERROR(VIR_ERR_NO_DOMAIN,
+ _("No domain with name %s"), name);
+ goto cleanup;
+ }
+
+ hypervMsvmComputerSystemToDomain(conn, computerSystem, &domain);
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return domain;
+}
+
+
+
+static int
+hypervDomainSuspend(virDomainPtr domain)
+{
+ int result = -1;
+ hypervPrivate *priv = domain->conn->privateData;
+ Msvm_ComputerSystem *computerSystem = NULL;
+
+ if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ if (computerSystem->data->EnabledState !=
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_ENABLED) {
+ HYPERV_ERROR(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Domain is not active"));
+ goto cleanup;
+ }
+
+ result = hypervInvokeMsvmComputerSystemRequestStateChange
+ (domain, MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_PAUSED);
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return result;
+}
+
+
+
+static int
+hypervDomainResume(virDomainPtr domain)
+{
+ int result = -1;
+ hypervPrivate *priv = domain->conn->privateData;
+ Msvm_ComputerSystem *computerSystem = NULL;
+
+ if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ if (computerSystem->data->EnabledState !=
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_PAUSED) {
+ HYPERV_ERROR(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Domain is not paused"));
+ goto cleanup;
+ }
+
+ result = hypervInvokeMsvmComputerSystemRequestStateChange
+ (domain, MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_ENABLED);
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return result;
+}
+
+
+
+static int
+hypervDomainDestroy(virDomainPtr domain)
+{
+ int result = -1;
+ hypervPrivate *priv = domain->conn->privateData;
+ Msvm_ComputerSystem *computerSystem = NULL;
+ bool in_transition = false;
+
+ if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ if (!hypervIsMsvmComputerSystemActive(computerSystem, &in_transition) ||
+ in_transition) {
+ HYPERV_ERROR(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Domain is not active or is in state transition"));
+ goto cleanup;
+ }
+
+ result = hypervInvokeMsvmComputerSystemRequestStateChange
+ (domain, MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_DISABLED);
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return result;
+}
+
+
+
+static char *
+hypervDomainGetOSType(virDomainPtr domain ATTRIBUTE_UNUSED)
+{
+ char *osType = strdup("hvm");
+
+ if (osType == NULL) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ return osType;
+}
+
+
+
+static int
+hypervDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
+{
+ int result = -1;
+ hypervPrivate *priv = domain->conn->privateData;
+ char uuid_string[VIR_UUID_STRING_BUFLEN];
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_ComputerSystem *computerSystem = NULL;
+ Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+ Msvm_ProcessorSettingData *processorSettingData = NULL;
+ Msvm_MemorySettingData *memorySettingData = NULL;
+
+ memset(info, 0, sizeof (*info));
+
+ virUUIDFormat(domain->uuid, uuid_string);
+
+ /* Get Msvm_ComputerSystem */
+ if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ /* Get Msvm_VirtualSystemSettingData */
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+ "Name=\"%s\"} "
+ "where AssocClass = Msvm_SettingsDefineState "
+ "ResultClass = Msvm_VirtualSystemSettingData",
+ uuid_string);
+
+ if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query,
+ &virtualSystemSettingData) < 0) {
+ goto cleanup;
+ }
+
+ if (virtualSystemSettingData == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup %s for domain %s"),
+ "Msvm_VirtualSystemSettingData",
+ computerSystem->data->ElementName);
+ goto cleanup;
+ }
+
+ /* Get Msvm_ProcessorSettingData */
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+ "where AssocClass = Msvm_VirtualSystemSettingDataComponent "
+ "ResultClass = Msvm_ProcessorSettingData",
+ virtualSystemSettingData->data->InstanceID);
+
+ if (hypervGetMsvmProcessorSettingDataList(priv, &query,
+ &processorSettingData) < 0) {
+ goto cleanup;
+ }
+
+ if (processorSettingData == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup %s for domain %s"),
+ "Msvm_ProcessorSettingData",
+ computerSystem->data->ElementName);
+ goto cleanup;
+ }
+
+ /* Get Msvm_MemorySettingData */
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+ "where AssocClass = Msvm_VirtualSystemSettingDataComponent "
+ "ResultClass = Msvm_MemorySettingData",
+ virtualSystemSettingData->data->InstanceID);
+
+ if (hypervGetMsvmMemorySettingDataList(priv, &query,
+ &memorySettingData) < 0) {
+ goto cleanup;
+ }
+
+
+ if (memorySettingData == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup %s for domain %s"),
+ "Msvm_MemorySettingData",
+ computerSystem->data->ElementName);
+ goto cleanup;
+ }
+
+ /* Fill struct */
+ info->state = hypervMsvmComputerSystemEnabledStateToDomainState(computerSystem);
+ info->maxMem = memorySettingData->data->Limit * 1024; /* megabyte to kilobyte */
+ info->memory = memorySettingData->data->VirtualQuantity * 1024; /* megabyte to kilobyte */
+ info->nrVirtCpu = processorSettingData->data->VirtualQuantity;
+ info->cpuTime = 0;
+
+ result = 0;
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+ hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+ hypervFreeObject(priv, (hypervObject *)processorSettingData);
+ hypervFreeObject(priv, (hypervObject *)memorySettingData);
+
+ return result;
+}
+
+
+
+static int
+hypervDomainGetState(virDomainPtr domain, int *state, int *reason,
+ unsigned int flags)
+{
+ int result = -1;
+ hypervPrivate *priv = domain->conn->privateData;
+ Msvm_ComputerSystem *computerSystem = NULL;
+
+ virCheckFlags(0, -1);
+
+ if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ *state = hypervMsvmComputerSystemEnabledStateToDomainState(computerSystem);
+
+ if (reason != NULL) {
+ *reason = 0;
+ }
+
+ result = 0;
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return result;
+}
+
+
+
+static char *
+hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
+{
+ char *xml = NULL;
+ hypervPrivate *priv = domain->conn->privateData;
+ virDomainDefPtr def = NULL;
+ char uuid_string[VIR_UUID_STRING_BUFLEN];
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_ComputerSystem *computerSystem = NULL;
+ Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+ Msvm_ProcessorSettingData *processorSettingData = NULL;
+ Msvm_MemorySettingData *memorySettingData = NULL;
+
+ if (VIR_ALLOC(def) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ virUUIDFormat(domain->uuid, uuid_string);
+
+ /* Get Msvm_ComputerSystem */
+ if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ /* Get Msvm_VirtualSystemSettingData */
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+ "Name=\"%s\"} "
+ "where AssocClass = Msvm_SettingsDefineState "
+ "ResultClass = Msvm_VirtualSystemSettingData",
+ uuid_string);
+
+ if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query,
+ &virtualSystemSettingData) < 0) {
+ goto cleanup;
+ }
+
+ if (virtualSystemSettingData == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup %s for domain %s"),
+ "Msvm_VirtualSystemSettingData",
+ computerSystem->data->ElementName);
+ goto cleanup;
+ }
+
+ /* Get Msvm_ProcessorSettingData */
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+ "where AssocClass = Msvm_VirtualSystemSettingDataComponent "
+ "ResultClass = Msvm_ProcessorSettingData",
+ virtualSystemSettingData->data->InstanceID);
+
+ if (hypervGetMsvmProcessorSettingDataList(priv, &query,
+ &processorSettingData) < 0) {
+ goto cleanup;
+ }
+
+ if (processorSettingData == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup %s for domain %s"),
+ "Msvm_ProcessorSettingData",
+ computerSystem->data->ElementName);
+ goto cleanup;
+ }
+
+ /* Get Msvm_MemorySettingData */
+ virBufferAsprintf(&query,
+ "associators of "
+ "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+ "where AssocClass = Msvm_VirtualSystemSettingDataComponent "
+ "ResultClass = Msvm_MemorySettingData",
+ virtualSystemSettingData->data->InstanceID);
+
+ if (hypervGetMsvmMemorySettingDataList(priv, &query,
+ &memorySettingData) < 0) {
+ goto cleanup;
+ }
+
+
+ if (memorySettingData == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup %s for domain %s"),
+ "Msvm_MemorySettingData",
+ computerSystem->data->ElementName);
+ goto cleanup;
+ }
+
+ /* Fill struct */
+ def->virtType = VIR_DOMAIN_VIRT_HYPERV;
+
+ if (hypervIsMsvmComputerSystemActive(computerSystem, NULL)) {
+ def->id = computerSystem->data->ProcessID;
+ } else {
+ def->id = -1;
+ }
+
+ if (virUUIDParse(computerSystem->data->Name, def->uuid) < 0) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not parse UUID from string '%s'"),
+ computerSystem->data->Name);
+ return NULL;
+ }
+
+ def->name = strdup(computerSystem->data->ElementName);
+
+ if (def->name == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (virtualSystemSettingData->data->Notes != NULL) {
+ def->description = strdup(virtualSystemSettingData->data->Notes);
+
+ if (def->description == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
+ def->mem.max_balloon = memorySettingData->data->Limit * 1024; /* megabyte to kilobyte */
+ def->mem.cur_balloon = memorySettingData->data->VirtualQuantity * 1024; /* megabyte to kilobyte */
+
+ def->vcpus = processorSettingData->data->VirtualQuantity;
+ def->maxvcpus = processorSettingData->data->VirtualQuantity;
+
+ def->os.type = strdup("hvm");
+
+ if (def->os.type == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ /* FIXME: devices section is totally missing */
+
+ xml = virDomainDefFormat(def, flags);
+
+ cleanup:
+ virDomainDefFree(def);
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+ hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+ hypervFreeObject(priv, (hypervObject *)processorSettingData);
+ hypervFreeObject(priv, (hypervObject *)memorySettingData);
+
+ return xml;
+}
+
+
+
+static int
+hypervListDefinedDomains(virConnectPtr conn, char **const names, int maxnames)
+{
+ bool success = false;
+ hypervPrivate *priv = conn->privateData;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_ComputerSystem *computerSystemList = NULL;
+ Msvm_ComputerSystem *computerSystem = NULL;
+ int count = 0;
+ int i;
+
+ if (maxnames == 0) {
+ return 0;
+ }
+
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+ virBufferAddLit(&query, "where ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL);
+ virBufferAddLit(&query, "and ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_INACTIVE);
+
+ if (hypervGetMsvmComputerSystemList(priv, &query,
+ &computerSystemList) < 0) {
+ goto cleanup;
+ }
+
+ for (computerSystem = computerSystemList; computerSystem != NULL;
+ computerSystem = computerSystem->next) {
+ names[count] = strdup(computerSystem->data->ElementName);
+
+ if (names[count] == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ ++count;
+
+ if (count >= maxnames) {
+ break;
+ }
+ }
+
+ success = true;
+
+ cleanup:
+ if (!success) {
+ for (i = 0; i < count; ++i) {
+ VIR_FREE(names[i]);
+ }
+
+ count = -1;
+ }
+
+ hypervFreeObject(priv, (hypervObject *)computerSystemList);
+
+ return count;
+}
+
+
+
+static int
+hypervNumberOfDefinedDomains(virConnectPtr conn)
+{
+ bool success = false;
+ hypervPrivate *priv = conn->privateData;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_ComputerSystem *computerSystemList = NULL;
+ Msvm_ComputerSystem *computerSystem = NULL;
+ int count = 0;
+
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+ virBufferAddLit(&query, "where ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL);
+ virBufferAddLit(&query, "and ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_INACTIVE);
+
+ if (hypervGetMsvmComputerSystemList(priv, &query,
+ &computerSystemList) < 0) {
+ goto cleanup;
+ }
+
+ for (computerSystem = computerSystemList; computerSystem != NULL;
+ computerSystem = computerSystem->next) {
+ ++count;
+ }
+
+ success = true;
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystemList);
+
+ return success ? count : -1;
+}
+
+
+
+static int
+hypervDomainCreate(virDomainPtr domain)
+{
+ int result = -1;
+ hypervPrivate *priv = domain->conn->privateData;
+ Msvm_ComputerSystem *computerSystem = NULL;
+
+ if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ if (hypervIsMsvmComputerSystemActive(computerSystem, NULL)) {
+ HYPERV_ERROR(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Domain is already active or is in state transition"));
+ goto cleanup;
+ }
+
+ result = hypervInvokeMsvmComputerSystemRequestStateChange
+ (domain, MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_ENABLED);
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return result;
+}
+
+
+
+static int
+hypervIsEncrypted(virConnectPtr conn)
+{
+ hypervPrivate *priv = conn->privateData;
+
+ if (STRCASEEQ(priv->parsedUri->transport, "https")) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+
+static int
+hypervIsSecure(virConnectPtr conn)
+{
+ hypervPrivate *priv = conn->privateData;
+
+ if (STRCASEEQ(priv->parsedUri->transport, "https")) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+
+static int
+hypervDomainIsActive(virDomainPtr domain)
+{
+ int result = -1;
+ hypervPrivate *priv = domain->conn->privateData;
+ Msvm_ComputerSystem *computerSystem = NULL;
+
+ if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ result = hypervIsMsvmComputerSystemActive(computerSystem, NULL) ? 1 : 0;
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return result;
+}
+
+
+
+static int
+hypervDomainIsPersistent(virDomainPtr domain ATTRIBUTE_UNUSED)
+{
+ /* Hyper-V has no concept of transient domains, so all of them are persistent */
+ return 1;
+}
+
+
+
+static int
+hypervDomainIsUpdated(virDomainPtr domain ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+
+static int
+hypervDomainManagedSave(virDomainPtr domain,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ int result = -1;
+ hypervPrivate *priv = domain->conn->privateData;
+ Msvm_ComputerSystem *computerSystem = NULL;
+ bool in_transition = false;
+
+ if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ if (!hypervIsMsvmComputerSystemActive(computerSystem, &in_transition) ||
+ in_transition) {
+ HYPERV_ERROR(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Domain is not active or is in state transition"));
+ goto cleanup;
+ }
+
+ result = hypervInvokeMsvmComputerSystemRequestStateChange
+ (domain, MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_SUSPENDED);
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return result;
+}
+
+
+
+static int
+hypervDomainHasManagedSaveImage(virDomainPtr domain,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ int result = -1;
+ hypervPrivate *priv = domain->conn->privateData;
+ Msvm_ComputerSystem *computerSystem = NULL;
+
+ if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ result = computerSystem->data->EnabledState ==
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SUSPENDED ? 1 : 0;
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return result;
+}
+
+
+
+static int
+hypervDomainManagedSaveRemove(virDomainPtr domain,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ int result = -1;
+ hypervPrivate *priv = domain->conn->privateData;
+ Msvm_ComputerSystem *computerSystem = NULL;
+
+ if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+ goto cleanup;
+ }
+
+ if (computerSystem->data->EnabledState !=
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SUSPENDED) {
+ HYPERV_ERROR(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Domain has no managed save image"));
+ goto cleanup;
+ }
+
+ result = hypervInvokeMsvmComputerSystemRequestStateChange
+ (domain, MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_DISABLED);
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *)computerSystem);
+
+ return result;
+}
+
+
+
+static virDriver hypervDriver = {
+ .no = VIR_DRV_HYPERV,
+ .name = "Hyper-V",
+ .open = hypervOpen, /* 0.9.4 */
+ .close = hypervClose, /* 0.9.4 */
+ .type = hypervGetType, /* 0.9.4 */
+ .getHostname = hypervGetHostname, /* 0.9.4 */
+ .nodeGetInfo = hypervNodeGetInfo, /* 0.9.4 */
+ .listDomains = hypervListDomains, /* 0.9.4 */
+ .numOfDomains = hypervNumberOfDomains, /* 0.9.4 */
+ .domainLookupByID = hypervDomainLookupByID, /* 0.9.4 */
+ .domainLookupByUUID = hypervDomainLookupByUUID, /* 0.9.4 */
+ .domainLookupByName = hypervDomainLookupByName, /* 0.9.4 */
+ .domainSuspend = hypervDomainSuspend, /* 0.9.4 */
+ .domainResume = hypervDomainResume, /* 0.9.4 */
+ .domainDestroy = hypervDomainDestroy, /* 0.9.4 */
+ .domainGetOSType = hypervDomainGetOSType, /* 0.9.4 */
+ .domainGetInfo = hypervDomainGetInfo, /* 0.9.4 */
+ .domainGetState = hypervDomainGetState, /* 0.9.4 */
+ .domainGetXMLDesc = hypervDomainGetXMLDesc, /* 0.9.4 */
+ .listDefinedDomains = hypervListDefinedDomains, /* 0.9.4 */
+ .numOfDefinedDomains = hypervNumberOfDefinedDomains, /* 0.9.4 */
+ .domainCreate = hypervDomainCreate, /* 0.9.4 */
+ .isEncrypted = hypervIsEncrypted, /* 0.9.4 */
+ .isSecure = hypervIsSecure, /* 0.9.4 */
+ .domainIsActive = hypervDomainIsActive, /* 0.9.4 */
+ .domainIsPersistent = hypervDomainIsPersistent, /* 0.9.4 */
+ .domainIsUpdated = hypervDomainIsUpdated, /* 0.9.4 */
+ .domainManagedSave = hypervDomainManagedSave, /* 0.9.4 */
+ .domainHasManagedSaveImage = hypervDomainHasManagedSaveImage, /* 0.9.4 */
+ .domainManagedSaveRemove = hypervDomainManagedSaveRemove, /* 0.9.4 */
+};
+
+
+
+static void
+hypervDebugHandler(const char *message, debug_level_e level,
+ void *user_data ATTRIBUTE_UNUSED)
+{
+ switch (level) {
+ case DEBUG_LEVEL_ERROR:
+ case DEBUG_LEVEL_CRITICAL:
+ VIR_ERROR(_("openwsman error: %s"), message);
+ break;
+
+ case DEBUG_LEVEL_WARNING:
+ VIR_WARN("openwsman warning: %s", message);
+ break;
+
+ default:
+ /* Ignore the rest */
+ break;
+ }
+}
+
+
+
+int
+hypervRegister(void)
+{
+ if (virRegisterDriver(&hypervDriver) < 0 ||
+ hypervInterfaceRegister() < 0 ||
+ hypervNetworkRegister() < 0 ||
+ hypervStorageRegister() < 0 ||
+ hypervDeviceRegister() < 0 ||
+ hypervSecretRegister() < 0 ||
+ hypervNWFilterRegister() < 0) {
+ return -1;
+ }
+
+ /* Forward openwsman errors and warnings to libvirt's logging */
+ debug_add_handler(hypervDebugHandler, DEBUG_LEVEL_WARNING, NULL);
+
+ return 0;
+}
diff --git a/src/hyperv/hyperv_driver.h b/src/hyperv/hyperv_driver.h
new file mode 100644
index 0000000..17ffa2c
--- /dev/null
+++ b/src/hyperv/hyperv_driver.h
@@ -0,0 +1,29 @@
+
+/*
+ * hyperv_driver.h: core driver functions for managing Microsoft Hyper-V hosts
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ * Copyright (C) 2009 Michael Sievers <msievers83(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __HYPERV_DRIVER_H__
+# define __HYPERV_DRIVER_H__
+
+int hypervRegister(void);
+
+#endif /* __HYPERV_DRIVER_H__ */
diff --git a/src/hyperv/hyperv_interface_driver.c b/src/hyperv/hyperv_interface_driver.c
new file mode 100644
index 0000000..9dd3360
--- /dev/null
+++ b/src/hyperv/hyperv_interface_driver.c
@@ -0,0 +1,77 @@
+
+/*
+ * hyperv_interface_driver.c: interface driver functions for managing
+ * Microsoft Hyper-V host interfaces
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#include "internal.h"
+#include "datatypes.h"
+#include "util.h"
+#include "memory.h"
+#include "logging.h"
+#include "uuid.h"
+#include "hyperv_private.h"
+#include "hyperv_interface_driver.h"
+
+#define VIR_FROM_THIS VIR_FROM_HYPERV
+
+
+
+static virDrvOpenStatus
+hypervInterfaceOpen(virConnectPtr conn,
+ virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ if (conn->driver->no != VIR_DRV_HYPERV) {
+ return VIR_DRV_OPEN_DECLINED;
+ }
+
+ conn->interfacePrivateData = conn->privateData;
+
+ return VIR_DRV_OPEN_SUCCESS;
+}
+
+
+
+static int
+hypervInterfaceClose(virConnectPtr conn)
+{
+ conn->interfacePrivateData = NULL;
+
+ return 0;
+}
+
+
+
+static virInterfaceDriver hypervInterfaceDriver = {
+ .name = "Hyper-V",
+ .open = hypervInterfaceOpen, /* 0.9.4 */
+ .close = hypervInterfaceClose, /* 0.9.4 */
+};
+
+
+
+int
+hypervInterfaceRegister(void)
+{
+ return virRegisterInterfaceDriver(&hypervInterfaceDriver);
+}
diff --git a/src/hyperv/hyperv_interface_driver.h b/src/hyperv/hyperv_interface_driver.h
new file mode 100644
index 0000000..730234c
--- /dev/null
+++ b/src/hyperv/hyperv_interface_driver.h
@@ -0,0 +1,29 @@
+
+/*
+ * hyperv_interface_driver.h: interface driver functions for managing
+ * Microsoft Hyper-V host interfaces
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __HYPERV_INTERFACE_DRIVER_H__
+# define __HYPERV_INTERFACE_DRIVER_H__
+
+int hypervInterfaceRegister(void);
+
+#endif /* __HYPERV_INTERFACE_DRIVER_H__ */
diff --git a/src/hyperv/hyperv_network_driver.c b/src/hyperv/hyperv_network_driver.c
new file mode 100644
index 0000000..5e054fc
--- /dev/null
+++ b/src/hyperv/hyperv_network_driver.c
@@ -0,0 +1,80 @@
+
+/*
+ * hyperv_network_driver.c: network driver functions for managing
+ * Microsoft Hyper-V host networks
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#include "internal.h"
+#include "datatypes.h"
+#include "util.h"
+#include "memory.h"
+#include "logging.h"
+#include "uuid.h"
+#include "network_conf.h"
+#include "hyperv_private.h"
+#include "hyperv_network_driver.h"
+#include "hyperv_util.h"
+#include "hyperv_wmi.h"
+
+#define VIR_FROM_THIS VIR_FROM_HYPERV
+
+
+
+static virDrvOpenStatus
+hypervNetworkOpen(virConnectPtr conn,
+ virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ if (conn->driver->no != VIR_DRV_HYPERV) {
+ return VIR_DRV_OPEN_DECLINED;
+ }
+
+ conn->networkPrivateData = conn->privateData;
+
+ return VIR_DRV_OPEN_SUCCESS;
+}
+
+
+
+static int
+hypervNetworkClose(virConnectPtr conn)
+{
+ conn->networkPrivateData = NULL;
+
+ return 0;
+}
+
+
+
+static virNetworkDriver hypervNetworkDriver = {
+ .name = "Hyper-V",
+ .open = hypervNetworkOpen, /* 0.9.4 */
+ .close = hypervNetworkClose, /* 0.9.4 */
+};
+
+
+
+int
+hypervNetworkRegister(void)
+{
+ return virRegisterNetworkDriver(&hypervNetworkDriver);
+}
diff --git a/src/hyperv/hyperv_network_driver.h b/src/hyperv/hyperv_network_driver.h
new file mode 100644
index 0000000..49c856f
--- /dev/null
+++ b/src/hyperv/hyperv_network_driver.h
@@ -0,0 +1,29 @@
+
+/*
+ * hyperv_network_driver.h: network driver functions for managing
+ * Microsoft Hyper-V host networks
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __HYPERV_NETWORK_DRIVER_H__
+# define __HYPERV_NETWORK_DRIVER_H__
+
+int hypervNetworkRegister(void);
+
+#endif /* __HYPERV_NETWORK_DRIVER_H__ */
diff --git a/src/hyperv/hyperv_nwfilter_driver.c b/src/hyperv/hyperv_nwfilter_driver.c
new file mode 100644
index 0000000..9774108
--- /dev/null
+++ b/src/hyperv/hyperv_nwfilter_driver.c
@@ -0,0 +1,77 @@
+
+/*
+ * hyperv_nwfilter_driver.c: nwfilter driver functions for managing
+ * Microsoft Hyper-V firewall rules
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#include "internal.h"
+#include "datatypes.h"
+#include "util.h"
+#include "memory.h"
+#include "logging.h"
+#include "uuid.h"
+#include "hyperv_private.h"
+#include "hyperv_nwfilter_driver.h"
+
+#define VIR_FROM_THIS VIR_FROM_HYPERV
+
+
+
+static virDrvOpenStatus
+hypervNWFilterOpen(virConnectPtr conn,
+ virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ if (conn->driver->no != VIR_DRV_HYPERV) {
+ return VIR_DRV_OPEN_DECLINED;
+ }
+
+ conn->nwfilterPrivateData = conn->privateData;
+
+ return VIR_DRV_OPEN_SUCCESS;
+}
+
+
+
+static int
+hypervNWFilterClose(virConnectPtr conn)
+{
+ conn->nwfilterPrivateData = NULL;
+
+ return 0;
+}
+
+
+
+static virNWFilterDriver hypervNWFilterDriver = {
+ .name = "Hyper-V",
+ .open = hypervNWFilterOpen, /* 0.9.4 */
+ .close = hypervNWFilterClose, /* 0.9.4 */
+};
+
+
+
+int
+hypervNWFilterRegister(void)
+{
+ return virRegisterNWFilterDriver(&hypervNWFilterDriver);
+}
diff --git a/src/hyperv/hyperv_nwfilter_driver.h b/src/hyperv/hyperv_nwfilter_driver.h
new file mode 100644
index 0000000..ef4f660
--- /dev/null
+++ b/src/hyperv/hyperv_nwfilter_driver.h
@@ -0,0 +1,29 @@
+
+/*
+ * hyperv_nwfilter_driver.h: nwfilter driver functions for managing
+ * Microsoft Hyper-V firewall rules
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __HYPERV_NWFILTER_DRIVER_H__
+# define __HYPERV_NWFILTER_DRIVER_H__
+
+int hypervNWFilterRegister(void);
+
+#endif /* __HYPERV_NWFILTER_DRIVER_H__ */
diff --git a/src/hyperv/hyperv_private.h b/src/hyperv/hyperv_private.h
new file mode 100644
index 0000000..1588f90
--- /dev/null
+++ b/src/hyperv/hyperv_private.h
@@ -0,0 +1,43 @@
+
+/*
+ * hyperv_private.h: private driver struct for the Microsoft Hyper-V driver
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ * Copyright (C) 2009 Michael Sievers <msievers83(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __HYPERV_PRIVATE_H__
+# define __HYPERV_PRIVATE_H__
+
+# include "internal.h"
+# include "virterror_internal.h"
+# include "openwsman.h"
+# include "hyperv_util.h"
+
+# define HYPERV_ERROR(code, ...) \
+ virReportErrorHelper(VIR_FROM_HYPERV, code, __FILE__, __FUNCTION__, \
+ __LINE__, __VA_ARGS__)
+
+typedef struct _hypervPrivate hypervPrivate;
+
+struct _hypervPrivate {
+ hypervParsedUri *parsedUri;
+ WsManClient *client;
+};
+
+#endif /* __HYPERV_PRIVATE_H__ */
diff --git a/src/hyperv/hyperv_secret_driver.c b/src/hyperv/hyperv_secret_driver.c
new file mode 100644
index 0000000..314bfd5
--- /dev/null
+++ b/src/hyperv/hyperv_secret_driver.c
@@ -0,0 +1,77 @@
+
+/*
+ * hyperv_secret_driver.c: secret driver functions for Microsoft Hyper-V
+ * secret manipulation
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#include "internal.h"
+#include "datatypes.h"
+#include "util.h"
+#include "memory.h"
+#include "logging.h"
+#include "uuid.h"
+#include "hyperv_private.h"
+#include "hyperv_secret_driver.h"
+
+#define VIR_FROM_THIS VIR_FROM_Microsoft Hyper-V
+
+
+
+static virDrvOpenStatus
+hypervSecretOpen(virConnectPtr conn,
+ virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ if (conn->driver->no != VIR_DRV_HYPERV) {
+ return VIR_DRV_OPEN_DECLINED;
+ }
+
+ conn->secretPrivateData = conn->privateData;
+
+ return VIR_DRV_OPEN_SUCCESS;
+}
+
+
+
+static int
+hypervSecretClose(virConnectPtr conn)
+{
+ conn->secretPrivateData = NULL;
+
+ return 0;
+}
+
+
+
+static virSecretDriver hypervSecretDriver = {
+ .name = "Hyper-V",
+ .open = hypervSecretOpen, /* 0.9.4 */
+ .close = hypervSecretClose, /* 0.9.4 */
+};
+
+
+
+int
+hypervSecretRegister(void)
+{
+ return virRegisterSecretDriver(&hypervSecretDriver);
+}
diff --git a/src/hyperv/hyperv_secret_driver.h b/src/hyperv/hyperv_secret_driver.h
new file mode 100644
index 0000000..a7e9f25
--- /dev/null
+++ b/src/hyperv/hyperv_secret_driver.h
@@ -0,0 +1,29 @@
+
+/*
+ * hyperv_secret_driver.h: secret driver functions for Microsoft Hyper-V
+ * secret manipulation
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __HYPERV_SECRET_DRIVER_H__
+# define __HYPERV_SECRET_DRIVER_H__
+
+int hypervSecretRegister(void);
+
+#endif /* __HYPERV_SECRET_DRIVER_H__ */
diff --git a/src/hyperv/hyperv_storage_driver.c b/src/hyperv/hyperv_storage_driver.c
new file mode 100644
index 0000000..2cb4878
--- /dev/null
+++ b/src/hyperv/hyperv_storage_driver.c
@@ -0,0 +1,79 @@
+
+/*
+ * hyperv_storage_driver.c: storage driver functions for managing
+ * Microsoft Hyper-V host storage
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#include "internal.h"
+#include "datatypes.h"
+#include "util.h"
+#include "memory.h"
+#include "logging.h"
+#include "uuid.h"
+#include "storage_conf.h"
+#include "storage_file.h"
+#include "hyperv_private.h"
+#include "hyperv_storage_driver.h"
+
+#define VIR_FROM_THIS VIR_FROM_HYPERV
+
+
+
+static virDrvOpenStatus
+hypervStorageOpen(virConnectPtr conn,
+ virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ if (conn->driver->no != VIR_DRV_HYPERV) {
+ return VIR_DRV_OPEN_DECLINED;
+ }
+
+ conn->storagePrivateData = conn->privateData;
+
+ return VIR_DRV_OPEN_SUCCESS;
+}
+
+
+
+static int
+hypervStorageClose(virConnectPtr conn)
+{
+ conn->storagePrivateData = NULL;
+
+ return 0;
+}
+
+
+
+static virStorageDriver hypervStorageDriver = {
+ .name = "Hyper-V",
+ .open = hypervStorageOpen, /* 0.9.4 */
+ .close = hypervStorageClose, /* 0.9.4 */
+};
+
+
+
+int
+hypervStorageRegister(void)
+{
+ return virRegisterStorageDriver(&hypervStorageDriver);
+}
diff --git a/src/hyperv/hyperv_storage_driver.h b/src/hyperv/hyperv_storage_driver.h
new file mode 100644
index 0000000..c9bca22
--- /dev/null
+++ b/src/hyperv/hyperv_storage_driver.h
@@ -0,0 +1,29 @@
+
+/*
+ * hyperv_storage_driver.h: storage driver methods for managing
+ * Microsoft Hyper-V host storage
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __HYPERV_STORAGE_DRIVER_H__
+# define __HYPERV_STORAGE_DRIVER_H__
+
+int hypervStorageRegister(void);
+
+#endif /* __HYPERV_STORAGE_DRIVER_H__ */
diff --git a/src/hyperv/hyperv_util.c b/src/hyperv/hyperv_util.c
new file mode 100644
index 0000000..298cfe0
--- /dev/null
+++ b/src/hyperv/hyperv_util.c
@@ -0,0 +1,129 @@
+
+/*
+ * hyperv_util.c: utility functions for the Microsoft Hyper-V driver
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#include "internal.h"
+#include "datatypes.h"
+#include "qparams.h"
+#include "util.h"
+#include "memory.h"
+#include "logging.h"
+#include "uuid.h"
+#include "hyperv_private.h"
+#include "hyperv_util.h"
+
+#define VIR_FROM_THIS VIR_FROM_HYPERV
+
+
+
+int
+hypervParseUri(hypervParsedUri **parsedUri, xmlURIPtr uri)
+{
+ int result = -1;
+ struct qparam_set *queryParamSet = NULL;
+ struct qparam *queryParam = NULL;
+ int i;
+
+ if (parsedUri == NULL || *parsedUri != NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+ return -1;
+ }
+
+ if (VIR_ALLOC(*parsedUri) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+#ifdef HAVE_XMLURI_QUERY_RAW
+ queryParamSet = qparam_query_parse(uri->query_raw);
+#else
+ queryParamSet = qparam_query_parse(uri->query);
+#endif
+
+ if (queryParamSet == NULL) {
+ goto cleanup;
+ }
+
+ for (i = 0; i < queryParamSet->n; i++) {
+ queryParam = &queryParamSet->p[i];
+
+ if (STRCASEEQ(queryParam->name, "transport")) {
+ VIR_FREE((*parsedUri)->transport);
+
+ (*parsedUri)->transport = strdup(queryParam->value);
+
+ if ((*parsedUri)->transport == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (STRNEQ((*parsedUri)->transport, "http") &&
+ STRNEQ((*parsedUri)->transport, "https")) {
+ HYPERV_ERROR(VIR_ERR_INVALID_ARG,
+ _("Query parameter 'transport' has unexpected value "
+ "'%s' (should be http|https)"),
+ (*parsedUri)->transport);
+ goto cleanup;
+ }
+ } else {
+ VIR_WARN("Ignoring unexpected query parameter '%s'",
+ queryParam->name);
+ }
+ }
+
+ if ((*parsedUri)->transport == NULL) {
+ (*parsedUri)->transport = strdup("https");
+
+ if ((*parsedUri)->transport == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
+ result = 0;
+
+ cleanup:
+ if (result < 0) {
+ hypervFreeParsedUri(parsedUri);
+ }
+
+ if (queryParamSet != NULL) {
+ free_qparam_set(queryParamSet);
+ }
+
+ return result;
+}
+
+
+
+void
+hypervFreeParsedUri(hypervParsedUri **parsedUri)
+{
+ if (parsedUri == NULL || *parsedUri == NULL) {
+ return;
+ }
+
+ VIR_FREE((*parsedUri)->transport);
+
+ VIR_FREE(*parsedUri);
+}
diff --git a/src/hyperv/hyperv_util.h b/src/hyperv/hyperv_util.h
new file mode 100644
index 0000000..a6fa6a1
--- /dev/null
+++ b/src/hyperv/hyperv_util.h
@@ -0,0 +1,39 @@
+/*
+ * hyperv_util.h: utility functions for the Microsoft Hyper-V driver
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __HYPERV_UTIL_H__
+# define __HYPERV_UTIL_H__
+
+# include <libxml/uri.h>
+
+# include "internal.h"
+
+typedef struct _hypervParsedUri hypervParsedUri;
+
+struct _hypervParsedUri {
+ char *transport;
+};
+
+int hypervParseUri(hypervParsedUri **parsedUri, xmlURIPtr uri);
+
+void hypervFreeParsedUri(hypervParsedUri **parsedUri);
+
+#endif /* __HYPERV_UTIL_H__ */
diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c
new file mode 100644
index 0000000..c584b03
--- /dev/null
+++ b/src/hyperv/hyperv_wmi.c
@@ -0,0 +1,692 @@
+
+/*
+ * hyperv_wmi.h: general WMI over WSMAN related functions and structures for
+ * managing Microsoft Hyper-V hosts
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ * Copyright (C) 2009 Michael Sievers <msievers83(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#ifdef WIN32
+# include <windows.h>
+#endif
+
+#include "internal.h"
+#include "virterror_internal.h"
+#include "datatypes.h"
+#include "logging.h"
+#include "memory.h"
+#include "util.h"
+#include "uuid.h"
+#include "buf.h"
+#include "hyperv_private.h"
+#include "hyperv_wmi.h"
+
+#define ROOT_CIMV2 \
+ "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/*"
+#define ROOT_VIRTUALIZATION \
+ "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/*"
+
+#define VIR_FROM_THIS VIR_FROM_HYPERV
+
+
+
+int
+hyperyVerifyResponse(WsManClient *client, WsXmlDocH response,
+ const char *detail)
+{
+ int lastError = wsmc_get_last_error(client);
+ int responseCode = wsmc_get_response_code(client);
+ WsManFault *fault;
+
+ if (lastError != WS_LASTERR_OK) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Transport error during %s: %s (%d)"),
+ detail, wsman_transport_get_last_error_string(lastError),
+ lastError);
+ return -1;
+ }
+
+ if (responseCode != 200 && responseCode != 400 && responseCode != 500) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Unexpected HTTP response during %s: %d"),
+ detail, responseCode);
+ return -1;
+ }
+
+ if (response == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Empty response during %s"), detail);
+ return -1;
+ }
+
+ if (wsmc_check_for_fault(response)) {
+ fault = wsmc_fault_new();
+
+ if (fault == NULL) {
+ virReportOOMError();
+ return -1;
+ }
+
+ wsmc_get_fault_data(response, fault);
+
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("SOAP fault during %s: code '%s', subcode '%s', "
+ "reason '%s', detail '%s'"),
+ detail, NULLSTR(fault->code), NULLSTR(fault->subcode),
+ NULLSTR(fault->reason), NULLSTR(fault->fault_detail));
+
+ wsmc_fault_destroy(fault);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Object
+ */
+
+int
+hypervEnumAndPull(hypervPrivate *priv, virBufferPtr query, const char *root,
+ XmlSerializerInfo *serializerInfo, const char *resourceUri,
+ const char *className, hypervObject **list)
+{
+ int result = -1;
+ WsSerializerContextH serializerContext;
+ client_opt_t *options = NULL;
+ char *query_string = NULL;
+ filter_t *filter = NULL;
+ WsXmlDocH response = NULL;
+ char *enumContext = NULL;
+ hypervObject *head = NULL;
+ hypervObject *tail = NULL;
+ WsXmlNodeH node = NULL;
+ XML_TYPE_PTR data = NULL;
+ hypervObject *object;
+
+ if (list == NULL || *list != NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+ return -1;
+ }
+
+ if (virBufferError(query)) {
+ virReportOOMError();
+ return -1;
+ }
+
+ serializerContext = wsmc_get_serialization_context(priv->client);
+
+ options = wsmc_options_init();
+
+ if (options == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not initialize options"));
+ goto cleanup;
+ }
+
+ query_string = virBufferContentAndReset(query);
+ filter = filter_create_simple(WSM_WQL_FILTER_DIALECT, query_string);
+
+ if (filter == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not create filter"));
+ goto cleanup;
+ }
+
+ response = wsmc_action_enumerate(priv->client, root, options, filter);
+
+ if (hyperyVerifyResponse(priv->client, response, "enumeration") < 0) {
+ goto cleanup;
+ }
+
+ enumContext = wsmc_get_enum_context(response);
+
+ ws_xml_destroy_doc(response);
+ response = NULL;
+
+ while (enumContext != NULL && *enumContext != '\0' ) {
+ response = wsmc_action_pull(priv->client, resourceUri, options,
+ filter, enumContext);
+
+ if (hyperyVerifyResponse(priv->client, response, "pull") < 0) {
+ goto cleanup;
+ }
+
+ node = ws_xml_get_soap_body(response);
+
+ if (node == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not lookup SOAP body"));
+ goto cleanup;
+ }
+
+ node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_PULL_RESP);
+
+ if (node == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not lookup pull response"));
+ goto cleanup;
+ }
+
+ node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_ITEMS);
+
+ if (node == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not lookup pull response items"));
+ goto cleanup;
+ }
+
+ if (ws_xml_get_child(node, 0, resourceUri, className) == NULL) {
+ break;
+ }
+
+ data = ws_deserialize(serializerContext, node, serializerInfo,
+ className, resourceUri, NULL, 0, 0);
+
+ if (data == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not deserialize pull response item"));
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC(object) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ object->serializerInfo = serializerInfo;
+ object->data = data;
+
+ data = NULL;
+
+ if (head == NULL) {
+ head = object;
+ } else {
+ tail->next = object;
+ }
+
+ tail = object;
+
+ VIR_FREE(enumContext);
+ enumContext = wsmc_get_enum_context(response);
+
+ ws_xml_destroy_doc(response);
+ response = NULL;
+ }
+
+ *list = head;
+ head = NULL;
+
+ result = 0;
+
+ cleanup:
+ if (options != NULL) {
+ wsmc_options_destroy(options);
+ }
+
+ if (filter != NULL) {
+ filter_destroy(filter);
+ }
+
+ if (data != NULL) {
+#if 0
+ /* FIXME: ws_serializer_free_mem is broken in openwsman <= 2.2.6,
+ * see hypervFreeObject for a detailed explanation. */
+ if (ws_serializer_free_mem(serializerContext, data,
+ serializerInfo) < 0) {
+ VIR_ERROR(_("Could not free deserialized data"));
+ }
+#endif
+ }
+
+ VIR_FREE(query_string);
+ ws_xml_destroy_doc(response);
+ VIR_FREE(enumContext);
+ hypervFreeObject(priv, head);
+
+ return result;
+}
+
+void
+hypervFreeObject(hypervPrivate *priv ATTRIBUTE_UNUSED, hypervObject *object)
+{
+ hypervObject *next;
+#if 0
+ WsSerializerContextH serializerContext;
+#endif
+
+ if (object == NULL) {
+ return;
+ }
+
+#if 0
+ serializerContext = wsmc_get_serialization_context(priv->client);
+#endif
+
+ while (object != NULL) {
+ next = object->next;
+
+#if 0
+ /* FIXME: ws_serializer_free_mem is broken in openwsman <= 2.2.6,
+ * but this is not that critical, because openwsman keeps
+ * track of all allocations of the deserializer and frees
+ * them in wsmc_release. So this doesn't result in a real
+ * memory leak, but just in piling up unused memory until
+ * the connection is closed. */
+ if (ws_serializer_free_mem(serializerContext, object->data,
+ object->serializerInfo) < 0) {
+ VIR_ERROR(_("Could not free deserialized data"));
+ }
+#endif
+
+ VIR_FREE(object);
+
+ object = next;
+ }
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * CIM/Msvm_ReturnCode
+ */
+
+const char *
+hypervReturnCodeToString(int returnCode)
+{
+ switch (returnCode) {
+ case CIM_RETURNCODE_COMPLETED_WITH_NO_ERROR:
+ return _("Completed with no error");
+
+ case CIM_RETURNCODE_NOT_SUPPORTED:
+ return _("Not supported");
+
+ case CIM_RETURNCODE_UNKNOWN_ERROR:
+ return _("Unknown error");
+
+ case CIM_RETURNCODE_CANNOT_COMPLETE_WITHIN_TIMEOUT_PERIOD:
+ return _("Cannot complete within timeout period");
+
+ case CIM_RETURNCODE_FAILED:
+ return _("Failed");
+
+ case CIM_RETURNCODE_INVALID_PARAMETER:
+ return _("Invalid parameter");
+
+ case CIM_RETURNCODE_IN_USE:
+ return _("In use");
+
+ case CIM_RETURNCODE_TRANSITION_STARTED:
+ return _("Transition started");
+
+ case CIM_RETURNCODE_INVALID_STATE_TRANSITION:
+ return _("Invalid state transition");
+
+ case CIM_RETURNCODE_TIMEOUT_PARAMETER_NOT_SUPPORTED:
+ return _("Timeout parameter not supported");
+
+ case CIM_RETURNCODE_BUSY:
+ return _("Busy");
+
+ case MSVM_RETURNCODE_FAILED:
+ return _("Failed");
+
+ case MSVM_RETURNCODE_ACCESS_DENIED:
+ return _("Access denied");
+
+ case MSVM_RETURNCODE_NOT_SUPPORTED:
+ return _("Not supported");
+
+ case MSVM_RETURNCODE_STATUS_IS_UNKNOWN:
+ return _("Status is unknown");
+
+ case MSVM_RETURNCODE_TIMEOUT:
+ return _("Timeout");
+
+ case MSVM_RETURNCODE_INVALID_PARAMETER:
+ return _("Invalid parameter");
+
+ case MSVM_RETURNCODE_SYSTEM_IS_IN_USE:
+ return _("System is in use");
+
+ case MSVM_RETURNCODE_INVALID_STATE_FOR_THIS_OPERATION:
+ return _("Invalid state for this operation");
+
+ case MSVM_RETURNCODE_INCORRECT_DATA_TYPE:
+ return _("Incorrect data type");
+
+ case MSVM_RETURNCODE_SYSTEM_IS_NOT_AVAILABLE:
+ return _("System is not available");
+
+ case MSVM_RETURNCODE_OUT_OF_MEMORY:
+ return _("Out of memory");
+
+ default:
+ return _("Unknown return code");
+ }
+}
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Msvm_ComputerSystem
+ */
+
+int
+hypervInvokeMsvmComputerSystemRequestStateChange(virDomainPtr domain,
+ int requestedState)
+{
+ int result = -1;
+ hypervPrivate *priv = domain->conn->privateData;
+ char uuid_string[VIR_UUID_STRING_BUFLEN];
+ WsXmlDocH response = NULL;
+ client_opt_t *options = NULL;
+ char *selector = NULL;
+ char *properties = NULL;
+ char *returnValue = NULL;
+ int returnCode;
+ char *instanceID = NULL;
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+ Msvm_ConcreteJob *concreteJob = NULL;
+ bool completed = false;
+
+ virUUIDFormat(domain->uuid, uuid_string);
+
+ if (virAsprintf(&selector, "Name=%s&CreationClassName=Msvm_ComputerSystem",
+ uuid_string) < 0 ||
+ virAsprintf(&properties, "RequestedState=%d", requestedState) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ options = wsmc_options_init();
+
+ if (options == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not initialize options"));
+ goto cleanup;
+ }
+
+ wsmc_add_selectors_from_str(options, selector);
+ wsmc_add_prop_from_str(options, properties);
+
+ /* Invoke method */
+ response = wsmc_action_invoke(priv->client, MSVM_COMPUTERSYSTEM_RESOURCE_URI,
+ options, "RequestStateChange", NULL);
+
+ if (hyperyVerifyResponse(priv->client, response, "invocation") < 0) {
+ goto cleanup;
+ }
+
+ /* Check return value */
+ returnValue = ws_xml_get_xpath_value(response, (char *)"/s:Envelope/s:Body/p:RequestStateChange_OUTPUT/p:ReturnValue");
+
+ if (returnValue == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup %s for %s invocation"),
+ "ReturnValue", "RequestStateChange");
+ goto cleanup;
+ }
+
+ if (virStrToLong_i(returnValue, NULL, 10, &returnCode) < 0) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not parse return code from '%s'"), returnValue);
+ goto cleanup;
+ }
+
+ if (returnCode == CIM_RETURNCODE_TRANSITION_STARTED) {
+ /* Get concrete job object */
+ instanceID = ws_xml_get_xpath_value(response, (char *)"/s:Envelope/s:Body/p:RequestStateChange_OUTPUT/p:Job/a:ReferenceParameters/w:SelectorSet/w:Selector[@Name='InstanceID']");
+
+ if (instanceID == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup %s for %s invocation"),
+ "InstanceID", "RequestStateChange");
+ goto cleanup;
+ }
+
+ /* FIXME: Poll every 100ms until the job completes or fails. There
+ * seems to be no other way than polling. */
+ while (!completed) {
+ virBufferAddLit(&query, MSVM_CONCRETEJOB_WQL_SELECT);
+ virBufferAsprintf(&query, "where InstanceID = \"%s\"", instanceID);
+
+ if (hypervGetMsvmConcreteJobList(priv, &query, &concreteJob) < 0) {
+ goto cleanup;
+ }
+
+ if (concreteJob == NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup %s for %s invocation"),
+ "Msvm_ConcreteJob", "RequestStateChange");
+ goto cleanup;
+ }
+
+ switch (concreteJob->data->JobState) {
+ case MSVM_CONCRETEJOB_JOBSTATE_NEW:
+ case MSVM_CONCRETEJOB_JOBSTATE_STARTING:
+ case MSVM_CONCRETEJOB_JOBSTATE_RUNNING:
+ case MSVM_CONCRETEJOB_JOBSTATE_SHUTTING_DOWN:
+ hypervFreeObject(priv, (hypervObject *)concreteJob);
+ concreteJob = NULL;
+
+#ifdef WIN32
+ Sleep(100);
+#else
+ usleep(100 * 1000);
+#endif
+
+ continue;
+
+ case MSVM_CONCRETEJOB_JOBSTATE_COMPLETED:
+ completed = true;
+ break;
+
+ case MSVM_CONCRETEJOB_JOBSTATE_TERMINATED:
+ case MSVM_CONCRETEJOB_JOBSTATE_KILLED:
+ case MSVM_CONCRETEJOB_JOBSTATE_EXCEPTION:
+ case MSVM_CONCRETEJOB_JOBSTATE_SERVICE:
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Concrete job for %s invocation is in error state"),
+ "RequestStateChange");
+ goto cleanup;
+
+ default:
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Concrete job for %s invocation is in unknown state"),
+ "RequestStateChange");
+ goto cleanup;
+ }
+ }
+ } else if (returnCode != CIM_RETURNCODE_COMPLETED_WITH_NO_ERROR) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Invocation of %s returned an error: %s (%d)"),
+ "RequestStateChange", hypervReturnCodeToString(returnCode),
+ returnCode);
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ if (options != NULL) {
+ wsmc_options_destroy(options);
+ }
+
+ ws_xml_destroy_doc(response);
+ VIR_FREE(selector);
+ VIR_FREE(properties);
+ VIR_FREE(returnValue);
+ VIR_FREE(instanceID);
+ hypervFreeObject(priv, (hypervObject *)concreteJob);
+
+ return result;
+}
+
+int
+hypervMsvmComputerSystemEnabledStateToDomainState
+ (Msvm_ComputerSystem *computerSystem)
+{
+ switch (computerSystem->data->EnabledState) {
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_UNKNOWN:
+ return VIR_DOMAIN_NOSTATE;
+
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_ENABLED:
+ return VIR_DOMAIN_RUNNING;
+
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_DISABLED:
+ return VIR_DOMAIN_SHUTOFF;
+
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_PAUSED:
+ return VIR_DOMAIN_PAUSED;
+
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SUSPENDED:
+ return VIR_DOMAIN_SHUTOFF;
+
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_STARTING:
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SNAPSHOTTING:
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SAVING:
+ return VIR_DOMAIN_RUNNING;
+
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_STOPPING:
+ return VIR_DOMAIN_SHUTDOWN;
+
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_PAUSING:
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_RESUMING:
+ return VIR_DOMAIN_RUNNING;
+
+ default:
+ return VIR_DOMAIN_NOSTATE;
+ }
+}
+
+bool
+hypervIsMsvmComputerSystemActive(Msvm_ComputerSystem *computerSystem,
+ bool *in_transition)
+{
+ if (in_transition != NULL) {
+ *in_transition = false;
+ }
+
+ switch (computerSystem->data->EnabledState) {
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_UNKNOWN:
+ return false;
+
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_ENABLED:
+ return true;
+
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_DISABLED:
+ return false;
+
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_PAUSED:
+ return true;
+
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SUSPENDED:
+ return false;
+
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_STARTING:
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SNAPSHOTTING:
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SAVING:
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_STOPPING:
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_PAUSING:
+ case MSVM_COMPUTERSYSTEM_ENABLEDSTATE_RESUMING:
+ if (in_transition != NULL) {
+ *in_transition = true;
+ }
+
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+int
+hypervMsvmComputerSystemToDomain(virConnectPtr conn,
+ Msvm_ComputerSystem *computerSystem,
+ virDomainPtr *domain)
+{
+ unsigned char uuid[VIR_UUID_BUFLEN];
+
+ if (domain == NULL || *domain != NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+ return -1;
+ }
+
+ if (virUUIDParse(computerSystem->data->Name, uuid) < 0) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not parse UUID from string '%s'"),
+ computerSystem->data->Name);
+ return -1;
+ }
+
+ *domain = virGetDomain(conn, computerSystem->data->ElementName, uuid);
+
+ if (*domain == NULL) {
+ return -1;
+ }
+
+ if (hypervIsMsvmComputerSystemActive(computerSystem, NULL)) {
+ (*domain)->id = computerSystem->data->ProcessID;
+ } else {
+ (*domain)->id = -1;
+ }
+
+ return 0;
+}
+
+int
+hypervMsvmComputerSystemFromDomain(virDomainPtr domain,
+ Msvm_ComputerSystem **computerSystem)
+{
+ hypervPrivate *priv = domain->conn->privateData;
+ char uuid_string[VIR_UUID_STRING_BUFLEN];
+ virBuffer query = VIR_BUFFER_INITIALIZER;
+
+ if (computerSystem == NULL || *computerSystem != NULL) {
+ HYPERV_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+ return -1;
+ }
+
+ virUUIDFormat(domain->uuid, uuid_string);
+
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+ virBufferAddLit(&query, "where ");
+ virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL);
+ virBufferAsprintf(&query, "and Name = \"%s\"", uuid_string);
+
+ if (hypervGetMsvmComputerSystemList(priv, &query, computerSystem) < 0) {
+ return -1;
+ }
+
+ if (*computerSystem == NULL) {
+ HYPERV_ERROR(VIR_ERR_NO_DOMAIN,
+ _("No domain with UUID %s"), uuid_string);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+#include "hyperv_wmi.generated.c"
diff --git a/src/hyperv/hyperv_wmi.h b/src/hyperv/hyperv_wmi.h
new file mode 100644
index 0000000..18c05da
--- /dev/null
+++ b/src/hyperv/hyperv_wmi.h
@@ -0,0 +1,119 @@
+
+/*
+ * hyperv_wmi.h: general WMI over WSMAN related functions and structures for
+ * managing Microsoft Hyper-V hosts
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ * Copyright (C) 2009 Michael Sievers <msievers83(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __HYPERV_WMI_H__
+# define __HYPERV_WMI_H__
+
+# include "buf.h"
+# include "openwsman.h"
+# include "hyperv_private.h"
+# include "hyperv_wmi_classes.h"
+
+typedef struct _hypervObject hypervObject;
+
+int hyperyVerifyResponse(WsManClient *client, WsXmlDocH response,
+ const char *detail);
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Object
+ */
+
+struct _hypervObject {
+ XmlSerializerInfo *serializerInfo;
+ XML_TYPE_PTR data;
+ hypervObject *next;
+};
+
+int hypervEnumAndPull(hypervPrivate *priv, virBufferPtr query,
+ const char *root, XmlSerializerInfo *serializerInfo,
+ const char *resourceUri, const char *className,
+ hypervObject **list);
+
+void hypervFreeObject(hypervPrivate *priv, hypervObject *object);
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * CIM/Msvm_ReturnCode
+ */
+
+enum _CIM_ReturnCode {
+ CIM_RETURNCODE_COMPLETED_WITH_NO_ERROR = 0,
+ CIM_RETURNCODE_NOT_SUPPORTED = 1,
+ CIM_RETURNCODE_UNKNOWN_ERROR = 2,
+ CIM_RETURNCODE_CANNOT_COMPLETE_WITHIN_TIMEOUT_PERIOD = 3,
+ CIM_RETURNCODE_FAILED = 4,
+ CIM_RETURNCODE_INVALID_PARAMETER = 5,
+ CIM_RETURNCODE_IN_USE = 6,
+ CIM_RETURNCODE_TRANSITION_STARTED = 4096,
+ CIM_RETURNCODE_INVALID_STATE_TRANSITION = 4097,
+ CIM_RETURNCODE_TIMEOUT_PARAMETER_NOT_SUPPORTED = 4098,
+ CIM_RETURNCODE_BUSY = 4099,
+};
+
+enum _Msvm_ReturnCode {
+ MSVM_RETURNCODE_FAILED = 32768,
+ MSVM_RETURNCODE_ACCESS_DENIED = 32769,
+ MSVM_RETURNCODE_NOT_SUPPORTED = 32770,
+ MSVM_RETURNCODE_STATUS_IS_UNKNOWN = 32771,
+ MSVM_RETURNCODE_TIMEOUT = 32772,
+ MSVM_RETURNCODE_INVALID_PARAMETER = 32773,
+ MSVM_RETURNCODE_SYSTEM_IS_IN_USE = 32774,
+ MSVM_RETURNCODE_INVALID_STATE_FOR_THIS_OPERATION = 32775,
+ MSVM_RETURNCODE_INCORRECT_DATA_TYPE = 32776,
+ MSVM_RETURNCODE_SYSTEM_IS_NOT_AVAILABLE = 32777,
+ MSVM_RETURNCODE_OUT_OF_MEMORY = 32778,
+};
+
+const char *hypervReturnCodeToString(int returnCode);
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Msvm_ComputerSystem
+ */
+
+int hypervInvokeMsvmComputerSystemRequestStateChange(virDomainPtr domain,
+ int requestedState);
+
+int hypervMsvmComputerSystemEnabledStateToDomainState
+ (Msvm_ComputerSystem *computerSystem);
+
+bool hypervIsMsvmComputerSystemActive(Msvm_ComputerSystem *computerSystem,
+ bool *in_transition);
+
+int hypervMsvmComputerSystemToDomain(virConnectPtr conn,
+ Msvm_ComputerSystem *computerSystem,
+ virDomainPtr *domain);
+
+int hypervMsvmComputerSystemFromDomain(virDomainPtr domain,
+ Msvm_ComputerSystem **computerSystem);
+
+
+
+# include "hyperv_wmi.generated.h"
+
+#endif /* __HYPERV_WMI_H__ */
diff --git a/src/hyperv/hyperv_wmi_classes.c b/src/hyperv/hyperv_wmi_classes.c
new file mode 100644
index 0000000..ed5e314
--- /dev/null
+++ b/src/hyperv/hyperv_wmi_classes.c
@@ -0,0 +1,37 @@
+
+/*
+ * hyperv_wmi_classes.c: WMI classes for managing Microsoft Hyper-V hosts
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ * Copyright (C) 2009 Michael Sievers <msievers83(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#include "hyperv_wmi_classes.h"
+
+SER_TYPEINFO_BOOL;
+SER_TYPEINFO_STRING;
+SER_TYPEINFO_INT8;
+SER_TYPEINFO_INT16;
+SER_TYPEINFO_INT32;
+SER_TYPEINFO_UINT8;
+SER_TYPEINFO_UINT16;
+SER_TYPEINFO_UINT32;
+
+#include "hyperv_wmi_classes.generated.c"
diff --git a/src/hyperv/hyperv_wmi_classes.h b/src/hyperv/hyperv_wmi_classes.h
new file mode 100644
index 0000000..5c97ca6
--- /dev/null
+++ b/src/hyperv/hyperv_wmi_classes.h
@@ -0,0 +1,94 @@
+
+/*
+ * hyperv_wmi_classes.h: WMI classes for managing Microsoft Hyper-V hosts
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ * Copyright (C) 2009 Michael Sievers <msievers83(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __HYPERV_WMI_CLASSES_H__
+# define __HYPERV_WMI_CLASSES_H__
+
+# include "openwsman.h"
+
+# include "hyperv_wmi_classes.generated.typedef"
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Msvm_ComputerSystem
+ */
+
+# define MSVM_COMPUTERSYSTEM_WQL_VIRTUAL \
+ "Description = \"Microsoft Virtual Machine\" "
+
+# define MSVM_COMPUTERSYSTEM_WQL_PHYSICAL \
+ "Description = \"Microsoft Hosting Computer System\" "
+
+# define MSVM_COMPUTERSYSTEM_WQL_ACTIVE \
+ "(EnabledState != 0 and EnabledState != 3 and EnabledState != 32769) "
+
+# define MSVM_COMPUTERSYSTEM_WQL_INACTIVE \
+ "(EnabledState = 0 or EnabledState = 3 or EnabledState = 32769) "
+
+enum _Msvm_ComputerSystem_EnabledState {
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_UNKNOWN = 0, /* inactive */
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_ENABLED = 2, /* active */
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_DISABLED = 3, /* inactive */
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_PAUSED = 32768, /* active */
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SUSPENDED = 32769, /* inactive */
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_STARTING = 32770, /* active */
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SNAPSHOTTING = 32771, /* active */
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SAVING = 32773, /* active */
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_STOPPING = 32774, /* active */
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_PAUSING = 32776, /* active */
+ MSVM_COMPUTERSYSTEM_ENABLEDSTATE_RESUMING = 32777 /* active */
+};
+
+enum _Msvm_ComputerSystem_RequestedState {
+ MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_ENABLED = 2,
+ MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_DISABLED = 3,
+ MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_REBOOT = 10,
+ MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_PAUSED = 32768,
+ MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_SUSPENDED = 32769,
+};
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Msvm_ConcreteJob
+ */
+
+enum _Msvm_ConcreteJob_JobState {
+ MSVM_CONCRETEJOB_JOBSTATE_NEW = 2,
+ MSVM_CONCRETEJOB_JOBSTATE_STARTING = 3,
+ MSVM_CONCRETEJOB_JOBSTATE_RUNNING = 4,
+ MSVM_CONCRETEJOB_JOBSTATE_SUSPENDED = 5,
+ MSVM_CONCRETEJOB_JOBSTATE_SHUTTING_DOWN = 6,
+ MSVM_CONCRETEJOB_JOBSTATE_COMPLETED = 7,
+ MSVM_CONCRETEJOB_JOBSTATE_TERMINATED = 8,
+ MSVM_CONCRETEJOB_JOBSTATE_KILLED = 9,
+ MSVM_CONCRETEJOB_JOBSTATE_EXCEPTION = 10,
+ MSVM_CONCRETEJOB_JOBSTATE_SERVICE = 11,
+};
+
+
+
+# include "hyperv_wmi_classes.generated.h"
+
+#endif /* __HYPERV_WMI_CLASSES_H__ */
diff --git a/src/hyperv/hyperv_wmi_generator.input b/src/hyperv/hyperv_wmi_generator.input
new file mode 100644
index 0000000..da874ac
--- /dev/null
+++ b/src/hyperv/hyperv_wmi_generator.input
@@ -0,0 +1,294 @@
+#
+# Definitions of WMI classes used as input for the hyperv_wmi_generator.py
+# script.
+#
+# This format is line-based, so end-of-line is important.
+#
+#
+# Class definition:
+#
+# class <name>
+# <type> <name>
+# ...
+# end
+#
+# Allowed values for <type> are: boolean, string, datetime, int8, int16,
+# int32, int64, uint8, uint16, uint32 and uint64
+#
+# The property <name> can be followed by [] to define a dynamic array.
+#
+
+
+class Msvm_ComputerSystem
+ string Caption
+ string Description
+ string ElementName
+ datetime InstallDate
+ uint16 OperationalStatus[]
+ string StatusDescriptions[]
+ string Status
+ uint16 HealthState
+ uint16 EnabledState
+ string OtherEnabledState
+ uint16 RequestedState
+ uint16 EnabledDefault
+ datetime TimeOfLastStateChange
+ string CreationClassName
+ string Name
+ string PrimaryOwnerName
+ string PrimaryOwnerContact
+ string Roles[]
+ string NameFormat
+ string OtherIdentifyingInfo[]
+ string IdentifyingDescriptions[]
+ uint16 Dedicated[]
+ string OtherDedicatedDescriptions[]
+ uint16 ResetCapability
+ uint16 PowerManagementCapabilities[]
+ uint64 OnTimeInMilliseconds
+ datetime TimeOfLastConfigurationChange
+ uint32 ProcessID
+ uint16 AssignedNumaNodeList[]
+end
+
+
+class Msvm_ConcreteJob
+ string Caption
+ string Description
+ string ElementName
+ datetime InstallDate
+ uint16 OperationalStatus[]
+ string StatusDescriptions[]
+ string Status
+ uint16 HealthState
+ string JobStatus
+ datetime TimeSubmitted
+ datetime ScheduledStartTime
+ datetime StartTime
+ datetime ElapsedTime
+ uint32 JobRunTimes
+ uint8 RunMonth
+ int8 RunDay
+ int8 RunDayOfWeek
+ datetime RunStartInterval
+ uint16 LocalOrUtcTime
+ datetime UntilTime
+ string Notify
+ string Owner
+ uint32 Priority
+ uint16 PercentComplete
+ boolean DeleteOnCompletion
+ uint16 ErrorCode
+ string ErrorDescription
+ string ErrorSummaryDescription
+ uint16 RecoveryAction
+ string OtherRecoveryAction
+ string InstanceID
+ string Name
+ uint16 JobState
+ datetime TimeOfLastStateChange
+ datetime TimeBeforeRemoval
+ boolean Cancellable
+end
+
+
+class Msvm_MemorySettingData
+ string Caption
+ string Description
+ string InstanceID
+ string ElementName
+ uint16 ResourceType
+ string OtherResourceType
+ string ResourceSubType
+ string PoolID
+ uint16 ConsumerVisibility
+ string HostResource[]
+ string AllocationUnits
+ uint64 VirtualQuantity
+ uint64 Reservation
+ uint64 Limit
+ uint32 Weight
+ boolean AutomaticAllocation
+ boolean AutomaticDeallocation
+ string Parent
+ string Connection[]
+ string Address
+ uint16 MappingBehavior
+ boolean IsVirtualized
+ string DeviceID
+ string DeviceIDFormat
+ boolean DynamicMemoryEnabled
+# uint32 TargetMemoryBuffer # Available only on Windows Server 2008 R2 SP1
+end
+
+
+class Msvm_ProcessorSettingData
+ string Caption
+ string Description
+ string InstanceID
+ string ElementName
+ uint16 ResourceType
+ string OtherResourceType
+ string ResourceSubType
+ string PoolID
+ uint16 ConsumerVisibility
+ string HostResource[]
+ string AllocationUnits
+ uint64 VirtualQuantity
+ uint64 Reservation
+ uint64 Limit
+ uint32 Weight
+ boolean AutomaticAllocation
+ boolean AutomaticDeallocation
+ string Parent
+ string Connection[]
+ string Address
+ uint16 MappingBehavior
+ boolean IsVirtualized
+ string DeviceID
+ string DeviceIDFormat
+ uint16 ProcessorsPerSocket
+ uint16 SocketCount
+ boolean ThreadsEnabled
+ boolean LimitCPUID
+ boolean LimitProcessorFeatures
+end
+
+
+class Msvm_VirtualSystemSettingData
+ string Caption
+ string Description
+ string ElementName
+ string InstanceID
+ string SystemName
+ uint16 SettingType
+ uint16 VirtualSystemType
+ string OtherVirtualSystemType
+ boolean AutoActivate
+ datetime CreationTime
+ string Notes
+ string BIOSGUID
+ string BIOSSerialNumber
+ string BaseBoardSerialNumber
+ string ChassisSerialNumber
+ string ChassisAssetTag
+ boolean BIOSNumLock
+ uint16 BootOrder[]
+ string Parent
+ uint16 NumaNodeList[]
+ boolean NumaNodesAreRequired
+end
+
+
+class Win32_ComputerSystem
+ uint16 AdminPasswordStatus
+ boolean AutomaticManagedPagefile
+ boolean AutomaticResetBootOption
+ boolean AutomaticResetCapability
+ uint16 BootOptionOnLimit
+ uint16 BootOptionOnWatchDog
+ boolean BootROMSupported
+ string BootupState
+ string Caption
+ uint16 ChassisBootupState
+ string CreationClassName
+ int16 CurrentTimeZone
+ boolean DaylightInEffect
+ string Description
+ string DNSHostName
+ string Domain
+ uint16 DomainRole
+ boolean EnableDaylightSavingsTime
+ uint16 FrontPanelResetStatus
+ boolean InfraredSupported
+# string InitialLoadInfo # MSDN documents it, but it's not there
+ datetime InstallDate
+ uint16 KeyboardPasswordStatus
+ string LastLoadInfo
+ string Manufacturer
+ string Model
+ string Name
+ string NameFormat
+ boolean NetworkServerModeEnabled
+ uint32 NumberOfLogicalProcessors
+ uint32 NumberOfProcessors
+ uint8 OEMLogoBitmap[]
+ string OEMStringArray[]
+ boolean PartOfDomain
+ int64 PauseAfterReset
+ uint16 PCSystemType
+ uint16 PowerManagementCapabilities[]
+ boolean PowerManagementSupported
+ uint16 PowerOnPasswordStatus
+ uint16 PowerState
+ uint16 PowerSupplyState
+ string PrimaryOwnerContact
+ string PrimaryOwnerName
+ uint16 ResetCapability
+ int16 ResetCount
+ int16 ResetLimit
+ string Roles[]
+ string Status
+ string SupportContactDescription[]
+ uint16 SystemStartupDelay
+ string SystemStartupOptions[]
+ uint8 SystemStartupSetting
+ string SystemType
+ uint16 ThermalState
+ uint64 TotalPhysicalMemory
+ string UserName
+ uint16 WakeUpType
+ string Workgroup
+end
+
+
+class Win32_Processor
+ uint16 AddressWidth
+ uint16 Architecture
+ uint16 Availability
+ string Caption
+ uint32 ConfigManagerErrorCode
+ boolean ConfigManagerUserConfig
+ uint16 CpuStatus
+ string CreationClassName
+ uint32 CurrentClockSpeed
+ uint16 CurrentVoltage
+ uint16 DataWidth
+ string Description
+ string DeviceID
+ boolean ErrorCleared
+ string ErrorDescription
+ uint32 ExtClock
+ uint16 Family
+ datetime InstallDate
+ uint32 L2CacheSize
+ uint32 L2CacheSpeed
+ uint32 L3CacheSize
+ uint32 L3CacheSpeed
+ uint32 LastErrorCode
+ uint16 Level
+ uint16 LoadPercentage
+ string Manufacturer
+ uint32 MaxClockSpeed
+ string Name
+ uint32 NumberOfCores
+ uint32 NumberOfLogicalProcessors
+ string OtherFamilyDescription
+ string PNPDeviceID
+ uint16 PowerManagementCapabilities[]
+ boolean PowerManagementSupported
+ string ProcessorId
+ uint16 ProcessorType
+ uint16 Revision
+ string Role
+ string SocketDesignation
+ string Status
+ uint16 StatusInfo
+ string Stepping
+ string SystemCreationClassName
+ string SystemName
+ string UniqueId
+ uint16 UpgradeMethod
+ string Version
+ uint32 VoltageCaps
+end
diff --git a/src/hyperv/hyperv_wmi_generator.py b/src/hyperv/hyperv_wmi_generator.py
new file mode 100755
index 0000000..077c3a0
--- /dev/null
+++ b/src/hyperv/hyperv_wmi_generator.py
@@ -0,0 +1,309 @@
+#!/usr/bin/env python
+
+#
+# hyperv_wmi_generator.py: generates most of the WMI type mapping code
+#
+# Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+#
+# 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
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+import sys
+import os
+import os.path
+
+
+
+separator = "/* " + ("* " * 37) + "*\n"
+
+
+
+class Class:
+ def __init__(self, name, properties):
+ self.name = name
+ self.properties = properties
+
+
+ def generate_header(self):
+ name_upper = self.name.upper()
+
+ header = separator
+ header += " * %s\n" % self.name
+ header += " */\n"
+ header += "\n"
+ header += "int hypervGet%sList(hypervPrivate *priv, virBufferPtr query, %s **list);\n" \
+ % (self.name.replace("_", ""), self.name)
+ header += "\n"
+ header += "\n"
+ header += "\n"
+
+ return header
+
+
+ def generate_classes_typedef(self):
+ typedef = "typedef struct _%s_Data %s_Data;\n" % (self.name, self.name)
+ typedef += "typedef struct _%s %s;\n" % (self.name, self.name)
+
+ return typedef
+
+
+ def generate_classes_header(self):
+ name_upper = self.name.upper()
+
+ header = separator
+ header += " * %s\n" % self.name
+ header += " */\n"
+ header += "\n"
+ header += "#define %s_RESOURCE_URI \\\n" % name_upper
+
+ if self.name.startswith("Win32_"):
+ header += " \"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/%s\"\n" % self.name
+ else:
+ header += " \"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/%s\"\n" % self.name
+
+ header += "\n"
+ header += "#define %s_CLASSNAME \\\n" % name_upper
+ header += " \"%s\"\n" % self.name
+ header += "\n"
+ header += "#define %s_WQL_SELECT \\\n" % name_upper
+ header += " \"select * from %s \"\n" % self.name
+ header += "\n"
+ header += "struct _%s_Data {\n" % self.name
+
+ for property in self.properties:
+ header += property.generate_classes_header()
+
+ header += "};\n"
+ header += "\n"
+ header += "SER_DECLARE_TYPE(%s_Data);\n" % self.name
+ header += "\n"
+ header += "struct _%s {\n" % self.name
+ header += " XmlSerializerInfo *serializerInfo;\n"
+ header += " %s_Data *data;\n" % self.name
+ header += " %s *next;\n" % self.name
+ header += "};\n"
+ header += "\n"
+ header += "\n"
+ header += "\n"
+
+ return header
+
+
+ def generate_source(self):
+ name_upper = self.name.upper()
+
+ source = separator
+ source += " * %s\n" % self.name
+ source += " */\n"
+ source += "\n"
+ source += "int\n"
+ source += "hypervGet%sList(hypervPrivate *priv, virBufferPtr query, %s **list)\n" \
+ % (self.name.replace("_", ""), self.name)
+ source += "{\n"
+
+ if self.name.startswith("Win32_"):
+ source += " return hypervEnumAndPull(priv, query, ROOT_CIMV2,\n"
+ else:
+ source += " return hypervEnumAndPull(priv, query, ROOT_VIRTUALIZATION,\n"
+
+ source += " %s_Data_TypeInfo,\n" % self.name
+ source += " %s_RESOURCE_URI,\n" % name_upper
+ source += " %s_CLASSNAME,\n" % name_upper
+ source += " (hypervObject **)list);\n"
+ source += "}\n"
+ source += "\n"
+ source += "\n"
+ source += "\n"
+
+ return source
+
+
+ def generate_classes_source(self):
+ name_upper = self.name.upper()
+
+ source = separator
+ source += " * %s\n" % self.name
+ source += " */\n"
+ source += "\n"
+ source += "SER_START_ITEMS(%s_Data)\n" % self.name
+
+ for property in self.properties:
+ source += property.generate_classes_source(self.name)
+
+ source += "SER_END_ITEMS(%s_Data);\n" % self.name
+ source += "\n"
+ source += "\n"
+ source += "\n"
+
+ return source
+
+
+class Property:
+ typemap = {"boolean" : "BOOL",
+ "string" : "STR",
+ "datetime" : "STR",
+ "int8" : "INT8",
+ "int16" : "INT16",
+ "int32" : "INT32",
+ "int64" : "INT64",
+ "uint8" : "UINT8",
+ "uint16" : "UINT16",
+ "uint32" : "UINT32",
+ "uint64" : "UINT64"}
+
+
+ def __init__(self, type, name, is_array):
+ if type not in Property.typemap:
+ report_error("unhandled property type %s" % type)
+
+ self.type = type
+ self.name = name
+ self.is_array = is_array
+
+
+ def generate_classes_header(self):
+ if self.is_array:
+ return " XML_TYPE_DYN_ARRAY %s;\n" % self.name
+ else:
+ return " XML_TYPE_%s %s;\n" \
+ % (Property.typemap[self.type], self.name)
+
+
+ def generate_classes_source(self, class_name):
+ if self.is_array:
+ return " SER_NS_DYN_ARRAY(%s_RESOURCE_URI, \"%s\", 0, 0, %s),\n" \
+ % (class_name.upper(), self.name, self.type)
+ else:
+ return " SER_NS_%s(%s_RESOURCE_URI, \"%s\", 1),\n" \
+ % (Property.typemap[self.type], class_name.upper(), self.name)
+
+
+
+def open_and_print(filename):
+ if filename.startswith("./"):
+ print " GEN " + filename[2:]
+ else:
+ print " GEN " + filename
+
+ return open(filename, "wb")
+
+
+
+def report_error(message):
+ print "error: " + message
+ sys.exit(1)
+
+
+
+def parse_class(block):
+ # expected format: class <name>
+ header_items = block[0][1].split()
+
+ if len(header_items) != 2:
+ report_error("line %d: invalid block header" % (number))
+
+ assert header_items[0] == "class"
+
+ name = header_items[1]
+
+ properties = []
+
+ for line in block[1:]:
+ # expected format: <type> <name>
+ items = line[1].split()
+
+ if len(items) != 2:
+ report_error("line %d: invalid property" % line[0])
+
+ if items[1].endswith("[]"):
+ items[1] = items[1][:-2]
+ is_array = True
+ else:
+ is_array = False
+
+ properties.append(Property(type=items[0], name=items[1],
+ is_array=is_array))
+
+ return Class(name=name, properties=properties)
+
+
+
+def main():
+ if "srcdir" in os.environ:
+ input_filename = os.path.join(os.environ["srcdir"], "hyperv/hyperv_wmi_generator.input")
+ output_dirname = os.path.join(os.environ["srcdir"], "hyperv")
+ else:
+ input_filename = os.path.join(os.getcwd(), "hyperv_wmi_generator.input")
+ output_dirname = os.getcwd()
+
+ header = open_and_print(os.path.join(output_dirname, "hyperv_wmi.generated.h"))
+ source = open_and_print(os.path.join(output_dirname, "hyperv_wmi.generated.c"))
+ classes_typedef = open_and_print(os.path.join(output_dirname, "hyperv_wmi_classes.generated.typedef"))
+ classes_header = open_and_print(os.path.join(output_dirname, "hyperv_wmi_classes.generated.h"))
+ classes_source = open_and_print(os.path.join(output_dirname, "hyperv_wmi_classes.generated.c"))
+
+ # parse input file
+ number = 0
+ classes_by_name = {}
+ block = None
+
+ for line in file(input_filename, "rb").readlines():
+ number += 1
+
+ if "#" in line:
+ line = line[:line.index("#")]
+
+ line = line.lstrip().rstrip()
+
+ if len(line) < 1:
+ continue
+
+ if line.startswith("class"):
+ if block is not None:
+ report_error("line %d: nested block found" % (number))
+ else:
+ block = []
+
+ if block is not None:
+ if line == "end":
+ if block[0][1].startswith("class"):
+ cls = parse_class(block)
+ classes_by_name[cls.name] = cls
+
+ block = None
+ else:
+ block.append((number, line))
+
+ # write output files
+ header.write("/* Generated by hyperv_wmi_generator.py */\n\n\n\n")
+ source.write("/* Generated by hyperv_wmi_generator.py */\n\n\n\n")
+ classes_typedef.write("/* Generated by hyperv_wmi_generator.py */\n\n\n\n")
+ classes_header.write("/* Generated by hyperv_wmi_generator.py */\n\n\n\n")
+ classes_source.write("/* Generated by hyperv_wmi_generator.py */\n\n\n\n")
+
+ names = classes_by_name.keys()
+ names.sort()
+
+ for name in names:
+ header.write(classes_by_name[name].generate_header())
+ source.write(classes_by_name[name].generate_source())
+ classes_typedef.write(classes_by_name[name].generate_classes_typedef())
+ classes_header.write(classes_by_name[name].generate_classes_header())
+ classes_source.write(classes_by_name[name].generate_classes_source())
+
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/hyperv/openwsman.h b/src/hyperv/openwsman.h
new file mode 100644
index 0000000..8bc0604
--- /dev/null
+++ b/src/hyperv/openwsman.h
@@ -0,0 +1,47 @@
+
+/*
+ * openwsman.h: workarounds for bugs in openwsman
+ *
+ * Copyright (C) 2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __OPENWSMAN_H__
+# define __OPENWSMAN_H__
+
+/* Workaround openwsman <= 2.2.6 unconditionally defining optarg. Just pretend
+ * that u/os.h was already included. Need to explicitly include time.h because
+ * wsman-xml-serializer.h needs it and u/os.h would have included it. */
+# include <time.h>
+# define _LIBU_OS_H_
+# include <wsman-api.h>
+
+/* wsman-xml-serializer.h in openwsman <= 2.2.6 is missing this defines */
+# ifndef SER_NS_INT8
+# define SER_NS_INT8(ns, n, x) SER_NS_INT8_FLAGS(ns, n, x, 0)
+# endif
+# ifndef SER_NS_INT16
+# define SER_NS_INT16(ns, n, x) SER_NS_INT16_FLAGS(ns, n, x, 0)
+# endif
+# ifndef SER_NS_INT32
+# define SER_NS_INT32(ns, n, x) SER_NS_INT32_FLAGS(ns, n, x, 0)
+# endif
+# ifndef SER_NS_INT64
+# define SER_NS_INT64(ns, n, x) SER_NS_INT64_FLAGS(ns, n, x, 0)
+# endif
+
+#endif /* __OPENWSMAN_H__ */
diff --git a/src/libvirt.c b/src/libvirt.c
index 7e70caa..8eb8905 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -66,6 +66,9 @@
# ifdef WITH_ESX
# include "esx/esx_driver.h"
# endif
+# ifdef WITH_HYPERV
+# include "hyperv/hyperv_driver.h"
+# endif
# ifdef WITH_XENAPI
# include "xenapi/xenapi_driver.h"
# endif
@@ -446,6 +449,9 @@ virInitialize(void)
# ifdef WITH_ESX
virDriverLoadModule("esx");
# endif
+# ifdef WITH_HYPERV
+ virDriverLoadModule("hyperv");
+# endif
# ifdef WITH_XENAPI
virDriverLoadModule("xenapi");
# endif
@@ -474,6 +480,9 @@ virInitialize(void)
# ifdef WITH_ESX
if (esxRegister() == -1) return -1;
# endif
+# ifdef WITH_HYPERV
+ if (hypervRegister() == -1) return -1;
+# endif
# ifdef WITH_XENAPI
if (xenapiRegister() == -1) return -1;
# endif
@@ -1038,6 +1047,9 @@ do_open (const char *name,
STRCASEEQ(ret->uri->scheme, "esx") ||
STRCASEEQ(ret->uri->scheme, "gsx") ||
#endif
+#ifndef WITH_HYPERV
+ STRCASEEQ(ret->uri->scheme, "hyperv") ||
+#endif
#ifndef WITH_XENAPI
STRCASEEQ(ret->uri->scheme, "xenapi") ||
#endif
diff --git a/src/util/virterror.c b/src/util/virterror.c
index 75058f3..e13bac3 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -172,6 +172,9 @@ static const char *virErrorDomainName(virErrorDomain domain) {
case VIR_FROM_LOCKING:
dom = "Locking ";
break;
+ case VIR_FROM_HYPERV:
+ dom = "Hyper-V ";
+ break;
}
return(dom);
}
--
1.7.4.1
1
1
[libvirt] [PATCH] virsh: fix missing prompt message for 'snapshot-delete' command
by Nan Zhang 13 Jul '11
by Nan Zhang 13 Jul '11
13 Jul '11
Make the command 'virsh snapshot-delete' has the appropriate prompt
message when executing sucessful or failed.
---
tools/virsh.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index cd17f42..b7cea58 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -11534,8 +11534,12 @@ cmdSnapshotDelete(vshControl *ctl, const vshCmd *cmd)
if (snapshot == NULL)
goto cleanup;
- if (virDomainSnapshotDelete(snapshot, flags) < 0)
+ if (virDomainSnapshotDelete(snapshot, flags) == 0) {
+ vshPrint(ctl, _("Domain snapshot %s deleted\n"), name);
+ } else {
+ vshError(ctl, _("Failed to delete snapshot %s"), name);
goto cleanup;
+ }
ret = true;
--
1.7.4.4
3
2
13 Jul '11
While compiling on F15 build crashed (probably because of new GCC).
---
AUTHORS | 1 +
src/qemu/qemu_driver.c | 7 ++++---
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index 4b16a2c..636fa63 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -185,6 +185,7 @@ Patches have also been contributed by:
Michael Santos <michael.santos(a)gmail.com>
Alex Jia <ajia(a)redhat.com>
Oskari Saarenmaa <os(a)ohmu.fi>
+ Peter Krempa <pkrempa(a)redhat.com>
[....send patches to get your name here....]
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0a6b48e..5c9c7bc 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1498,7 +1498,9 @@ static int qemuDomainReboot(virDomainPtr dom, unsigned int flags) {
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
int ret = -1;
+#if HAVE_YAJL
qemuDomainObjPrivatePtr priv;
+#endif
virCheckFlags(0, -1);
@@ -1513,9 +1515,10 @@ static int qemuDomainReboot(virDomainPtr dom, unsigned int flags) {
_("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
- priv = vm->privateData;
#if HAVE_YAJL
+ priv = vm->privateData;
+
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON)) {
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
@@ -2598,7 +2601,6 @@ static int qemudDomainCoreDump(virDomainPtr dom,
int resume = 0, paused = 0;
int ret = -1;
virDomainEventPtr event = NULL;
- qemuDomainObjPrivatePtr priv;
virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH, -1);
@@ -2612,7 +2614,6 @@ static int qemudDomainCoreDump(virDomainPtr dom,
_("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
- priv = vm->privateData;
if (qemuDomainObjBeginAsyncJobWithDriver(driver, vm,
QEMU_ASYNC_JOB_DUMP) < 0)
--
1.7.6
3
2
13 Jul '11
Getting metadata on storage allocates a memory (path) which need to
be freed after use otherwise it gets leaked. This means after use of
virStorageFileGetMetadataFromFD or virStorageFileGetMetadata one
must call virStorageFileFreeMetadata to free it. Right now this
function frees only one variable in metadata structure, but is prepared
to be extended in the future.
---
src/conf/domain_conf.c | 8 +++++++-
src/libvirt_private.syms | 1 +
src/qemu/qemu_driver.c | 3 +++
src/storage/storage_backend_fs.c | 5 +++--
src/util/storage_file.c | 15 +++++++++++++++
src/util/storage_file.h | 2 ++
6 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 39e59b9..2ebd012 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11055,6 +11055,9 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
int ret = -1;
size_t depth = 0;
char *nextpath = NULL;
+ virStorageFileMetadata meta;
+
+ memset(&meta, 0, sizeof(virStorageFileMetadata));
if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
return 0;
@@ -11084,7 +11087,6 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
paths = virHashCreate(5, NULL);
do {
- virStorageFileMetadata meta;
const char *path = nextpath ? nextpath : disk->src;
int fd;
@@ -11127,6 +11129,7 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
depth++;
nextpath = meta.backingStore;
+ meta.backingStore = NULL;
/* Stop iterating if we reach a non-file backing store */
if (nextpath && !meta.backingStoreIsFile) {
@@ -11137,6 +11140,8 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
format = meta.backingStoreFormat;
+ virStorageFileFreeMetadata(meta);
+
if (format == VIR_STORAGE_FILE_AUTO &&
!allowProbing)
format = VIR_STORAGE_FILE_RAW; /* Stops further recursion */
@@ -11151,6 +11156,7 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
cleanup:
virHashFree(paths);
VIR_FREE(nextpath);
+ virStorageFileFreeMetadata(meta);
return ret;
}
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3237d18..e06c7fc 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -940,6 +940,7 @@ virStorageGenerateQcowPassphrase;
# storage_file.h
virStorageFileFormatTypeFromString;
virStorageFileFormatTypeToString;
+virStorageFileFreeMetadata;
virStorageFileGetMetadata;
virStorageFileGetMetadataFromFD;
virStorageFileIsSharedFS;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0a6b48e..54f9bba 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6358,6 +6358,8 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
virCheckFlags(0, -1);
+ memset(&meta, 0, sizeof(virStorageFileMetadata));
+
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
qemuDriverUnlock(driver);
@@ -6511,6 +6513,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
cleanup:
VIR_FORCE_CLOSE(fd);
+ virStorageFileFreeMetadata(meta);
if (vm)
virDomainObjUnlock(vm);
return ret;
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index d87401f..02b1637 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -118,7 +118,6 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
ret = 0;
}
} else {
- VIR_FREE(meta.backingStore);
ret = 0;
}
@@ -147,10 +146,12 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
*/
}
+ virStorageFileFreeMetadata(meta);
+
return ret;
cleanup:
- VIR_FREE(*backingStore);
+ virStorageFileFreeMetadata(meta);
return -1;
}
diff --git a/src/util/storage_file.c b/src/util/storage_file.c
index 06cabc8..19c2464 100644
--- a/src/util/storage_file.c
+++ b/src/util/storage_file.c
@@ -819,6 +819,8 @@ virStorageFileProbeFormat(const char *path)
* it indicates the image didn't specify an explicit format for its
* backing store. Callers are advised against probing for the
* backing store format in this case.
+ *
+ * Caller must free @meta after use via virStorageFileFreeMetadata.
*/
int
virStorageFileGetMetadataFromFD(const char *path,
@@ -892,6 +894,8 @@ cleanup:
* it indicates the image didn't specify an explicit format for its
* backing store. Callers are advised against probing for the
* backing store format in this case.
+ *
+ * Caller MUST free @meta after use via virStorageFileFreeMetadata.
*/
int
virStorageFileGetMetadata(const char *path,
@@ -912,6 +916,17 @@ virStorageFileGetMetadata(const char *path,
return ret;
}
+/**
+ * virStorageFileFreeMetadata:
+ *
+ * Free pointers in passed structure, but not memory used by
+ * structure itself.
+ */
+void
+virStorageFileFreeMetadata(virStorageFileMetadata meta)
+{
+ VIR_FREE(meta.backingStore);
+}
#ifdef __linux__
diff --git a/src/util/storage_file.h b/src/util/storage_file.h
index f1bdd02..b362796 100644
--- a/src/util/storage_file.h
+++ b/src/util/storage_file.h
@@ -70,6 +70,8 @@ int virStorageFileGetMetadataFromFD(const char *path,
int format,
virStorageFileMetadata *meta);
+void virStorageFileFreeMetadata(virStorageFileMetadata meta);
+
enum {
VIR_STORAGE_FILE_SHFS_NFS = (1 << 0),
VIR_STORAGE_FILE_SHFS_GFS2 = (1 << 1),
--
1.7.5.rc3
2
1
[libvirt] [PATCH] util: honor anchored names when searching for executables
by Eric Blake 13 Jul '11
by Eric Blake 13 Jul '11
13 Jul '11
I got bit in a debugging session on an uninstalled libvirtd; the
code tried to call out to the installed $LIBEXECDIR/libvirt_iohelper
instead of my just-built version. So I set a breakpoint and altered
the binary name to be "./src/libvirt_iohelper", and it still failed
because I don't have "." on my PATH.
According to POSIX, execvp only searches PATH if the name does
not contain a slash. Since we are trying to mimic that behavior,
an anchored name should be relative to the current working dir.
* src/util/util.c (virFindFileInPath): Anchored relative names do
not invoke a PATH search.
---
src/util/util.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/src/util/util.c b/src/util/util.c
index 1441c51..20ccfa7 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -596,6 +596,14 @@ char *virFindFileInPath(const char *file)
return NULL;
}
+ /* If we are passed an anchored path (containing a /), then there
+ * is no path search - it must exist in the current directory
+ */
+ if (strchr(file, '/')) {
+ virFileAbsPath(file, &path);
+ return path;
+ }
+
/* copy PATH env so we can tweak it */
path = getenv("PATH");
--
1.7.4.4
2
2
13 Jul '11
The following series converts libvirt-qpid into a matahari agent using the
QMFv2 APIs.
Since the patches are rather large, I have also pushed them to GitHub for
easier reviewing:
https://github.com/zaneb/libvirt-qpid/commits/review
Any and all comments are welcome.
thanks,
Zane.
---
Zane Bitter (3):
Convert to QMFv2 APIs
Convert class names to lower case
Make libvirt-qpid a matahari agent
AUTHORS | 4
configure.ac | 1
libvirt-qpid.spec | 6
src/DomainWrap.cpp | 444 ++++++++++++++++++---------------
src/DomainWrap.h | 49 +---
src/Error.h | 8 +
src/Exception.cpp | 38 +++
src/Exception.h | 30 ++
src/LibvirtAgent.cpp | 97 +++++++
src/LibvirtAgent.h | 36 +++
src/Makefile.am | 34 +--
src/ManagedObject.h | 78 ++++++
src/NodeWrap.cpp | 643 ++++++++++++++++++++----------------------------
src/NodeWrap.h | 64 ++---
src/PoolWrap.cpp | 365 +++++++++++++++------------
src/PoolWrap.h | 60 ++--
src/VolumeWrap.cpp | 153 ++++++-----
src/VolumeWrap.h | 58 +---
src/libvirt-schema.xml | 8 -
19 files changed, 1198 insertions(+), 978 deletions(-)
create mode 100644 src/Exception.cpp
create mode 100644 src/Exception.h
create mode 100644 src/LibvirtAgent.cpp
create mode 100644 src/LibvirtAgent.h
create mode 100644 src/ManagedObject.h
5
12
13 Jul '11
* src/uml_conf.h: Add queue for dispatch of domain events
* src/uml_driver.c: Trigger domain events upon important lifecycle transitions
---
src/uml/uml_conf.h | 4 +
src/uml/uml_driver.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 194 insertions(+), 4 deletions(-)
diff --git a/src/uml/uml_conf.h b/src/uml/uml_conf.h
index 1105f84..5401a7e 100644
--- a/src/uml/uml_conf.h
+++ b/src/uml/uml_conf.h
@@ -29,6 +29,7 @@
# include "capabilities.h"
# include "network_conf.h"
# include "domain_conf.h"
+# include "domain_event.h"
# include "virterror_internal.h"
# include "threads.h"
# include "command.h"
@@ -60,6 +61,9 @@ struct uml_driver {
int inotifyWatch;
virCapsPtr caps;
+
+ /* Event handling */
+ virDomainEventStatePtr domainEventState;
};
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 91591f1..d0736df 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -113,6 +113,9 @@ static int umlOpenMonitor(struct uml_driver *driver,
virDomainObjPtr vm);
static int umlReadPidFile(struct uml_driver *driver,
virDomainObjPtr vm);
+static void umlDomainEventFlush(int timer, void *opaque);
+static void umlDomainEventQueue(struct uml_driver *driver,
+ virDomainEventPtr event);
static int umlSetCloseExec(int fd) {
int flags;
@@ -166,6 +169,13 @@ umlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaqu
virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to autostart VM '%s': %s"),
vm->def->name, err ? err->message : _("unknown error"));
+ } else {
+ virDomainEventPtr event =
+ virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STARTED,
+ VIR_DOMAIN_EVENT_STARTED_BOOTED);
+ if (event)
+ umlDomainEventQueue(data->driver, event);
}
}
virDomainObjUnlock(vm);
@@ -185,7 +195,9 @@ umlAutostartConfigs(struct uml_driver *driver) {
struct umlAutostartData data = { driver, conn };
+ umlDriverLock(driver);
virHashForEach(driver->domains.objs, umlAutostartDomain, &data);
+ umlDriverUnlock(driver);
if (conn)
virConnectClose(conn);
@@ -266,6 +278,7 @@ umlInotifyEvent(int watch,
char *tmp, *name;
struct uml_driver *driver = data;
virDomainObjPtr dom;
+ virDomainEventPtr event = NULL;
umlDriverLock(driver);
if (watch != driver->inotifyWatch)
@@ -311,6 +324,9 @@ reread:
umlShutdownVMDaemon(NULL, driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
virDomainAuditStop(dom, "shutdown");
+ event = virDomainEventNewFromObj(dom,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
if (!dom->persistent) {
virDomainRemoveInactive(&driver->domains,
dom);
@@ -337,6 +353,9 @@ reread:
umlShutdownVMDaemon(NULL, driver, dom,
VIR_DOMAIN_SHUTOFF_FAILED);
virDomainAuditStop(dom, "failed");
+ event = virDomainEventNewFromObj(dom,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_FAILED);
if (!dom->persistent) {
virDomainRemoveInactive(&driver->domains,
dom);
@@ -347,6 +366,9 @@ reread:
umlShutdownVMDaemon(NULL, driver, dom,
VIR_DOMAIN_SHUTOFF_FAILED);
virDomainAuditStop(dom, "failed");
+ event = virDomainEventNewFromObj(dom,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_FAILED);
if (!dom->persistent) {
virDomainRemoveInactive(&driver->domains,
dom);
@@ -359,6 +381,8 @@ reread:
}
cleanup:
+ if (event)
+ umlDomainEventQueue(driver, event);
umlDriverUnlock(driver);
}
@@ -392,6 +416,13 @@ umlStartup(int privileged)
if (virDomainObjListInit(¨_driver->domains) < 0)
goto error;
+ uml_driver->domainEventState = virDomainEventStateNew(umlDomainEventFlush,
+ uml_driver,
+ NULL,
+ true);
+ if (!uml_driver->domainEventState)
+ goto error;
+
userdir = virGetUserDirectory(uid);
if (!userdir)
goto error;
@@ -469,9 +500,10 @@ umlStartup(int privileged)
0, NULL, NULL) < 0)
goto error;
+ umlDriverUnlock(uml_driver);
+
umlAutostartConfigs(uml_driver);
- umlDriverUnlock(uml_driver);
VIR_FREE(userdir);
return 0;
@@ -487,6 +519,21 @@ error:
return -1;
}
+static void umlNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque)
+{
+ struct uml_driver *driver = opaque;
+
+ if (newVM) {
+ virDomainEventPtr event =
+ virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_DEFINED,
+ VIR_DOMAIN_EVENT_DEFINED_ADDED);
+ if (event)
+ umlDomainEventQueue(driver, event);
+ }
+}
+
+
/**
* umlReload:
*
@@ -503,10 +550,10 @@ umlReload(void) {
¨_driver->domains,
uml_driver->configDir,
uml_driver->autostartDir,
- 0, NULL, NULL);
+ 0, umlNotifyLoadDomain, uml_driver);
+ umlDriverUnlock(uml_driver);
umlAutostartConfigs(uml_driver);
- umlDriverUnlock(uml_driver);
return 0;
}
@@ -569,6 +616,8 @@ umlShutdown(void) {
virDomainObjListDeinit(¨_driver->domains);
+ virDomainEventStateFree(uml_driver->domainEventState);
+
VIR_FREE(uml_driver->logDir);
VIR_FREE(uml_driver->configDir);
VIR_FREE(uml_driver->autostartDir);
@@ -929,6 +978,7 @@ cleanup:
/* XXX what if someone else tries to start it again
before we get the inotification ? Sounds like
trouble.... */
+ /* XXX this is bad for events too. must fix this better */
return ret;
}
@@ -1025,7 +1075,12 @@ static virDrvOpenStatus umlOpen(virConnectPtr conn,
}
static int umlClose(virConnectPtr conn) {
- /*struct uml_driver *driver = conn->privateData;*/
+ struct uml_driver *driver = conn->privateData;
+
+ umlDriverLock(driver);
+ virDomainEventCallbackListRemoveConn(conn,
+ driver->domainEventState->callbacks);
+ umlDriverUnlock(driver);
conn->privateData = NULL;
@@ -1293,6 +1348,7 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml,
virDomainDefPtr def;
virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL;
+ virDomainEventPtr event = NULL;
virCheckFlags(0, NULL);
@@ -1318,6 +1374,9 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml,
goto cleanup;
}
virDomainAuditStart(vm, "booted", true);
+ event = virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STARTED,
+ VIR_DOMAIN_EVENT_STARTED_BOOTED);
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) dom->id = vm->def->id;
@@ -1326,6 +1385,8 @@ cleanup:
virDomainDefFree(def);
if (vm)
virDomainObjUnlock(vm);
+ if (event)
+ umlDomainEventQueue(driver, event);
umlDriverUnlock(driver);
return dom;
}
@@ -1366,6 +1427,7 @@ cleanup:
static int umlDomainDestroy(virDomainPtr dom) {
struct uml_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
+ virDomainEventPtr event = NULL;
int ret = -1;
umlDriverLock(driver);
@@ -1378,6 +1440,9 @@ static int umlDomainDestroy(virDomainPtr dom) {
umlShutdownVMDaemon(dom->conn, driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED);
virDomainAuditStop(vm, "destroyed");
+ event = virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
if (!vm->persistent) {
virDomainRemoveInactive(&driver->domains,
vm);
@@ -1388,6 +1453,8 @@ static int umlDomainDestroy(virDomainPtr dom) {
cleanup:
if (vm)
virDomainObjUnlock(vm);
+ if (event)
+ umlDomainEventQueue(driver, event);
umlDriverUnlock(driver);
return ret;
}
@@ -1640,6 +1707,7 @@ static int umlNumDefinedDomains(virConnectPtr conn) {
static int umlDomainStartWithFlags(virDomainPtr dom, unsigned int flags) {
struct uml_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
+ virDomainEventPtr event = NULL;
int ret = -1;
virCheckFlags(0, -1);
@@ -1655,10 +1723,16 @@ static int umlDomainStartWithFlags(virDomainPtr dom, unsigned int flags) {
ret = umlStartVMDaemon(dom->conn, driver, vm);
virDomainAuditStart(vm, "booted", ret >= 0);
+ if (ret == 0)
+ event = virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STARTED,
+ VIR_DOMAIN_EVENT_STARTED_BOOTED);
cleanup:
if (vm)
virDomainObjUnlock(vm);
+ if (event)
+ umlDomainEventQueue(driver, event);
umlDriverUnlock(driver);
return ret;
}
@@ -2208,6 +2282,114 @@ cleanup:
}
+static int
+umlDomainEventRegister(virConnectPtr conn,
+ virConnectDomainEventCallback callback,
+ void *opaque,
+ virFreeCallback freecb)
+{
+ struct uml_driver *driver = conn->privateData;
+ int ret;
+
+ umlDriverLock(driver);
+ ret = virDomainEventCallbackListAdd(conn,
+ driver->domainEventState->callbacks,
+ callback, opaque, freecb);
+ umlDriverUnlock(driver);
+
+ return ret;
+}
+
+static int
+umlDomainEventDeregister(virConnectPtr conn,
+ virConnectDomainEventCallback callback)
+{
+ struct uml_driver *driver = conn->privateData;
+ int ret;
+
+ umlDriverLock(driver);
+ ret = virDomainEventStateDeregister(conn,
+ driver->domainEventState,
+ callback);
+ umlDriverUnlock(driver);
+
+ return ret;
+}
+static int
+umlDomainEventRegisterAny(virConnectPtr conn,
+ virDomainPtr dom,
+ int eventID,
+ virConnectDomainEventGenericCallback callback,
+ void *opaque,
+ virFreeCallback freecb)
+{
+ struct uml_driver *driver = conn->privateData;
+ int ret;
+
+ umlDriverLock(driver);
+ ret = virDomainEventCallbackListAddID(conn,
+ driver->domainEventState->callbacks,
+ dom, eventID,
+ callback, opaque, freecb);
+ umlDriverUnlock(driver);
+
+ return ret;
+}
+
+
+static int
+umlDomainEventDeregisterAny(virConnectPtr conn,
+ int callbackID)
+{
+ struct uml_driver *driver = conn->privateData;
+ int ret;
+
+ umlDriverLock(driver);
+ ret = virDomainEventStateDeregisterAny(conn,
+ driver->domainEventState,
+ callbackID);
+ umlDriverUnlock(driver);
+
+ return ret;
+}
+
+
+static void umlDomainEventDispatchFunc(virConnectPtr conn,
+ virDomainEventPtr event,
+ virConnectDomainEventGenericCallback cb,
+ void *cbopaque,
+ void *opaque)
+{
+ struct uml_driver *driver = opaque;
+
+ /* Drop the lock whle dispatching, for sake of re-entrancy */
+ umlDriverUnlock(driver);
+ virDomainEventDispatchDefaultFunc(conn, event, cb, cbopaque, NULL);
+ umlDriverLock(driver);
+}
+
+
+static void umlDomainEventFlush(int timer ATTRIBUTE_UNUSED, void *opaque)
+{
+ struct uml_driver *driver = opaque;
+
+ umlDriverLock(driver);
+ virDomainEventStateFlush(driver->domainEventState,
+ umlDomainEventDispatchFunc,
+ driver);
+ umlDriverUnlock(driver);
+}
+
+
+/* driver must be locked before calling */
+static void umlDomainEventQueue(struct uml_driver *driver,
+ virDomainEventPtr event)
+{
+ virDomainEventStateQueue(driver->domainEventState, event);
+}
+
+
+
static virDriver umlDriver = {
.no = VIR_DRV_UML,
.name = "UML",
@@ -2250,11 +2432,15 @@ static virDriver umlDriver = {
.nodeGetMemoryStats = nodeGetMemoryStats, /* 0.9.3 */
.nodeGetCellsFreeMemory = nodeGetCellsFreeMemory, /* 0.5.0 */
.nodeGetFreeMemory = nodeGetFreeMemory, /* 0.5.0 */
+ .domainEventRegister = umlDomainEventRegister, /* 0.9.4 */
+ .domainEventDeregister = umlDomainEventDeregister, /* 0.9.4 */
.isEncrypted = umlIsEncrypted, /* 0.7.3 */
.isSecure = umlIsSecure, /* 0.7.3 */
.domainIsActive = umlDomainIsActive, /* 0.7.3 */
.domainIsPersistent = umlDomainIsPersistent, /* 0.7.3 */
.domainIsUpdated = umlDomainIsUpdated, /* 0.8.6 */
+ .domainEventRegisterAny = umlDomainEventRegisterAny, /* 0.9.4 */
+ .domainEventDeregisterAny = umlDomainEventDeregisterAny, /* 0.9.4 */
.domainOpenConsole = umlDomainOpenConsole, /* 0.8.6 */
};
--
1.7.4.4
2
2
Add --cache option to allow user to specify cache mode of disk device
from virsh command line when attaching a disk device.
---
tools/virsh.c | 10 ++++++++--
tools/virsh.pod | 5 +++--
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 9a189fd..cab5a35 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -10176,6 +10176,7 @@ static const vshCmdOptDef opts_attach_disk[] = {
{"target", VSH_OT_DATA, VSH_OFLAG_REQ, N_("target of disk device")},
{"driver", VSH_OT_STRING, 0, N_("driver of disk device")},
{"subdriver", VSH_OT_STRING, 0, N_("subdriver of disk device")},
+ {"cache", VSH_OT_STRING, 0, N_("cache mode of disk device")},
{"type", VSH_OT_STRING, 0, N_("target device type")},
{"mode", VSH_OT_STRING, 0, N_("mode of device reading and writing")},
{"persistent", VSH_OT_BOOL, 0, N_("persist disk attachment")},
@@ -10188,7 +10189,8 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
{
virDomainPtr dom = NULL;
const char *source = NULL, *target = NULL, *driver = NULL,
- *subdriver = NULL, *type = NULL, *mode = NULL;
+ *subdriver = NULL, *type = NULL, *mode = NULL,
+ *cache = NULL;
bool isFile = false, functionReturn = false;
int ret;
unsigned int flags;
@@ -10217,6 +10219,8 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
goto cleanup;
}
+ ignore_value(vshCommandOptString(cmd, "cache", &cache));
+
if (!stype) {
if (driver && (STREQ(driver, "file") || STREQ(driver, "tap")))
isFile = true;
@@ -10249,8 +10253,10 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
virBufferAsprintf(&buf, " name='%s'", driver);
if (subdriver)
virBufferAsprintf(&buf, " type='%s'", subdriver);
+ if (cache)
+ virBufferAsprintf(&buf, " cache='%s'", cache);
- if (driver || subdriver)
+ if (driver || subdriver || cache)
virBufferAddLit(&buf, "/>\n");
virBufferAsprintf(&buf, " <source %s='%s'/>\n",
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 736b919..79f49ba 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -874,8 +874,8 @@ For cdrom and floppy devices, this command only replaces the media within
the single existing device; consider using B<update-device> for this usage.
=item B<attach-disk> I<domain-id> I<source> I<target> optional
-I<--driver driver> I<--subdriver subdriver> I<--type type>
-I<--mode mode> I<--persistent> I<--sourcetype soucetype>
+I<--driver driver> I<--subdriver subdriver> I<--cache cache>
+I<--type type> I<--mode mode> I<--persistent> I<--sourcetype soucetype>
Attach a new disk device to the domain.
I<source> and I<target> are paths for the files and devices.
@@ -886,6 +886,7 @@ floppy device; consider using B<update-device> for this usage instead.
I<mode> can specify the two specific mode I<readonly> or I<shareable>.
I<persistent> indicates the changes will affect the next boot of the domain.
I<sourcetype> can indicate the type of source (block|file)
+I<cache> can be one of "default", "none", "writethrough" or "writeback".
=item B<attach-interface> I<domain-id> I<type> I<source> optional
I<--target target> I<--mac mac> I<--script script> I<--model model>
--
1.7.5.1
3
9
Hi,
When I run a VM(qemu-0.13) on my host with the latest libvirt,
I used following settings.
==
<domain type='kvm' id='1'>
<name>RHEL6</name>
<uuid>f7ad6bc3-e82a-1254-efb0-9e1a87d83d88</uuid>
<memory>2048000</memory>
<currentMemory>2048000</currentMemory>
<vcpu cpuset='4-7'>2</vcpu>
==
I expected all works for this domain will be tied to cpu 4-7.
After minites, I checked the VM behavior and it shows
==
[root@bluextal src]# cat /cgroup/cpuacct/libvirt/qemu/RHEL6/cpuacct.usage_percpu
0 511342 3027636 94237 657712515 257104928 513463748303 252386161
==
Hmm, cpu 1,2,3 are used for some purpose.
All threads for this qemu may be following.
==
[root@bluextal src]# cat /cgroup/cpuacct/libvirt/qemu/RHEL6/tasks
25707
25727
25728
25729
==
And I found
==
[root@bluextal src]# grep Cpus /proc/25707/status
Cpus_allowed: f0
Cpus_allowed_list: 4-7
[root@bluextal src]# grep Cpus /proc/25727/status
Cpus_allowed: ff
Cpus_allowed_list: 0-7
[root@bluextal src]# grep Cpus /proc/25728/status
Cpus_allowed: f0
Cpus_allowed_list: 4-7
[root@bluextal src]# grep Cpus /proc/25729/status
Cpus_allowed: f0
Cpus_allowed_list: 4-7
==
Thread 25727 has no limitation.
Is this an expected behavior and I need more setting in XML definition ?
Thanks,
-Kame
5
12
Since libvirt is multi-threaded, we should use FD_CLOEXEC as much
as possible in the parent, and only relax fds to inherited after
forking, to avoid leaking an fd created in one thread to a fork
run in another thread. This gets us closer to that ideal, by
making virCommand automatically clear FD_CLOEXEC on fds intended
for the child, as well as avoiding a window of time with non-cloexec
pipes created for capturing output.
* src/util/command.c (virExecWithHook): Use CLOEXEC in parent. In
child, guarantee that all fds to pass to child are inheritable.
(getDevNull): Use CLOEXEC.
(prepareStdFd): New helper function.
* src/qemu/qemu_command.c (qemuBuildCommandLine): Simplify caller.
---
src/qemu/qemu_command.c | 16 --------------
src/util/command.c | 51 ++++++++++++++++++++++++-----------------------
2 files changed, 26 insertions(+), 41 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a3bce4a..ee706f9 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4575,14 +4575,6 @@ qemuBuildCommandLine(virConnectPtr conn,
} else if (STREQ(migrateFrom, "stdio")) {
if (qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) {
virCommandAddArgFormat(cmd, "fd:%d", migrateFd);
- /* migrateFd might be cloexec, but qemu must inherit
- * it if vmop indicates qemu will be executed */
- if (vmop != VIR_VM_OP_NO_OP &&
- virSetInherit(migrateFd, true) < 0) {
- qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Failed to clear cloexec flag"));
- goto error;
- }
virCommandPreserveFD(cmd, migrateFd);
} else if (qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) {
virCommandAddArg(cmd, "exec:cat");
@@ -4612,14 +4604,6 @@ qemuBuildCommandLine(virConnectPtr conn,
goto error;
}
virCommandAddArg(cmd, migrateFrom);
- /* migrateFd might be cloexec, but qemu must inherit
- * it if vmop indicates qemu will be executed */
- if (vmop != VIR_VM_OP_NO_OP &&
- virSetInherit(migrateFd, true) < 0) {
- qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Failed to clear cloexec flag"));
- goto error;
- }
virCommandPreserveFD(cmd, migrateFd);
} else if (STRPREFIX(migrateFrom, "unix")) {
if (!qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_UNIX)) {
diff --git a/src/util/command.c b/src/util/command.c
index 83d4e88..e4cf389 100644
--- a/src/util/command.c
+++ b/src/util/command.c
@@ -257,7 +257,7 @@ cleanup:
static int
getDevNull(int *null)
{
- if (*null == -1 && (*null = open("/dev/null", O_RDWR)) < 0) {
+ if (*null == -1 && (*null = open("/dev/null", O_RDWR|O_CLOEXEC)) < 0) {
virReportSystemError(errno,
_("cannot open %s"),
"/dev/null");
@@ -266,6 +266,18 @@ getDevNull(int *null)
return 0;
}
+/* Ensure that STD is an inheritable copy of FD. Return 0 on success,
+ * -1 on failure. */
+static int
+prepareStdFd(int fd, int std)
+{
+ if (fd == std)
+ return virSetInherit(fd, true);
+ if (dup2(fd, std) != std)
+ return -1;
+ return 0;
+}
+
/*
* @argv argv to exec
* @envp optional environment to use for exec
@@ -325,7 +337,7 @@ virExecWithHook(const char *const*argv,
if (outfd != NULL) {
if (*outfd == -1) {
- if (pipe(pipeout) < 0) {
+ if (pipe2(pipeout, O_CLOEXEC) < 0) {
virReportSystemError(errno,
"%s", _("cannot create pipe"));
goto cleanup;
@@ -338,12 +350,6 @@ virExecWithHook(const char *const*argv,
goto cleanup;
}
- if (virSetCloseExec(pipeout[0]) == -1) {
- virReportSystemError(errno,
- "%s", _("Failed to set close-on-exec file descriptor flag"));
- goto cleanup;
- }
-
childout = pipeout[1];
} else {
childout = *outfd;
@@ -356,7 +362,7 @@ virExecWithHook(const char *const*argv,
if (errfd != NULL) {
if (*errfd == -1) {
- if (pipe(pipeerr) < 0) {
+ if (pipe2(pipeerr, O_CLOEXEC) < 0) {
virReportSystemError(errno,
"%s", _("Failed to create pipe"));
goto cleanup;
@@ -369,12 +375,6 @@ virExecWithHook(const char *const*argv,
goto cleanup;
}
- if (virSetCloseExec(pipeerr[0]) == -1) {
- virReportSystemError(errno,
- "%s", _("Failed to set close-on-exec file descriptor flag"));
- goto cleanup;
- }
-
childerr = pipeerr[1];
} else {
childerr = *errfd;
@@ -424,28 +424,29 @@ virExecWithHook(const char *const*argv,
}
openmax = sysconf(_SC_OPEN_MAX);
- for (i = 3; i < openmax; i++)
- if (i != infd &&
- i != childout &&
- i != childerr &&
- (!keepfd || i >= FD_SETSIZE || !FD_ISSET(i, keepfd))) {
+ for (i = 3; i < openmax; i++) {
+ if (i == infd || i == childout || i == childerr)
+ continue;
+ if (!keepfd || i >= FD_SETSIZE || !FD_ISSET(i, keepfd)) {
tmpfd = i;
VIR_FORCE_CLOSE(tmpfd);
+ } else if (virSetInherit(i, true) < 0) {
+ virReportSystemError(errno, _("failed to preserve fd %d"), i);
+ goto fork_error;
}
+ }
- if (dup2(infd, STDIN_FILENO) < 0) {
+ if (prepareStdFd(infd, STDIN_FILENO) < 0) {
virReportSystemError(errno,
"%s", _("failed to setup stdin file handle"));
goto fork_error;
}
- if (childout > 0 &&
- dup2(childout, STDOUT_FILENO) < 0) {
+ if (childout > 0 && prepareStdFd(childout, STDOUT_FILENO) < 0) {
virReportSystemError(errno,
"%s", _("failed to setup stdout file handle"));
goto fork_error;
}
- if (childerr > 0 &&
- dup2(childerr, STDERR_FILENO) < 0) {
+ if (childerr > 0 && prepareStdFd(childerr, STDERR_FILENO) < 0) {
virReportSystemError(errno,
"%s", _("failed to setup stderr file handle"));
goto fork_error;
--
1.7.4.4
1
1
12 Jul '11
The following series converts libvirt-qpid into a matahari agent using the
QMFv2 APIs.
Since the patches are rather large, I have also pushed them to GitHub for
easier reviewing:
https://github.com/zaneb/libvirt-qpid/commits/review
Any and all comments are welcome.
thanks,
Zane.
---
Zane Bitter (3):
Convert to QMFv2 APIs
Convert class names to lower case
Make libvirt-qpid a matahari agent
AUTHORS | 4
configure.ac | 1
libvirt-qpid.spec | 6
src/DomainWrap.cpp | 444 ++++++++++++++++++---------------
src/DomainWrap.h | 49 +---
src/Error.h | 8 +
src/Exception.cpp | 38 +++
src/Exception.h | 30 ++
src/LibvirtAgent.cpp | 97 +++++++
src/LibvirtAgent.h | 36 +++
src/Makefile.am | 34 +--
src/ManagedObject.h | 78 ++++++
src/NodeWrap.cpp | 643 ++++++++++++++++++++----------------------------
src/NodeWrap.h | 64 ++---
src/PoolWrap.cpp | 365 +++++++++++++++------------
src/PoolWrap.h | 60 ++--
src/VolumeWrap.cpp | 153 ++++++-----
src/VolumeWrap.h | 58 +---
src/libvirt-schema.xml | 8 -
19 files changed, 1198 insertions(+), 978 deletions(-)
create mode 100644 src/Exception.cpp
create mode 100644 src/Exception.h
create mode 100644 src/LibvirtAgent.cpp
create mode 100644 src/LibvirtAgent.h
create mode 100644 src/ManagedObject.h
2
1
12 Jul '11
Incrementally running 'make syntax-check' on a tree previously
built after commit 62dee6f but before 44036460 fails sc_po_check
(because the generated qemu_dispatch.h gained translatable strings).
This is a followup to commit addaa537 for that scenario.
* cfg.mk (sc_po_check): Add another prereq.
($(srcdir)/daemon/qemu_dispatch.h): Add rule.
---
Pushing under the build-breaker rule.
cfg.mk | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index b00cda3..5178a31 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -606,11 +606,15 @@ _autogen:
syntax-check: $(top_srcdir)/HACKING
# sc_po_check can fail if generated files are not built first
-sc_po_check: $(srcdir)/daemon/remote_dispatch.h \
+sc_po_check: \
+ $(srcdir)/daemon/remote_dispatch.h \
+ $(srcdir)/daemon/qemu_dispatch.h \
$(srcdir)/src/remote/remote_client_bodies.h
-$(srcdir)/daemon/remote_dispatch.h:
+$(srcdir)/daemon/remote_dispatch.h: $(srcdir)/src/remote/remote_protocol.x
$(MAKE) -C daemon remote_dispatch.h
-$(srcdir)/src/remote/remote_client_bodies.h:
+$(srcdir)/daemon/qemu_dispatch.h: $(srcdir)/src/remote/qemu_protocol.x
+ $(MAKE) -C daemon qemu_dispatch.h
+$(srcdir)/src/remote/remote_client_bodies.h: $(srcdir)/src/remote/remote_protocol.x
$(MAKE) -C src remote/remote_client_bodies.h
# List all syntax-check exemptions:
--
1.7.4.4
1
0
12 Jul '11
I'm only 80% convinced that this patch is a good idea
because in some cases I'm not entirely happy about
commenting out macros that may well be used in the near
future. On the plus side it has identified a reasonable
number of unused legacy crufty macros
This enables the -Wunused-macros GCC flag to identify
historical macros which are no longer used due to
code refactoring.
* m4/virt-compile-warnings.m4: Enable -Wunused-macros
* daemon/libvirtd.c: Remove MAX_LISTEN
* daemon/remote.c: Remove VIR_FROM_THIS
* examples/domain-events/events-c/event-test.c: Remove VIR_DEBUG
* python/libvirt-override.c: Put NAME() inside DEBUG_ERROR
* src/esx/esx*.c: Comment out unused VIR_FROM_THIS
* src/node_device/node_device_hal.c: Remove pointless macros
for accessing privateData
* src/openvz/openvz_driver.c: Remove CMDBUF_LEN/CMDOP_LEN
* src/qemu/qemu_monitor_text.c: Remove QEMU_CMD_PROMPT
and QEMU_PASSWD_PROMPT
* src/remote/remote_driver.c: Remove UNIX_PATH_MAX
* src/security/security_stack.c: Remove VIR_FROM_THIS
* src/uml/uml_conf.c: Remove umlLog()
* src/uml/uml_driver.c: Remove TEMPDIR
* src/util/bridge.c: Remove JIFFIES_TO_MS/MS_TO_JIFFIES
* src/util/hooks.c: Ensure VIR_FROM_THIS is used
* src/util/logging.c: Remove VIR_FROM_THIS
* src/util/macvtap.c: Disable unused constants
* src/util/storage_file.c: Disable QCOW1_HDR_TOTAL_SIZE
* src/vbox/vbox_driver.c: Remove duplicated VIR_FROM_THIS
and make sure it is used
* src/util/pci.c: Disable some unused constants
* src/xen/xen_hypervisor.c: Remove XEN_V0_IOCTL_HYPERCALL_CMD
and unused DOMFLAGS_CPUMASK/DOMFLAGS_CPUSHIFT
* src/xen/xm_internal.c: Remove XM_XML_ERROR,
XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU and
XEND_CONFIG_MIN_VERS_PVFB_NEWCONF
* tools/virsh.c: Remove DIR_MODE/LOCK_MODE, LVL_NOTICE constants
* tests/sockettest.c: Remove DO_TEST_PARSE
---
daemon/libvirtd.c | 2 +-
daemon/remote.c | 8 ++++++--
m4/virt-compile-warnings.m4 | 1 -
python/libvirt-override.c | 4 +++-
src/driver.c | 3 +--
src/esx/esx_device_monitor.c | 2 +-
src/esx/esx_interface_driver.c | 2 +-
src/esx/esx_network_driver.c | 2 +-
src/esx/esx_nwfilter_driver.c | 2 +-
src/esx/esx_secret_driver.c | 2 +-
src/esx/esx_vi.c | 12 +++---------
src/esx/esx_vi_methods.c | 11 ++++++-----
src/esx/esx_vi_types.c | 5 +++--
src/libvirt.c | 3 ---
src/locking/domain_lock.c | 2 --
src/node_device/node_device_hal.c | 17 ++++-------------
src/openvz/openvz_driver.c | 2 --
src/qemu/qemu_monitor_text.c | 3 ---
src/remote/remote_driver.c | 8 ++++++--
src/security/security_stack.c | 2 --
src/uml/uml_conf.c | 2 --
src/uml/uml_driver.c | 3 ---
src/util/bridge.c | 3 ---
src/util/hooks.c | 2 +-
src/util/logging.c | 2 --
src/util/macvtap.c | 6 ++++--
src/util/netlink.c | 8 +++++---
src/util/pci.c | 4 ++--
src/util/storage_file.c | 4 +++-
src/vbox/vbox_driver.c | 4 +---
src/xen/xen_hypervisor.c | 14 +++++---------
src/xen/xm_internal.c | 9 ---------
tests/sockettest.c | 10 ----------
tools/virsh.c | 16 +++-------------
34 files changed, 62 insertions(+), 118 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 06d2077..3c3ebe1 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -1263,7 +1263,7 @@ enum {
OPT_VERSION = 129
};
-#define MAX_LISTEN 5
+
int main(int argc, char **argv) {
virNetServerPtr srv = NULL;
char *remote_config_file = NULL;
diff --git a/daemon/remote.c b/daemon/remote.c
index 2889908..5f089ce 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -65,10 +65,14 @@
(_to) = (_from); \
} while (0)
-# define HYPER_TO_LONG(_to, _from) HYPER_TO_TYPE(long, _to, _from)
+# if 0
+# define HYPER_TO_LONG(_to, _from) HYPER_TO_TYPE(long, _to, _from)
+# endif
# define HYPER_TO_ULONG(_to, _from) HYPER_TO_TYPE(unsigned long, _to, _from)
#else
-# define HYPER_TO_LONG(_to, _from) (_to) = (_from)
+# if 0
+# define HYPER_TO_LONG(_to, _from) (_to) = (_from)
+# endif
# define HYPER_TO_ULONG(_to, _from) (_to) = (_from)
#endif
diff --git a/m4/virt-compile-warnings.m4 b/m4/virt-compile-warnings.m4
index 305036f..4e98bc1 100644
--- a/m4/virt-compile-warnings.m4
+++ b/m4/virt-compile-warnings.m4
@@ -63,7 +63,6 @@ AC_DEFUN([LIBVIRT_COMPILE_WARNINGS],[
dontwarn="$dontwarn -Wconversion"
dontwarn="$dontwarn -Wsign-conversion"
dontwarn="$dontwarn -Wpacked"
- dontwarn="$dontwarn -Wunused-macros"
dontwarn="$dontwarn -Woverlength-strings"
dontwarn="$dontwarn -Wstack-protector"
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 8be9af7..4bf0bfb 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -2663,7 +2663,9 @@ static char *updateTimeoutName = NULL;
static PyObject *removeTimeoutObj = NULL;
static char *removeTimeoutName = NULL;
-#define NAME(fn) ( fn ## Name ? fn ## Name : # fn )
+#if DEBUG_ERROR
+# define NAME(fn) ( fn ## Name ? fn ## Name : # fn )
+#endif
static int
libvirt_virEventAddHandleFunc (int fd,
diff --git a/src/driver.c b/src/driver.c
index 579c2b3..16c9661 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -30,13 +30,12 @@
#include "util.h"
#include "configmake.h"
-#define DEFAULT_DRIVER_DIR LIBDIR "/libvirt/connection-driver"
-
/* Make sure ... INTERNAL_CALL cannot be set by the caller */
verify((VIR_SECRET_GET_VALUE_INTERNAL_CALL &
VIR_SECRET_GET_VALUE_FLAGS_MASK) == 0);
#ifdef WITH_DRIVER_MODULES
+# define DEFAULT_DRIVER_DIR LIBDIR "/libvirt/connection-driver"
/* XXX re-implment this for other OS, or use libtools helper lib ? */
diff --git a/src/esx/esx_device_monitor.c b/src/esx/esx_device_monitor.c
index 4bc8e7f..fc7b4de 100644
--- a/src/esx/esx_device_monitor.c
+++ b/src/esx/esx_device_monitor.c
@@ -35,7 +35,7 @@
#include "esx_vi_methods.h"
#include "esx_util.h"
-#define VIR_FROM_THIS VIR_FROM_ESX
+/* #define VIR_FROM_THIS VIR_FROM_ESX */
diff --git a/src/esx/esx_interface_driver.c b/src/esx/esx_interface_driver.c
index a468976..f324f0f 100644
--- a/src/esx/esx_interface_driver.c
+++ b/src/esx/esx_interface_driver.c
@@ -35,7 +35,7 @@
#include "esx_vi_methods.h"
#include "esx_util.h"
-#define VIR_FROM_THIS VIR_FROM_ESX
+/* #define VIR_FROM_THIS VIR_FROM_ESX */
diff --git a/src/esx/esx_network_driver.c b/src/esx/esx_network_driver.c
index 3c76fae..3a72f27 100644
--- a/src/esx/esx_network_driver.c
+++ b/src/esx/esx_network_driver.c
@@ -35,7 +35,7 @@
#include "esx_vi_methods.h"
#include "esx_util.h"
-#define VIR_FROM_THIS VIR_FROM_ESX
+/* #define VIR_FROM_THIS VIR_FROM_ESX */
diff --git a/src/esx/esx_nwfilter_driver.c b/src/esx/esx_nwfilter_driver.c
index 13cacd4..80bf5ff 100644
--- a/src/esx/esx_nwfilter_driver.c
+++ b/src/esx/esx_nwfilter_driver.c
@@ -34,7 +34,7 @@
#include "esx_vi_methods.h"
#include "esx_util.h"
-#define VIR_FROM_THIS VIR_FROM_ESX
+/* #define VIR_FROM_THIS VIR_FROM_ESX */
diff --git a/src/esx/esx_secret_driver.c b/src/esx/esx_secret_driver.c
index 656224e..68dd2bb 100644
--- a/src/esx/esx_secret_driver.c
+++ b/src/esx/esx_secret_driver.c
@@ -34,7 +34,7 @@
#include "esx_vi_methods.h"
#include "esx_util.h"
-#define VIR_FROM_THIS VIR_FROM_ESX
+/* #define VIR_FROM_THIS VIR_FROM_ESX */
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 64e5b73..fd3b447 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -40,13 +40,6 @@
#define VIR_FROM_THIS VIR_FROM_ESX
-
-#define ESX_VI__SOAP__RESPONSE_XPATH(_type) \
- ((char *)"/soapenv:Envelope/soapenv:Body/" \
- "vim:"_type"Response/vim:returnval")
-
-
-
#define ESX_VI__TEMPLATE__ALLOC(_type) \
int \
esxVI_##_type##_Alloc(esxVI_##_type **ptrptr) \
@@ -3928,11 +3921,12 @@ esxVI_ProductVersionToDefaultVirtualHWVersion(esxVI_ProductVersion productVersio
-
-#define ESX_VI__TEMPLATE__PROPERTY__CAST_FROM_ANY_TYPE_IGNORE(_name) \
+#if 0
+# define ESX_VI__TEMPLATE__PROPERTY__CAST_FROM_ANY_TYPE_IGNORE(_name) \
if (STREQ(dynamicProperty->name, #_name)) { \
continue; \
}
+#endif
diff --git a/src/esx/esx_vi_methods.c b/src/esx/esx_vi_methods.c
index 1f1780f..0284ba7 100644
--- a/src/esx/esx_vi_methods.c
+++ b/src/esx/esx_vi_methods.c
@@ -1,4 +1,3 @@
-
/*
* esx_vi_methods.c: client for the VMware VI API 2.5 to manage ESX hosts
*
@@ -52,8 +51,10 @@
-#define ESX_VI__METHOD__CHECK_OUTPUT__RequiredList \
+#if 0
+# define ESX_VI__METHOD__CHECK_OUTPUT__RequiredList \
ESX_VI__METHOD__CHECK_OUTPUT__NotNone
+#endif
@@ -78,12 +79,12 @@
}
-
-#define ESX_VI__METHOD__DESERIALIZE_OUTPUT__RequiredList(_type, _suffix) \
+#if 0
+# define ESX_VI__METHOD__DESERIALIZE_OUTPUT__RequiredList(_type) \
if (esxVI_##_type##_DeserializeList(response->node, output) < 0) { \
goto cleanup; \
}
-
+#endif
#define ESX_VI__METHOD__DESERIALIZE_OUTPUT__OptionalItem(_type, _suffix) \
diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c
index 2332fde..5d07103 100644
--- a/src/esx/esx_vi_types.c
+++ b/src/esx/esx_vi_types.c
@@ -557,11 +557,12 @@
-#define ESX_VI__TEMPLATE__DISPATCH__DEEP_COPY(_type) \
+#if 0
+# define ESX_VI__TEMPLATE__DISPATCH__DEEP_COPY(_type) \
case esxVI_Type_##_type: \
return esxVI_##_type##_DeepCopy((esxVI_##_type **)dst, \
(esxVI_##_type *)src);
-
+#endif
#define ESX_VI__TEMPLATE__DISPATCH__CAST_FROM_ANY_TYPE(_type) \
diff --git a/src/libvirt.c b/src/libvirt.c
index e00c64f..c00823e 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -543,9 +543,6 @@ DllMain (HINSTANCE instance ATTRIBUTE_UNUSED,
#define virLibSecretError(code, ...) \
virReportErrorHelper(VIR_FROM_SECRET, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__)
-#define virLibStreamError(code, ...) \
- virReportErrorHelper(VIR_FROM_STREAMS, code, __FILE__, \
- __FUNCTION__, __LINE__, __VA_ARGS__)
#define virLibNWFilterError(code, ...) \
virReportErrorHelper(VIR_FROM_NWFILTER, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__)
diff --git a/src/locking/domain_lock.c b/src/locking/domain_lock.c
index de1937c..58cbd3c 100644
--- a/src/locking/domain_lock.c
+++ b/src/locking/domain_lock.c
@@ -27,8 +27,6 @@
#include "virterror_internal.h"
#include "logging.h"
-#define VIR_FROM_THIS VIR_FROM_LOCKING
-
static int virDomainLockManagerAddLease(virLockManagerPtr lock,
virDomainLeaseDefPtr lease)
diff --git a/src/node_device/node_device_hal.c b/src/node_device/node_device_hal.c
index 27fedc9..2aa7dd9 100644
--- a/src/node_device/node_device_hal.c
+++ b/src/node_device/node_device_hal.c
@@ -37,21 +37,12 @@
#include "logging.h"
#include "node_device_driver.h"
-#define VIR_FROM_THIS VIR_FROM_NODEDEV
-
/*
* Host device enumeration (HAL implementation)
*/
static virDeviceMonitorStatePtr driverState;
-#define CONN_DRV_STATE(conn) \
- ((virDeviceMonitorStatePtr)((conn)->devMonPrivateData))
-#define DRV_STATE_HAL_CTX(ds) ((LibHalContext *)((ds)->privateData))
-#define CONN_HAL_CTX(conn) DRV_STATE_HAL_CTX(CONN_DRV_STATE(conn))
-
-#define NODE_DEV_UDI(obj) ((const char *)((obj)->privateData)
-
static const char *hal_name(const char *udi)
{
@@ -440,7 +431,7 @@ static void dev_create(const char *udi)
return;
nodeDeviceLock(driverState);
- ctx = DRV_STATE_HAL_CTX(driverState);
+ ctx = driverState->privateData;
if (VIR_ALLOC(def) < 0)
goto failure;
@@ -599,7 +590,7 @@ static void dbus_watch_callback(int fdatch ATTRIBUTE_UNUSED,
(void)dbus_watch_handle(watch, dbus_flags);
nodeDeviceLock(driverState);
- hal_ctx = DRV_STATE_HAL_CTX(driverState);
+ hal_ctx = driverState->privateData;
dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
nodeDeviceUnlock(driverState);
while (dbus_connection_dispatch(dbus_conn) == DBUS_DISPATCH_DATA_REMAINS)
@@ -807,7 +798,7 @@ static int halDeviceMonitorShutdown(void)
{
if (driverState) {
nodeDeviceLock(driverState);
- LibHalContext *hal_ctx = DRV_STATE_HAL_CTX(driverState);
+ LibHalContext *hal_ctx = driverState->privateData;
virNodeDeviceObjListFree(&driverState->devs);
(void)libhal_ctx_shutdown(hal_ctx, NULL);
(void)libhal_ctx_free(hal_ctx);
@@ -833,7 +824,7 @@ static int halDeviceMonitorReload(void)
virNodeDeviceObjListFree(&driverState->devs);
nodeDeviceUnlock(driverState);
- hal_ctx = DRV_STATE_HAL_CTX(driverState);
+ hal_ctx = driverState->privateData;
VIR_INFO("Creating new objects");
dbus_error_init(&err);
udi = libhal_get_all_devices(hal_ctx, &num_devs, &err);
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index c13f346..74b31ad 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -62,8 +62,6 @@
#define VIR_FROM_THIS VIR_FROM_OPENVZ
#define OPENVZ_MAX_ARG 28
-#define CMDBUF_LEN 1488
-#define CMDOP_LEN 288
static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid);
static int openvzGetMaxVCPUs(virConnectPtr conn, const char *type);
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index aa5d1c6..6fbbaf0 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -43,9 +43,6 @@
#define VIR_FROM_THIS VIR_FROM_QEMU
-#define QEMU_CMD_PROMPT "\n(qemu) "
-#define QEMU_PASSWD_PROMPT "Password: "
-
#define DEBUG_IO 0
/* Return -1 for error, 0 for success */
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index f318740..8a56c9c 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -60,10 +60,14 @@
(_to) = (_from); \
} while (0)
-# define HYPER_TO_LONG(_to, _from) HYPER_TO_TYPE(long, _to, _from)
+# if 0
+# define HYPER_TO_LONG(_to, _from) HYPER_TO_TYPE(long, _to, _from)
+# endif
# define HYPER_TO_ULONG(_to, _from) HYPER_TO_TYPE(unsigned long, _to, _from)
#else
-# define HYPER_TO_LONG(_to, _from) (_to) = (_from)
+# if 0
+# define HYPER_TO_LONG(_to, _from) (_to) = (_from)
+# endif
# define HYPER_TO_ULONG(_to, _from) (_to) = (_from)
#endif
diff --git a/src/security/security_stack.c b/src/security/security_stack.c
index b63e4c8..5e8ead9 100644
--- a/src/security/security_stack.c
+++ b/src/security/security_stack.c
@@ -24,8 +24,6 @@
#include "virterror_internal.h"
-#define VIR_FROM_THIS VIR_FROM_SECURITY
-
typedef struct _virSecurityStackData virSecurityStackData;
typedef virSecurityStackData *virSecurityStackDataPtr;
diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c
index 0122472..d2c9ea6 100644
--- a/src/uml/uml_conf.c
+++ b/src/uml/uml_conf.c
@@ -52,8 +52,6 @@
#define VIR_FROM_THIS VIR_FROM_UML
-#define umlLog(level, msg, ...) \
- virLogMessage(__FILE__, level, 0, msg, __VA_ARGS__)
virCapsPtr umlCapsInit(void) {
struct utsname utsname;
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index a71ea21..3cc4f1b 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -64,9 +64,6 @@
#define VIR_FROM_THIS VIR_FROM_UML
-/* For storing short-lived temporary files. */
-#define TEMPDIR LOCALSTATEDIR "/cache/libvirt"
-
typedef struct _umlDomainObjPrivate umlDomainObjPrivate;
typedef umlDomainObjPrivate *umlDomainObjPrivatePtr;
struct _umlDomainObjPrivate {
diff --git a/src/util/bridge.c b/src/util/bridge.c
index 7204e64..8d6e0ce 100644
--- a/src/util/bridge.c
+++ b/src/util/bridge.c
@@ -52,9 +52,6 @@
# include "logging.h"
# include "network.h"
-# define JIFFIES_TO_MS(j) (((j)*1000)/HZ)
-# define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000)
-
struct _brControl {
int fd;
};
diff --git a/src/util/hooks.c b/src/util/hooks.c
index 30e20ac..b5a399c 100644
--- a/src/util/hooks.c
+++ b/src/util/hooks.c
@@ -42,7 +42,7 @@
#define VIR_FROM_THIS VIR_FROM_HOOK
#define virHookReportError(code, ...) \
- virReportErrorHelper(VIR_FROM_HOOK, code, __FILE__, \
+ virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__)
#define LIBVIRT_HOOK_DIR SYSCONFDIR "/libvirt/hooks"
diff --git a/src/util/logging.c b/src/util/logging.c
index c86fcda..927fe6d 100644
--- a/src/util/logging.c
+++ b/src/util/logging.c
@@ -44,8 +44,6 @@
#include "threads.h"
#include "files.h"
-#define VIR_FROM_THIS VIR_FROM_NONE
-
/*
* A logging buffer to keep some history over logs
*/
diff --git a/src/util/macvtap.c b/src/util/macvtap.c
index 30343c8..832e952 100644
--- a/src/util/macvtap.c
+++ b/src/util/macvtap.c
@@ -78,8 +78,10 @@ VIR_ENUM_IMPL(virMacvtapMode, VIR_MACVTAP_MODE_LAST,
# define MICROSEC_PER_SEC (1000 * 1000)
-# define NLMSGBUF_SIZE 256
-# define RATTBUF_SIZE 64
+# if 0
+# define NLMSGBUF_SIZE 256
+# define RATTBUF_SIZE 64
+# endif
# define STATUS_POLL_TIMEOUT_USEC (10 * MICROSEC_PER_SEC)
# define STATUS_POLL_INTERVL_USEC (MICROSEC_PER_SEC / 8)
diff --git a/src/util/netlink.c b/src/util/netlink.c
index 0672184..6986b93 100644
--- a/src/util/netlink.c
+++ b/src/util/netlink.c
@@ -37,9 +37,11 @@
#define VIR_FROM_THIS VIR_FROM_NET
-#define netlinkError(code, ...) \
- virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \
- __FUNCTION__, __LINE__, __VA_ARGS__)
+#if ! (defined(__linux__) && defined(HAVE_LIBNL))
+# define netlinkError(code, ...) \
+ virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \
+ __FUNCTION__, __LINE__, __VA_ARGS__)
+#endif
#define NETLINK_ACK_TIMEOUT_S 2
diff --git a/src/util/pci.c b/src/util/pci.c
index 21c12b9..70de273 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -101,7 +101,7 @@ struct _pciDeviceList {
#define PCI_HEADER_TYPE 0x0e /* Header type */
#define PCI_HEADER_TYPE_BRIDGE 0x1
#define PCI_HEADER_TYPE_MASK 0x7f
-#define PCI_HEADER_TYPE_MULTI 0x80
+/*#define PCI_HEADER_TYPE_MULTI 0x80*/
/* PCI30 6.2.1 Device Identification */
#define PCI_CLASS_DEVICE 0x0a /* Device class */
@@ -128,7 +128,7 @@ struct _pciDeviceList {
#define PCI_EXP_DEVCAP_FLR (1<<28) /* Function Level Reset */
/* Header type 1 BR12 3.2 PCI-to-PCI Bridge Configuration Space Header Format */
-#define PCI_PRIMARY_BUS 0x18 /* BR12 3.2.5.2 Primary bus number */
+/*#define PCI_PRIMARY_BUS 0x18*/ /* BR12 3.2.5.2 Primary bus number */
#define PCI_SECONDARY_BUS 0x19 /* BR12 3.2.5.3 Secondary bus number */
#define PCI_SUBORDINATE_BUS 0x1a /* BR12 3.2.5.4 Highest bus number behind the bridge */
#define PCI_BRIDGE_CONTROL 0x3e
diff --git a/src/util/storage_file.c b/src/util/storage_file.c
index 06cabc8..78ab730 100644
--- a/src/util/storage_file.c
+++ b/src/util/storage_file.c
@@ -102,7 +102,9 @@ qedGetBackingStore(char **, int *, const unsigned char *, size_t);
#define QCOW1_HDR_CRYPT (QCOWX_HDR_IMAGE_SIZE+8+1+1)
#define QCOW2_HDR_CRYPT (QCOWX_HDR_IMAGE_SIZE+8)
-#define QCOW1_HDR_TOTAL_SIZE (QCOW1_HDR_CRYPT+4+8)
+#if 0
+# define QCOW1_HDR_TOTAL_SIZE (QCOW1_HDR_CRYPT+4+8)
+#endif
#define QCOW2_HDR_TOTAL_SIZE (QCOW2_HDR_CRYPT+4+4+8+8+4+4+8)
#define QCOW2_HDR_EXTENSION_END 0
diff --git a/src/vbox/vbox_driver.c b/src/vbox/vbox_driver.c
index eab4679..05aa7fa 100644
--- a/src/vbox/vbox_driver.c
+++ b/src/vbox/vbox_driver.c
@@ -42,8 +42,6 @@
#include "virterror_internal.h"
#include "util.h"
-#define VIR_FROM_THIS VIR_FROM_VBOX
-
extern virDriver vbox22Driver;
extern virNetworkDriver vbox22NetworkDriver;
@@ -66,7 +64,7 @@ static virDriver vboxDriverDummy;
#define VIR_FROM_THIS VIR_FROM_VBOX
#define vboxError(code, ...) \
- virReportErrorHelper(VIR_FROM_VBOX, code, __FILE__, \
+ virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__)
int vboxRegister(void) {
diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c
index 6a46a39..770df03 100644
--- a/src/xen/xen_hypervisor.c
+++ b/src/xen/xen_hypervisor.c
@@ -80,16 +80,12 @@ typedef struct v0_hypercall_struct {
} v0_hypercall_t;
#ifdef __linux__
-# define XEN_V0_IOCTL_HYPERCALL_CMD \
- _IOC(_IOC_NONE, 'P', 0, sizeof(v0_hypercall_t))
/* the new one */
typedef struct v1_hypercall_struct
{
uint64_t op;
uint64_t arg[5];
} v1_hypercall_t;
-# define XEN_V1_IOCTL_HYPERCALL_CMD \
- _IOC(_IOC_NONE, 'P', 0, sizeof(v1_hypercall_t))
typedef v1_hypercall_t hypercall_t;
#elif defined(__sun)
typedef privcmd_hypercall_t hypercall_t;
@@ -140,8 +136,6 @@ static regex_t xen_cap_rec;
# define DOMFLAGS_PAUSED (1<<3) /* Currently paused by control software. */
# define DOMFLAGS_BLOCKED (1<<4) /* Currently blocked pending an event. */
# define DOMFLAGS_RUNNING (1<<5) /* Domain is currently running. */
-# define DOMFLAGS_CPUMASK 255 /* CPU to which this domain is bound. */
-# define DOMFLAGS_CPUSHIFT 8
# define DOMFLAGS_SHUTDOWNMASK 255 /* DOMFLAGS_SHUTDOWN guest-supplied code. */
# define DOMFLAGS_SHUTDOWNSHIFT 16
#endif
@@ -2729,13 +2723,13 @@ xenHypervisorMakeCapabilities(virConnectPtr conn)
}
}
- capabilities = fopen ("/sys/hypervisor/properties/capabilities", "r");
+ capabilities = fopen(HYPERVISOR_CAPABILITIES, "r");
if (capabilities == NULL) {
if (errno != ENOENT) {
VIR_FORCE_FCLOSE(cpuinfo);
virReportSystemError(errno,
_("cannot read file %s"),
- "/sys/hypervisor/properties/capabilities");
+ HYPERVISOR_CAPABILITIES);
return NULL;
}
}
@@ -3195,7 +3189,9 @@ xenHypervisorGetDomInfo(virConnectPtr conn, int id, virDomainInfoPtr info)
break;
case DOMFLAGS_SHUTDOWN:
/* The domain is shutdown. Determine the cause. */
- domain_shutdown_cause = domain_flags >> DOMFLAGS_SHUTDOWNSHIFT;
+ domain_shutdown_cause =
+ (domain_flags >> DOMFLAGS_SHUTDOWNSHIFT) &
+ DOMFLAGS_SHUTDOWNMASK;
switch (domain_shutdown_cause) {
case SHUTDOWN_crash:
info->state = VIR_DOMAIN_CRASHED;
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index 530b0d4..0f5d146 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -52,14 +52,6 @@
#define VIR_FROM_THIS VIR_FROM_XENXM
-#ifdef WITH_RHEL5_API
-# define XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU 0
-# define XEND_CONFIG_MIN_VERS_PVFB_NEWCONF 2
-#else
-# define XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU 3
-# define XEND_CONFIG_MIN_VERS_PVFB_NEWCONF 3
-#endif
-
/* The true Xen limit varies but so far is always way
less than 1024, which is the Linux kernel limit according
to sched.h, so we'll match that for now */
@@ -78,7 +70,6 @@ static int xenXMDomainDetachDeviceFlags(virDomainPtr domain, const char *xml,
#define XEND_CONFIG_FILE "xend-config.sxp"
#define XEND_PCI_CONFIG_PREFIX "xend-pci-"
#define QEMU_IF_SCRIPT "qemu-ifup"
-#define XM_XML_ERROR "Invalid xml"
struct xenUnifiedDriver xenXMDriver = {
xenXMOpen, /* open */
diff --git a/tests/sockettest.c b/tests/sockettest.c
index b9e37ab..9e5b678 100644
--- a/tests/sockettest.c
+++ b/tests/sockettest.c
@@ -169,16 +169,6 @@ mymain(void)
if (!virTestGetDebug())
virSetErrorFunc(NULL, testQuietError);
-#define DO_TEST_PARSE(addrstr, family, pass) \
- do { \
- virSocketAddr addr; \
- struct testParseData data = { &addr, addrstr, family, pass }; \
- memset(&addr, 0, sizeof(addr)); \
- if (virtTestRun("Test parse " addrstr, \
- 1, testParseHelper, &data) < 0) \
- ret = -1; \
- } while (0)
-
#define DO_TEST_PARSE_AND_FORMAT(addrstr, family, pass) \
do { \
virSocketAddr addr; \
diff --git a/tools/virsh.c b/tools/virsh.c
index 9a189fd..988fbab 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -74,14 +74,13 @@ static char *progname;
/**
* The log configuration
*/
-#define MSG_BUFFER 4096
#define SIGN_NAME "virsh"
-#define DIR_MODE (S_IWUSR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) /* 0755 */
#define FILE_MODE (S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH) /* 0644 */
-#define LOCK_MODE (S_IWUSR | S_IRUSR) /* 0600 */
#define LVL_DEBUG "DEBUG"
#define LVL_INFO "INFO"
-#define LVL_NOTICE "NOTICE"
+#if 0
+# define LVL_NOTICE "NOTICE"
+#endif
#define LVL_WARNING "WARNING"
#define LVL_ERROR "ERROR"
@@ -423,15 +422,6 @@ _vshStrdup(vshControl *ctl, const char *s, const char *filename, int line)
exit(EXIT_FAILURE);
}
-/* Poison the raw allocating identifiers in favor of our vsh variants. */
-#undef malloc
-#undef calloc
-#undef realloc
-#undef strdup
-#define malloc use_vshMalloc_instead_of_malloc
-#define calloc use_vshCalloc_instead_of_calloc
-#define realloc use_vshRealloc_instead_of_realloc
-#define strdup use_vshStrdup_instead_of_strdup
static int idsorter(const void *a, const void *b) {
const int *ia = (const int *)a;
--
1.7.4.4
2
2
[libvirt] [PATCH] Don't exist if the libvirtd config does not exist
by Daniel P. Berrange 12 Jul '11
by Daniel P. Berrange 12 Jul '11
12 Jul '11
From: "Daniel P. Berrange" <berrange(a)redhat.com>
It is common for the $HOME/.libvirt/libvirtd.conf file to not
exist. Treat this situation as non-fatal since we can carry
on with our default settings just fine.
* daemon/libvirtd.c: Treat ENOENT as non-fatal when loading
config
---
daemon/libvirtd.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 06d2077..fe0fa27 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -1028,6 +1028,10 @@ daemonConfigLoad(struct daemonConfig *data,
{
virConfPtr conf;
+ if (access(filename, R_OK) == -1 &&
+ errno == ENOENT)
+ return 0;
+
conf = virConfReadFile (filename, 0);
if (!conf)
return -1;
--
1.7.6
3
5
Initialize ptr data.datastorePathWithoutFileName as NULL, otherwise
it might cause crash when trying to free it in cleanup.
---
src/esx/esx_driver.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index ddb8c23..ae614a6 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -2698,6 +2698,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
char *vmx = NULL;
virVMXContext ctx;
esxVMX_Data data;
+ data.datastorePathWithoutFileName = NULL;
virDomainDefPtr def = NULL;
char *xml = NULL;
--
1.7.6
3
5
[libvirt] [PATCH] rpc: Fix compile error due to potentially unused parameter
by Matthias Bolte 12 Jul '11
by Matthias Bolte 12 Jul '11
12 Jul '11
connectDBus is only used if HAVE_DBUS is set. Therefore mark
it as potentially unused.
---
Pushed under the build-break rule.
src/rpc/virnetserver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index 94d46f6..66edd11 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -277,7 +277,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
size_t max_workers,
size_t max_clients,
const char *mdnsGroupName,
- bool connectDBus,
+ bool connectDBus ATTRIBUTE_UNUSED,
virNetServerClientInitHook clientInitHook)
{
virNetServerPtr srv;
--
1.7.4.1
1
0
Here's a hacked attempt at fixing the build on older distros using
polkit0. It works and user is authorized or denied depending on
settings in PolicyKit.conf.
I'm not too happy with it but haven't yet digested all the changes in
rpc and daemon code. In the meantime, hopefully someone can suggest
improvements.
Regards,
Jim
2
5
12 Jul '11
This series adds auditing to the LXC and UML drivers. As a side
effect it also fixes missing auditing of filesystem passthrough
in the QEMU driver and a bug in UML vm cleanup
2
13
From: Alex Jia <ajia(a)redhat.com>
* src/qemu/qemu.conf: Add blkio controller into qemu.conf.
---
src/qemu/qemu.conf | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index 2c50d9d..934f99b 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -156,18 +156,19 @@
# - 'cpu' - use for schedular tunables
# - 'devices' - use for device whitelisting
# - 'memory' - use for memory tunables
+# - 'blkio' - use for block devices I/O tunables
#
# NB, even if configured here, they won't be used unless
# the administrator has mounted cgroups, e.g.:
#
# mkdir /dev/cgroup
-# mount -t cgroup -o devices,cpu,memory none /dev/cgroup
+# mount -t cgroup -o devices,cpu,memory,blkio none /dev/cgroup
#
# They can be mounted anywhere, and different controllers
# can be mounted in different locations. libvirt will detect
# where they are located.
#
-# cgroup_controllers = [ "cpu", "devices", "memory" ]
+# cgroup_controllers = [ "cpu", "devices", "memory", "blkio" ]
# This is the basic set of devices allowed / required by
# all virtual machines.
--
1.7.1
2
1
12 Jul '11
* src/util/virtaudit.[ch]: Rename...
* src/util/viraudit.[ch]: ...to match virAudit* API.
* src/Makefile.am (UTIL_SOURCES): Reflect rename.
* daemon/libvirtd.c: Likewise.
* po/POTFILES.in: Likewise.
* src/libvirt_private.syms: Likewise.
* src/qemu/qemu_audit.c: Likewise.
---
First suggested here:
https://www.redhat.com/archives/libvir-list/2011-April/msg00368.html
although we still don't have viratomic.h or virobject.h implemented yet.
daemon/libvirtd.c | 2 +-
po/POTFILES.in | 2 +-
src/Makefile.am | 2 +-
src/libvirt_private.syms | 2 +-
src/qemu/qemu_audit.c | 2 +-
src/util/{virtaudit.c => viraudit.c} | 4 ++--
src/util/{virtaudit.h => viraudit.h} | 4 ++--
7 files changed, 9 insertions(+), 9 deletions(-)
rename src/util/{virtaudit.c => viraudit.c} (98%)
rename src/util/{virtaudit.h => viraudit.h} (96%)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index a4198d9..97db696 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -52,7 +52,7 @@
#include "remote_driver.h"
#include "hooks.h"
#include "uuid.h"
-#include "virtaudit.h"
+#include "viraudit.h"
#ifdef WITH_DRIVER_MODULES
# include "driver.h"
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 32eaa2d..1b63378 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -120,7 +120,7 @@ src/util/stats_linux.c
src/util/storage_file.c
src/util/sysinfo.c
src/util/util.c
-src/util/virtaudit.c
+src/util/viraudit.c
src/util/virterror.c
src/util/xml.c
src/vbox/vbox_MSCOMGlue.c
diff --git a/src/Makefile.am b/src/Makefile.am
index cd8a7e9..ff85db3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -79,8 +79,8 @@ UTIL_SOURCES = \
util/threadpool.c util/threadpool.h \
util/uuid.c util/uuid.h \
util/util.c util/util.h \
+ util/viraudit.c util/viraudit.h \
util/xml.c util/xml.h \
- util/virtaudit.c util/virtaudit.h \
util/virterror.c util/virterror_internal.h
EXTRA_DIST += util/threads-pthread.c util/threads-win32.c
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 1112398..4d78fcf 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1058,7 +1058,7 @@ virUUIDGenerate;
virUUIDParse;
-# virtaudit.h
+# viraudit.h
virAuditClose;
virAuditEncode;
virAuditLog;
diff --git a/src/qemu/qemu_audit.c b/src/qemu/qemu_audit.c
index 1baef40..1d88fb5 100644
--- a/src/qemu/qemu_audit.c
+++ b/src/qemu/qemu_audit.c
@@ -27,7 +27,7 @@
#include <sys/types.h>
#include "qemu_audit.h"
-#include "virtaudit.h"
+#include "viraudit.h"
#include "uuid.h"
#include "logging.h"
#include "memory.h"
diff --git a/src/util/virtaudit.c b/src/util/viraudit.c
similarity index 98%
rename from src/util/virtaudit.c
rename to src/util/viraudit.c
index 560f7b7..ebf3119 100644
--- a/src/util/virtaudit.c
+++ b/src/util/viraudit.c
@@ -1,5 +1,5 @@
/*
- * virtaudit.c: auditing support
+ * viraudit.c: auditing support
*
* Copyright (C) 2010-2011 Red Hat, Inc.
*
@@ -29,7 +29,7 @@
#include "virterror_internal.h"
#include "logging.h"
-#include "virtaudit.h"
+#include "viraudit.h"
#include "util.h"
#include "files.h"
#include "memory.h"
diff --git a/src/util/virtaudit.h b/src/util/viraudit.h
similarity index 96%
rename from src/util/virtaudit.h
rename to src/util/viraudit.h
index a558a17..9d8c359 100644
--- a/src/util/virtaudit.h
+++ b/src/util/viraudit.h
@@ -1,7 +1,7 @@
/*
- * virtaudit.h: auditing support
+ * viraudit.h: auditing support
*
- * Copyright (C) 2010 Red Hat, Inc.
+ * Copyright (C) 2010-2011 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
--
1.7.4.4
2
5
Set StrictHostKeyChecking=no to auto-accept new ssh host keys if the
no_verify extra parameter was specified. This won't disable host key
checking for already known hosts.
---
src/remote/remote_driver.c | 1 +
src/rpc/virnetclient.c | 3 ++-
src/rpc/virnetclient.h | 1 +
src/rpc/virnetsocket.c | 3 +++
src/rpc/virnetsocket.h | 1 +
tests/virnetsockettest.c | 2 ++
6 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index f318740..a2f54c8 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -571,6 +571,7 @@ doRemoteOpen (virConnectPtr conn,
command,
username,
no_tty,
+ no_verify,
netcat ? netcat : "nc",
sockname)))
goto failed;
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index b551b99..fc0fef8 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -187,12 +187,13 @@ virNetClientPtr virNetClientNewSSH(const char *nodename,
const char *binary,
const char *username,
bool noTTY,
+ bool noVerify,
const char *netcat,
const char *path)
{
virNetSocketPtr sock;
- if (virNetSocketNewConnectSSH(nodename, service, binary, username, noTTY, netcat, path, &sock) < 0)
+ if (virNetSocketNewConnectSSH(nodename, service, binary, username, noTTY, noVerify, netcat, path, &sock) < 0)
return NULL;
return virNetClientNew(sock, NULL);
diff --git a/src/rpc/virnetclient.h b/src/rpc/virnetclient.h
index de0782c..6acdf50 100644
--- a/src/rpc/virnetclient.h
+++ b/src/rpc/virnetclient.h
@@ -44,6 +44,7 @@ virNetClientPtr virNetClientNewSSH(const char *nodename,
const char *binary,
const char *username,
bool noTTY,
+ bool noVerify,
const char *netcat,
const char *path);
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index 4b0c2ee..e827b4f 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -576,6 +576,7 @@ int virNetSocketNewConnectSSH(const char *nodename,
const char *binary,
const char *username,
bool noTTY,
+ bool noVerify,
const char *netcat,
const char *path,
virNetSocketPtr *retsock)
@@ -596,6 +597,8 @@ int virNetSocketNewConnectSSH(const char *nodename,
if (noTTY)
virCommandAddArgList(cmd, "-T", "-o", "BatchMode=yes",
"-e", "none", NULL);
+ if (noVerify)
+ virCommandAddArgList(cmd, "-oStrictHostKeyChecking=no", NULL);
virCommandAddArgList(cmd, nodename,
netcat ? netcat : "nc",
"-U", path, NULL);
diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h
index 356d6c6..5f882ac 100644
--- a/src/rpc/virnetsocket.h
+++ b/src/rpc/virnetsocket.h
@@ -67,6 +67,7 @@ int virNetSocketNewConnectSSH(const char *nodename,
const char *binary,
const char *username,
bool noTTY,
+ bool noVerify,
const char *netcat,
const char *path,
virNetSocketPtr *addr);
diff --git a/tests/virnetsockettest.c b/tests/virnetsockettest.c
index f6c7274..87f3dfa 100644
--- a/tests/virnetsockettest.c
+++ b/tests/virnetsockettest.c
@@ -377,6 +377,7 @@ struct testSSHData {
const char *binary;
const char *username;
bool noTTY;
+ bool noVerify;
const char *netcat;
const char *path;
@@ -397,6 +398,7 @@ static int testSocketSSH(const void *opaque)
data->binary,
data->username,
data->noTTY,
+ data->noVerify,
data->netcat,
data->path,
&csock) < 0)
--
1.7.5.4
3
4
virCopyLastError simply overwrites destination, which may lead to leak
if there already was error. Therefore we need first to free destination.
---
src/qemu/qemu_migration.c | 1 +
src/qemu/qemu_monitor.c | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 3e4f4fe..56dd26b 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1586,6 +1586,7 @@ static void qemuMigrationIOFunc(void *arg)
return;
error:
+ virResetError(&data->err);
virCopyLastError(&data->err);
virResetLastError();
}
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 8573262..66a4e48 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -603,6 +603,7 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
if (!err)
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("Error while processing monitor IO"));
+ virResetError(&mon->lastError);
virCopyLastError(&mon->lastError);
virResetLastError();
}
--
1.7.5.rc3
3
3