[PATCH 0/6] Improve setting of logging with 'virt-admin' when daemon uses auto-shutdown

Allow setting of the timeout so that users can bypass it when they are setting runtime-logging. Update the docs to mention the caveat and suggest the bypass. Peter Krempa (6): virnetdaemon: Extract autoShutdownTimer operations from virNetDaemonRun virNetDaemonAutoShutdown: Allow live update of shutdown timeout scripts: apibuild: Improve error when API is missing from symbol file admin: Introduce virAdmConnectSetDaemonTimeout virt-admin: Introduce 'daemon-timeout' kbase: debuglogs: Add a note about auto-shutdown of daemons docs/kbase/debuglogs.rst | 20 +++++ docs/manpages/virt-admin.rst | 12 +++ include/libvirt/libvirt-admin.h | 4 + scripts/apibuild.py | 2 + src/admin/admin_protocol.x | 12 ++- src/admin/admin_server_dispatch.c | 12 +++ src/admin/libvirt-admin.c | 34 ++++++++ src/admin/libvirt_admin_public.syms | 5 ++ src/admin_protocol-structs | 5 ++ src/locking/lock_daemon.c | 5 +- src/logging/log_daemon.c | 5 +- src/remote/remote_daemon.c | 4 +- src/rpc/virnetdaemon.c | 127 ++++++++++++++++++---------- src/rpc/virnetdaemon.h | 4 +- tools/virt-admin.c | 45 ++++++++++ 15 files changed, 240 insertions(+), 56 deletions(-) -- 2.36.1

