[PATCH] src: Fix return types of .stateInitialize callbacks
by Michal Privoznik
The virStateDriver struct has .stateInitialize callback which is
declared to return virDrvStateInitResult enum. But some drivers
return a plain int in their implementation which is UB.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/bhyve/bhyve_driver.c | 2 +-
src/ch/ch_driver.c | 11 ++++++-----
src/interface/interface_backend_netcf.c | 2 +-
src/interface/interface_backend_udev.c | 2 +-
src/libxl/libxl_driver.c | 2 +-
src/lxc/lxc_driver.c | 11 ++++++-----
src/network/bridge_driver.c | 2 +-
src/node_device/node_device_udev.c | 2 +-
src/nwfilter/nwfilter_driver.c | 2 +-
src/qemu/qemu_driver.c | 2 +-
src/remote/remote_driver.c | 2 +-
src/secret/secret_driver.c | 2 +-
src/storage/storage_driver.c | 2 +-
src/vz/vz_driver.c | 2 +-
14 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index 4203b13f94..2bd1e4c387 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -1176,7 +1176,7 @@ bhyveStateCleanup(void)
return 0;
}
-static int
+static virDrvStateInitResult
bhyveStateInitialize(bool privileged,
const char *root,
bool monolithic G_GNUC_UNUSED,
diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index 7308f40249..fbeac60825 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -1365,11 +1365,12 @@ static int chStateCleanup(void)
return 0;
}
-static int chStateInitialize(bool privileged,
- const char *root,
- bool monolithic G_GNUC_UNUSED,
- virStateInhibitCallback callback G_GNUC_UNUSED,
- void *opaque G_GNUC_UNUSED)
+static virDrvStateInitResult
+chStateInitialize(bool privileged,
+ const char *root,
+ bool monolithic G_GNUC_UNUSED,
+ virStateInhibitCallback callback G_GNUC_UNUSED,
+ void *opaque G_GNUC_UNUSED)
{
int ret = VIR_DRV_STATE_INIT_ERROR;
int rv;
diff --git a/src/interface/interface_backend_netcf.c b/src/interface/interface_backend_netcf.c
index d4a11157cc..16e1215663 100644
--- a/src/interface/interface_backend_netcf.c
+++ b/src/interface/interface_backend_netcf.c
@@ -86,7 +86,7 @@ virNetcfDriverStateDispose(void *obj)
}
-static int
+static virDrvStateInitResult
netcfStateInitialize(bool privileged,
const char *root,
bool monolithic G_GNUC_UNUSED,
diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c
index 8bb19d7764..fdf11a8318 100644
--- a/src/interface/interface_backend_udev.c
+++ b/src/interface/interface_backend_udev.c
@@ -1091,7 +1091,7 @@ udevInterfaceIsActive(virInterfacePtr ifinfo)
static int
udevStateCleanup(void);
-static int
+static virDrvStateInitResult
udevStateInitialize(bool privileged,
const char *root,
bool monolithic G_GNUC_UNUSED,
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 4d5eb920bf..7dcae58413 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -645,7 +645,7 @@ libxlAddDom0(libxlDriverPrivate *driver)
return ret;
}
-static int
+static virDrvStateInitResult
libxlStateInitialize(bool privileged,
const char *root,
bool monolithic G_GNUC_UNUSED,
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 1842ae8f0e..f76d09e8a9 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1429,11 +1429,12 @@ lxcSecurityInit(virLXCDriverConfig *cfg)
}
-static int lxcStateInitialize(bool privileged,
- const char *root,
- bool monolithic G_GNUC_UNUSED,
- virStateInhibitCallback callback G_GNUC_UNUSED,
- void *opaque G_GNUC_UNUSED)
+static virDrvStateInitResult
+lxcStateInitialize(bool privileged,
+ const char *root,
+ bool monolithic G_GNUC_UNUSED,
+ virStateInhibitCallback callback G_GNUC_UNUSED,
+ void *opaque G_GNUC_UNUSED)
{
virLXCDriverConfig *cfg = NULL;
bool autostart = true;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index e5f9ecf9e8..d7c1ef172d 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -576,7 +576,7 @@ firewalld_dbus_signal_callback(GDBusConnection *connection G_GNUC_UNUSED,
*
* Initialization function for the QEMU daemon
*/
-static int
+static virDrvStateInitResult
networkStateInitialize(bool privileged,
const char *root,
bool monolithic G_GNUC_UNUSED,
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index f1e402f8f7..237cd7f645 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -2229,7 +2229,7 @@ mdevctlEventHandleCallback(GFileMonitor *monitor G_GNUC_UNUSED,
}
-static int
+static virDrvStateInitResult
nodeStateInitialize(bool privileged,
const char *root,
bool monolithic G_GNUC_UNUSED,
diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index 09719edd75..8ece91bf7c 100644
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -208,7 +208,7 @@ nwfilterStateCleanup(void)
*
* Initialization function for the QEMU daemon
*/
-static int
+static virDrvStateInitResult
nwfilterStateInitialize(bool privileged,
const char *root,
bool monolithic G_GNUC_UNUSED,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d01f788aea..e2698c7924 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -546,7 +546,7 @@ qemuDomainFindMaxID(virDomainObj *vm,
*
* Initialization function for the QEMU daemon
*/
-static int
+static virDrvStateInitResult
qemuStateInitialize(bool privileged,
const char *root,
bool monolithic G_GNUC_UNUSED,
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 7b73d97b7a..e76d9e9ba4 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -174,7 +174,7 @@ static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapsho
/* Helper functions for remoteOpen. */
-static int
+static virDrvStateInitResult
remoteStateInitialize(bool privileged G_GNUC_UNUSED,
const char *root G_GNUC_UNUSED,
bool monolithic,
diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
index c7bd65b4e9..a2d6b879d0 100644
--- a/src/secret/secret_driver.c
+++ b/src/secret/secret_driver.c
@@ -488,7 +488,7 @@ secretStateCleanup(void)
}
-static int
+static virDrvStateInitResult
secretStateInitialize(bool privileged,
const char *root,
bool monolithic G_GNUC_UNUSED,
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 314fe930e0..86c03762d2 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -239,7 +239,7 @@ storageDriverAutostart(void)
*
* Initialization function for the Storage Driver
*/
-static int
+static virDrvStateInitResult
storageStateInitialize(bool privileged,
const char *root,
bool monolithic G_GNUC_UNUSED,
diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index 380fdcb57e..4edea4bf18 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -4068,7 +4068,7 @@ vzStateCleanup(void)
return 0;
}
-static int
+static virDrvStateInitResult
vzStateInitialize(bool privileged,
const char *root,
bool monolithic G_GNUC_UNUSED,
--
2.44.1
11 months
[Call for Paper - late-breaking] VHPC'24: June 7th submission
deadline
by Remo Andreoli
====================================================================
CALL FOR PAPERS
19th Workshop on Virtualization in High-Performance Cloud Computing
(VHPC '24) held in conjunction with the European Conference on
Parallel and Distributed Computing Aug 26-30, 2024, Madrid, Spain.
(Springer LNCS Proceedings)
====================================================================
Paper submission deadline: June 7th, 2024 AoE (extended)
Date: August 26, 27, 2024
Workshop URL: vhpc dot org
To submit an abstract or paper, please follow the link provided
in the Call for Papers (CfP) announcement at the end of this message.
Call for Papers
Containers and virtualization technologies constitute key enabling
factors for flexible resource management in modern data centers, and
particularly in cloud environments. Cloud providers need to manage
complex infrastructures in a seamless fashion to support the highly
dynamic and heterogeneous workloads and hosted applications customers
deploy. Similarly, HPC environments have been increasingly adopting
techniques that enable flexible management of vast computing and
networking resources, close to marginal provisioning cost, which is
unprecedented in the history of scientific and commercial computing.
Various virtualization-containerization technologies contribute to
the overall picture in different ways: machine virtualization, with
its capability to enable consolidation of multiple underutilized
servers with heterogeneous software and operating systems (OSes),
and its capability to live-migrate a fully operating virtual machine
(VM) with a very short downtime, enables novel and dynamic ways to
manage physical servers; OS-level virtualization (i.e.,
containerization), with its capability to isolate multiple user-space
environments and to allow for their co-existence within the same OS
kernel, promises to provide many of the advantages of machine
virtualization with high levels of responsiveness and performance;
lastly, unikernels provide for manyvirtualization benefits with a
minimized OS/library surface. I/O virtualization, in turn, allows
physical network interfaces to exchange traffic with multiple VMs
or containers; network virtualization, with its capability to create
logical network overlays independently from the underlying physical
topology, is another fundamental enabling technology for Cloud/HPC
infrastructures. Last, storage virtualization needs to evolve to
support increasingly demanding requirements in terms of performance
and reliability for the managed application data.
Publication
Accepted papers will be published in a Springer LNCS proceedings volume.
Topics of Interest
The VHPC program committee solicits original, high-quality
submissions related to virtualization across the entire software
stack with a special focus on the intersection of HPC, containers/
virtualization and cloud computing.
Each topic encompasses aspects related to design/architecture,
management, performance management, modeling and\
configuration/tooling:
Design / Architecture:
- Containers and OS-level virtualization (LXC, Docker/Podman,
Nitro/Firecracke, Singularity)
- Hypervisor support for heterogeneous resources (GPUs, NPUs,
co-processors, FPGAs, etc.)
- GPU hypervisor memory virtualization in support of high-memory LLM
training workloads
- Hypervisor extensions to mitigate side-channel attacks
([micro-]architectural timing attacks, privilege escalation)
- Use of Risc-V related technologies for cloud, virtualized and HPC
use-cases
- VM & Container trust and security models
- Multi-environment coupling, system software supporting in-situ
analysis with HPC simulation
- Cloud reliability, fault-tolerance and high-availability
- Cloud-based quantum compute services
- Energy-efficient and power-aware virtualization
- Containers inside VMs with hypervisor isolation
- Virtualization support for emerging memory and storage technologies
- Lightweight/specialized operating systems in conjunction with
virtual machines
- Unikernels and use cases for virtualized HPC environments
- Formal definition and verification of hypervisors and virtualization
system properties
- ARM-based hypervisors, ARM virtualization extensions
Management:
- Container and VM management for HPC and cloud environments
- Virtualized/Cloudified instances to support Lambda / Function-as-a-
Service (FaaS) Paradigms
- HPC services integration, services to support HPC
- Service and on-demand scheduling & resource management
- Dedicated workload management with VMs or containers
- Workflow coupling with VMs and containers
- Unikernels and lightweight VM application management
- Environments and tools for operating containerized environments
(batch, orchestration)
- Models for non-HPC workload provisioning on HPC resources
Performance Measurements and Modeling:
- Performance improvements for or driven by unikernels
- Optimizations of virtual machine monitor platforms and hypervisors
- Scalability analysis of VMs and/or containers at large scale
- Performance measurement, modeling and monitoring of virtualized/
cloud workloads
- Virtualization in supercomputing environments, HPC clusters,
HPC in the cloud with an emphasis on AI GPUs/TPUs/NPUs
- Energy-efficient deployment of high-performance, ultra-low
latency and real-time workloads in cloud infrastructures
- Modeling, control and isolation of end-to-end performance for
parallel & distributed cloud/HPC applications, including the use of
cloud functions / FaaS
Configuration / Tooling:
- Tool support for unikernels: configuration/build environments,
debuggers, profilers
- Job scheduling/control/policy and container placement in
virtualized environments
- Measuring and controlling "OS/Virtualization noise"
- Operating MPI in containers/VMs and Unikernels
- GPU virtualization operationalization
This year, we are calling the timely topic of virtualization in support
of high-memory LLM training workloads including, but not limited to:
- GPU hypervisor memory virtualization: Techniques for virtualizing GPU
memory to allow flexible and efficient allocation across multiple
workloads, enabling higher utilization of GPU resources
- Flat CPU/GPU memory page tables/TLB: Unified virtual memory spaces
and page table structures that allow both GPUs to address CPU memory
mapped to accelerator global memory space
- Storage/filesystem to virtual memory mapped approaches
- Distributed memory virtualization
- Memory compression and reduction techniques: approaches for
compressing model parameters, activations, and gradients to reduce
memory requirements during training
- Out-of-core training algorithms
- Efficient memory allocation and management: Techniques for optimizing
memory allocation, reducing fragmentation, and improving memory
utilization during training
- Memory-efficient data formats and processing: Data formats and
processing techniques that minimize memory overhead while maintaining
training efficiency
- Benchmarking and profiling tools: Tools and methodologies for
measuring, analyzing, and optimizing memory usage in
LLM training workloads
- Case studies and applications: Real-world examples and applications of
virtualization techniques in LLM training scenarios
The Workshop on Virtualization in High-Performance Cloud Computing
(VHPC) aims to bring together researchers and industrial practitioners
facing the challenges posed by virtualization in order to foster
discussion, collaboration, mutual exchange of knowledge and
experience, enabling research to ultimately provide novel solutions
for virtualized computing systems of tomorrow.
The workshop will be one day in length, composed of 20 min paper
presentations, each followed by 10 min discussion sections, plus
lightning talks that are limited to 5 minutes. Presentations may be
accompanied by interactive demonstrations.
Important Dates
Rolling abstract submission
Jun 7th, 2024 AoE (extended) - Paper submission deadline
Jun 20th, 2024 - Acceptance notification
Jul 1st, 2024 - Camera-ready due
Aug 26th-27th, 2024 - Workshop Day(s)
Chair
Michael Alexander (chair), Austrian Academy of Sciences
Anastassios Nanos (co-chair), Nubificus Ltd., UK
Tommaso Cucinotta (co-chair), Scuola Superiore Sant'Anna, Italy
Publicity chair
Remo Andreoli, Scuola Superiore Sant'Anna, Italy
Technical Program Committee
- Stergios Anastasiadis, University of Ioannina, Greece
- Gabriele Ara, Scuola Superiore Sant'Anna
- Jakob Blomer, CERN, Switzerland
- Eduardo César, Universidad Autonoma de Barcelona, Spain
- Taylor Childers, Argonne National Laboratory, USA
- François Diakhaté, CEA DAM, France
- Roberto Giorgi, University of Siena, Italy
- Kyle Hale, Northwestern University, USA
- Giuseppe Lettieri, University of Pisa, Italy
- Nikos Parlavantzas, IRISA, France
- Amer Qouneh, Western New England University, USA
- Carlos Reaño, Queen’s University Belfast, UK
- Riccardo Rocha, CERN, Switzerland
- Lutz Schubert, University of Ulm, Germany
- Jonathan Sparks, Cray, USA
- Kurt Tutschku, Blekinge Institute of Technology, Sweden
- John Walters, USC ISI, USA
- Yasuhiro Watashiba, Osaka University, Japan
- Chao-Tung Yang, Tunghai University, Taiwan
Paper Submission-Publication
Papers submitted to the workshop will be reviewed by at least two
members of the program committee and external reviewers. Submissions
should include abstract, keywords, the e-mail address of the
corresponding author, and must not exceed 12 pages, including tables
and figures at a main font size no smaller than 11 points.
Submission of a paper should be regarded as a commitment that, should
the paper be accepted, at least one of the authors will register and
attend the conference to present the work.
Accepted papers will be published in a Springer LNCS volume. Initial
submissions are in PDF; authors of accepted papers will be requested
to provide source files.
Lightning Talks
Lightning Talks are in a non-paper track, synoptical in nature and are
strictly limited to 5 minutes. They can be used to gain early feedback
on ongoing research, for demonstrations, to present research results,
early research ideas, perspectives and positions of interest to the
community. Submit abstracts via the main submission link.
General Information
The workshop will be held in conjunction with the International European
Conference on Parallel and Distributed Computing on Aug 26-30, 2024,
Madrid, Spain.
Please contact ahead of time for presenting remotely via video.
Abstract, Paper Submission Link:
https://edas.info/newPaper.php?c=31582
LNCS Format Guidelines:
https://www.springer.com/gp/computer-science/lncs/conference-proceedings-...
Follow VHPC Updates on X:
https://twitter.com/VHPCworkshop
11 months
[PATCH] qemu: Optimize monitor event name lookup with hash tables
by Rayhan Faizel
Currently, monitor event names are looked up using binary search which has
O(log(n)) time complexity. This can be optimized even further with a
compile-time static hash table generated by the gperf tool. As gperf ensures
perfect hashing, lookup times are guaranteed to be O(1).
This patch also makes gperf a requirement for compiling libvirt if the QEMU
driver is enabled.
Signed-off-by: Rayhan Faizel <rayhan.faizel(a)gmail.com>
---
docs/kbase/internals/qemu-event-handlers.rst | 13 +-
meson.build | 2 +
src/qemu/meson.build | 9 +
src/qemu/qemu_monitor_event.gperf | 68 ++++++++
src/qemu/qemu_monitor_json.c | 171 +++++--------------
src/qemu/qemu_monitor_json.h | 45 +++++
6 files changed, 170 insertions(+), 138 deletions(-)
create mode 100644 src/qemu/qemu_monitor_event.gperf
diff --git a/docs/kbase/internals/qemu-event-handlers.rst b/docs/kbase/internals/qemu-event-handlers.rst
index 3589c4c48c..5ec11e28bd 100644
--- a/docs/kbase/internals/qemu-event-handlers.rst
+++ b/docs/kbase/internals/qemu-event-handlers.rst
@@ -23,16 +23,15 @@ QEMU monitor events
Any event emitted by qemu is received by
``qemu_monitor_json.c:qemuMonitorJSONIOProcessEvent()``. It looks up the
-event by name in the table ``eventHandlers`` (in the same file), which
-should have an entry like this for each event that libvirt
-understands::
+event by name from a hash-table, generated at compile-time by ``gperf``
+based on a list of entries defined in ``qemu_monitor_event.gperf``.
+``qemu_monitor_event.gperf`` should should have an entry like this
+for each event that libvirt understands::
- { "NIC_RX_FILTER_CHANGED", qemuMonitorJSONHandleNicRxFilterChanged, },
-
-NB: This table is searched with bsearch, so it *must* be alphabetically sorted.
+ "NIC_RX_FILTER_CHANGED", qemuMonitorJSONHandleNicRxFilterChanged
``qemuMonitorJSONIOProcessEvent`` calls the function listed in
-``eventHandlers``, e.g.::
+``qemu_monitor_event.gperf``, e.g.::
qemu_monitor_json.c:qemuMonitorJSONHandleNicRxFilterChanged()
diff --git a/meson.build b/meson.build
index e8b0094b91..03f1f0d56d 100644
--- a/meson.build
+++ b/meson.build
@@ -1708,6 +1708,8 @@ if not get_option('driver_qemu').disabled()
qemu_slirp_path = '/usr/bin/slirp-helper'
endif
conf.set_quoted('QEMU_SLIRP_HELPER', qemu_slirp_path)
+
+ gperf_prog = find_program('gperf')
endif
endif
diff --git a/src/qemu/meson.build b/src/qemu/meson.build
index 907893d431..2440476a7b 100644
--- a/src/qemu/meson.build
+++ b/src/qemu/meson.build
@@ -88,11 +88,20 @@ qemu_shim_sources = files(
'qemu_shim.c',
)
+qemu_driver_gperf_sources = []
+
+qemu_driver_gperf_sources += custom_target(
+ 'qemu_monitor_event.c',
+ input : 'qemu_monitor_event.gperf',
+ output : 'qemu_monitor_event.c',
+ command : [gperf_prog, '@INPUT@', '--output-file', '@OUTPUT@'])
+
if conf.has('WITH_QEMU')
qemu_driver_impl = static_library(
'virt_driver_qemu_impl',
[
qemu_driver_sources,
+ qemu_driver_gperf_sources,
qemu_dtrace_gen_headers,
],
dependencies: [
diff --git a/src/qemu/qemu_monitor_event.gperf b/src/qemu/qemu_monitor_event.gperf
new file mode 100644
index 0000000000..de2f958b9e
--- /dev/null
+++ b/src/qemu/qemu_monitor_event.gperf
@@ -0,0 +1,68 @@
+/*
+ * qemu_monitor_event.gperf: QEMU Monitor Event Lookup Table
+ *
+ * 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, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+%{
+#include "qemu_monitor_json.h"
+%}
+qemuEventHandler;
+%null_strings
+%define initializer-suffix ,NULL
+%language=ANSI-C
+%define slot-name type
+%define lookup-function-name qemu_monitor_event_lookup
+%define hash-function-name qemu_monitor_event_hash
+%readonly-tables
+%omit-struct-type
+%struct-type
+%%
+"ACPI_DEVICE_OST", qemuMonitorJSONHandleAcpiOstInfo
+"BALLOON_CHANGE", qemuMonitorJSONHandleBalloonChange
+"BLOCK_IO_ERROR", qemuMonitorJSONHandleIOError
+"BLOCK_WRITE_THRESHOLD", qemuMonitorJSONHandleBlockThreshold
+"DEVICE_DELETED", qemuMonitorJSONHandleDeviceDeleted
+"DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange
+"DEVICE_UNPLUG_GUEST_ERROR", qemuMonitorJSONHandleDeviceUnplugErr
+"DUMP_COMPLETED", qemuMonitorJSONHandleDumpCompleted
+"GUEST_CRASHLOADED", qemuMonitorJSONHandleGuestCrashloaded
+"GUEST_PANICKED", qemuMonitorJSONHandleGuestPanic
+"JOB_STATUS_CHANGE", qemuMonitorJSONHandleJobStatusChange
+"MEMORY_DEVICE_SIZE_CHANGE", qemuMonitorJSONHandleMemoryDeviceSizeChange
+"MEMORY_FAILURE", qemuMonitorJSONHandleMemoryFailure
+"MIGRATION", qemuMonitorJSONHandleMigrationStatus
+"MIGRATION_PASS", qemuMonitorJSONHandleMigrationPass
+"NETDEV_STREAM_DISCONNECTED", qemuMonitorJSONHandleNetdevStreamDisconnected
+"NIC_RX_FILTER_CHANGED", qemuMonitorJSONHandleNicRxFilterChanged
+"PR_MANAGER_STATUS_CHANGED", qemuMonitorJSONHandlePRManagerStatusChanged
+"RDMA_GID_STATUS_CHANGED", qemuMonitorJSONHandleRdmaGidStatusChanged
+"RESET", qemuMonitorJSONHandleReset
+"RESUME", qemuMonitorJSONHandleResume
+"RTC_CHANGE", qemuMonitorJSONHandleRTCChange
+"SHUTDOWN", qemuMonitorJSONHandleShutdown
+"SPICE_CONNECTED", qemuMonitorJSONHandleSPICEConnect
+"SPICE_DISCONNECTED", qemuMonitorJSONHandleSPICEDisconnect
+"SPICE_INITIALIZED", qemuMonitorJSONHandleSPICEInitialize
+"SPICE_MIGRATE_COMPLETED", qemuMonitorJSONHandleSpiceMigrated
+"STOP", qemuMonitorJSONHandleStop
+"SUSPEND", qemuMonitorJSONHandlePMSuspend
+"SUSPEND_DISK", qemuMonitorJSONHandlePMSuspendDisk
+"VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect
+"VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect
+"VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize
+"VSERPORT_CHANGE", qemuMonitorJSONHandleSerialChange
+"WAKEUP", qemuMonitorJSONHandlePMWakeup
+"WATCHDOG", qemuMonitorJSONHandleWatchdog
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index eb84a3d938..93df4490ad 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -49,102 +49,12 @@ VIR_LOG_INIT("qemu.qemu_monitor_json");
#define LINE_ENDING "\r\n"
-static void qemuMonitorJSONHandleShutdown(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleReset(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleStop(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleResume(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleRTCChange(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleWatchdog(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleIOError(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleVNCConnect(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleVNCInitialize(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleSPICEConnect(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleSPICEInitialize(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleTrayChange(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandlePMWakeup(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandlePMSuspend(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleJobStatusChange(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleBalloonChange(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleGuestCrashloaded(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleGuestPanic(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleDeviceDeleted(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleSerialChange(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleSpiceMigrated(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleMigrationStatus(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleMigrationPass(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleAcpiOstInfo(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleBlockThreshold(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleDumpCompleted(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandlePRManagerStatusChanged(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleRdmaGidStatusChanged(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleMemoryFailure(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleMemoryDeviceSizeChange(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleDeviceUnplugErr(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleNetdevStreamDisconnected(qemuMonitor *mon, virJSONValue *data);
-
-typedef struct {
- const char *type;
- void (*handler)(qemuMonitor *mon, virJSONValue *data);
-} qemuEventHandler;
-
-static qemuEventHandler eventHandlers[] = {
- { "ACPI_DEVICE_OST", qemuMonitorJSONHandleAcpiOstInfo, },
- { "BALLOON_CHANGE", qemuMonitorJSONHandleBalloonChange, },
- { "BLOCK_IO_ERROR", qemuMonitorJSONHandleIOError, },
- { "BLOCK_WRITE_THRESHOLD", qemuMonitorJSONHandleBlockThreshold, },
- { "DEVICE_DELETED", qemuMonitorJSONHandleDeviceDeleted, },
- { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
- { "DEVICE_UNPLUG_GUEST_ERROR", qemuMonitorJSONHandleDeviceUnplugErr, },
- { "DUMP_COMPLETED", qemuMonitorJSONHandleDumpCompleted, },
- { "GUEST_CRASHLOADED", qemuMonitorJSONHandleGuestCrashloaded, },
- { "GUEST_PANICKED", qemuMonitorJSONHandleGuestPanic, },
- { "JOB_STATUS_CHANGE", qemuMonitorJSONHandleJobStatusChange, },
- { "MEMORY_DEVICE_SIZE_CHANGE", qemuMonitorJSONHandleMemoryDeviceSizeChange, },
- { "MEMORY_FAILURE", qemuMonitorJSONHandleMemoryFailure, },
- { "MIGRATION", qemuMonitorJSONHandleMigrationStatus, },
- { "MIGRATION_PASS", qemuMonitorJSONHandleMigrationPass, },
- { "NETDEV_STREAM_DISCONNECTED", qemuMonitorJSONHandleNetdevStreamDisconnected, },
- { "NIC_RX_FILTER_CHANGED", qemuMonitorJSONHandleNicRxFilterChanged, },
- { "PR_MANAGER_STATUS_CHANGED", qemuMonitorJSONHandlePRManagerStatusChanged, },
- { "RDMA_GID_STATUS_CHANGED", qemuMonitorJSONHandleRdmaGidStatusChanged, },
- { "RESET", qemuMonitorJSONHandleReset, },
- { "RESUME", qemuMonitorJSONHandleResume, },
- { "RTC_CHANGE", qemuMonitorJSONHandleRTCChange, },
- { "SHUTDOWN", qemuMonitorJSONHandleShutdown, },
- { "SPICE_CONNECTED", qemuMonitorJSONHandleSPICEConnect, },
- { "SPICE_DISCONNECTED", qemuMonitorJSONHandleSPICEDisconnect, },
- { "SPICE_INITIALIZED", qemuMonitorJSONHandleSPICEInitialize, },
- { "SPICE_MIGRATE_COMPLETED", qemuMonitorJSONHandleSpiceMigrated, },
- { "STOP", qemuMonitorJSONHandleStop, },
- { "SUSPEND", qemuMonitorJSONHandlePMSuspend, },
- { "SUSPEND_DISK", qemuMonitorJSONHandlePMSuspendDisk, },
- { "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, },
- { "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
- { "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
- { "VSERPORT_CHANGE", qemuMonitorJSONHandleSerialChange, },
- { "WAKEUP", qemuMonitorJSONHandlePMWakeup, },
- { "WATCHDOG", qemuMonitorJSONHandleWatchdog, },
- /* We use bsearch, so keep this list sorted. */
-};
-
-static int
-qemuMonitorEventCompare(const void *key, const void *elt)
-{
- const char *type = key;
- const qemuEventHandler *handler = elt;
- return strcmp(type, handler->type);
-}
-
static int
qemuMonitorJSONIOProcessEvent(qemuMonitor *mon,
virJSONValue *obj)
{
const char *type;
- qemuEventHandler *handler;
+ const qemuEventHandler *handler;
virJSONValue *data;
g_autofree char *details = NULL;
virJSONValue *timestamp;
@@ -171,8 +81,7 @@ qemuMonitorJSONIOProcessEvent(qemuMonitor *mon,
}
qemuMonitorEmitEvent(mon, type, seconds, micros, details);
- handler = bsearch(type, eventHandlers, G_N_ELEMENTS(eventHandlers),
- sizeof(eventHandlers[0]), qemuMonitorEventCompare);
+ handler = qemu_monitor_event_lookup(type, strlen(type));
if (handler) {
VIR_DEBUG("handle %s handler=%p data=%p", type,
handler->handler, data);
@@ -543,7 +452,7 @@ qemuMonitorJSONMakeCommand(const char *cmdname,
}
-static void qemuMonitorJSONHandleShutdown(qemuMonitor *mon, virJSONValue *data)
+void qemuMonitorJSONHandleShutdown(qemuMonitor *mon, virJSONValue *data)
{
bool guest = false;
virTristateBool guest_initiated = VIR_TRISTATE_BOOL_ABSENT;
@@ -554,17 +463,17 @@ static void qemuMonitorJSONHandleShutdown(qemuMonitor *mon, virJSONValue *data)
qemuMonitorEmitShutdown(mon, guest_initiated);
}
-static void qemuMonitorJSONHandleReset(qemuMonitor *mon, virJSONValue *data G_GNUC_UNUSED)
+void qemuMonitorJSONHandleReset(qemuMonitor *mon, virJSONValue *data G_GNUC_UNUSED)
{
qemuMonitorEmitReset(mon);
}
-static void qemuMonitorJSONHandleStop(qemuMonitor *mon, virJSONValue *data G_GNUC_UNUSED)
+void qemuMonitorJSONHandleStop(qemuMonitor *mon, virJSONValue *data G_GNUC_UNUSED)
{
qemuMonitorEmitStop(mon);
}
-static void qemuMonitorJSONHandleResume(qemuMonitor *mon, virJSONValue *data G_GNUC_UNUSED)
+void qemuMonitorJSONHandleResume(qemuMonitor *mon, virJSONValue *data G_GNUC_UNUSED)
{
qemuMonitorEmitResume(mon);
}
@@ -635,7 +544,7 @@ qemuMonitorJSONGuestPanicExtractInfo(virJSONValue *data)
}
-static void
+void
qemuMonitorJSONHandleGuestPanic(qemuMonitor *mon,
virJSONValue *data)
{
@@ -649,7 +558,7 @@ qemuMonitorJSONHandleGuestPanic(qemuMonitor *mon,
}
-static void qemuMonitorJSONHandleRTCChange(qemuMonitor *mon, virJSONValue *data)
+void qemuMonitorJSONHandleRTCChange(qemuMonitor *mon, virJSONValue *data)
{
long long offset = 0;
if (virJSONValueObjectGetNumberLong(data, "offset", &offset) < 0) {
@@ -665,7 +574,7 @@ VIR_ENUM_IMPL(qemuMonitorWatchdogAction,
"none", "pause", "reset", "poweroff", "shutdown", "debug", "inject-nmi",
);
-static void qemuMonitorJSONHandleWatchdog(qemuMonitor *mon, virJSONValue *data)
+void qemuMonitorJSONHandleWatchdog(qemuMonitor *mon, virJSONValue *data)
{
const char *action;
int actionID;
@@ -689,7 +598,7 @@ VIR_ENUM_IMPL(qemuMonitorIOErrorAction,
);
-static void
+void
qemuMonitorJSONHandleIOError(qemuMonitor *mon, virJSONValue *data)
{
const char *device;
@@ -802,19 +711,19 @@ qemuMonitorJSONHandleGraphicsVNC(qemuMonitor *mon,
authScheme, x509dname, saslUsername);
}
-static void qemuMonitorJSONHandleVNCConnect(qemuMonitor *mon, virJSONValue *data)
+void qemuMonitorJSONHandleVNCConnect(qemuMonitor *mon, virJSONValue *data)
{
qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_CONNECT);
}
-static void qemuMonitorJSONHandleVNCInitialize(qemuMonitor *mon, virJSONValue *data)
+void qemuMonitorJSONHandleVNCInitialize(qemuMonitor *mon, virJSONValue *data)
{
qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE);
}
-static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitor *mon, virJSONValue *data)
+void qemuMonitorJSONHandleVNCDisconnect(qemuMonitor *mon, virJSONValue *data)
{
qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT);
}
@@ -884,24 +793,24 @@ qemuMonitorJSONHandleGraphicsSPICE(qemuMonitor *mon,
}
-static void qemuMonitorJSONHandleSPICEConnect(qemuMonitor *mon, virJSONValue *data)
+void qemuMonitorJSONHandleSPICEConnect(qemuMonitor *mon, virJSONValue *data)
{
qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_CONNECT);
}
-static void qemuMonitorJSONHandleSPICEInitialize(qemuMonitor *mon, virJSONValue *data)
+void qemuMonitorJSONHandleSPICEInitialize(qemuMonitor *mon, virJSONValue *data)
{
qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE);
}
-static void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitor *mon, virJSONValue *data)
+void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitor *mon, virJSONValue *data)
{
qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT);
}
-static void
+void
qemuMonitorJSONHandleJobStatusChange(qemuMonitor *mon,
virJSONValue *data)
{
@@ -924,7 +833,7 @@ qemuMonitorJSONHandleJobStatusChange(qemuMonitor *mon,
}
-static void
+void
qemuMonitorJSONHandleTrayChange(qemuMonitor *mon,
virJSONValue *data)
{
@@ -955,14 +864,14 @@ qemuMonitorJSONHandleTrayChange(qemuMonitor *mon,
qemuMonitorEmitTrayChange(mon, devAlias, devid, reason);
}
-static void
+void
qemuMonitorJSONHandlePMWakeup(qemuMonitor *mon,
virJSONValue *data G_GNUC_UNUSED)
{
qemuMonitorEmitPMWakeup(mon);
}
-static void
+void
qemuMonitorJSONHandlePMSuspend(qemuMonitor *mon,
virJSONValue *data G_GNUC_UNUSED)
{
@@ -970,7 +879,7 @@ qemuMonitorJSONHandlePMSuspend(qemuMonitor *mon,
}
-static void
+void
qemuMonitorJSONHandleBalloonChange(qemuMonitor *mon,
virJSONValue *data)
{
@@ -983,14 +892,14 @@ qemuMonitorJSONHandleBalloonChange(qemuMonitor *mon,
qemuMonitorEmitBalloonChange(mon, actual);
}
-static void
+void
qemuMonitorJSONHandlePMSuspendDisk(qemuMonitor *mon,
virJSONValue *data G_GNUC_UNUSED)
{
qemuMonitorEmitPMSuspendDisk(mon);
}
-static void
+void
qemuMonitorJSONHandleDeviceDeleted(qemuMonitor *mon, virJSONValue *data)
{
const char *device;
@@ -1004,7 +913,7 @@ qemuMonitorJSONHandleDeviceDeleted(qemuMonitor *mon, virJSONValue *data)
}
-static void
+void
qemuMonitorJSONHandleDeviceUnplugErr(qemuMonitor *mon, virJSONValue *data)
{
const char *device;
@@ -1021,7 +930,7 @@ qemuMonitorJSONHandleDeviceUnplugErr(qemuMonitor *mon, virJSONValue *data)
}
-static void
+void
qemuMonitorJSONHandleNetdevStreamDisconnected(qemuMonitor *mon, virJSONValue *data)
{
const char *name;
@@ -1035,7 +944,7 @@ qemuMonitorJSONHandleNetdevStreamDisconnected(qemuMonitor *mon, virJSONValue *da
}
-static void
+void
qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitor *mon, virJSONValue *data)
{
const char *name;
@@ -1049,7 +958,7 @@ qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitor *mon, virJSONValue *data)
}
-static void
+void
qemuMonitorJSONHandleSerialChange(qemuMonitor *mon,
virJSONValue *data)
{
@@ -1070,7 +979,7 @@ qemuMonitorJSONHandleSerialChange(qemuMonitor *mon,
}
-static void
+void
qemuMonitorJSONHandleSpiceMigrated(qemuMonitor *mon,
virJSONValue *data G_GNUC_UNUSED)
{
@@ -1078,7 +987,7 @@ qemuMonitorJSONHandleSpiceMigrated(qemuMonitor *mon,
}
-static void
+void
qemuMonitorJSONHandleMemoryDeviceSizeChange(qemuMonitor *mon,
virJSONValue *data)
{
@@ -1100,7 +1009,7 @@ qemuMonitorJSONHandleMemoryDeviceSizeChange(qemuMonitor *mon,
}
-static void
+void
qemuMonitorJSONHandleMemoryFailure(qemuMonitor *mon,
virJSONValue *data)
{
@@ -1147,7 +1056,7 @@ qemuMonitorJSONHandleMemoryFailure(qemuMonitor *mon,
}
-static void
+void
qemuMonitorJSONHandleMigrationStatus(qemuMonitor *mon,
virJSONValue *data)
{
@@ -1168,7 +1077,7 @@ qemuMonitorJSONHandleMigrationStatus(qemuMonitor *mon,
}
-static void
+void
qemuMonitorJSONHandleMigrationPass(qemuMonitor *mon,
virJSONValue *data)
{
@@ -1183,7 +1092,7 @@ qemuMonitorJSONHandleMigrationPass(qemuMonitor *mon,
}
-static void
+void
qemuMonitorJSONHandleAcpiOstInfo(qemuMonitor *mon, virJSONValue *data)
{
virJSONValue *info;
@@ -1220,7 +1129,7 @@ qemuMonitorJSONHandleAcpiOstInfo(qemuMonitor *mon, virJSONValue *data)
}
-static void
+void
qemuMonitorJSONHandleBlockThreshold(qemuMonitor *mon, virJSONValue *data)
{
const char *nodename;
@@ -1280,7 +1189,7 @@ qemuMonitorJSONExtractDumpStats(virJSONValue *result,
}
-static void
+void
qemuMonitorJSONHandleDumpCompleted(qemuMonitor *mon,
virJSONValue *data)
{
@@ -1302,8 +1211,8 @@ qemuMonitorJSONHandleDumpCompleted(qemuMonitor *mon,
}
-static void qemuMonitorJSONHandlePRManagerStatusChanged(qemuMonitor *mon,
- virJSONValue *data)
+void qemuMonitorJSONHandlePRManagerStatusChanged(qemuMonitor *mon,
+ virJSONValue *data)
{
const char *name;
bool connected;
@@ -1323,8 +1232,8 @@ static void qemuMonitorJSONHandlePRManagerStatusChanged(qemuMonitor *mon,
}
-static void qemuMonitorJSONHandleRdmaGidStatusChanged(qemuMonitor *mon,
- virJSONValue *data)
+void qemuMonitorJSONHandleRdmaGidStatusChanged(qemuMonitor *mon,
+ virJSONValue *data)
{
const char *netdev;
bool gid_status;
@@ -1357,7 +1266,7 @@ static void qemuMonitorJSONHandleRdmaGidStatusChanged(qemuMonitor *mon,
}
-static void
+void
qemuMonitorJSONHandleGuestCrashloaded(qemuMonitor *mon,
virJSONValue *data)
{
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 9684660d86..5bd4b21b7d 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -27,6 +27,51 @@
#include "cpu/cpu.h"
#include "util/virgic.h"
+typedef struct {
+ const char *type;
+ void (*handler)(qemuMonitor *mon, virJSONValue *data);
+} qemuEventHandler;
+
+const qemuEventHandler *
+qemu_monitor_event_lookup(const char *str, size_t len);
+
+void qemuMonitorJSONHandleShutdown(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleReset(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleStop(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleResume(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleRTCChange(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleWatchdog(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleIOError(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleVNCConnect(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleVNCInitialize(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleVNCDisconnect(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleSPICEConnect(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleSPICEInitialize(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleTrayChange(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandlePMWakeup(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandlePMSuspend(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleJobStatusChange(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleBalloonChange(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleGuestCrashloaded(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleGuestPanic(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleDeviceDeleted(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleSerialChange(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleSpiceMigrated(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleMigrationStatus(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleMigrationPass(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleAcpiOstInfo(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleBlockThreshold(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleDumpCompleted(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandlePRManagerStatusChanged(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleRdmaGidStatusChanged(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleMemoryFailure(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleMemoryDeviceSizeChange(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleDeviceUnplugErr(qemuMonitor *mon, virJSONValue *data);
+void qemuMonitorJSONHandleNetdevStreamDisconnected(qemuMonitor *mon, virJSONValue *data);
+
int
qemuMonitorJSONIOProcessLine(qemuMonitor *mon,
const char *line,
--
2.34.1
11 months
[PATCH v2] network: add modify-or-add feature to net-update
by Abhiram Tilak
The current way of updating a network configuration uses `virsh
net-update` to add, delete or modify entries. But with such a mechansim
one should know if an entry with current info already exists. Adding
modify-or-add option automatically performs either modify or add
depending on the current state.
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/363
Signed-off-by: Abhiram Tilak <atp.exp(a)gmail.com>
---
Changes in v2:
- Removed the modify-or-add functionality for sections
where modify is not applicable.
- Changed the existing implementation of `UpdateIPDHCPHost`,
to avoid code duplication.
- Changed the implementation of modify-or-delete to reassign
the `command` variable instead of using multiple nested conditions.
docs/manpages/virsh.rst | 5 +-
include/libvirt/libvirt-network.h | 12 +--
src/conf/network_conf.c | 134 +++++++++++++++++++++---------
tools/virsh-network.c | 6 +-
4 files changed, 110 insertions(+), 47 deletions(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 115b802c45..0da3827f6b 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -5908,7 +5908,10 @@ changes optionally taking effect immediately, without needing to
destroy and re-start the network.
*command* is one of "add-first", "add-last", "add" (a synonym for
-add-last), "delete", or "modify".
+add-last), "delete", "modify", "modify-or-add" (modify + add-last), or
+"modify-or-add-first". The 'modify-or-add*' commands perform modify or
+add operation depending on the given state, and can be useful for
+scripting.
*section* is one of "bridge", "domain", "ip", "ip-dhcp-host",
"ip-dhcp-range", "forward", "forward-interface", "forward-pf",
diff --git a/include/libvirt/libvirt-network.h b/include/libvirt/libvirt-network.h
index 58591be7ac..bb4468b160 100644
--- a/include/libvirt/libvirt-network.h
+++ b/include/libvirt/libvirt-network.h
@@ -176,11 +176,13 @@ int virNetworkUndefine (virNetworkPtr network);
* Since: 0.10.2
*/
typedef enum {
- VIR_NETWORK_UPDATE_COMMAND_NONE = 0, /* invalid (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_MODIFY = 1, /* modify an existing element (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_DELETE = 2, /* delete an existing element (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_ADD_LAST = 3, /* add an element at end of list (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST = 4, /* add an element at start of list (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_NONE = 0, /* invalid (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_MODIFY = 1, /* modify an existing element (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_DELETE = 2, /* delete an existing element (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_ADD_LAST = 3, /* add an element at end of list (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST = 4, /* add an element at start of list (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST = 5, /* conditionally modify or add an element at end (Since: 10.4.0) */
+ VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST = 6, /* conditionally modify or add an element at start (Since: 10.4.0) */
# ifdef VIR_ENUM_SENTINELS
VIR_NETWORK_UPDATE_COMMAND_LAST /* (Since: 0.10.2) */
# endif
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index cc92ed0b03..a7c3dea163 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -2720,6 +2720,7 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
virNetworkIPDef *ipdef = virNetworkIPDefByIndex(def, parentIndex);
virNetworkDHCPHostDef host = { 0 };
bool partialOkay = (command == VIR_NETWORK_UPDATE_COMMAND_DELETE);
+ int foundMatchedEntry = -1, foundExactEntry = -1;
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "host") < 0)
goto cleanup;
@@ -2740,22 +2741,47 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
goto cleanup;
}
- if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
+ /* check if the entry already exsits */
+ for (i = 0; i < ipdef->nhosts; i++) {
- /* search for the entry with this (ip|mac|name),
- * and update the IP+(mac|name) */
- for (i = 0; i < ipdef->nhosts; i++) {
- if ((host.mac && ipdef->hosts[i].mac &&
- !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
- (VIR_SOCKET_ADDR_VALID(&host.ip) &&
- virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip)) ||
- (host.name &&
- STREQ_NULLABLE(host.name, ipdef->hosts[i].name))) {
- break;
- }
+ /* try to match any of (ip|mac|name) attributes */
+ if ((host.mac && ipdef->hosts[i].mac &&
+ !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
+ (VIR_SOCKET_ADDR_VALID(&host.ip) &&
+ virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip)) ||
+ (host.name &&
+ STREQ_NULLABLE(host.name, ipdef->hosts[i].name))) {
+ foundMatchedEntry = i;
+ }
+
+ /* find exact entry - all specified attributes must match */
+ if ((!host.mac || !ipdef->hosts[i].mac ||
+ !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) &&
+ (!host.name ||
+ STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) &&
+ (!VIR_SOCKET_ADDR_VALID(&host.ip) ||
+ virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
+ foundExactEntry = i;
+ break;
}
+ }
+
+ /* modify-or-add: convert command to add or modify based on foundEntry */
+ if (foundEntry == -1) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST;
+ else if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_LAST;
+ } else if (foundEntry >= 0) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_MODIFY;
+ }
+
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
- if (i == ipdef->nhosts) {
+ /* log error if no such entry exists to be modified */
+ if (foundMatchedEntry == -1) {
g_autofree char *ip = virSocketAddrFormat(&host.ip);
virReportError(VIR_ERR_OPERATION_INVALID,
_("couldn't locate an existing dhcp host entry with \"mac='%1$s'\" \"name='%2$s'\" \"ip='%3$s'\" in network '%4$s'"),
@@ -2779,21 +2805,13 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
goto cleanup;
/* log error if an entry with same name/address/ip already exists */
- for (i = 0; i < ipdef->nhosts; i++) {
- if ((host.mac && ipdef->hosts[i].mac &&
- !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
- (host.name &&
- STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) ||
- (VIR_SOCKET_ADDR_VALID(&host.ip) &&
- virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
- g_autofree char *ip = virSocketAddrFormat(&host.ip);
+ if (foundMatchedEntry >= 0) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("there is an existing dhcp host entry in network '%1$s' that matches \"<host mac='%2$s' name='%3$s' ip='%4$s'/>\""),
+ def->name, host.mac ? host.mac : _("unknown"),
+ host.name, ip ? ip : _("unknown"));
+ goto cleanup;
- virReportError(VIR_ERR_OPERATION_INVALID,
- _("there is an existing dhcp host entry in network '%1$s' that matches \"<host mac='%2$s' name='%3$s' ip='%4$s'/>\""),
- def->name, host.mac ? host.mac : _("unknown"),
- host.name, ip ? ip : _("unknown"));
- goto cleanup;
- }
}
/* add to beginning/end of list */
@@ -2804,18 +2822,8 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
goto cleanup;
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
- /* find matching entry - all specified attributes must match */
- for (i = 0; i < ipdef->nhosts; i++) {
- if ((!host.mac || !ipdef->hosts[i].mac ||
- !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) &&
- (!host.name ||
- STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) &&
- (!VIR_SOCKET_ADDR_VALID(&host.ip) ||
- virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
- break;
- }
- }
- if (i == ipdef->nhosts) {
+ /* log error if there is no entry with exact match*/
+ if (foundExactEntry == -1) {
virReportError(VIR_ERR_OPERATION_INVALID,
_("couldn't locate a matching dhcp host entry in network '%1$s'"),
def->name);
@@ -2865,6 +2873,14 @@ virNetworkDefUpdateIPDHCPRange(virNetworkDef *def,
return -1;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("dhcp ranges cannot be modified, use add command instead of modify-or-add"));
+ return -1;
+ }
+
if (virNetworkDHCPRangeDefParseXML(def->name, ipdef, ctxt->node, &range) < 0)
return -1;
@@ -2964,6 +2980,13 @@ virNetworkDefUpdateForwardInterface(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("forward interface entries cannot be modified, use add command instead of modify-or-add"));
+ goto cleanup;
+ }
+
/* parsing this is so simple that it doesn't have its own function */
iface.type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV;
if (!(iface.device.dev = virXMLPropString(ctxt->node, "dev"))) {
@@ -3085,6 +3108,18 @@ virNetworkDefUpdatePortGroup(virNetworkDef *def,
goto cleanup;
}
+ /* modify-or-add: convert command to add or modify based on foundName */
+ if (foundName == -1) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST;
+ else if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_LAST;
+ } else if (foundName >= 0) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_MODIFY;
+ }
+
/* if there is already a different default, we can't make this
* one the default.
*/
@@ -3153,6 +3188,13 @@ virNetworkDefUpdateDNSHost(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("DNS HOST records cannot be modified, use add instead of modify-or-add"));
+ goto cleanup;
+ }
+
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "host") < 0)
goto cleanup;
@@ -3249,6 +3291,13 @@ virNetworkDefUpdateDNSSrv(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("DNS SRV records cannot be modified, use add command instead of modify-or-add"));
+ goto cleanup;
+ }
+
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "srv") < 0)
goto cleanup;
@@ -3330,6 +3379,13 @@ virNetworkDefUpdateDNSTxt(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("DNS TXT records cannot be modified, use add command instead of modify-or-add"));
+ goto cleanup;
+ }
+
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "txt") < 0)
goto cleanup;
diff --git a/tools/virsh-network.c b/tools/virsh-network.c
index 597e3d4530..d7dc5df5a8 100644
--- a/tools/virsh-network.c
+++ b/tools/virsh-network.c
@@ -1231,7 +1231,8 @@ static const vshCmdOptDef opts_network_update[] = {
.positional = true,
.required = true,
.completer = virshNetworkUpdateCommandCompleter,
- .help = N_("type of update (add-first, add-last (add), delete, or modify)")
+ .help = N_("type of update (add-first, add-last (add), delete, modify,"
+ "modify-or-add, or modify-or-add-first)")
},
{.name = "section",
.type = VSH_OT_STRING,
@@ -1260,7 +1261,8 @@ static const vshCmdOptDef opts_network_update[] = {
VIR_ENUM_IMPL(virshNetworkUpdateCommand,
VIR_NETWORK_UPDATE_COMMAND_LAST,
- "none", "modify", "delete", "add-last", "add-first");
+ "none", "modify", "delete", "add-last", "add-first", "modify-or-add",
+ "modify-or-add-first");
VIR_ENUM_IMPL(virshNetworkSection,
VIR_NETWORK_SECTION_LAST,
--
2.42.1
11 months
[PATCH v3] network: add modify-or-add feature to net-update
by Abhiram Tilak
The current way of updating a network configuration uses `virsh
net-update` to add, delete or modify entries. But with such a mechansim
one should know if an entry with current info already exists. Adding
modify-or-add option automatically performs either modify or add
depending on the current state.
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/363
Signed-off-by: Abhiram Tilak <atp.exp(a)gmail.com>
---
Changes in v3:
- Changed the indexes used to delete or modify instead of `i`.
Changes in v2:
- Removed the modify-or-add functionality for sections
where modify is not applicable.
- Changed the existing implementation of `UpdateIPDHCPHost`,
to avoid code duplication.
- Changed the implementation of modify-or-delete to reassign
the `command` variable instead of using multiple nested conditions.
docs/manpages/virsh.rst | 5 +-
include/libvirt/libvirt-network.h | 12 +--
src/conf/network_conf.c | 142 +++++++++++++++++++++---------
tools/virsh-network.c | 6 +-
4 files changed, 114 insertions(+), 51 deletions(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index fa038e4547..918e6db30c 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -5906,7 +5906,10 @@ changes optionally taking effect immediately, without needing to
destroy and re-start the network.
*command* is one of "add-first", "add-last", "add" (a synonym for
-add-last), "delete", or "modify".
+add-last), "delete", "modify", "modify-or-add" (modify + add-last), or
+"modify-or-add-first". The 'modify-or-add*' commands perform modify or
+add operation depending on the given state, and can be useful for
+scripting.
*section* is one of "bridge", "domain", "ip", "ip-dhcp-host",
"ip-dhcp-range", "forward", "forward-interface", "forward-pf",
diff --git a/include/libvirt/libvirt-network.h b/include/libvirt/libvirt-network.h
index 58591be7ac..bb4468b160 100644
--- a/include/libvirt/libvirt-network.h
+++ b/include/libvirt/libvirt-network.h
@@ -176,11 +176,13 @@ int virNetworkUndefine (virNetworkPtr network);
* Since: 0.10.2
*/
typedef enum {
- VIR_NETWORK_UPDATE_COMMAND_NONE = 0, /* invalid (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_MODIFY = 1, /* modify an existing element (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_DELETE = 2, /* delete an existing element (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_ADD_LAST = 3, /* add an element at end of list (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST = 4, /* add an element at start of list (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_NONE = 0, /* invalid (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_MODIFY = 1, /* modify an existing element (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_DELETE = 2, /* delete an existing element (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_ADD_LAST = 3, /* add an element at end of list (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST = 4, /* add an element at start of list (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST = 5, /* conditionally modify or add an element at end (Since: 10.4.0) */
+ VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST = 6, /* conditionally modify or add an element at start (Since: 10.4.0) */
# ifdef VIR_ENUM_SENTINELS
VIR_NETWORK_UPDATE_COMMAND_LAST /* (Since: 0.10.2) */
# endif
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index cc92ed0b03..4f76257d06 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -2720,6 +2720,7 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
virNetworkIPDef *ipdef = virNetworkIPDefByIndex(def, parentIndex);
virNetworkDHCPHostDef host = { 0 };
bool partialOkay = (command == VIR_NETWORK_UPDATE_COMMAND_DELETE);
+ int foundMatchedEntry = -1, foundExactEntry = -1;
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "host") < 0)
goto cleanup;
@@ -2740,22 +2741,47 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
goto cleanup;
}
- if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
+ /* check if the entry already exsits */
+ for (i = 0; i < ipdef->nhosts; i++) {
- /* search for the entry with this (ip|mac|name),
- * and update the IP+(mac|name) */
- for (i = 0; i < ipdef->nhosts; i++) {
- if ((host.mac && ipdef->hosts[i].mac &&
- !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
- (VIR_SOCKET_ADDR_VALID(&host.ip) &&
- virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip)) ||
- (host.name &&
- STREQ_NULLABLE(host.name, ipdef->hosts[i].name))) {
- break;
- }
+ /* try to match any of (ip|mac|name) attributes */
+ if ((host.mac && ipdef->hosts[i].mac &&
+ !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
+ (VIR_SOCKET_ADDR_VALID(&host.ip) &&
+ virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip)) ||
+ (host.name &&
+ STREQ_NULLABLE(host.name, ipdef->hosts[i].name))) {
+ foundMatchedEntry = i;
+ }
+
+ /* find exact entry - all attributes must match if they exist */
+ if ((!host.mac || !ipdef->hosts[i].mac ||
+ !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) &&
+ (!host.name ||
+ STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) &&
+ (!VIR_SOCKET_ADDR_VALID(&host.ip) ||
+ virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
+ foundExactEntry = i;
+ break;
}
+ }
+
+ /* modify-or-add: convert command to add or modify based on foundEntry */
+ if (foundEntry == -1) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST;
+ else if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_LAST;
+ } else if (foundEntry >= 0) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_MODIFY;
+ }
+
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
- if (i == ipdef->nhosts) {
+ /* log error if no such entry exists to be modified */
+ if (foundMatchedEntry == -1) {
g_autofree char *ip = virSocketAddrFormat(&host.ip);
virReportError(VIR_ERR_OPERATION_INVALID,
_("couldn't locate an existing dhcp host entry with \"mac='%1$s'\" \"name='%2$s'\" \"ip='%3$s'\" in network '%4$s'"),
@@ -2768,8 +2794,8 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
* then clear out the extra copy to get rid of the duplicate pointers
* to its data (mac and name strings).
*/
- virNetworkDHCPHostDefClear(&ipdef->hosts[i]);
- ipdef->hosts[i] = host;
+ virNetworkDHCPHostDefClear(&ipdef->hosts[foundMatchedEntry]);
+ ipdef->hosts[foundMatchedEntry] = host;
memset(&host, 0, sizeof(host));
} else if ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ||
@@ -2779,21 +2805,13 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
goto cleanup;
/* log error if an entry with same name/address/ip already exists */
- for (i = 0; i < ipdef->nhosts; i++) {
- if ((host.mac && ipdef->hosts[i].mac &&
- !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
- (host.name &&
- STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) ||
- (VIR_SOCKET_ADDR_VALID(&host.ip) &&
- virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
- g_autofree char *ip = virSocketAddrFormat(&host.ip);
+ if (foundMatchedEntry >= 0) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("there is an existing dhcp host entry in network '%1$s' that matches \"<host mac='%2$s' name='%3$s' ip='%4$s'/>\""),
+ def->name, host.mac ? host.mac : _("unknown"),
+ host.name, ip ? ip : _("unknown"));
+ goto cleanup;
- virReportError(VIR_ERR_OPERATION_INVALID,
- _("there is an existing dhcp host entry in network '%1$s' that matches \"<host mac='%2$s' name='%3$s' ip='%4$s'/>\""),
- def->name, host.mac ? host.mac : _("unknown"),
- host.name, ip ? ip : _("unknown"));
- goto cleanup;
- }
}
/* add to beginning/end of list */
@@ -2804,18 +2822,8 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
goto cleanup;
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
- /* find matching entry - all specified attributes must match */
- for (i = 0; i < ipdef->nhosts; i++) {
- if ((!host.mac || !ipdef->hosts[i].mac ||
- !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) &&
- (!host.name ||
- STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) &&
- (!VIR_SOCKET_ADDR_VALID(&host.ip) ||
- virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
- break;
- }
- }
- if (i == ipdef->nhosts) {
+ /* log error if there is no entry with exact match*/
+ if (foundExactEntry == -1) {
virReportError(VIR_ERR_OPERATION_INVALID,
_("couldn't locate a matching dhcp host entry in network '%1$s'"),
def->name);
@@ -2823,8 +2831,8 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
}
/* remove it */
- virNetworkDHCPHostDefClear(&ipdef->hosts[i]);
- VIR_DELETE_ELEMENT(ipdef->hosts, i, ipdef->nhosts);
+ virNetworkDHCPHostDefClear(&ipdef->hosts[foundExactEntry]);
+ VIR_DELETE_ELEMENT(ipdef->hosts, foundExactEntry, ipdef->nhosts);
} else {
virNetworkDefUpdateUnknownCommand(command);
@@ -2865,6 +2873,14 @@ virNetworkDefUpdateIPDHCPRange(virNetworkDef *def,
return -1;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("dhcp ranges cannot be modified, use add command instead of modify-or-add"));
+ return -1;
+ }
+
if (virNetworkDHCPRangeDefParseXML(def->name, ipdef, ctxt->node, &range) < 0)
return -1;
@@ -2964,6 +2980,13 @@ virNetworkDefUpdateForwardInterface(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("forward interface entries cannot be modified, use add command instead of modify-or-add"));
+ goto cleanup;
+ }
+
/* parsing this is so simple that it doesn't have its own function */
iface.type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV;
if (!(iface.device.dev = virXMLPropString(ctxt->node, "dev"))) {
@@ -3085,6 +3108,18 @@ virNetworkDefUpdatePortGroup(virNetworkDef *def,
goto cleanup;
}
+ /* modify-or-add: convert command to add or modify based on foundName */
+ if (foundName == -1) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST;
+ else if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_LAST;
+ } else if (foundName >= 0) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_MODIFY;
+ }
+
/* if there is already a different default, we can't make this
* one the default.
*/
@@ -3153,6 +3188,13 @@ virNetworkDefUpdateDNSHost(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("DNS HOST records cannot be modified, use add instead of modify-or-add"));
+ goto cleanup;
+ }
+
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "host") < 0)
goto cleanup;
@@ -3249,6 +3291,13 @@ virNetworkDefUpdateDNSSrv(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("DNS SRV records cannot be modified, use add command instead of modify-or-add"));
+ goto cleanup;
+ }
+
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "srv") < 0)
goto cleanup;
@@ -3330,6 +3379,13 @@ virNetworkDefUpdateDNSTxt(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("DNS TXT records cannot be modified, use add command instead of modify-or-add"));
+ goto cleanup;
+ }
+
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "txt") < 0)
goto cleanup;
diff --git a/tools/virsh-network.c b/tools/virsh-network.c
index 6fcc7fd8ee..88eb673482 100644
--- a/tools/virsh-network.c
+++ b/tools/virsh-network.c
@@ -1215,7 +1215,8 @@ static const vshCmdOptDef opts_network_update[] = {
.positional = true,
.required = true,
.completer = virshNetworkUpdateCommandCompleter,
- .help = N_("type of update (add-first, add-last (add), delete, or modify)")
+ .help = N_("type of update (add-first, add-last (add), delete, modify,"
+ "modify-or-add, or modify-or-add-first)")
},
{.name = "section",
.type = VSH_OT_STRING,
@@ -1245,7 +1246,8 @@ static const vshCmdOptDef opts_network_update[] = {
VIR_ENUM_IMPL(virshNetworkUpdateCommand,
VIR_NETWORK_UPDATE_COMMAND_LAST,
- "none", "modify", "delete", "add-last", "add-first");
+ "none", "modify", "delete", "add-last", "add-first", "modify-or-add",
+ "modify-or-add-first");
VIR_ENUM_IMPL(virshNetworkSection,
VIR_NETWORK_SECTION_LAST,
--
2.39.2
11 months
[PATCH] docs: Fix broken links
by Han Han
For the links of drvinterface, drvnetwork, drvnwfilter, and Nagios-virt,
there are no alternative docs. Just remove them directly.
Signed-off-by: Han Han <hhan(a)redhat.com>
---
docs/apps.rst | 10 ++--------
docs/kbase/live_full_disk_backup.rst | 2 +-
docs/manpages/virt-sanlock-cleanup.rst | 2 +-
docs/manpages/virtinterfaced.rst | 1 -
docs/manpages/virtnetworkd.rst | 1 -
docs/manpages/virtnwfilterd.rst | 1 -
docs/manpages/virtstoraged.rst | 2 +-
docs/manpages/virtvzd.rst | 2 +-
docs/windows.rst | 2 +-
9 files changed, 7 insertions(+), 16 deletions(-)
diff --git a/docs/apps.rst b/docs/apps.rst
index b7d19e15d5..443c888c4d 100644
--- a/docs/apps.rst
+++ b/docs/apps.rst
@@ -35,7 +35,7 @@ virsh
machine to be cloned to form a new virtual machine. It automates
copying of data across to new disk images, and updates the UUID, MAC
address, and name in the configuration.
-`virt-df <https://people.redhat.com/rjones/virt-df/>`__
+`virt-df <https://libguestfs.org/virt-df.1.html>`__
Examine the utilization of each filesystem in a virtual machine from
the comfort of the host machine. This tool peeks into the guest disks
and determines how much space is used. It can cope with common Linux
@@ -235,13 +235,7 @@ Monitoring
The plugins provided by Guido G��nther allow to monitor various things
like network and block I/O with
`Munin <https://munin-monitoring.org/>`__.
-`Nagios-virt <https://people.redhat.com/rjones/nagios-virt/>`__
- Nagios-virt is a configuration tool to add monitoring of your
- virtualised domains to `Nagios <https://www.nagios.org/>`__. You can
- use this tool to either set up a new Nagios installation for your Xen
- or QEMU/KVM guests, or to integrate with your existing Nagios
- installation.
-`PCP <https://pcp.io/man/man1/pmdalibvirt.1.html>`__
+`PCP <https://man7.org/linux/man-pages/man1/pmdalibvirt.1.html>`__
The PCP libvirt PMDA (plugin) is part of the
`PCP <https://pcp.io/>`__ toolkit and provides hypervisor and guest
information and complete set of guest performance metrics. It
diff --git a/docs/kbase/live_full_disk_backup.rst b/docs/kbase/live_full_disk_backup.rst
index 562a9e87b0..f20169e314 100644
--- a/docs/kbase/live_full_disk_backup.rst
+++ b/docs/kbase/live_full_disk_backup.rst
@@ -12,7 +12,7 @@ space requirements. The following outlines an efficient method to do
that using libvirt's APIs. This method involves concepts: the notion of
`backing chains <https://libvirt.org/kbase/backing_chains.html>`_,
`QCOW2 overlays
-<https://qemu.readthedocs.io/en/latest/interop/live-block-operations.html#...>`_,
+<https://www.qemu.org/docs/master/interop/live-block-operations.html#disk-...>`_,
and a special operation called "active block-commit", which allows
live-merging an overlay disk image into its backing file.
diff --git a/docs/manpages/virt-sanlock-cleanup.rst b/docs/manpages/virt-sanlock-cleanup.rst
index 3ad70ce683..bf3ef6742b 100644
--- a/docs/manpages/virt-sanlock-cleanup.rst
+++ b/docs/manpages/virt-sanlock-cleanup.rst
@@ -75,5 +75,5 @@ PURPOSE
SEE ALSO
========
-virsh(1), `online instructions <https://libvirt.org/locking.html>`_,
+virsh(1), `online instructions <https://libvirt.org/kbase/locking.html>`_,
`https://libvirt.org/ <https://libvirt.org/>`_
diff --git a/docs/manpages/virtinterfaced.rst b/docs/manpages/virtinterfaced.rst
index 247a8c4009..ef63f4c278 100644
--- a/docs/manpages/virtinterfaced.rst
+++ b/docs/manpages/virtinterfaced.rst
@@ -211,4 +211,3 @@ SEE ALSO
virsh(1), libvirtd(8),
`https://libvirt.org/daemons.html <https://libvirt.org/daemons.html>`_,
-`https://libvirt.org/drvinterface.html <https://libvirt.org/drvinterface.html>`_
diff --git a/docs/manpages/virtnetworkd.rst b/docs/manpages/virtnetworkd.rst
index 22b3fc0f2d..3bd1dd3221 100644
--- a/docs/manpages/virtnetworkd.rst
+++ b/docs/manpages/virtnetworkd.rst
@@ -211,4 +211,3 @@ SEE ALSO
virsh(1), libvirtd(8),
`https://libvirt.org/daemons.html <https://libvirt.org/daemons.html>`_,
-`https://libvirt.org/drvnetwork.html <https://libvirt.org/drvnetwork.html>`_
diff --git a/docs/manpages/virtnwfilterd.rst b/docs/manpages/virtnwfilterd.rst
index b1fc45e7a2..1ec11c247f 100644
--- a/docs/manpages/virtnwfilterd.rst
+++ b/docs/manpages/virtnwfilterd.rst
@@ -211,4 +211,3 @@ SEE ALSO
virsh(1), libvirtd(8),
`https://libvirt.org/daemons.html <https://libvirt.org/daemons.html>`_,
-`https://libvirt.org/drvnwfilter.html <https://libvirt.org/drvnwfilter.html>`_
diff --git a/docs/manpages/virtstoraged.rst b/docs/manpages/virtstoraged.rst
index 70863282d1..fe966f3123 100644
--- a/docs/manpages/virtstoraged.rst
+++ b/docs/manpages/virtstoraged.rst
@@ -211,4 +211,4 @@ SEE ALSO
virsh(1), libvirtd(8),
`https://libvirt.org/daemons.html <https://libvirt.org/daemons.html>`_,
-`https://libvirt.org/drvstorage.html <https://libvirt.org/drvstorage.html>`_
+`https://libvirt.org/storage.html <https://libvirt.org/drvstorage.html>`_
diff --git a/docs/manpages/virtvzd.rst b/docs/manpages/virtvzd.rst
index aa44885d46..52aac2259c 100644
--- a/docs/manpages/virtvzd.rst
+++ b/docs/manpages/virtvzd.rst
@@ -211,4 +211,4 @@ SEE ALSO
virsh(1), libvirtd(8),
`https://libvirt.org/daemons.html <https://libvirt.org/daemons.html>`_,
-`https://libvirt.org/drvvz.html <https://libvirt.org/drvvz.html>`_
+`https://libvirt.org/drvopenvz.html <https://libvirt.org/drvopenvz.html>`_
diff --git a/docs/windows.rst b/docs/windows.rst
index b9aa5626cf..ee3caef41a 100644
--- a/docs/windows.rst
+++ b/docs/windows.rst
@@ -13,7 +13,7 @@ Installation packages
Users who need pre-built Windows DLLs of libvirt are advised to use the `Virt
Viewer <https://virt-manager.org>`__ pre-compiled `Windows MSI
-packages <https://virt-manager.org/download/>`__
+packages <https://virt-manager.org/download.html>`__
These installers include the libvirt, gtk-vnc and spice-gtk DLLs along with any
of their pre-requisite supporting DLLs, the virsh command line tool and the
--
2.45.1
11 months
[PATCH] virt-host-validate: Improve translatability of messages printed by 'virHostMsgCheck()'
by Peter Krempa
Move the word 'Checking' into the appropriate formatting strings and
mark all outstanding ones for translation.
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/637
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
tools/virt-host-validate-bhyve.c | 2 +-
tools/virt-host-validate-ch.c | 2 +-
tools/virt-host-validate-common.c | 18 +++++++++---------
tools/virt-host-validate-qemu.c | 4 ++--
4 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/tools/virt-host-validate-bhyve.c b/tools/virt-host-validate-bhyve.c
index db1cdd8e2c..adb5ae1717 100644
--- a/tools/virt-host-validate-bhyve.c
+++ b/tools/virt-host-validate-bhyve.c
@@ -28,7 +28,7 @@
#include "virt-host-validate-common.h"
#define MODULE_STATUS(mod, err_msg, err_code) \
- virHostMsgCheck("BHYVE", _("for %1$s module"), #mod); \
+ virHostMsgCheck("BHYVE", _("Checking for %1$s module"), #mod); \
if (mod ## _loaded) { \
virHostMsgPass(); \
} else { \
diff --git a/tools/virt-host-validate-ch.c b/tools/virt-host-validate-ch.c
index 9d235ed7ab..3f96423836 100644
--- a/tools/virt-host-validate-ch.c
+++ b/tools/virt-host-validate-ch.c
@@ -57,7 +57,7 @@ int virHostValidateCh(void)
}
if (hasVirtFlag) {
- virHostMsgCheck("CH", "%s", _("for hardware virtualization"));
+ virHostMsgCheck("CH", "%s", _("Checking for hardware virtualization"));
if (hasHwVirt) {
virHostMsgPass();
} else {
diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-common.c
index c8a23e2e99..58d8dbbaa1 100644
--- a/tools/virt-host-validate-common.c
+++ b/tools/virt-host-validate-common.c
@@ -66,7 +66,7 @@ void virHostMsgCheck(const char *prefix,
msg = g_strdup_vprintf(format, args);
va_end(args);
- fprintf(stdout, _("%1$6s: Checking %2$-60s: "), prefix, msg);
+ fprintf(stdout, "%1$6s: %2$-60s: ", prefix, msg);
}
static bool virHostMsgWantEscape(void)
@@ -137,7 +137,7 @@ int virHostValidateDeviceExists(const char *hvname,
virHostValidateLevel level,
const char *hint)
{
- virHostMsgCheck(hvname, "if device %s exists", dev_name);
+ virHostMsgCheck(hvname, _("Checking if device '%1$s' exists"), dev_name);
if (access(dev_name, F_OK) < 0) {
virHostMsgFail(level, "%s", hint);
@@ -154,7 +154,7 @@ int virHostValidateDeviceAccessible(const char *hvname,
virHostValidateLevel level,
const char *hint)
{
- virHostMsgCheck(hvname, "if device %s is accessible", dev_name);
+ virHostMsgCheck(hvname, _("Checking if device '%1$s' is accessible"), dev_name);
if (access(dev_name, R_OK|W_OK) < 0) {
virHostMsgFail(level, "%s", hint);
@@ -173,7 +173,7 @@ int virHostValidateNamespace(const char *hvname,
{
char nspath[100];
- virHostMsgCheck(hvname, "for namespace %s", ns_name);
+ virHostMsgCheck(hvname, _("Checking for namespace '%1$s'"), ns_name);
g_snprintf(nspath, sizeof(nspath), "/proc/self/ns/%s", ns_name);
@@ -256,7 +256,7 @@ int virHostValidateLinuxKernel(const char *hvname,
uname(&uts);
- virHostMsgCheck(hvname, _("for Linux >= %1$d.%2$d.%3$d"),
+ virHostMsgCheck(hvname, _("Checking for Linux >= %1$d.%2$d.%3$d"),
((version >> 16) & 0xff),
((version >> 8) & 0xff),
(version & 0xff));
@@ -302,7 +302,7 @@ int virHostValidateCGroupControllers(const char *hvname,
if (!(controllers & flag))
continue;
- virHostMsgCheck(hvname, "for cgroup '%s' controller support", cg_name);
+ virHostMsgCheck(hvname, _("Checking for cgroup '%1$s' controller support"), cg_name);
if (!virCgroupHasController(group, i)) {
ret = VIR_HOST_VALIDATE_FAILURE(level);
@@ -337,7 +337,7 @@ int virHostValidateIOMMU(const char *hvname,
struct dirent *dent;
int rc;
- virHostMsgCheck(hvname, "%s", _("for device assignment IOMMU support"));
+ virHostMsgCheck(hvname, "%s", _("Checking for device assignment IOMMU support"));
flags = virHostValidateGetCPUFlags();
@@ -423,7 +423,7 @@ int virHostValidateIOMMU(const char *hvname,
if (!S_ISDIR(sb.st_mode))
return 0;
- virHostMsgCheck(hvname, "%s", _("if IOMMU is enabled by kernel"));
+ virHostMsgCheck(hvname, "%s", _("Checking if IOMMU is enabled by kernel"));
if (sb.st_nlink <= 2) {
if (bootarg)
virHostMsgFail(level,
@@ -483,7 +483,7 @@ int virHostValidateSecureGuests(const char *hvname,
else if (flags && virBitmapIsBitSet(flags, VIR_HOST_VALIDATE_CPU_FLAG_SEV))
hasAMDSev = true;
- virHostMsgCheck(hvname, "%s", _("for secure guest support"));
+ virHostMsgCheck(hvname, "%s", _("Checking for secure guest support"));
if (ARCH_IS_S390(arch)) {
if (hasFac158) {
if (!virFileIsDir("/sys/firmware/uv")) {
diff --git a/tools/virt-host-validate-qemu.c b/tools/virt-host-validate-qemu.c
index 3eeee516d3..b685fa01ba 100644
--- a/tools/virt-host-validate-qemu.c
+++ b/tools/virt-host-validate-qemu.c
@@ -64,7 +64,7 @@ int virHostValidateQEMU(void)
}
if (hasVirtFlag) {
- virHostMsgCheck("QEMU", "%s", _("for hardware virtualization"));
+ virHostMsgCheck("QEMU", "%s", _("Checking for hardware virtualization"));
if (hasHwVirt) {
virHostMsgPass();
} else {
@@ -86,7 +86,7 @@ int virHostValidateQEMU(void)
}
if (arch == VIR_ARCH_PPC64 || arch == VIR_ARCH_PPC64LE) {
- virHostMsgCheck("QEMU", "%s", _("for PowerPC KVM module loaded"));
+ virHostMsgCheck("QEMU", "%s", _("Checking for PowerPC KVM module loaded"));
if (!virHostKernelModuleIsLoaded("kvm_hv"))
virHostMsgFail(VIR_HOST_VALIDATE_WARN,
--
2.45.0
11 months
[PATCH] Сheck snapshot disk is not NULL when searching it in the VM config
by Fima Shevrin
When creating a snapshot of a VM with multiple hard disks,
the snapshot takes into account the presence of all disks
in the system. If, over time, one of the disks is deleted,
the snapshot will continue to store knowledge of the deleted disk.
This results in the fact that at the moment of deleting the snapshot,
at the validation stage, a disk from the snapshot will be searched which
is not in the VM configuration. As a result, vmdisk variable will
be equal to NULL. Dereferencing a null pointer at the time of calling
virStorageSourceIsSameLocation(vmdisk->src, disk->src) will result in SIGSEGV.
Signed-off-by: Fima Shevrin <efim.shevrin(a)virtuozzo.com>
---
src/qemu/qemu_snapshot.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 09ec959f10..bf93cd485e 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -3806,7 +3806,7 @@ qemuSnapshotDeleteValidate(virDomainObj *vm,
vmdisk = qemuDomainDiskByName(vm->def, snapDisk->name);
disk = qemuDomainDiskByName(snapdef->parent.dom, snapDisk->name);
- if (!virStorageSourceIsSameLocation(vmdisk->src, disk->src)) {
+ if (vmdisk != NULL && !virStorageSourceIsSameLocation(vmdisk->src, disk->src)) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("disk image '%1$s' for internal snapshot '%2$s' is not the same as disk image currently used by VM"),
snapDisk->name, snap->def->name);
--
2.34.1
11 months
Plans for 10.4.0 release (freeze on Tuesday 28 May)
by Jiri Denemark
We are getting close to 10.4.0 release of libvirt. To aim for the
release on Monday 03 Jun I suggest entering the freeze on Tuesday 28
May and tagging RC2 on Thursday 30 May.
I hope this works for everyone.
Jirka
11 months
[PATCH] rpc: avoid leak of GSource in use for interrupting main loop
by Daniel P. Berrangé
We never release the reference on the GSource created for
interrupting the main loop, nor do we remove it from the
main context if our thread is woken up prior to the wakeup
callback firing.
This can result in a leak of GSource objects, along with an
ever growing list of GSources attached to the main context,
which will gradually slow down execution of the loop, as
several operations are O(N) for the number of attached GSource
objects.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/rpc/virnetclient.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 147b0d661a..6d424eb599 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -1946,7 +1946,7 @@ static int virNetClientIO(virNetClient *client,
/* Check to see if another thread is dispatching */
if (client->haveTheBuck) {
/* Force other thread to wakeup from poll */
- GSource *wakeup = g_idle_source_new();
+ g_autoptr(GSource) wakeup = g_idle_source_new();
g_source_set_callback(wakeup, virNetClientIOWakeup, client->eventLoop, NULL);
g_source_attach(wakeup, client->eventCtx);
@@ -1968,6 +1968,7 @@ static int virNetClientIO(virNetClient *client,
return -1;
}
+ g_source_destroy(wakeup);
VIR_DEBUG("Woken up from sleep head=%p call=%p",
client->waitDispatch, thiscall);
/* Three reasons we can be woken up
--
2.43.0
11 months