From 56ef123777b7a29f5b813696a69865d6033c3c78 Mon Sep 17 00:00:00 2001 From: Jean-Louis Dupond Date: Wed, 2 Oct 2024 12:06:35 +0200 Subject: [PATCH 1/3] qga: skip bind mounts in fs list The filesystem list in build_fs_mount_list should skip bind mounts. This because we end up in locking situations when doing fsFreeze. Like mentioned in [1] and [2]. Next to that, the build_fs_mount_list call did a fallback via build_fs_mount_list_from_mtab if mountinfo did not exist. There it skipped bind mounts, but this is broken for newer OS. This as mounts does not return the path of the bind mount but the underlying dev/partition, so S_ISDIR will never return true in dev_major_minor call. This patch simply checks the existing devmajor:devminor tuple in the mounts, and if it already exists, this means we have the same devices mounted again, a bind mount. So skip this. Same approach is used in open-vm-tools [3]. [1]: https://gitlab.com/qemu-project/qemu/-/issues/592 [2]: https://gitlab.com/qemu-project/qemu/-/issues/520 [3]: https://github.com/vmware/open-vm-tools/commit/d58847b497e212737007958c945af1df22a8ab58 Signed-off-by: Jean-Louis Dupond Reviewed-by: Konstantin Kostiuk Link: https://lore.kernel.org/r/20241002100634.162499-2-jean-louis@dupond.be Signed-off-by: Konstantin Kostiuk --- qga/commands-linux.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/qga/commands-linux.c b/qga/commands-linux.c index cf077eb03d..9e8a934b9a 100644 --- a/qga/commands-linux.c +++ b/qga/commands-linux.c @@ -58,6 +58,22 @@ static int dev_major_minor(const char *devpath, return -1; } +/* + * Check if we already have the devmajor:devminor in the mounts + * If thats the case return true. + */ +static bool dev_exists(FsMountList *mounts, unsigned int devmajor, unsigned int devminor) +{ + FsMount *mount; + + QTAILQ_FOREACH(mount, mounts, next) { + if (mount->devmajor == devmajor && mount->devminor == devminor) { + return true; + } + } + return false; +} + static bool build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp) { struct mntent *ment; @@ -88,6 +104,10 @@ static bool build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp) /* Skip bind mounts */ continue; } + if (dev_exists(mounts, devmajor, devminor)) { + /* Skip already existing devices (bind mounts) */ + continue; + } mount = g_new0(FsMount, 1); mount->dirname = g_strdup(ment->mnt_dir); @@ -171,6 +191,11 @@ bool build_fs_mount_list(FsMountList *mounts, Error **errp) } } + if (dev_exists(mounts, devmajor, devminor)) { + /* Skip already existing devices (bind mounts) */ + continue; + } + mount = g_new0(FsMount, 1); mount->dirname = g_strdup(line + dir_s); mount->devtype = g_strdup(dash + type_s); From 5788e9602416d24533a19d24b087d56a75119c36 Mon Sep 17 00:00:00 2001 From: Dehan Meng Date: Tue, 10 Dec 2024 13:46:16 +0800 Subject: [PATCH 2/3] qemu-ga-win: Fix a typo error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a typo error for api 'guest-get-osinfo', the win2025's version in WIN_10_0_SERVER_VERSION_MATRIX should be adjusted. Signed-off-by: Dehan Meng Reviewed-by: Daniel P. Berrangé Reviewed-by: Konstantin Kostiuk Link: https://lore.kernel.org/r/20241210054616.260386-1-demeng@redhat.com Signed-off-by: Konstantin Kostiuk --- qga/commands-win32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 038beb8cfa..99c026c0a0 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -2088,7 +2088,7 @@ static const ga_win_10_0_t WIN_10_0_SERVER_VERSION_MATRIX[] = { {14393, "Microsoft Windows Server 2016", "2016"}, {17763, "Microsoft Windows Server 2019", "2019"}, {20344, "Microsoft Windows Server 2022", "2022"}, - {26040, "MIcrosoft Windows Server 2025", "2025"}, + {26040, "Microsoft Windows Server 2025", "2025"}, { } }; From 2657a92b5479c8705b128ed1e55feb8960ed498a Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Thu, 5 Dec 2024 17:18:45 +0100 Subject: [PATCH 3/3] qga: Don't access global variable in run_agent_once() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The run_agent_once() function is already given GAState via an argument. There's no need to access the global ga_state variable which points to the argument anyways (thanks to initialize_agent()). Worse, some parts of the function use the argument and the other use the global variable. Stick with the function argument. Signed-off-by: Michal Privoznik Reviewed-by: Ján Tomko Reviewed-by: Konstantin Kostiuk Link: https://lore.kernel.org/r/8ae7f5d5032b14a5b956fe8aaf47bae5ca401699.1733414906.git.mprivozn@redhat.com Signed-off-by: Konstantin Kostiuk --- qga/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qga/main.c b/qga/main.c index 50186760bf..4a695235f0 100644 --- a/qga/main.c +++ b/qga/main.c @@ -1519,7 +1519,7 @@ static int run_agent_once(GAState *s) return EXIT_FAILURE; } - g_main_loop_run(ga_state->main_loop); + g_main_loop_run(s->main_loop); if (s->channel) { ga_channel_free(s->channel);