Introduce 'virNetDaemonShutdownTimerRegister' and 'virNetDaemonShutdownTimerUpdate' to aggregate the code to deal with the auto-shutdown timer. The code is also placed so that it can be called from 'virNetDaemonAutoShutdown' which involved the move of 'virNetDaemonAutoShutdownTimer'. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/rpc/virnetdaemon.c | 108 +++++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 42 deletions(-) diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c index 1f32bae35f..7bf27eed9d 100644 --- a/src/rpc/virnetdaemon.c +++ b/src/rpc/virnetdaemon.c @@ -77,6 +77,8 @@ struct _virNetDaemon { bool execRestart; unsigned int autoShutdownTimeout; + int autoShutdownTimerID; + bool autoShutdownTimerActive; size_t autoShutdownInhibitions; int autoShutdownInhibitFd; }; @@ -153,6 +155,8 @@ virNetDaemonNew(void) if (virEventRegisterDefaultImpl() < 0) goto error; + dmn->autoShutdownTimerID = -1; + #ifndef WIN32 memset(&sig_action, 0, sizeof(sig_action)); sig_action.sa_handler = SIG_IGN; @@ -403,6 +407,65 @@ virNetDaemonIsPrivileged(virNetDaemon *dmn) } +static void +virNetDaemonAutoShutdownTimer(int timerid G_GNUC_UNUSED, + void *opaque) +{ + virNetDaemon *dmn = opaque; + VIR_LOCK_GUARD lock = virObjectLockGuard(dmn); + + if (!dmn->autoShutdownInhibitions) { + VIR_DEBUG("Automatic shutdown triggered"); + dmn->quit = true; + } +} + + +static int +virNetDaemonShutdownTimerRegister(virNetDaemon *dmn) +{ + if (dmn->autoShutdownTimeout == 0) + return 0; + + if ((dmn->autoShutdownTimerID = virEventAddTimeout(-1, + virNetDaemonAutoShutdownTimer, + dmn, NULL)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Failed to register shutdown timeout")); + return -1; + } + + return 0; +} + + +static void +virNetDaemonShutdownTimerUpdate(virNetDaemon *dmn) +{ + if (dmn->autoShutdownTimeout == 0) + return; + + /* A shutdown timeout is specified, so check + * if any drivers have active state, if not + * shutdown after timeout seconds + */ + if (dmn->autoShutdownTimerActive) { + if (virNetDaemonHasClients(dmn)) { + VIR_DEBUG("Deactivating shutdown timer %d", dmn->autoShutdownTimerID); + virEventUpdateTimeout(dmn->autoShutdownTimerID, -1); + dmn->autoShutdownTimerActive = false; + } + } else { + if (!virNetDaemonHasClients(dmn)) { + VIR_DEBUG("Activating shutdown timer %d", dmn->autoShutdownTimerID); + virEventUpdateTimeout(dmn->autoShutdownTimerID, + dmn->autoShutdownTimeout * 1000); + dmn->autoShutdownTimerActive = true; + } + } +} + + void virNetDaemonAutoShutdown(virNetDaemon *dmn, unsigned int timeout) @@ -657,19 +720,6 @@ virNetDaemonAddSignalHandler(virNetDaemon *dmn G_GNUC_UNUSED, #endif /* WIN32 */ -static void -virNetDaemonAutoShutdownTimer(int timerid G_GNUC_UNUSED, - void *opaque) -{ - virNetDaemon *dmn = opaque; - VIR_LOCK_GUARD lock = virObjectLockGuard(dmn); - - if (!dmn->autoShutdownInhibitions) { - VIR_DEBUG("Automatic shutdown triggered"); - dmn->quit = true; - } -} - static int daemonServerUpdateServices(void *payload, const char *key G_GNUC_UNUSED, @@ -743,11 +793,10 @@ virNetDaemonFinishTimer(int timerid G_GNUC_UNUSED, dmn->finished = true; } + void virNetDaemonRun(virNetDaemon *dmn) { - int timerid = -1; - bool timerActive = false; virThread shutdownThread; virObjectLock(dmn); @@ -763,14 +812,8 @@ virNetDaemonRun(virNetDaemon *dmn) dmn->finished = false; dmn->graceful = false; - if (dmn->autoShutdownTimeout && - (timerid = virEventAddTimeout(-1, - virNetDaemonAutoShutdownTimer, - dmn, NULL)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Failed to register shutdown timeout")); + if (virNetDaemonShutdownTimerRegister(dmn) < 0) goto cleanup; - } /* We are accepting connections now. Notify systemd * so it can start dependent services. */ @@ -778,26 +821,7 @@ virNetDaemonRun(virNetDaemon *dmn) VIR_DEBUG("dmn=%p quit=%d", dmn, dmn->quit); while (!dmn->finished) { - /* A shutdown timeout is specified, so check - * if any drivers have active state, if not - * shutdown after timeout seconds - */ - if (dmn->autoShutdownTimeout) { - if (timerActive) { - if (virNetDaemonHasClients(dmn)) { - VIR_DEBUG("Deactivating shutdown timer %d", timerid); - virEventUpdateTimeout(timerid, -1); - timerActive = false; - } - } else { - if (!virNetDaemonHasClients(dmn)) { - VIR_DEBUG("Activating shutdown timer %d", timerid); - virEventUpdateTimeout(timerid, - dmn->autoShutdownTimeout * 1000); - timerActive = true; - } - } - } + virNetDaemonShutdownTimerUpdate(dmn); virObjectUnlock(dmn); if (virEventRunDefaultImpl() < 0) { -- 2.36.1

