Compare commits

...

2 Commits

Author SHA1 Message Date
Benjamin Taubmann
a39dd25715 Extend libvirt-guests to shutdown only persistent VMs
At the moment, there is no configuration option for the libvirt-guests
service that allows users to define that only persistent virtual machines
should be shutdown on host shutdown.

Currently, the service config allows to choose between two ON_SHUTDOWN
actions that are executed on running virtual machines when the host goes
down: shutdown, suspend.
The ON_SHUTDOWN action should be orthogonal to the type of the virtual
machine. However, the existing implementation, does not suspend
transient virtual machines.
This is the matrix of actions that is executed on virtual machines based
on the configured ON_SHUTDOWN action and the type of a virtual machine.

         | persistent | transient
shutdown | shutdown   | shutdown (what we want to change)
suspend  | suspend    | nothing

Add config option PERSISTENT_ONLY to libvirt-guests config that allows
users to define if the ON_SHUTDOWN action should be applied only on
persistent virtual machines. PERSISTENT_ONLY can be set to true, false,
default. The default option will implement the already existing logic.

Case 1: PERSISTENT_ONLY=default
         | persistent | transient
shutdown | shutdown   | shutdown
suspend  | suspend    | nothing

Case 2: PERSISTENT_ONLY=true
         | persistent | transient
shutdown | shutdown   | nothing
suspend  | suspend    | nothing

Case 3: PERSISTENT_ONLY=false
         | persistent | transient
shutdown | shutdown   | shutdown
suspend  | suspend    | suspend

Signed-off-by: Benjamin Taubmann <benjamin.taubmann@nutanix.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2024-04-04 09:10:00 +02:00
Marc Hartmayer
5138dd2478 node_device_conf: virNodeDeviceGetSCSITargetCaps: fix memory leak
Make sure the old value in `scsi_target->wwpn` is free'd before replacing it.
While at it, simplify the code.

==9104== 38 bytes in 2 blocks are definitely lost in loss record 1,943 of 3,250
==9104==    at 0x483B8C0: malloc (vg_replace_malloc.c:442)
==9104==    by 0x4DFB69B: g_malloc (gmem.c:130)
==9104==    by 0x4E1921D: g_strdup (gstrfuncs.c:363)
==9104==    by 0x495D60B: g_strdup_inline (gstrfuncs.h:321)
==9104==    by 0x495D60B: virFCReadRportValue (virfcp.c:62)
==9104==    by 0x4A5F5CB: virNodeDeviceGetSCSITargetCaps (node_device_conf.c:2914)
==9104==    by 0xBF62529: udevProcessSCSITarget (node_device_udev.c:657)
==9104==    by 0xBF62529: udevGetDeviceDetails (node_device_udev.c:1406)
==9104==    by 0xBF62529: udevAddOneDevice (node_device_udev.c:1563)
==9104==    by 0xBF639B5: udevProcessDeviceListEntry (node_device_udev.c:1637)
==9104==    by 0xBF639B5: udevEnumerateDevices (node_device_udev.c:1691)
==9104==    by 0xBF639B5: nodeStateInitializeEnumerate (node_device_udev.c:2009)
==9104==    by 0x49BDBFD: virThreadHelper (virthread.c:256)
==9104==    by 0x5242069: start_thread (in /usr/lib64/libc.so.6)

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2024-04-04 09:05:11 +02:00
3 changed files with 63 additions and 25 deletions

View File

@ -113,6 +113,28 @@ The following variables are supported:
this requires guest agent with support for time synchronization this requires guest agent with support for time synchronization
running in the guest. By default, this functionality is turned off. running in the guest. By default, this functionality is turned off.
- PERSISTENT_ONLY=default
Defines what type of guest virtual machine ON_SHUTDOWN action is applied to
* default
This implements the already existing default behavior.
If ON_SHUTDOWN action is shutdown, transient and persistent guest virtual
machines are asked to shutdown.
If ON_SHUTDOWN action is suspend, only persistent guest virtual machines
are asked to suspend.
* true
ON_SHUTDOWN action is executed only on persistent guest virtual machines.
Transient guest virtual machines are not affected.
* false
ON_SHUTDOWN action is executed on persistent and transient guest virtual
machines.
BUGS BUGS
==== ====

View File

