RFC: New APIs for delegation of privileged operations
by Andrea Bolognani
Hi,
this is a proposal for introducing a new family of APIs in libvirt,
with the goal of improving integration with management applications.
KubeVirt is intended to be the primary consumer of these APIs.
Background
----------
KubeVirt makes it possible to run VMs on a Kubernetes cluster, side
by side with containers.
It does so by running QEMU and libvirtd themselves inside a
container. The architecture is explained in more detail at
https://kubevirt.io/user-guide/architecture/
but …
[View More]for the purpose of this discussion we only need to keep in mind
two components:
* virt-launcher
- runs in the same container as QEMU and libvirtd
- one instance per VM
* virt-handler
- runs in a separate container
- one instance per node
Conceptually, these two components roughly map to QEMU processes and
libvirtd respectively.
>From a security perspective, there is a strong push in Kubernetes to
run workloads under unprivileged user accounts and without additional
capabilities. Again, this is similar to how libvirtd itself runs as
root but the QEMU processes it starts are under the unprivileged
"qemu" account.
KubeVirt has been working towards the goal of running VMs as
completely unprivileged workloads and made excellent progress so far.
Some of the operations needed for running a VM, however, inherently
require elevated privilege. In KubeVirt, the conundrum is solved by
having virt-handler (a privileged component) take care of those
operations, making it possible for virt-launcher (as well as QEMU and
libvirtd) to run in an unprivileged context.
Examples
--------
Here are a few examples of how KubeVirt has been able to reduce the
privilege required by virt-launcher by selectively handing over
responsibilities to virt-handler:
* Remove SYS_RESOURCE capability from launcher pod
https://github.com/kubevirt/kubevirt/pull/2584
* Drop SYS_RESOURCE capability
https://github.com/kubevirt/kubevirt/pull/5558
* Housekeeping cgroup
https://github.com/kubevirt/kubevirt/pull/8233
* Real time VMs fail to change vCPU scheduler and priority in
non-root deployments
https://github.com/kubevirt/kubevirt/pull/8750
* virt-launcher: Drop SYS_PTRACE capability
https://github.com/kubevirt/kubevirt/pull/8842
The pattern we can see is that, initially, libvirt just assumes that
it can perform a certain privileged operation. This fails in the
context of KubeVirt, where libvirtd runs with significantly reduced
privileges. As a consequence, libvirt is patched to be more resilient
to such lack of privilege: for example, instead of attempting to
create a file and erroring out due to lack of permissions, it will
instead first check whether the file already exists and, if it does,
assume that it has been prepared ahead of time by an external entity.
Limitations
-----------
This approach works fine, but only for the privileged operations that
would be performed by libvirt before the VM starts running.
Looking at the "housekeeping cgroup" PR in particular, we notice that
the VM is initially created in paused state: this is necessary in
order to create a point in time in which all the VM threads already
exist but, crucially, none of the vCPUs have stated running yet. This
is the only opportunity to move threads across cgroups without
invalidating the expectations of a real time workload.
When it comes to live migration, however, there is no way to create
similar conditions, since the VM is running on the destination host
right out of the gate. As a consequence, live migration has to be
blocked when the housekeeping cgroup is in use, which is an
unfortunate limitation.
Moreover, there's an overall sense of fragility surrounding these
interactions: both KubeVirt and, to some extent, libvirt need to be
acutely aware of what the other component is going to do, but there
is never an explicit handover and the whole thing only works if you
just so happen to do everything with the exact right order and
timing.
Proposal
--------
In order to address the issues outlined above, I propose that we
introduce a new set of APIs in libvirt.
These APIs would expose some of the inner workings of libvirt, and
as such would come with *massively reduced* stability guarantees
compared to the rest of our public API.
The idea is that applications such as KubeVirt, which track libvirt
fairly closely and stay pinned to specific versions, would be able to
adapt to changes in these APIs relatively painlessly. More
traditional management applications such as virt-manager would simply
not opt into using the new APIs and maintain the status quo.
Using memlock as an example, the new API could look like
typedef int (*virInternalSetMaxMemLockHandler)(pid_t pid,
unsigned long long bytes);
int virInternalSetProcessSetMaxMemLockHandler(virConnectPtr conn,
virInternalSetMaxMemLockHandler handler);
The application-provided handler would be responsible for performing
the privileged operation (in this case raising the memlock limit for
a process). For KubeVirt, virt-launcher would have to pass the baton
to virt-handler.
If such an handler is installed, libvirt would invoke it (and likely
go through some sanity checks afterwards); if not, it would attempt
to perform the privileged operation itself, as it does today.
This would make the interaction between libvirt and the management
application explicit rather than implicit. Not having to stick to our
usual API stability guarantees would make it possible to be more
liberal in exposing the internals of libvirt as interaction points.
Scope
-----
I think we should initially limit the new APIs to the scenarios that
have already been identified, then gradually expand the scope as
needed. In other words, we shouldn't comb through the codebase
looking for potential adopters.
Since the intended consumers of these APIs are those that can
adopt a new libvirt release fairly quickly, this shouldn't be a
problem.
Once the pattern has been established, we might consider introducing
support for it at the same time as a new feature that might benefit
from it is added.
Caveats
-------
libvirt is all about stable API, so introducing an API that is
unstable *by design* is completely uncharted territory.
To ensure that the new APIs are 100% opt-in, we could define them in
a separate <libvirt/libvirt-internal.h> header. Furthermore, we could
have a separate libvirt-internal.so shared library for the symbols
and a corresponding libvirt-internal.pc pkg-config file. We could
even go as far as requiring a preprocessor symbol such as
VIR_INTERNAL_UNSTABLE_API_OPT_IN
to be defined before the entry points are visible to the compiler.
Whatever the mechanism, we would need to make sure that it's usable
from language bindings as well.
Internal APIs are amendable to not only come and go, but also change
semantics between versions. We should make sure that such changes are
clearly exposed to the user, for example by requiring them to pass a
version number to the function and erroring out immediately if the
value doesn't match our expectations. KubeVirt has a massive suite of
functional tests, so this kind of change would immediately be spotted
when a new version of libvirt is imported, with no risk of an
incompatibility lingering in the codebase until it affects users.
Disclaimer
----------
This proposal is intentionally vague on several of the details.
Before attempting to nail those down, I want to gather feedback on
the high-level idea, both from the libvirt and KubeVirt side.
Credits
-------
Thanks to Michal and Martin for helping shape and polish the idea
from its initial rough state.
--
Andrea Bolognani / Red Hat / Virtualization
[View Less]
2 years, 4 months
[PATCH] tools: Fix install_mode for some scripts
by Michal Privoznik
Scripts from the following list were installed with group write
bit set: virt-xml-validate, virt-pki-validate,
virt-sanlock-cleanup, libvirt-guests.sh. This is very unusual and
in contrast with the way other scripts/binaries are installed.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2151202
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
tools/meson.build | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/meson.build b/tools/meson.…
[View More]build
index c41c619af4..fad7f202ad 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -249,7 +249,7 @@ configure_file(
configuration: tools_conf,
install: true,
install_dir: bindir,
- install_mode: 'rwxrwxr-x',
+ install_mode: 'rwxr-xr-x',
)
configure_file(
@@ -258,7 +258,7 @@ configure_file(
configuration: tools_conf,
install: true,
install_dir: bindir,
- install_mode: 'rwxrwxr-x',
+ install_mode: 'rwxr-xr-x',
)
executable(
@@ -295,7 +295,7 @@ if conf.has('WITH_SANLOCK')
configuration: tools_conf,
install: true,
install_dir: sbindir,
- install_mode: 'rwxrwxr-x',
+ install_mode: 'rwxr-xr-x',
)
endif
@@ -311,7 +311,7 @@ if conf.has('WITH_LIBVIRTD')
configuration: tools_conf,
install: true,
install_dir: libexecdir,
- install_mode: 'rwxrwxr-x',
+ install_mode: 'rwxr-xr-x',
)
if init_script == 'systemd'
--
2.37.4
[View Less]
2 years, 4 months
Release of libvirt-php-0.5.7
by Michal Prívozník
The 0.5.7 release of libvirt-php is tagged and tarball is available at:
https://libvirt.org/sources/php/
Notable changes:
* Dropped support for PHP-6.0 and older
* Fixed libvirt_connect_get_machine_types() with PHP-7.0 and newer
* Dropped imagick dependency
* Bug fixes
Thanks to everybody who helped with this release.
Michal
2 years, 4 months
[PATCH v4] virsh: Add message to terminal when running snapshot-revert
by Haruka Ohata
When running virsh snapshot-* command, such as snapshot-create-as /
snapshot-delete, it prints a result message.
On the other hand virsh snapshot-revert command doesn't print a result
message.
So, This patch fixes to add message when running virsh snapshot-revert
command.
---
# virsh snapshot-create-as vm1 test1
Domain snapshot test01 created
# virsh snapshot-revert vm1 test1
# virsh snapshot-delete vm1 test1
Domain snapshot test01 deleted
#
---
Signed-off-by: Haruka …
[View More]Ohata <ohata.haruka(a)fujitsu.com>
---
tests/virsh-snapshot | 3 +++
tools/virsh-snapshot.c | 4 ++++
2 files changed, 7 insertions(+)
diff --git a/tests/virsh-snapshot b/tests/virsh-snapshot
index 4c64bb537b..b09273917b 100755
--- a/tests/virsh-snapshot
+++ b/tests/virsh-snapshot
@@ -100,11 +100,14 @@ Domain snapshot s1 created
Domain snapshot s3 created
Domain snapshot s2 created
+Domain snapshot s3 reverted
Domain snapshot s6 created
Domain snapshot s5 created
+Domain snapshot s6 reverted
Domain snapshot s4 created
+Domain snapshot s1 reverted
Domain snapshot s7 created
Domain snapshot s8 created
diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c
index 8fa64ba903..68908cd10a 100644
--- a/tools/virsh-snapshot.c
+++ b/tools/virsh-snapshot.c
@@ -1783,6 +1783,10 @@ cmdDomainSnapshotRevert(vshControl *ctl, const vshCmd *cmd)
result = virDomainRevertToSnapshot(snapshot, flags);
}
+ if (result < 0)
+ vshError(ctl, _("Failed to revert snapshot %s"), name);
+ else
+ vshPrintExtra(ctl, _("Domain snapshot %s reverted\n"), name);
return result >= 0;
}
--
2.38.1
[View Less]
2 years, 4 months
[PATCH 0/5] qemu: Prefer PNG for domain screenshots
by Michal Privoznik
Whilst preparing for libvirt-php release, I want to ditch its imagick
dependency which is needed to convert PPM to PNG. But I've learned that
QEMU is able to return PNG already which looks more versatile than PPM
anyways.
Michal Prívozník (5):
qemu_caps: Introduce QEMU_CAPS_SCREENSHOT_FORMAT_PNG
qemu_monitor: Debug print all arguments in qemuMonitorScreendump()
qemu_monitor: Extend qemuMonitorScreendump() for @format
qemu: Prefer PNG for domain screenshots
NEWS: Document change of …
[View More]screenshot format for QEMU
NEWS.rst | 4 ++++
src/qemu/qemu_capabilities.c | 2 ++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_driver.c | 13 +++++++++++--
src/qemu/qemu_monitor.c | 6 ++++--
src/qemu/qemu_monitor.h | 1 +
src/qemu/qemu_monitor_json.c | 2 ++
src/qemu/qemu_monitor_json.h | 1 +
tests/qemucapabilitiesdata/caps_7.1.0.ppc64.xml | 1 +
tests/qemucapabilitiesdata/caps_7.1.0.x86_64.xml | 1 +
tests/qemucapabilitiesdata/caps_7.2.0.x86_64.xml | 1 +
tests/qemumonitorjsontest.c | 2 +-
12 files changed, 30 insertions(+), 5 deletions(-)
--
2.37.4
[View Less]
2 years, 4 months
[libvirt PATCH v3] tools: add virt-qemu-qmp-proxy for proxying QMP via libvirt QEMU guests
by Daniel P. Berrangé
Libvirt provides QMP passthrough APIs for the QEMU driver and these are
exposed in virsh. It is not especially pleasant, however, using the raw
QMP JSON syntax. QEMU has a tool 'qmp-shell' which can speak QMP and
exposes a human friendly interactive shell. It is not possible to use
this with libvirt managed guest, however, since only one client can
attach to the QMP socket at any point in time. While it would be
possible to configure a second QMP socket for a VM, it may not be
an known …
[View More]requirement at the time the guest is provisioned.
The virt-qmp-proxy tool aims to solve this problem. It opens a UNIX
socket and listens for incoming client connections, speaking QMP on
the connected socket. It will forward any QMP commands received onto
the running libvirt QEMU guest, and forward any replies back to the
QMP client. It will also forward back events.
$ virsh start demo
$ virt-qmp-proxy demo demo.qmp &
$ qmp-shell demo.qmp
Welcome to the QMP low-level shell!
Connected to QEMU 6.2.0
(QEMU) query-kvm
{
"return": {
"enabled": true,
"present": true
}
}
Note this tool of course has the same risks as the raw libvirt
QMP passthrough. It is safe to run query commands to fetch information
but commands which change the QEMU state risk disrupting libvirt's
management of QEMU, potentially resulting in data loss/corruption in
the worst case. Any use of this tool will cause the guest to be marked
as tainted as an warning that it could be in an unexpected state.
Since this tool introduces a python dependency it is not desirable
to include it in any of the existing RPMs in libvirt. This tool is
also QEMU specific, so isn't appropriate to bundle with the generic
tools. Thus a new RPM is introduced 'libvirt-clients-qemu', to
contain additional QEMU specific tools, with extra external deps.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
In v3:
- Added to libvirt-clients-qemu RPM
- Renamed to virt-qemu-qmp-proxy
docs/manpages/meson.build | 1 +
docs/manpages/virt-qemu-qmp-proxy.rst | 120 +++++++++
libvirt.spec.in | 15 ++
tools/meson.build | 5 +
tools/virt-qemu-qmp-proxy | 360 ++++++++++++++++++++++++++
5 files changed, 501 insertions(+)
create mode 100644 docs/manpages/virt-qemu-qmp-proxy.rst
create mode 100755 tools/virt-qemu-qmp-proxy
diff --git a/docs/manpages/meson.build b/docs/manpages/meson.build
index ba673cf472..83933227d9 100644
--- a/docs/manpages/meson.build
+++ b/docs/manpages/meson.build
@@ -18,6 +18,7 @@ docs_man_files = [
{ 'name': 'virt-pki-query-dn', 'section': '1', 'install': true },
{ 'name': 'virt-pki-validate', 'section': '1', 'install': true },
{ 'name': 'virt-qemu-run', 'section': '1', 'install': conf.has('WITH_QEMU') },
+ { 'name': 'virt-qemu-qmp-proxy', 'section': '1', 'install': conf.has('WITH_QEMU') },
{ 'name': 'virt-xml-validate', 'section': '1', 'install': true },
{ 'name': 'libvirt-guests', 'section': '8', 'install': conf.has('WITH_LIBVIRTD') },
diff --git a/docs/manpages/virt-qemu-qmp-proxy.rst b/docs/manpages/virt-qemu-qmp-proxy.rst
new file mode 100644
index 0000000000..b387474b19
--- /dev/null
+++ b/docs/manpages/virt-qemu-qmp-proxy.rst
@@ -0,0 +1,120 @@
+===================
+virt-qemu-qmp-proxy
+===================
+
+--------------------------------------------------
+Expose a QMP proxy server for a libvirt QEMU guest
+--------------------------------------------------
+
+:Manual section: 1
+:Manual group: Virtualization Support
+
+.. contents::
+
+
+SYNOPSIS
+========
+
+``virt-qemu-qmp-proxy`` [*OPTION*]... *DOMAIN* *QMP-SOCKET-PATH*
+
+
+DESCRIPTION
+===========
+
+This tool provides a way to expose a QMP proxy server that communicates
+with a QEMU guest managed by libvirt. This enables standard QMP client
+tools to interact with libvirt managed guests.
+
+**NOTE: use of this tool will result in the running QEMU guest being
+marked as tainted.** It is strongly recommended that this tool *only be
+used to send commands which query information* about the running guest.
+If this tool is used to make changes to the state of the guest, this
+may have negative interactions with the QEMU driver, resulting in an
+inability to manage the guest operation thereafter, and in the worst
+case **potentially lead to data loss or corruption**.
+
+The ``virt-qemu-qmp-proxy`` program will listen on a UNIX socket for incoming
+client connections, and run the QMP protocol over the connection. Any
+commands received will be sent to the running libvirt guest, and replies
+sent back.
+
+The ``virt-qemu-qmp-proxy`` program may be interrupted (eg Ctrl-C) when it
+is no longer required. The libvirt QEMU guest will continue running.
+
+
+OPTIONS
+=======
+
+*DOMAIN*
+
+The ID or UUID or Name of the libvirt QEMU guest.
+
+*QMP-SOCKET-PATH*
+
+The filesystem path at which to run the QMP server, listening for
+incoming connections.
+
+``-c`` *CONNECTION-URI*
+``--connect``\ =\ *CONNECTION-URI*
+
+The URI for the connection to the libvirt QEMU driver. If omitted,
+a URI will be auto-detected.
+
+``-v``, ``--verbose``
+
+Run in verbose mode, printing all QMP commands and replies that
+are handled.
+
+``-h``, ``--help``
+
+Display the command line help.
+
+
+EXIT STATUS
+===========
+
+Upon successful shutdown, an exit status of 0 will be set. Upon
+failure a non-zero status will be set.
+
+
+AUTHOR
+======
+
+Daniel P. Berrangé
+
+
+BUGS
+====
+
+Please report all bugs you discover. This should be done via either:
+
+#. the mailing list
+
+ `https://libvirt.org/contact.html <https://libvirt.org/contact.html>`_
+
+#. the bug tracker
+
+ `https://libvirt.org/bugs.html <https://libvirt.org/bugs.html>`_
+
+Alternatively, you may report bugs to your software distributor / vendor.
+
+COPYRIGHT
+=========
+
+Copyright (C) 2022 by Red Hat, Inc.
+
+
+LICENSE
+=======
+
+``virt-qemu-qmp-proxy`` is distributed under the terms of the GNU LGPL v2+.
+This is free software; see the source for copying conditions. There
+is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE
+
+
+SEE ALSO
+========
+
+virsh(1), `https://libvirt.org/ <https://libvirt.org/>`_,
+`QMP reference <https://www.qemu.org/docs/master/interop/qemu-qmp-ref.html>`_
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 950c5a3b6d..3082285dc0 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -899,6 +899,15 @@ Obsoletes: libvirt-bash-completion < 7.3.0
The client binaries needed to access the virtualization
capabilities of recent versions of Linux (and other OSes).
+%package client-qemu
+Summary: Additional client side utilities for QEMU
+Requires: %{name}-libs = %{version}-%{release}
+Requires: python3-libvirt >= %{version}-%{release}
+
+%description client-qemu
+The additional client binaries are used to interact
+with some QEMU specific features of libvirt.
+
%package libs
Summary: Client side libraries
# So remote clients can access libvirt over SSH tunnel
@@ -2159,6 +2168,12 @@ exit 0
%{_datadir}/bash-completion/completions/virsh
+%if %{with_qemu}
+%files client-qemu
+%{_mandir}/man1/virt-qemu-qmp-proxy.1*
+%{_bindir}/virt-qemu-qmp-proxy
+%endif
+
%files libs -f %{name}.lang
%license COPYING COPYING.LESSER
%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/
diff --git a/tools/meson.build b/tools/meson.build
index bb28a904dc..20509906af 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -320,6 +320,11 @@ if conf.has('WITH_LIBVIRTD')
endif
endif
+if conf.has('WITH_QEMU')
+ install_data('virt-qemu-qmp-proxy',
+ install_dir: bindir)
+endif
+
if bash_completion_dep.found()
subdir('bash-completion')
endif
diff --git a/tools/virt-qemu-qmp-proxy b/tools/virt-qemu-qmp-proxy
new file mode 100755
index 0000000000..d85342bd2b
--- /dev/null
+++ b/tools/virt-qemu-qmp-proxy
@@ -0,0 +1,360 @@
+#!/usr/bin/env python3
+
+import argparse
+import array
+import libvirt
+import libvirt_qemu
+import os
+import re
+import socket
+import sys
+import traceback
+import json
+import fcntl
+
+
+debug = False
+
+def get_domain(uri, domstr):
+ conn = libvirt.open(uri)
+
+ dom = None
+ saveex = None
+
+ def try_lookup(cb):
+ try:
+ return cb()
+ except libvirt.libvirtError as ex:
+ nonlocal saveex
+ if saveex is None:
+ saveex = ex
+
+ if re.match(r'^\d+$', domstr):
+ dom = try_lookup(lambda: conn.lookupByID(int(domstr)))
+
+ if dom is None and re.match(r'^[-a-f0-9]{36}|[a-f0-9]{32}$', domstr):
+ dom = try_lookup(lambda: conn.lookupByUUIDString(domstr))
+
+ if dom is None:
+ dom = try_lookup(lambda: conn.lookupByName(domstr))
+
+ if dom is None:
+ raise saveex
+
+ if not dom.isActive():
+ raise Exception("Domain must be running to use QMP")
+
+ return conn, dom
+
+
+class QMPProxy(object):
+
+ def __init__(self, conn, dom, serversock, verbose):
+ self.conn = conn
+ self.dom = dom
+ self.verbose = verbose
+
+ self.serversock = serversock
+ self.serverwatch = 0
+
+ self.clientsock = None
+ self.clientwatch = 0
+
+ self.api2sock = bytes([])
+ self.api2sockfds = []
+
+ self.sock2api = bytes([])
+ self.sock2apifds = []
+
+ self.serverwatch = libvirt.virEventAddHandle(
+ self.serversock.fileno(), libvirt.VIR_EVENT_HANDLE_READABLE,
+ self.handle_server_io, self)
+
+ libvirt_qemu.qemuMonitorEventRegister(self.conn, self.dom,
+ None,
+ self.handle_qmp_event,
+ self)
+
+
+ @staticmethod
+ def handle_qmp_event(conn, dom, event, secs, usecs, details, self):
+ evdoc = {
+ "event": event,
+ "timestamp": {"seconds": secs, "microseconds": usecs }
+ }
+ if details is not None:
+ evdoc["data"] = details
+
+ ev = json.dumps(evdoc)
+ if self.verbose:
+ print(ev)
+ ev += "\r\n"
+ self.api2sock += ev.encode("utf-8")
+ self.update_client_events()
+
+
+ def recv_with_fds(self):
+ # Match VIR_NET_MESSAGE_NUM_FDS_MAX in virnetprotocol.x
+ maxfds = 32
+ fds = array.array('i')
+ cmsgdatalen = socket.CMSG_LEN(maxfds * fds.itemsize)
+
+ data, cmsgdata, flags, addr = self.clientsock.recvmsg(1024,
+ cmsgdatalen)
+ for cmsg_level, cmsg_type, cmsg_data in cmsgdata:
+ if (cmsg_level == socket.SOL_SOCKET and
+ cmsg_type == socket.SCM_RIGHTS):
+ fds.frombytes(cmsg_data[:len(cmsg_data) -
+ (len(cmsg_data) % fds.itemsize)])
+ else:
+ raise Exception("Unexpected CMSGDATA level %d type %d" % (
+ cmsg_level, cmsg_type))
+
+ return data, [self.make_file(fd) for fd in fds]
+
+
+ def send_with_fds(self, data, fds):
+ cfds = [fd.fileno() for fd in fds]
+
+ cmsgdata = [(socket.SOL_SOCKET, socket.SCM_RIGHTS,
+ array.array("i", cfds))]
+
+ return self.clientsock.sendmsg([data], cmsgdata)
+
+
+ @staticmethod
+ def make_file(fd):
+ flags = fcntl.fcntl(fd, fcntl.F_GETFL)
+
+ mask = os.O_RDONLY | os.O_WRONLY | os.O_RDWR | os.O_APPEND
+ flags = flags & mask
+ mode = ""
+ if flags == os.O_RDONLY:
+ mode = "rb"
+ elif flags == os.O_WRONLY:
+ mode = "wb"
+ elif flags == os.O_RDWR:
+ mode = "r+b"
+ elif flags == (os.O_WRONLY | os.O_APPEND):
+ mode = "ab"
+ elif flags == (os.O_RDWR | os.O_APPEND):
+ mode = "a+b"
+
+ return os.fdopen(fd, mode)
+
+
+ def add_client(self, sock):
+ ver = self.conn.getVersion()
+ major = int(ver / 1000000) % 1000
+ minor = int(ver / 1000) % 1000
+ micro = ver % 1000
+
+ greetingobj = {
+ "QMP": {
+ "version": {
+ "qemu": {
+ "major": major,
+ "minor": minor,
+ "micro": micro,
+ },
+ "package": f"qemu-{major}.{minor}.{micro}",
+ },
+ "capabilities": [
+ "oob"
+ ],
+ }
+ }
+ greeting = json.dumps(greetingobj)
+ if self.verbose:
+ print(greeting)
+ greeting += "\r\n"
+
+ self.clientsock = sock
+ self.clientwatch = libvirt.virEventAddHandle(
+ self.clientsock.fileno(), libvirt.VIR_EVENT_HANDLE_WRITABLE,
+ self.handle_client_io, self)
+ self.api2sock += greeting.encode("utf-8")
+ self.update_server_events()
+
+
+ def remove_client(self):
+ libvirt.virEventRemoveHandle(self.clientwatch)
+ self.clientsock.close()
+ self.clientsock = None
+ self.clientwatch = 0
+ self.update_server_events()
+
+ self.api2sock = bytes([])
+ self.api2sockfds = []
+
+ self.sock2api = bytes([])
+ self.sock2apifds = []
+
+
+ def update_client_events(self):
+ # For simplicity of tracking distinct QMP cmds and their passed FDs
+ # we don't try to support "pipelining", only a single cmd may be
+ # inflight
+ if len(self.api2sock) > 0:
+ events = libvirt.VIR_EVENT_HANDLE_WRITABLE
+ else:
+ events = libvirt.VIR_EVENT_HANDLE_READABLE
+
+ libvirt.virEventUpdateHandle(self.clientwatch, events)
+
+
+ def update_server_events(self):
+ if self.clientsock is not None:
+ libvirt.virEventUpdateHandle(self.serverwatch, 0)
+ else:
+ libvirt.virEventUpdateHandle(self.serverwatch,
+ libvirt.VIR_EVENT_HANDLE_READABLE)
+
+
+ def try_command(self):
+ try:
+ cmdstr = self.sock2api.decode("utf-8")
+ cmd = json.loads(cmdstr)
+
+ if self.verbose:
+ cmdstr = cmdstr.strip()
+ print(cmdstr)
+ except Exception as ex:
+ if debug:
+ print("Incomplete %s: %s" % ( self.sock2api, ex))
+ return
+
+ id = None
+ if "id" in cmd:
+ id = cmd["id"]
+ del cmd["id"]
+
+ if cmd.get("execute", "") == "qmp_capabilities":
+ resobj = {
+ "return": {},
+ }
+ resfds = []
+ else:
+ if hasattr(libvirt_qemu, "qemuMonitorCommandWithFiles"):
+ res, resfds = libvirt_qemu.qemuMonitorCommandWithFiles(
+ self.dom, json.dumps(cmd), [f.fileno() for f in self.sock2apifds])
+ resobj = json.loads(res)
+ else:
+ if len(self.sock2apifds) > 0:
+ raise Exception("FD passing not supported")
+ res = libvirt_qemu.qemuMonitorCommand(
+ self.dom, json.dumps(cmd))
+ resfds = []
+ resobj = json.loads(res)
+
+ if "id" in resobj:
+ del resobj["id"]
+ if id is not None:
+ resobj["id"] = id
+
+ res = json.dumps(resobj)
+ if self.verbose:
+ print(res)
+ res += "\r\n"
+
+ self.sock2api = bytes([])
+ self.sock2apifds = []
+ self.api2sock += res.encode("utf-8")
+ self.api2sockfds = resfds
+
+
+ @staticmethod
+ def handle_client_io(watch, fd, events, self):
+ error = False
+ try:
+ if events & libvirt.VIR_EVENT_HANDLE_WRITABLE:
+ done = self.send_with_fds(self.api2sock, self.api2sockfds)
+ if done > 0:
+ self.api2sock = self.api2sock[done:]
+ self.api2sockfds = []
+ elif events & libvirt.VIR_EVENT_HANDLE_READABLE:
+ data, fds = self.recv_with_fds()
+ if len(data) == 0:
+ error = True
+ else:
+ self.sock2api += data
+ if len(fds):
+ self.sock2apifds += fds
+
+ self.try_command()
+ else:
+ error = True
+ except Exception as e:
+ global debug
+ if debug:
+ print("%s: %s" % (sys.argv[0], str(e)))
+ print(traceback.format_exc())
+ error = True
+
+ if error:
+ self.remove_client()
+ else:
+ self.update_client_events()
+
+
+ @staticmethod
+ def handle_server_io(watch, fd, events, self):
+ if self.clientsock is None:
+ sock, addr = self.serversock.accept()
+ self.add_client(sock)
+ else:
+ self.update_server_events()
+
+
+def parse_commandline():
+ parser = argparse.ArgumentParser(description="Libvirt QMP proxy")
+ parser.add_argument("--connect", "-c",
+ help="Libvirt QEMU driver connection URI")
+ parser.add_argument("--debug", "-d", action='store_true',
+ help="Display debugging information")
+ parser.add_argument("--verbose", "-v", action='store_true',
+ help="Display QMP traffic")
+ parser.add_argument("domain", metavar="DOMAIN",
+ help="Libvirt guest domain ID/UUID/Name")
+ parser.add_argument("sockpath", metavar="QMP-SOCK-PATH",
+ help="UNIX socket path for QMP server")
+
+ return parser.parse_args()
+
+
+def main():
+ args = parse_commandline()
+ global debug
+ debug = args.debug
+
+ if not debug:
+ libvirt.registerErrorHandler(lambda opaque, error: None, None)
+
+ libvirt.virEventRegisterDefaultImpl()
+
+ conn, dom = get_domain(args.connect, args.domain)
+
+ if conn.getType() != "QEMU":
+ raise Exception("QMP proxy requires a QEMU driver connection not %s" %
+ conn.getType())
+
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ if os.path.exists(args.sockpath):
+ os.unlink(args.sockpath)
+ sock.bind(args.sockpath)
+ sock.listen(1)
+
+ proxy = QMPProxy(conn, dom, sock, args.verbose)
+
+ while True:
+ libvirt.virEventRunDefaultImpl()
+
+
+try:
+ main()
+ sys.exit(0)
+except Exception as e:
+ print("%s: %s" % (sys.argv[0], str(e)))
+ if debug:
+ print(traceback.format_exc())
+ sys.exit(1)
--
2.37.3
[View Less]
2 years, 4 months
[PATCH] spec: Remove extra blank lines
by Jim Fehlig
The spec file contains inconsistent use of blank lines. While trying to
make significant changes to the file, I found it hurts both readability
and maintainability. Remove blank lines that interrupt the overall flow
and consistency.
Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
libvirt.spec.in | 91 -------------------------------------------------
1 file changed, 91 deletions(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index d07a43c721..562baea52e 100644
--- a/libvirt.spec.…
[View More]in
+++ b/libvirt.spec.in
@@ -138,7 +138,6 @@
%define with_netcf 0%{!?_without_netcf:1}
%endif
-
# fuse is used to provide virtualized /proc for LXC
%if %{with_lxc}
%define with_fuse 0%{!?_without_fuse:1}
@@ -258,7 +257,6 @@ Obsoletes: libvirt-daemon-uml <= 5.0.0
Requires: libvirt-daemon-driver-vbox = %{version}-%{release}
%endif
Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release}
-
Requires: libvirt-daemon-driver-interface = %{version}-%{release}
Requires: libvirt-daemon-driver-secret = %{version}-%{release}
Requires: libvirt-daemon-driver-storage = %{version}-%{release}
@@ -358,33 +356,25 @@ BuildRequires: libwsman-devel >= 2.6.3
BuildRequires: audit-libs-devel
# we need /usr/sbin/dtrace
BuildRequires: systemtap-sdt-devel
-
# For mount/umount in FS driver
BuildRequires: util-linux
# For showmount in FS driver (netfs discovery)
BuildRequires: nfs-utils
-
# Fedora build root suckage
BuildRequires: gawk
-
# For storage wiping with different algorithms
BuildRequires: scrub
-
%if %{with_numad}
BuildRequires: numad
%endif
-
%if %{with_wireshark}
BuildRequires: wireshark-devel
%endif
-
%if %{with_libssh}
BuildRequires: libssh-devel >= 0.8.1
%endif
-
BuildRequires: rpcgen
BuildRequires: libtirpc-devel
-
# Needed for the firewalld_reload macro
%if %{with_firewalld_zone}
BuildRequires: firewalld-filesystem
@@ -404,7 +394,6 @@ BuildRequires: mingw32-portablexdr
BuildRequires: mingw32-dlfcn
BuildRequires: mingw32-libssh2
BuildRequires: mingw32-curl
-
BuildRequires: mingw64-filesystem
BuildRequires: mingw64-gcc
BuildRequires: mingw64-binutils
@@ -440,28 +429,23 @@ Summary: Server side daemon and supporting files for libvirt library
# The client side, i.e. shared libs are in a subpackage
Requires: libvirt-libs = %{version}-%{release}
-
# The libvirt-guests.sh script requires virsh from libvirt-client subpackage,
# but not every deployment wants to use libvirt-guests service. Using
# Recommends here will install libvirt-client by default (if available), but
# RPM won't complain if the package is unavailable, masked, or removed later.
Recommends: libvirt-client = %{version}-%{release}
-
# netcat is needed on the server side so that clients that have
# libvirt < 6.9.0 can connect, but newer versions will prefer
# virt-ssh-helper. Making this a Recommends means that it gets
# installed by default, but can still be removed if compatibility
# with old clients is not required
Recommends: /usr/bin/nc
-
# for modprobe of pci devices
Requires: module-init-tools
-
# for /sbin/ip
Requires: iproute
# for /sbin/tc
Requires: iproute-tc
-
Requires: polkit >= 0.112
%if %{with_dmidecode}
# For virConnectGetSysinfo
@@ -523,7 +507,6 @@ The network driver plugin for the libvirtd daemon, providing
an implementation of the virtual network APIs using the Linux
bridge capabilities.
-
%package daemon-driver-nwfilter
Summary: Nwfilter driver plugin for the libvirtd daemon
Requires: libvirt-daemon = %{version}-%{release}
@@ -536,7 +519,6 @@ The nwfilter driver plugin for the libvirtd daemon, providing
an implementation of the firewall APIs using the ebtables,
iptables and ip6tables capabilities
-
%package daemon-driver-nodedev
Summary: Nodedev driver plugin for the libvirtd daemon
Requires: libvirt-daemon = %{version}-%{release}
@@ -551,7 +533,6 @@ The nodedev driver plugin for the libvirtd daemon, providing
an implementation of the node device APIs using the udev
capabilities.
-
%package daemon-driver-interface
Summary: Interface driver plugin for the libvirtd daemon
Requires: libvirt-daemon = %{version}-%{release}
@@ -604,7 +585,6 @@ Requires: lvm2
The storage driver backend adding implementation of the storage APIs for block
volumes using lvm.
-
%package daemon-driver-storage-disk
Summary: Storage driver plugin for disk
Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
@@ -616,7 +596,6 @@ Requires: device-mapper
The storage driver backend adding implementation of the storage APIs for block
volumes using the host disks.
-
%package daemon-driver-storage-scsi
Summary: Storage driver plugin for local scsi devices
Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
@@ -626,7 +605,6 @@ Requires: libvirt-libs = %{version}-%{release}
The storage driver backend adding implementation of the storage APIs for scsi
host devices.
-
%package daemon-driver-storage-iscsi
Summary: Storage driver plugin for iscsi
Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
@@ -637,7 +615,6 @@ Requires: iscsi-initiator-utils
The storage driver backend adding implementation of the storage APIs for iscsi
volumes using the host iscsi stack.
-
%if %{with_storage_iscsi_direct}
%package daemon-driver-storage-iscsi-direct
Summary: Storage driver plugin for iscsi-direct
@@ -649,7 +626,6 @@ The storage driver backend adding implementation of the storage APIs for iscsi
volumes using libiscsi direct connection.
%endif
-
%package daemon-driver-storage-mpath
Summary: Storage driver plugin for multipath volumes
Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
@@ -660,7 +636,6 @@ Requires: device-mapper
The storage driver backend adding implementation of the storage APIs for
multipath storage using device mapper.
-
%if %{with_storage_gluster}
%package daemon-driver-storage-gluster
Summary: Storage driver plugin for gluster
@@ -678,7 +653,6 @@ The storage driver backend adding implementation of the storage APIs for gluster
volumes using libgfapi.
%endif
-
%if %{with_storage_rbd}
%package daemon-driver-storage-rbd
Summary: Storage driver plugin for rbd
@@ -690,7 +664,6 @@ The storage driver backend adding implementation of the storage APIs for rbd
volumes using the ceph protocol.
%endif
-
%if %{with_storage_zfs}
%package daemon-driver-storage-zfs
Summary: Storage driver plugin for ZFS
@@ -705,7 +678,6 @@ The storage driver backend adding implementation of the storage APIs for
ZFS volumes.
%endif
-
%package daemon-driver-storage
Summary: Storage driver plugin including all backends for the libvirtd daemon
Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
@@ -732,7 +704,6 @@ The storage driver plugin for the libvirtd daemon, providing
an implementation of the storage APIs using LVM, iSCSI,
parted and more.
-
%if %{with_qemu}
%package daemon-driver-qemu
Summary: QEMU driver plugin for the libvirtd daemon
@@ -753,7 +724,6 @@ an implementation of the hypervisor driver APIs using
QEMU
%endif
-
%if %{with_lxc}
%package daemon-driver-lxc
Summary: LXC driver plugin for the libvirtd daemon
@@ -769,7 +739,6 @@ an implementation of the hypervisor driver APIs using
the Linux kernel
%endif
-
%if %{with_vbox}
%package daemon-driver-vbox
Summary: VirtualBox driver plugin for the libvirtd daemon
@@ -782,7 +751,6 @@ an implementation of the hypervisor driver APIs using
VirtualBox
%endif
-
%if %{with_libxl}
%package daemon-driver-libxl
Summary: Libxl driver plugin for the libvirtd daemon
@@ -796,8 +764,6 @@ an implementation of the hypervisor driver APIs using
Libxl
%endif
-
-
%if %{with_qemu_tcg}
%package daemon-qemu
Summary: Server side daemon & driver required to run QEMU guests
@@ -817,7 +783,6 @@ Server side daemon and driver required to manage the virtualization
capabilities of the QEMU TCG emulators
%endif
-
%if %{with_qemu_kvm}
%package daemon-kvm
Summary: Server side daemon & driver required to run KVM guests
@@ -837,7 +802,6 @@ Server side daemon and driver required to manage the virtualization
capabilities of the KVM hypervisor
%endif
-
%if %{with_lxc}
%package daemon-lxc
Summary: Server side daemon & driver required to run LXC guests
@@ -856,7 +820,6 @@ Server side daemon and driver required to manage the virtualization
capabilities of LXC
%endif
-
%if %{with_libxl}
%package daemon-xen
Summary: Server side daemon & driver required to run XEN guests
@@ -998,7 +961,6 @@ MinGW Windows libvirt virtualization library.
%endif
%prep
-
%autosetup -S git_am
%build
@@ -1152,7 +1114,6 @@ exit 1
%define who %{?packager}%{!?packager:Unknown}
%define arg_packager -Dpackager="%{who}, %{when}, %{where}"
%define arg_packager_version -Dpackager_version="%{release}"
-
%define arg_selinux_mount -Dselinux_mount="/sys/fs/selinux"
# place macros above and build commands below this comment
@@ -1396,7 +1357,6 @@ rm -rf $RPM_BUILD_ROOT%{mingw64_libexecdir}/libvirt-guests.sh
%endif
-
%check
# Building on slow archs, like emulated s390x in Fedora copr, requires
# raising the test timeout
@@ -1435,7 +1395,6 @@ fi \
# libvirtd. The uid number is irrelevant, so we use dynamic allocation
# described at the above link.
getent group libvirt >/dev/null || groupadd -r libvirt
-
exit 0
%post daemon
@@ -1446,14 +1405,11 @@ exit 0
%else
%libvirt_daemon_systemd_post_inet libvirtd
%endif
-
%systemd_post libvirt-guests.service
-
%libvirt_daemon_schedule_restart libvirtd
%preun daemon
%systemd_preun libvirt-guests.service
-
%libvirt_daemon_systemd_preun_inet libvirtd
%libvirt_daemon_systemd_preun_inet virtproxyd
%libvirt_daemon_systemd_preun_priv virtlogd
@@ -1499,7 +1455,6 @@ then
/bin/systemctl start libvirtd.service >/dev/null 2>&1 || :
fi
fi
-
%libvirt_daemon_finish_restart libvirtd
%pre daemon-driver-network
@@ -1591,7 +1546,6 @@ fi
%libvirt_sysconfig_posttrans virtsecretd
%libvirt_daemon_perform_restart virtsecretd
-
%pre daemon-driver-storage-core
%libvirt_sysconfig_pre virtstoraged
@@ -1608,7 +1562,6 @@ fi
%libvirt_sysconfig_posttrans virtstoraged
%libvirt_daemon_perform_restart virtstoraged
-
%if %{with_qemu}
%pre daemon-driver-qemu
%libvirt_sysconfig_pre virtqemud
@@ -1640,7 +1593,6 @@ exit 0
%libvirt_daemon_perform_restart virtqemud
%endif
-
%if %{with_lxc}
%pre daemon-driver-lxc
%libvirt_sysconfig_pre virtlxcd
@@ -1659,7 +1611,6 @@ exit 0
%libvirt_daemon_perform_restart virtlxcd
%endif
-
%if %{with_vbox}
%post daemon-driver-vbox
%if %{with_modular_daemons}
@@ -1678,7 +1629,6 @@ exit 0
%libvirt_daemon_perform_restart virtvboxd
%endif
-
%if %{with_libxl}
%post daemon-driver-libxl
%if %{with_modular_daemons}
@@ -1697,7 +1647,6 @@ exit 0
%libvirt_daemon_perform_restart virtxend
%endif
-
%post daemon-config-network
if test $1 -eq 1 && test ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml ; then
# see if the network used by default network creates a conflict,
@@ -1773,7 +1722,6 @@ exit 0
%doc libvirt-docs/*
%files daemon
-
%{_unitdir}/libvirtd.service
%{_unitdir}/libvirtd.socket
%{_unitdir}/libvirtd-ro.socket
@@ -1800,25 +1748,19 @@ exit 0
%config(noreplace) %{_sysconfdir}/libvirt/virtlockd.conf
%config(noreplace) %{_sysconfdir}/sasl2/libvirt.conf
%config(noreplace) %{_prefix}/lib/sysctl.d/60-libvirtd.conf
-
%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd
%dir %{_datadir}/libvirt/
-
%ghost %dir %{_rundir}/libvirt/
%ghost %dir %{_rundir}/libvirt/common/
-
%dir %attr(0755, root, root) %{_localstatedir}/lib/libvirt/
%dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/images/
%dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/filesystems/
%dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/boot/
%dir %attr(0711, root, root) %{_localstatedir}/cache/libvirt/
-
-
%dir %attr(0755, root, root) %{_libdir}/libvirt/
%dir %attr(0755, root, root) %{_libdir}/libvirt/connection-driver/
%dir %attr(0755, root, root) %{_libdir}/libvirt/lock-driver
%attr(0755, root, root) %{_libdir}/libvirt/lock-driver/lockd.so
-
%{_datadir}/augeas/lenses/libvirtd.aug
%{_datadir}/augeas/lenses/tests/test_libvirtd.aug
%{_datadir}/augeas/lenses/virtlogd.aug
@@ -1831,23 +1773,17 @@ exit 0
%if %{with_qemu}
%{_datadir}/augeas/lenses/tests/test_libvirt_lockd.aug
%endif
-
%{_datadir}/polkit-1/actions/org.libvirt.unix.policy
%{_datadir}/polkit-1/actions/org.libvirt.api.policy
%{_datadir}/polkit-1/rules.d/50-libvirt.rules
-
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/
-
%attr(0755, root, root) %{_libexecdir}/libvirt_iohelper
-
%attr(0755, root, root) %{_bindir}/virt-ssh-helper
-
%attr(0755, root, root) %{_sbindir}/libvirtd
%attr(0755, root, root) %{_sbindir}/virtproxyd
%attr(0755, root, root) %{_sbindir}/virtlogd
%attr(0755, root, root) %{_sbindir}/virtlockd
%attr(0755, root, root) %{_libexecdir}/libvirt-guests.sh
-
%{_mandir}/man1/virt-admin.1*
%{_mandir}/man1/virt-host-validate.1*
%{_mandir}/man8/virt-ssh-helper.8*
@@ -1856,7 +1792,6 @@ exit 0
%{_mandir}/man8/virtlogd.8*
%{_mandir}/man8/virtlockd.8*
%{_mandir}/man8/virtproxyd.8*
-
%{_bindir}/virt-host-validate
%{_bindir}/virt-admin
%{_datadir}/bash-completion/completions/virt-admin
@@ -1903,7 +1838,6 @@ exit 0
%attr(0755, root, root) %{_libexecdir}/libvirt_leaseshelper
%{_libdir}/libvirt/connection-driver/libvirt_driver_network.so
%{_mandir}/man8/virtnetworkd.8*
-
%if %{with_firewalld_zone}
%{_prefix}/lib/firewalld/zones/libvirt.xml
%{_prefix}/lib/firewalld/zones/libvirt-routed.xml
@@ -2165,7 +2099,6 @@ exit 0
%{_bindir}/virt-xml-validate
%{_bindir}/virt-pki-query-dn
%{_bindir}/virt-pki-validate
-
%{_datadir}/bash-completion/completions/virsh
%if %{with_qemu}
@@ -2187,17 +2120,13 @@ exit 0
%{_libdir}/libvirt-admin.so.*
%dir %{_datadir}/libvirt/
%dir %{_datadir}/libvirt/schemas/
-
%{_datadir}/systemtap/tapset/libvirt_probes*.stp
%{_datadir}/systemtap/tapset/libvirt_functions.stp
%if %{with_qemu}
%{_datadir}/systemtap/tapset/libvirt_qemu_probes*.stp
%endif
-
%{_datadir}/libvirt/schemas/*.rng
-
%{_datadir}/libvirt/cpu_map/*.xml
-
%{_datadir}/libvirt/test-screenshot.png
%if %{with_wireshark}
@@ -2245,7 +2174,6 @@ exit 0
%{_libdir}/pkgconfig/libvirt-admin.pc
%{_libdir}/pkgconfig/libvirt-qemu.pc
%{_libdir}/pkgconfig/libvirt-lxc.pc
-
%dir %{_datadir}/libvirt/api/
%{_datadir}/libvirt/api/libvirt-api.xml
%{_datadir}/libvirt/api/libvirt-admin-api.xml
@@ -2257,7 +2185,6 @@ exit 0
%dir %{mingw32_sysconfdir}/libvirt/
%config(noreplace) %{mingw32_sysconfdir}/libvirt/libvirt.conf
%config(noreplace) %{mingw32_sysconfdir}/libvirt/libvirt-admin.conf
-
%{mingw32_bindir}/libvirt-0.dll
%{mingw32_bindir}/virsh.exe
%{mingw32_bindir}/virt-admin.exe
@@ -2267,7 +2194,6 @@ exit 0
%{mingw32_bindir}/libvirt-lxc-0.dll
%{mingw32_bindir}/libvirt-qemu-0.dll
%{mingw32_bindir}/libvirt-admin-0.dll
-
%{mingw32_libdir}/libvirt.dll.a
%{mingw32_libdir}/pkgconfig/libvirt.pc
%{mingw32_libdir}/pkgconfig/libvirt-qemu.pc
@@ -2276,23 +2202,17 @@ exit 0
%{mingw32_libdir}/libvirt-lxc.dll.a
%{mingw32_libdir}/libvirt-qemu.dll.a
%{mingw32_libdir}/libvirt-admin.dll.a
-
%dir %{mingw32_datadir}/libvirt/
%dir %{mingw32_datadir}/libvirt/schemas/
%{mingw32_datadir}/libvirt/schemas/*.rng
-
%dir %{mingw32_datadir}/libvirt/api/
%{mingw32_datadir}/libvirt/api/libvirt-api.xml
%{mingw32_datadir}/libvirt/api/libvirt-lxc-api.xml
%{mingw32_datadir}/libvirt/api/libvirt-qemu-api.xml
%{mingw32_datadir}/libvirt/api/libvirt-admin-api.xml
-
%{mingw32_datadir}/libvirt/cpu_map/*.xml
-
%{mingw32_datadir}/libvirt/test-screenshot.png
-
%{mingw32_datadir}/locale/*/LC_MESSAGES/libvirt.mo
-
%dir %{mingw32_includedir}/libvirt
%{mingw32_includedir}/libvirt/libvirt.h
%{mingw32_includedir}/libvirt/libvirt-common.h
@@ -2312,7 +2232,6 @@ exit 0
%{mingw32_includedir}/libvirt/libvirt-lxc.h
%{mingw32_includedir}/libvirt/libvirt-qemu.h
%{mingw32_includedir}/libvirt/libvirt-admin.h
-
%{mingw32_mandir}/man1/virsh.1*
%{mingw32_mandir}/man1/virt-admin.1*
%{mingw32_mandir}/man1/virt-xml-validate.1*
@@ -2320,12 +2239,10 @@ exit 0
%{mingw32_mandir}/man1/virt-pki-validate.1*
%{mingw32_mandir}/man7/virkey*.7*
-
%files -n mingw64-libvirt
%dir %{mingw64_sysconfdir}/libvirt/
%config(noreplace) %{mingw64_sysconfdir}/libvirt/libvirt.conf
%config(noreplace) %{mingw64_sysconfdir}/libvirt/libvirt-admin.conf
-
%{mingw64_bindir}/libvirt-0.dll
%{mingw64_bindir}/virsh.exe
%{mingw64_bindir}/virt-admin.exe
@@ -2335,7 +2252,6 @@ exit 0
%{mingw64_bindir}/libvirt-lxc-0.dll
%{mingw64_bindir}/libvirt-qemu-0.dll
%{mingw64_bindir}/libvirt-admin-0.dll
-
%{mingw64_libdir}/libvirt.dll.a
%{mingw64_libdir}/pkgconfig/libvirt.pc
%{mingw64_libdir}/pkgconfig/libvirt-qemu.pc
@@ -2344,23 +2260,17 @@ exit 0
%{mingw64_libdir}/libvirt-lxc.dll.a
%{mingw64_libdir}/libvirt-qemu.dll.a
%{mingw64_libdir}/libvirt-admin.dll.a
-
%dir %{mingw64_datadir}/libvirt/
%dir %{mingw64_datadir}/libvirt/schemas/
%{mingw64_datadir}/libvirt/schemas/*.rng
-
%dir %{mingw64_datadir}/libvirt/api/
%{mingw64_datadir}/libvirt/api/libvirt-api.xml
%{mingw64_datadir}/libvirt/api/libvirt-lxc-api.xml
%{mingw64_datadir}/libvirt/api/libvirt-qemu-api.xml
%{mingw64_datadir}/libvirt/api/libvirt-admin-api.xml
-
%{mingw64_datadir}/libvirt/cpu_map/*.xml
-
%{mingw64_datadir}/libvirt/test-screenshot.png
-
%{mingw64_datadir}/locale/*/LC_MESSAGES/libvirt.mo
-
%dir %{mingw64_includedir}/libvirt
%{mingw64_includedir}/libvirt/libvirt.h
%{mingw64_includedir}/libvirt/libvirt-common.h
@@ -2380,7 +2290,6 @@ exit 0
%{mingw64_includedir}/libvirt/libvirt-lxc.h
%{mingw64_includedir}/libvirt/libvirt-qemu.h
%{mingw64_includedir}/libvirt/libvirt-admin.h
-
%{mingw64_mandir}/man1/virsh.1*
%{mingw64_mandir}/man1/virt-admin.1*
%{mingw64_mandir}/man1/virt-xml-validate.1*
--
2.38.1
[View Less]
2 years, 4 months
[PATCH 0/7] qemu: support updating device's bootindex
by Jiang Jiacheng
Support updating device's(support cdrom, disk and network) bootindex
online in virDomainUpdateDeviceFlags. The new bootindex will take effect
after guest rebooting. Enable bootindex can be set to 0, it means cancel
the device's bootindex.
To use this feature, we need to get the device's xml first and modify
the boot order in the xml, then use 'virsh update-device <domain> <xml>
--flag' to update the bootindex. Note that the flag should be --config
or --persistent if the vm is …
[View More]running.
diff to v1:
* add a bool bootIndexSpecified in device info to indicates that the
bootorder of the device can be set.
* use boot order = '0' to cancel the previous bootorder instead of '-1'
Jiang Jiacheng (7):
qemu: Introduce qemuDomainChangeBootIndex API
qemu: Add bootIndexSpecified and support set bootIndex to '0'
qemu: Introduce qemuCheckBootIndex and qemuChangeDiskBootIndex API
qemu: Support update disk's bootindex
qemu: Support update net's bootindex
qemu: Support add bootindex = 0 to boothash when its
bootIndexSpecified is true
qemu: Reserve bootIndexSpecified when update device
src/conf/device_conf.h | 3 +
src/conf/domain_conf.c | 9 ++-
src/conf/domain_postparse.c | 8 +-
src/qemu/qemu_conf.c | 140 +++++++++++++++++++++++++++++++++++
src/qemu/qemu_conf.h | 16 ++++
src/qemu/qemu_domain.c | 3 +-
src/qemu/qemu_driver.c | 35 +++++++++
src/qemu/qemu_hotplug.c | 17 +++--
src/qemu/qemu_monitor.c | 20 +++++
src/qemu/qemu_monitor.h | 6 ++
src/qemu/qemu_monitor_json.c | 33 +++++++++
src/qemu/qemu_monitor_json.h | 6 ++
12 files changed, 286 insertions(+), 10 deletions(-)
--
2.33.0
[View Less]
2 years, 4 months