Modify the code so that calling 'virNetDaemonAutoShutdown' will update the auto shutdown timeout also for running daemons. This involves changing the logic when to do the update of the timer so that it can be called from both when the daemon is not yet runnign and when doing a live update. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/locking/lock_daemon.c | 5 ++--- src/logging/log_daemon.c | 5 ++--- src/remote/remote_daemon.c | 4 ++-- src/rpc/virnetdaemon.c | 29 +++++++++++++++++++++-------- src/rpc/virnetdaemon.h | 4 ++-- 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c index 75f6c708db..59c110f62b 100644 --- a/src/locking/lock_daemon.c +++ b/src/locking/lock_daemon.c @@ -1051,9 +1051,8 @@ int main(int argc, char **argv) { } if (timeout > 0) { - VIR_DEBUG("Registering shutdown timeout %d", timeout); - virNetDaemonAutoShutdown(lockDaemon->dmn, - timeout); + if (virNetDaemonAutoShutdown(lockDaemon->dmn, timeout) < 0) + goto cleanup; } if ((virLockDaemonSetupSignals(lockDaemon->dmn)) < 0) { diff --git a/src/logging/log_daemon.c b/src/logging/log_daemon.c index 8ab334ff6d..8345d31a8c 100644 --- a/src/logging/log_daemon.c +++ b/src/logging/log_daemon.c @@ -859,9 +859,8 @@ int main(int argc, char **argv) { } if (timeout > 0) { - VIR_DEBUG("Registering shutdown timeout %d", timeout); - virNetDaemonAutoShutdown(logDaemon->dmn, - timeout); + if (virNetDaemonAutoShutdown(logDaemon->dmn, timeout) < 0) + return -1; } if ((virLogDaemonSetupSignals(logDaemon->dmn)) < 0) { diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index b8ecc51758..9ad71c37db 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -1126,8 +1126,8 @@ int main(int argc, char **argv) { } if (timeout > 0) { - VIR_DEBUG("Registering shutdown timeout %d", timeout); - virNetDaemonAutoShutdown(dmn, timeout); + if (virNetDaemonAutoShutdown(dmn, timeout) < 0) + goto cleanup; } if ((daemonSetupSignals(dmn)) < 0) { diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c index 7bf27eed9d..84af1adc06 100644 --- a/src/rpc/virnetdaemon.c +++ b/src/rpc/virnetdaemon.c @@ -75,6 +75,7 @@ struct _virNetDaemon { bool finished; bool graceful; bool execRestart; + bool running; /* the daemon has reached the running phase */ unsigned int autoShutdownTimeout; int autoShutdownTimerID; @@ -424,7 +425,7 @@ virNetDaemonAutoShutdownTimer(int timerid G_GNUC_UNUSED, static int virNetDaemonShutdownTimerRegister(virNetDaemon *dmn) { - if (dmn->autoShutdownTimeout == 0) + if (dmn->autoShutdownTimerID != -1) return 0; if ((dmn->autoShutdownTimerID = virEventAddTimeout(-1, @@ -442,7 +443,7 @@ virNetDaemonShutdownTimerRegister(virNetDaemon *dmn) static void virNetDaemonShutdownTimerUpdate(virNetDaemon *dmn) { - if (dmn->autoShutdownTimeout == 0) + if (dmn->autoShutdownTimerID == -1) return; /* A shutdown timeout is specified, so check @@ -450,13 +451,15 @@ virNetDaemonShutdownTimerUpdate(virNetDaemon *dmn) * shutdown after timeout seconds */ if (dmn->autoShutdownTimerActive) { - if (virNetDaemonHasClients(dmn)) { + if (virNetDaemonHasClients(dmn) || + dmn->autoShutdownTimeout == 0) { VIR_DEBUG("Deactivating shutdown timer %d", dmn->autoShutdownTimerID); virEventUpdateTimeout(dmn->autoShutdownTimerID, -1); dmn->autoShutdownTimerActive = false; } } else { - if (!virNetDaemonHasClients(dmn)) { + if (!virNetDaemonHasClients(dmn) || + dmn->autoShutdownTimeout != 0) { VIR_DEBUG("Activating shutdown timer %d", dmn->autoShutdownTimerID); virEventUpdateTimeout(dmn->autoShutdownTimerID, dmn->autoShutdownTimeout * 1000); @@ -466,13 +469,25 @@ virNetDaemonShutdownTimerUpdate(virNetDaemon *dmn) } -void +int virNetDaemonAutoShutdown(virNetDaemon *dmn, unsigned int timeout) { VIR_LOCK_GUARD lock = virObjectLockGuard(dmn); + VIR_DEBUG("Registering shutdown timeout %u", timeout); + + if (timeout > 0) { + if (virNetDaemonShutdownTimerRegister(dmn) < 0) + return -1; + } + dmn->autoShutdownTimeout = timeout; + + if (dmn->running) + virNetDaemonShutdownTimerUpdate(dmn); + + return 0; } @@ -811,9 +826,7 @@ virNetDaemonRun(virNetDaemon *dmn) dmn->finishTimer = -1; dmn->finished = false; dmn->graceful = false; - - if (virNetDaemonShutdownTimerRegister(dmn) < 0) - goto cleanup; + dmn->running = true; /* We are accepting connections now. Notify systemd * so it can start dependent services. */ diff --git a/src/rpc/virnetdaemon.h b/src/rpc/virnetdaemon.h index f91b59a4fd..bfee155a4b 100644 --- a/src/rpc/virnetdaemon.h +++ b/src/rpc/virnetdaemon.h @@ -49,8 +49,8 @@ virJSONValue *virNetDaemonPreExecRestart(virNetDaemon *dmn); bool virNetDaemonIsPrivileged(virNetDaemon *dmn); -void virNetDaemonAutoShutdown(virNetDaemon *dmn, - unsigned int timeout); +int virNetDaemonAutoShutdown(virNetDaemon *dmn, + unsigned int timeout) G_GNUC_WARN_UNUSED_RESULT; void virNetDaemonAddShutdownInhibition(virNetDaemon *dmn); void virNetDaemonRemoveShutdownInhibition(virNetDaemon *dmn); -- 2.36.1

On 6/13/22 15:56, Peter Krempa wrote:
Modify the code so that calling 'virNetDaemonAutoShutdown' will update the auto shutdown timeout also for running daemons.
This involves changing the logic when to do the update of the timer so that it can be called from both when the daemon is not yet runnign and when doing a live update.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/locking/lock_daemon.c | 5 ++--- src/logging/log_daemon.c | 5 ++--- src/remote/remote_daemon.c | 4 ++-- src/rpc/virnetdaemon.c | 29 +++++++++++++++++++++-------- src/rpc/virnetdaemon.h | 4 ++-- 5 files changed, 29 insertions(+), 18 deletions(-)
diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c index 7bf27eed9d..84af1adc06 100644 --- a/src/rpc/virnetdaemon.c +++ b/src/rpc/virnetdaemon.c @@ -75,6 +75,7 @@ struct _virNetDaemon { bool finished; bool graceful; bool execRestart; + bool running; /* the daemon has reached the running phase */
unsigned int autoShutdownTimeout; int autoShutdownTimerID; @@ -424,7 +425,7 @@ virNetDaemonAutoShutdownTimer(int timerid G_GNUC_UNUSED, static int virNetDaemonShutdownTimerRegister(virNetDaemon *dmn) { - if (dmn->autoShutdownTimeout == 0) + if (dmn->autoShutdownTimerID != -1) return 0;
if ((dmn->autoShutdownTimerID = virEventAddTimeout(-1, @@ -442,7 +443,7 @@ virNetDaemonShutdownTimerRegister(virNetDaemon *dmn) static void virNetDaemonShutdownTimerUpdate(virNetDaemon *dmn) { - if (dmn->autoShutdownTimeout == 0) + if (dmn->autoShutdownTimerID == -1) return;
/* A shutdown timeout is specified, so check @@ -450,13 +451,15 @@ virNetDaemonShutdownTimerUpdate(virNetDaemon *dmn) * shutdown after timeout seconds */ if (dmn->autoShutdownTimerActive) { - if (virNetDaemonHasClients(dmn)) { + if (virNetDaemonHasClients(dmn) || + dmn->autoShutdownTimeout == 0) {
Here the logical OR makes sense, because either of the conditions has to lead to timer deactivation, however ...
VIR_DEBUG("Deactivating shutdown timer %d", dmn->autoShutdownTimerID); virEventUpdateTimeout(dmn->autoShutdownTimerID, -1); dmn->autoShutdownTimerActive = false; } } else { - if (!virNetDaemonHasClients(dmn)) { + if (!virNetDaemonHasClients(dmn) || + dmn->autoShutdownTimeout != 0) {
... here both conditions have to be met. Otherwise setting timeout to 0 and disconnecting the last client will lead to immediate quit of the daemon. Michal

Improve: KeyError: 'virAdmConnectSetDaemonTimeout' to Exception: Missing symbol file entry for 'virAdmConnectSetDaemonTimeout' Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- scripts/apibuild.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/apibuild.py b/scripts/apibuild.py index 23a66734ac..c232b4e2c8 100755 --- a/scripts/apibuild.py +++ b/scripts/apibuild.py @@ -2405,6 +2405,8 @@ class docBuilder: # NB: this is consumed by a regex in 'getAPIFilenames' in hvsupport.pl if id.type == "function": + if name not in self.versions: + raise Exception("Missing symbol file entry for '%s'" % name) ver = self.versions[name] if ver is None: raise Exception("Missing version for '%s'" % name) -- 2.36.1

Use of the admin APIs to modify logging temporarily has a rather serious deficiency when the daemon whose config is being changed is using auto-shutdown (default with socket-activated deployments) as the configuration is discarded if there is no client or VM/other object blocking auto shutdown. This API allows users to disable/postpone shutdown timeout so that the configuration doesn't change under their hands. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- include/libvirt/libvirt-admin.h | 4 ++++ src/admin/admin_protocol.x | 12 +++++++++- src/admin/admin_server_dispatch.c | 12 ++++++++++ src/admin/libvirt-admin.c | 34 +++++++++++++++++++++++++++++ src/admin/libvirt_admin_public.syms | 5 +++++ src/admin_protocol-structs | 5 +++++ 6 files changed, 71 insertions(+), 1 deletion(-) diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h index 8533658932..ae4703f89b 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -480,6 +480,10 @@ int virAdmConnectSetLoggingFilters(virAdmConnectPtr conn, const char *filters, unsigned int flags); +int virAdmConnectSetDaemonTimeout(virAdmConnectPtr conn, + unsigned int timeout, + unsigned int flags); + # ifdef __cplusplus } # endif diff --git a/src/admin/admin_protocol.x b/src/admin/admin_protocol.x index 7dc6724032..f3130efd2d 100644 --- a/src/admin/admin_protocol.x +++ b/src/admin/admin_protocol.x @@ -214,6 +214,11 @@ struct admin_connect_set_logging_filters_args { unsigned int flags; }; +struct admin_connect_set_daemon_timeout_args { + unsigned int timeout; + unsigned int flags; +}; + /* Define the program number, protocol version and procedure numbers here. */ const ADMIN_PROGRAM = 0x06900690; const ADMIN_PROTOCOL_VERSION = 1; @@ -324,5 +329,10 @@ enum admin_procedure { /** * @generate: both */ - ADMIN_PROC_SERVER_UPDATE_TLS_FILES = 18 + ADMIN_PROC_SERVER_UPDATE_TLS_FILES = 18, + + /** + * @generate: both + */ + ADMIN_PROC_CONNECT_SET_DAEMON_TIMEOUT = 19 }; diff --git a/src/admin/admin_server_dispatch.c b/src/admin/admin_server_dispatch.c index 893c7f1de2..8ab243c8eb 100644 --- a/src/admin/admin_server_dispatch.c +++ b/src/admin/admin_server_dispatch.c @@ -466,6 +466,18 @@ adminConnectSetLoggingFilters(virNetDaemon *dmn G_GNUC_UNUSED, return virLogSetFilters(filters); } + +static int +adminConnectSetDaemonTimeout(virNetDaemon *dmn, + unsigned int timeout, + unsigned int flags) +{ + virCheckFlags(0, -1); + + return virNetDaemonAutoShutdown(dmn, timeout); +} + + static int adminDispatchConnectGetLoggingOutputs(virNetServer *server G_GNUC_UNUSED, virNetServerClient *client G_GNUC_UNUSED, diff --git a/src/admin/libvirt-admin.c b/src/admin/libvirt-admin.c index 5f64784a13..4b5d615e9d 100644 --- a/src/admin/libvirt-admin.c +++ b/src/admin/libvirt-admin.c @@ -1329,3 +1329,37 @@ virAdmConnectSetLoggingFilters(virAdmConnectPtr conn, virDispatchError(NULL); return -1; } + + +/** + * virAdmConnectSetDaemonTimeout: + * @conn: pointer to an active admin connection + * @timeout: timeout to set in seconds (0 disables timeout) + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Reconfigure the existing timeout of the daemon to @timeout. Setting timeout + * to 0 disables the daemon timeout. + * + * Returns 0 on success, -1 on error. + * + * Since: 8.5.0 + */ +int +virAdmConnectSetDaemonTimeout(virAdmConnectPtr conn, + unsigned int timeout, + unsigned int flags) +{ + int ret; + + VIR_DEBUG("conn=%p, timeout=%u, flags=0x%x", conn, timeout, flags); + + virResetLastError(); + virCheckAdmConnectReturn(conn, -1); + + if ((ret = remoteAdminConnectSetDaemonTimeout(conn, timeout, flags)) < 0) { + virDispatchError(NULL); + return -1; + } + + return ret; +} diff --git a/src/admin/libvirt_admin_public.syms b/src/admin/libvirt_admin_public.syms index 8126973e5b..554269613c 100644 --- a/src/admin/libvirt_admin_public.syms +++ b/src/admin/libvirt_admin_public.syms @@ -48,3 +48,8 @@ LIBVIRT_ADMIN_3.0.0 { virAdmConnectSetLoggingOutputs; virAdmConnectSetLoggingFilters; } LIBVIRT_ADMIN_2.0.0; + +LIBVIRT_ADMIN_8.5.0 { + global: + virAdmConnectSetDaemonTimeout; +} LIBVIRT_ADMIN_3.0.0; diff --git a/src/admin_protocol-structs b/src/admin_protocol-structs index 76c511babf..8caac59824 100644 --- a/src/admin_protocol-structs +++ b/src/admin_protocol-structs @@ -144,6 +144,10 @@ struct admin_connect_set_logging_filters_args { admin_string filters; u_int flags; }; +struct admin_connect_set_daemon_timeout_args { + u_int timeout; + u_int flags; +}; enum admin_procedure { ADMIN_PROC_CONNECT_OPEN = 1, ADMIN_PROC_CONNECT_CLOSE = 2, @@ -163,4 +167,5 @@ enum admin_procedure { ADMIN_PROC_CONNECT_SET_LOGGING_OUTPUTS = 16, ADMIN_PROC_CONNECT_SET_LOGGING_FILTERS = 17, ADMIN_PROC_SERVER_UPDATE_TLS_FILES = 18, + ADMIN_PROC_CONNECT_SET_DAEMON_TIMEOUT = 19, }; -- 2.36.1

Add a simple command to drive the new 'virAdmConnectSetDaemonTimeout' API. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- docs/manpages/virt-admin.rst | 12 ++++++++++ tools/virt-admin.c | 45 ++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/docs/manpages/virt-admin.rst b/docs/manpages/virt-admin.rst index 30cfd24e73..479e27b2c2 100644 --- a/docs/manpages/virt-admin.rst +++ b/docs/manpages/virt-admin.rst @@ -313,6 +313,18 @@ To define multiple outputs at once they need to be delimited by spaces: $ virt-admin daemon-log-outputs "4:stderr 2:syslog:<msg_ident>" +daemon-timeout +-------------- + +**Syntax:** + +:: + + daemon-timeout --timeout NUM + +Sets the daemon timeout to the value of '--timeout' argument. Use ``--timeout 0`` +to disable auto-shutdown of the daemon. + SERVER COMMANDS =============== diff --git a/tools/virt-admin.c b/tools/virt-admin.c index e010763e21..718df62854 100644 --- a/tools/virt-admin.c +++ b/tools/virt-admin.c @@ -1072,6 +1072,45 @@ static const vshCmdInfo info_daemon_log_outputs[] = { {.name = NULL} }; +static const vshCmdOptDef opts_daemon_timeout[] = { + {.name = "timeout", + .type = VSH_OT_INT, + .help = N_("number of seconds the daemon will run without any active connection"), + .flags = VSH_OFLAG_REQ | VSH_OFLAG_REQ_OPT + }, + {.name = NULL} +}; + +static bool +cmdDaemonTimeout(vshControl *ctl, const vshCmd *cmd) +{ + vshAdmControl *priv = ctl->privData; + unsigned int timeout = 0; + + if (vshCommandOptUInt(ctl, cmd, "timeout", &timeout) < 0) + return false; + + if (virAdmConnectSetDaemonTimeout(priv->conn, timeout, 0) < 0) + return false; + + return true; +} + + +/* -------------------------- + * Command daemon-timeout + * -------------------------- + */ +static const vshCmdInfo info_daemon_timeout[] = { + {.name = "help", + .data = N_("set the auto shutdown timeout of the daemon") + }, + {.name = "desc", + .data = N_("set the auto shutdown timeout of the daemon") + }, + {.name = NULL} +}; + static const vshCmdOptDef opts_daemon_log_outputs[] = { {.name = "outputs", .type = VSH_OT_STRING, @@ -1499,6 +1538,12 @@ static const vshCmdDef managementCmds[] = { .info = info_daemon_log_outputs, .flags = 0 }, + {.name = "daemon-timeout", + .handler = cmdDaemonTimeout, + .opts = opts_daemon_timeout, + .info = info_daemon_timeout, + .flags = 0 + }, {.name = NULL} }; -- 2.36.1

When using runtime setting of logging with 'virt-admin' it can be confusing that the settings are discarded when the shutdown timeout of a daemon is reached. Add a note about this behaviour along with a suggestion to use virt-admin to disable the behaviour if needed. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- docs/kbase/debuglogs.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/kbase/debuglogs.rst b/docs/kbase/debuglogs.rst index 83bc0e6ad7..68b9472a83 100644 --- a/docs/kbase/debuglogs.rst +++ b/docs/kbase/debuglogs.rst @@ -194,6 +194,26 @@ package manager provided by your distribution to install this package. guideline in the sections above in place of ``virt-admin`` in the examples below if needed. + +Timeout of the configured daemon +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Common deployments of libvirt start the libvirt daemons via socket activation +and with automatic shutdown timeout of 120 seconds when no client or object is +handled by the daemon. When a timeout is reached the daemon stops and all +settings done during runtime via ``virt-admin`` are discarded. The daemon then +is re-started with another command. + +To prevent auto-shutdown of the daemon you can use the following command:: + + virt-admin daemon-timeout 0 + +The above is introduced in libvirt-8.5.0. + + +Adding filters and outputs +~~~~~~~~~~~~~~~~~~~~~~~~~~ + The following command allows to query the list of currently active log filters: :: -- 2.36.1

On 6/13/22 15:56, Peter Krempa wrote:
Allow setting of the timeout so that users can bypass it when they are setting runtime-logging.
Update the docs to mention the caveat and suggest the bypass.
Peter Krempa (6): virnetdaemon: Extract autoShutdownTimer operations from virNetDaemonRun virNetDaemonAutoShutdown: Allow live update of shutdown timeout scripts: apibuild: Improve error when API is missing from symbol file admin: Introduce virAdmConnectSetDaemonTimeout virt-admin: Introduce 'daemon-timeout' kbase: debuglogs: Add a note about auto-shutdown of daemons
docs/kbase/debuglogs.rst | 20 +++++ docs/manpages/virt-admin.rst | 12 +++ include/libvirt/libvirt-admin.h | 4 + scripts/apibuild.py | 2 + src/admin/admin_protocol.x | 12 ++- src/admin/admin_server_dispatch.c | 12 +++ src/admin/libvirt-admin.c | 34 ++++++++ src/admin/libvirt_admin_public.syms | 5 ++ src/admin_protocol-structs | 5 ++ src/locking/lock_daemon.c | 5 +- src/logging/log_daemon.c | 5 +- src/remote/remote_daemon.c | 4 +- src/rpc/virnetdaemon.c | 127 ++++++++++++++++++---------- src/rpc/virnetdaemon.h | 4 +- tools/virt-admin.c | 45 ++++++++++ 15 files changed, 240 insertions(+), 56 deletions(-)
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal
participants (2)
-
Michal Prívozník
-
Peter Krempa