@ -2894,9 +2894,9 @@ int
virNodeDeviceGetSCSITargetCaps(const char *sysfsPath, virNodeDeviceGetSCSITargetCaps(const char *sysfsPath,
virNodeDevCapSCSITarget *scsi_target) virNodeDevCapSCSITarget *scsi_target)
{ {
int ret = -1;
g_autofree char *dir = NULL; g_autofree char *dir = NULL;
g_autofree char *rport = NULL; g_autofree char *rport = NULL;
g_autofree char *wwpn = NULL;
VIR_DEBUG("Checking if '%s' is an FC remote port", scsi_target->name); VIR_DEBUG("Checking if '%s' is an FC remote port", scsi_target->name);
@ -2906,28 +2906,21 @@ virNodeDeviceGetSCSITargetCaps(const char *sysfsPath,
rport = g_path_get_basename(dir); rport = g_path_get_basename(dir);
if (!virFCIsCapableRport(rport)) if (!virFCIsCapableRport(rport))
goto cleanup; return -1;
if (virFCReadRportValue(rport, "port_name",
&wwpn) < 0) {
VIR_WARN("Failed to read port_name for '%s'", rport);
return -1;
}
VIR_FREE(scsi_target->rport); VIR_FREE(scsi_target->rport);
scsi_target->rport = g_steal_pointer(&rport); scsi_target->rport = g_steal_pointer(&rport);
if (virFCReadRportValue(scsi_target->rport, "port_name", VIR_FREE(scsi_target->wwpn);
&scsi_target->wwpn) < 0) { scsi_target->wwpn = g_steal_pointer(&wwpn);
VIR_WARN("Failed to read port_name for '%s'", scsi_target->rport);
goto cleanup;
}
scsi_target->flags |= VIR_NODE_DEV_CAP_FLAG_FC_RPORT; scsi_target->flags |= VIR_NODE_DEV_CAP_FLAG_FC_RPORT;
ret = 0; return 0;
cleanup:
if (ret < 0) {
VIR_FREE(scsi_target->rport);
VIR_FREE(scsi_target->wwpn);
scsi_target->flags &= ~VIR_NODE_DEV_CAP_FLAG_FC_RPORT;
}
return ret;
} }

View File

@ -38,6 +38,7 @@ PARALLEL_SHUTDOWN=0
START_DELAY=0 START_DELAY=0
BYPASS_CACHE=0 BYPASS_CACHE=0
SYNC_TIME=0 SYNC_TIME=0
PERSISTENT_ONLY="default"
test -f "$initconfdir"/libvirt-guests && test -f "$initconfdir"/libvirt-guests &&
. "$initconfdir"/libvirt-guests . "$initconfdir"/libvirt-guests
@ -438,14 +439,16 @@ shutdown_guests_parallel()
# stop # stop
# Shutdown or save guests on the configured uris # Shutdown or save guests on the configured uris
stop() { stop() {
local suspending="true"
local uri= local uri=
local action="suspend"
local persistent_only="default"
# last stop was not followed by start # last stop was not followed by start
[ -f "$LISTFILE" ] && return 0 [ -f "$LISTFILE" ] && return 0
if [ "x$ON_SHUTDOWN" = xshutdown ]; then if [ "x$ON_SHUTDOWN" = xshutdown ]; then
suspending="false" action="shutdown"
if [ $SHUTDOWN_TIMEOUT -lt 0 ]; then if [ $SHUTDOWN_TIMEOUT -lt 0 ]; then
gettext "SHUTDOWN_TIMEOUT must be equal or greater than 0" gettext "SHUTDOWN_TIMEOUT must be equal or greater than 0"
echo echo
@ -454,6 +457,22 @@ stop() {
fi fi
fi fi
case "x$PERSISTENT_ONLY" in
xtrue)
persistent_only="true"
;;
xfalse)
persistent_only="false"
;;
*)
if [ "x$action" = xshutdown ]; then
persistent_only="false"
elif [ "x$action" = xsuspend ]; then
persistent_only="true"
fi
;;
esac
: >"$LISTFILE" : >"$LISTFILE"
set -f set -f
for uri in $URIS; do for uri in $URIS; do
@ -478,7 +497,7 @@ stop() {
echo echo
fi fi
if "$suspending"; then if "$persistent_only"; then
local transient="$(list_guests "$uri" "--transient")" local transient="$(list_guests "$uri" "--transient")"
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
local empty="true" local empty="true"
@ -486,7 +505,11 @@ stop() {
for uuid in $transient; do for uuid in $transient; do
if "$empty"; then if "$empty"; then
eval_gettext "Not suspending transient guests on URI: \$uri: " if [ "x$action" = xsuspend ]; then
eval_gettext "Not suspending transient guests on URI: \$uri: "
else
eval_gettext "Not shutting down transient guests on URI: \$uri: "
fi
empty="false" empty="false"
else else
printf ", " printf ", "
@ -520,19 +543,19 @@ stop() {
if [ -s "$LISTFILE" ]; then if [ -s "$LISTFILE" ]; then
while read uri list; do while read uri list; do
if "$suspending"; then if [ "x$action" = xsuspend ]; then
eval_gettext "Suspending guests on \$uri URI..."; echo eval_gettext "Suspending guests on \$uri URI..."; echo
else else
eval_gettext "Shutting down guests on \$uri URI..."; echo eval_gettext "Shutting down guests on \$uri URI..."; echo
fi fi
if [ "$PARALLEL_SHUTDOWN" -gt 1 ] && if [ "$PARALLEL_SHUTDOWN" -gt 1 ] &&
! "$suspending"; then [ "x$action" = xshutdown ]; then
shutdown_guests_parallel "$uri" "$list" shutdown_guests_parallel "$uri" "$list"
else else
local guest= local guest=
for guest in $list; do for guest in $list; do
if "$suspending"; then if [ "x$action" = xsuspend ]; then
suspend_guest "$uri" "$guest" suspend_guest "$uri" "$guest"
else else
shutdown_guest "$uri" "$guest" shutdown_guest "$uri" "$guest"