107 lines
3.7 KiB
Diff
107 lines
3.7 KiB
Diff
|
|
From 752d98d93459c87817be5e02c39257e0fa5934f8 Mon Sep 17 00:00:00 2001
|
||
|
|
From: qihao_yewu <qihao_yewu@cmss.chinamobile.com>
|
||
|
|
Date: Fri, 7 Mar 2025 21:07:11 -0500
|
||
|
|
Subject: [PATCH] qga: Don't daemonize before channel is initialized
|
||
|
|
MIME-Version: 1.0
|
||
|
|
Content-Type: text/plain; charset=UTF-8
|
||
|
|
Content-Transfer-Encoding: 8bit
|
||
|
|
|
||
|
|
cheery-pick from c6f5dd7ac8ef62dcdec4cdeda1467c658161afff
|
||
|
|
|
||
|
|
If the agent is set to daemonize but for whatever reason fails to
|
||
|
|
init the channel, the error message is lost. Worse, the agent
|
||
|
|
daemonizes needlessly and returns success. For instance:
|
||
|
|
|
||
|
|
# qemu-ga -m virtio-serial \
|
||
|
|
-p /dev/nonexistent_device \
|
||
|
|
-f /run/qemu-ga.pid \
|
||
|
|
-t /run \
|
||
|
|
-d
|
||
|
|
# echo $?
|
||
|
|
0
|
||
|
|
|
||
|
|
This makes it needlessly hard for init scripts to detect a
|
||
|
|
failure in qemu-ga startup. Though, they shouldn't pass '-d' in
|
||
|
|
the first place.
|
||
|
|
|
||
|
|
Let's open the channel first and only after that become a daemon.
|
||
|
|
|
||
|
|
Related bug: https://bugs.gentoo.org/810628
|
||
|
|
|
||
|
|
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||
|
|
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
||
|
|
Reviewed-by: Konstantin Kostiuk <kkostiuk@redhat.com>
|
||
|
|
Message-ID: <7a42b0cbda5c7e01cf76bc1b29a1210cd018fa78.1736261360.git.mprivozn@redhat.com>
|
||
|
|
Signed-off-by: Konstantin Kostiuk <kkostiuk@redhat.com>
|
||
|
|
Signed-off-by: qihao_yewu <qihao_yewu@cmss.chinamobile.com>
|
||
|
|
---
|
||
|
|
qga/main.c | 24 ++++++++++++++++++------
|
||
|
|
1 file changed, 18 insertions(+), 6 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/qga/main.c b/qga/main.c
|
||
|
|
index c4dcbb86be..8d341ffdf1 100644
|
||
|
|
--- a/qga/main.c
|
||
|
|
+++ b/qga/main.c
|
||
|
|
@@ -1407,7 +1407,6 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation)
|
||
|
|
if (config->daemonize) {
|
||
|
|
/* delay opening/locking of pidfile till filesystems are unfrozen */
|
||
|
|
s->deferred_options.pid_filepath = config->pid_filepath;
|
||
|
|
- become_daemon(NULL);
|
||
|
|
}
|
||
|
|
if (config->log_filepath) {
|
||
|
|
/* delay opening the log file till filesystems are unfrozen */
|
||
|
|
@@ -1416,9 +1415,6 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation)
|
||
|
|
ga_disable_logging(s);
|
||
|
|
qmp_for_each_command(&ga_commands, ga_disable_not_allowed_freeze, NULL);
|
||
|
|
} else {
|
||
|
|
- if (config->daemonize) {
|
||
|
|
- become_daemon(config->pid_filepath);
|
||
|
|
- }
|
||
|
|
if (config->log_filepath) {
|
||
|
|
FILE *log_file = ga_open_logfile(config->log_filepath);
|
||
|
|
if (!log_file) {
|
||
|
|
@@ -1482,6 +1478,20 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation)
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
+ if (!channel_init(s, s->config->method, s->config->channel_path,
|
||
|
|
+ s->socket_activation ? FIRST_SOCKET_ACTIVATION_FD : -1)) {
|
||
|
|
+ g_critical("failed to initialize guest agent channel");
|
||
|
|
+ return NULL;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (config->daemonize) {
|
||
|
|
+ if (ga_is_frozen(s)) {
|
||
|
|
+ become_daemon(NULL);
|
||
|
|
+ } else {
|
||
|
|
+ become_daemon(config->pid_filepath);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
ga_state = s;
|
||
|
|
return s;
|
||
|
|
failed:
|
||
|
|
@@ -1516,8 +1526,9 @@ static void cleanup_agent(GAState *s)
|
||
|
|
|
||
|
|
static int run_agent_once(GAState *s)
|
||
|
|
{
|
||
|
|
- if (!channel_init(s, s->config->method, s->config->channel_path,
|
||
|
|
- s->socket_activation ? FIRST_SOCKET_ACTIVATION_FD : -1)) {
|
||
|
|
+ if (!s->channel &&
|
||
|
|
+ channel_init(s, s->config->method, s->config->channel_path,
|
||
|
|
+ s->socket_activation ? FIRST_SOCKET_ACTIVATION_FD : -1)) {
|
||
|
|
g_critical("failed to initialize guest agent channel");
|
||
|
|
return EXIT_FAILURE;
|
||
|
|
}
|
||
|
|
@@ -1526,6 +1537,7 @@ static int run_agent_once(GAState *s)
|
||
|
|
|
||
|
|
if (s->channel) {
|
||
|
|
ga_channel_free(s->channel);
|
||
|
|
+ s->channel = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
return EXIT_SUCCESS;
|
||
|
|
--
|
||
|
|
2.41.0.windows.1
|
||
|
|
|