* [PATCH] migration: cpr socket permissions fix @ 2025-11-20 18:57 Ben Chaney 2025-11-21 16:07 ` Peter Xu 0 siblings, 1 reply; 11+ messages in thread From: Ben Chaney @ 2025-11-20 18:57 UTC (permalink / raw) To: berrange, farosas, peterx, armbru, mark.kanda, qemu-devel Cc: johunt, mtottenh, nhudson, Ben Chaney Fix an issue where cpr transfer fails when running with the -run-with user=$USERID with a permission denied error. This issue occurs because the destination host creates the transfer sockets before it drops permissions while the source host tries to connect after dropping permissions. Fix this by changing the ownership of the cpr socket to the lower level so it is accessible to both parties. Resolves: https://lore.kernel.org/all/3D32B62F-29E2-4470-86A5-9A2B3B29E371@akamai.com/ Signed-off-by: Ben Chaney <bchaney@akamai.com> --- include/system/os-posix.h | 1 + include/system/os-wasm.h | 1 + include/system/os-win32.h | 1 + os-posix.c | 12 ++++++++++++ stubs/meson.build | 1 + stubs/os-file.c | 6 ++++++ util/qemu-sockets.c | 6 ++++++ 7 files changed, 28 insertions(+) create mode 100644 stubs/os-file.c diff --git a/include/system/os-posix.h b/include/system/os-posix.h index ce5b3bccf8..e4b69fc316 100644 --- a/include/system/os-posix.h +++ b/include/system/os-posix.h @@ -54,6 +54,7 @@ void os_set_chroot(const char *path); void os_setup_limits(void); void os_setup_post(void); int os_mlock(bool on_fault); +void os_set_socket_permissions(const char *path); /** * qemu_alloc_stack: diff --git a/include/system/os-wasm.h b/include/system/os-wasm.h index 3abb3aaa03..eeac092183 100644 --- a/include/system/os-wasm.h +++ b/include/system/os-wasm.h @@ -57,6 +57,7 @@ static inline int os_set_daemonize(bool d) }; bool is_daemonized(void); static inline void os_daemonize(void) {} +static inline void os_set_socket_permissions(const char *dummy) {}; /** * qemu_alloc_stack: diff --git a/include/system/os-win32.h b/include/system/os-win32.h index 22d72babdf..79e42ec297 100644 --- a/include/system/os-win32.h +++ b/include/system/os-win32.h @@ -103,6 +103,7 @@ static inline void os_setup_post(void) {} static inline void os_set_proc_name(const char *dummy) {} void os_set_line_buffering(void); void os_setup_early_signal_handling(void); +static inline void os_set_socket_permissions(const char *dummy) {}; int getpagesize(void); diff --git a/os-posix.c b/os-posix.c index 52925c23d3..bbd17ff2b9 100644 --- a/os-posix.c +++ b/os-posix.c @@ -94,6 +94,18 @@ static struct passwd *user_pwd; /* NULL non-NULL NULL */ static uid_t user_uid = (uid_t)-1; /* -1 -1 >=0 */ static gid_t user_gid = (gid_t)-1; /* -1 -1 >=0 */ +void os_set_socket_permissions(const char *path) +{ + uid_t uid = user_pwd ? user_pwd->pw_uid : user_uid; + gid_t gid = user_pwd ? user_pwd->pw_gid : user_gid; + + if (chown(path, uid, gid) < 0) { + error_report("Failed to chown socket %s: %s", path, strerror(errno)); + exit(1); + } +} + + /* * Prepare to change user ID. user_id can be one of 3 forms: * - a username, in which case user ID will be changed to its uid, diff --git a/stubs/meson.build b/stubs/meson.build index 0b2778c568..4a4342344b 100644 --- a/stubs/meson.build +++ b/stubs/meson.build @@ -24,6 +24,7 @@ if have_block stub_ss.add(files('ram-block.c')) stub_ss.add(files('runstate-check.c')) stub_ss.add(files('uuid.c')) + stub_ss.add(files('os-file.c')) endif if have_block or have_ga diff --git a/stubs/os-file.c b/stubs/os-file.c new file mode 100644 index 0000000000..c32cbc7efa --- /dev/null +++ b/stubs/os-file.c @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "qemu/osdep.h" + +void os_set_socket_permissions(const char *dummy) +{ +} diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 4773755fd5..77b2d9287b 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -1026,6 +1026,12 @@ static int unix_listen_saddr(UnixSocketAddress *saddr, error_setg_errno(errp, errno, "Failed to bind socket to %s", path); goto err; } + /* + * Change the permissions on the socket to match the permission of the + * counterparty process + */ + os_set_socket_permissions(un.sun_path); + if (listen(sock, num) < 0) { error_setg_errno(errp, errno, "Failed to listen on socket"); goto err; -- 2.34.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] migration: cpr socket permissions fix 2025-11-20 18:57 [PATCH] migration: cpr socket permissions fix Ben Chaney @ 2025-11-21 16:07 ` Peter Xu 2025-11-21 16:54 ` Daniel P. Berrangé 2025-12-04 20:05 ` Chaney, Ben 0 siblings, 2 replies; 11+ messages in thread From: Peter Xu @ 2025-11-21 16:07 UTC (permalink / raw) To: Ben Chaney Cc: berrange, farosas, armbru, mark.kanda, qemu-devel, johunt, mtottenh, nhudson On Thu, Nov 20, 2025 at 01:57:33PM -0500, Ben Chaney wrote: > Fix an issue where cpr transfer fails when running with the > -run-with user=$USERID with a permission denied error. This issue > occurs because the destination host creates the transfer sockets before > it drops permissions while the source host tries to connect after > dropping permissions. Fix this by changing the ownership of the cpr > socket to the lower level so it is accessible to both parties. > > Resolves: https://lore.kernel.org/all/3D32B62F-29E2-4470-86A5-9A2B3B29E371@akamai.com/ > Signed-off-by: Ben Chaney <bchaney@akamai.com> > --- > include/system/os-posix.h | 1 + > include/system/os-wasm.h | 1 + > include/system/os-win32.h | 1 + > os-posix.c | 12 ++++++++++++ > stubs/meson.build | 1 + > stubs/os-file.c | 6 ++++++ > util/qemu-sockets.c | 6 ++++++ > 7 files changed, 28 insertions(+) > create mode 100644 stubs/os-file.c > > diff --git a/include/system/os-posix.h b/include/system/os-posix.h > index ce5b3bccf8..e4b69fc316 100644 > --- a/include/system/os-posix.h > +++ b/include/system/os-posix.h > @@ -54,6 +54,7 @@ void os_set_chroot(const char *path); > void os_setup_limits(void); > void os_setup_post(void); > int os_mlock(bool on_fault); > +void os_set_socket_permissions(const char *path); > > /** > * qemu_alloc_stack: > diff --git a/include/system/os-wasm.h b/include/system/os-wasm.h > index 3abb3aaa03..eeac092183 100644 > --- a/include/system/os-wasm.h > +++ b/include/system/os-wasm.h > @@ -57,6 +57,7 @@ static inline int os_set_daemonize(bool d) > }; > bool is_daemonized(void); > static inline void os_daemonize(void) {} > +static inline void os_set_socket_permissions(const char *dummy) {}; > > /** > * qemu_alloc_stack: > diff --git a/include/system/os-win32.h b/include/system/os-win32.h > index 22d72babdf..79e42ec297 100644 > --- a/include/system/os-win32.h > +++ b/include/system/os-win32.h > @@ -103,6 +103,7 @@ static inline void os_setup_post(void) {} > static inline void os_set_proc_name(const char *dummy) {} > void os_set_line_buffering(void); > void os_setup_early_signal_handling(void); > +static inline void os_set_socket_permissions(const char *dummy) {}; > > int getpagesize(void); > > diff --git a/os-posix.c b/os-posix.c > index 52925c23d3..bbd17ff2b9 100644 > --- a/os-posix.c > +++ b/os-posix.c > @@ -94,6 +94,18 @@ static struct passwd *user_pwd; /* NULL non-NULL NULL */ > static uid_t user_uid = (uid_t)-1; /* -1 -1 >=0 */ > static gid_t user_gid = (gid_t)-1; /* -1 -1 >=0 */ > > +void os_set_socket_permissions(const char *path) > +{ > + uid_t uid = user_pwd ? user_pwd->pw_uid : user_uid; > + gid_t gid = user_pwd ? user_pwd->pw_gid : user_gid; > + > + if (chown(path, uid, gid) < 0) { > + error_report("Failed to chown socket %s: %s", path, strerror(errno)); > + exit(1); > + } > +} > + > + > /* > * Prepare to change user ID. user_id can be one of 3 forms: > * - a username, in which case user ID will be changed to its uid, > diff --git a/stubs/meson.build b/stubs/meson.build > index 0b2778c568..4a4342344b 100644 > --- a/stubs/meson.build > +++ b/stubs/meson.build > @@ -24,6 +24,7 @@ if have_block > stub_ss.add(files('ram-block.c')) > stub_ss.add(files('runstate-check.c')) > stub_ss.add(files('uuid.c')) > + stub_ss.add(files('os-file.c')) > endif > > if have_block or have_ga > diff --git a/stubs/os-file.c b/stubs/os-file.c > new file mode 100644 > index 0000000000..c32cbc7efa > --- /dev/null > +++ b/stubs/os-file.c > @@ -0,0 +1,6 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +#include "qemu/osdep.h" > + > +void os_set_socket_permissions(const char *dummy) > +{ > +} > diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c > index 4773755fd5..77b2d9287b 100644 > --- a/util/qemu-sockets.c > +++ b/util/qemu-sockets.c > @@ -1026,6 +1026,12 @@ static int unix_listen_saddr(UnixSocketAddress *saddr, > error_setg_errno(errp, errno, "Failed to bind socket to %s", path); > goto err; > } > + /* > + * Change the permissions on the socket to match the permission of the > + * counterparty process > + */ > + os_set_socket_permissions(un.sun_path); QEMU's -run-with described user= as: user=username or user=uid:gid can be used to drop root privileges before starting guest execution. QEMU will use the setuid and setgid system calls to switch to the specified identity... So it explicitly mentioned "before starting guest execution", hence at least from that doc it's hard to say if unix socket should be created with the privilege or after dropped.. Here I believe cpr socket should be the case for latter, however when it's a generic change to unix listening ports, I wonder if there's other unwanted side effects. Considering unix socket itself doesn't really have a UID attached to it, it's only the unix path that needs a chmod(), meanwhile the mgmt of course knows both the right UID (as specified in -run-with) and the path, would it make sense if the mgmt chmod() after it starts dest QEMU? That'll reduce the scope of impact to minimum. Thanks, > + > if (listen(sock, num) < 0) { > error_setg_errno(errp, errno, "Failed to listen on socket"); > goto err; > -- > 2.34.1 > -- Peter Xu ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] migration: cpr socket permissions fix 2025-11-21 16:07 ` Peter Xu @ 2025-11-21 16:54 ` Daniel P. Berrangé 2025-12-04 20:05 ` Chaney, Ben 1 sibling, 0 replies; 11+ messages in thread From: Daniel P. Berrangé @ 2025-11-21 16:54 UTC (permalink / raw) To: Peter Xu Cc: Ben Chaney, farosas, armbru, mark.kanda, qemu-devel, johunt, mtottenh, nhudson On Fri, Nov 21, 2025 at 11:07:48AM -0500, Peter Xu wrote: > On Thu, Nov 20, 2025 at 01:57:33PM -0500, Ben Chaney wrote: > > Fix an issue where cpr transfer fails when running with the > > -run-with user=$USERID with a permission denied error. This issue > > occurs because the destination host creates the transfer sockets before > > it drops permissions while the source host tries to connect after > > dropping permissions. Fix this by changing the ownership of the cpr > > socket to the lower level so it is accessible to both parties. > > > > Resolves: https://lore.kernel.org/all/3D32B62F-29E2-4470-86A5-9A2B3B29E371@akamai.com/ > > Signed-off-by: Ben Chaney <bchaney@akamai.com> > > --- > > include/system/os-posix.h | 1 + > > include/system/os-wasm.h | 1 + > > include/system/os-win32.h | 1 + > > os-posix.c | 12 ++++++++++++ > > stubs/meson.build | 1 + > > stubs/os-file.c | 6 ++++++ > > util/qemu-sockets.c | 6 ++++++ > > 7 files changed, 28 insertions(+) > > create mode 100644 stubs/os-file.c > > > > diff --git a/include/system/os-posix.h b/include/system/os-posix.h > > index ce5b3bccf8..e4b69fc316 100644 > > --- a/include/system/os-posix.h > > +++ b/include/system/os-posix.h > > @@ -54,6 +54,7 @@ void os_set_chroot(const char *path); > > void os_setup_limits(void); > > void os_setup_post(void); > > int os_mlock(bool on_fault); > > +void os_set_socket_permissions(const char *path); > > > > /** > > * qemu_alloc_stack: > > diff --git a/include/system/os-wasm.h b/include/system/os-wasm.h > > index 3abb3aaa03..eeac092183 100644 > > --- a/include/system/os-wasm.h > > +++ b/include/system/os-wasm.h > > @@ -57,6 +57,7 @@ static inline int os_set_daemonize(bool d) > > }; > > bool is_daemonized(void); > > static inline void os_daemonize(void) {} > > +static inline void os_set_socket_permissions(const char *dummy) {}; > > > > /** > > * qemu_alloc_stack: > > diff --git a/include/system/os-win32.h b/include/system/os-win32.h > > index 22d72babdf..79e42ec297 100644 > > --- a/include/system/os-win32.h > > +++ b/include/system/os-win32.h > > @@ -103,6 +103,7 @@ static inline void os_setup_post(void) {} > > static inline void os_set_proc_name(const char *dummy) {} > > void os_set_line_buffering(void); > > void os_setup_early_signal_handling(void); > > +static inline void os_set_socket_permissions(const char *dummy) {}; > > > > int getpagesize(void); > > > > diff --git a/os-posix.c b/os-posix.c > > index 52925c23d3..bbd17ff2b9 100644 > > --- a/os-posix.c > > +++ b/os-posix.c > > @@ -94,6 +94,18 @@ static struct passwd *user_pwd; /* NULL non-NULL NULL */ > > static uid_t user_uid = (uid_t)-1; /* -1 -1 >=0 */ > > static gid_t user_gid = (gid_t)-1; /* -1 -1 >=0 */ > > > > +void os_set_socket_permissions(const char *path) > > +{ > > + uid_t uid = user_pwd ? user_pwd->pw_uid : user_uid; > > + gid_t gid = user_pwd ? user_pwd->pw_gid : user_gid; > > + > > + if (chown(path, uid, gid) < 0) { > > + error_report("Failed to chown socket %s: %s", path, strerror(errno)); > > + exit(1); > > + } > > +} > > + > > + > > /* > > * Prepare to change user ID. user_id can be one of 3 forms: > > * - a username, in which case user ID will be changed to its uid, > > diff --git a/stubs/meson.build b/stubs/meson.build > > index 0b2778c568..4a4342344b 100644 > > --- a/stubs/meson.build > > +++ b/stubs/meson.build > > @@ -24,6 +24,7 @@ if have_block > > stub_ss.add(files('ram-block.c')) > > stub_ss.add(files('runstate-check.c')) > > stub_ss.add(files('uuid.c')) > > + stub_ss.add(files('os-file.c')) > > endif > > > > if have_block or have_ga > > diff --git a/stubs/os-file.c b/stubs/os-file.c > > new file mode 100644 > > index 0000000000..c32cbc7efa > > --- /dev/null > > +++ b/stubs/os-file.c > > @@ -0,0 +1,6 @@ > > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > > +#include "qemu/osdep.h" > > + > > +void os_set_socket_permissions(const char *dummy) > > +{ > > +} > > diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c > > index 4773755fd5..77b2d9287b 100644 > > --- a/util/qemu-sockets.c > > +++ b/util/qemu-sockets.c > > @@ -1026,6 +1026,12 @@ static int unix_listen_saddr(UnixSocketAddress *saddr, > > error_setg_errno(errp, errno, "Failed to bind socket to %s", path); > > goto err; > > } > > + /* > > + * Change the permissions on the socket to match the permission of the > > + * counterparty process > > + */ > > + os_set_socket_permissions(un.sun_path); > > QEMU's -run-with described user= as: > > user=username or user=uid:gid can be used to drop root privileges before > starting guest execution. QEMU will use the setuid and setgid system > calls to switch to the specified identity... > > So it explicitly mentioned "before starting guest execution", hence at > least from that doc it's hard to say if unix socket should be created with > the privilege or after dropped.. Here I believe cpr socket should be the > case for latter, however when it's a generic change to unix listening > ports, I wonder if there's other unwanted side effects. > > Considering unix socket itself doesn't really have a UID attached to it, > it's only the unix path that needs a chmod(), meanwhile the mgmt of course > knows both the right UID (as specified in -run-with) and the path, would it > make sense if the mgmt chmod() after it starts dest QEMU? That'll reduce > the scope of impact to minimum. My guiding principal is that the behaviour of cold-plugging a backend on the CLI and hot-plugging a backend via QMP should be the same, since we want to eventually get to a point where everything can be configured via QMP and zero CLI except for basic process related things. hot-plugging will honour -run-with setting, therefore cold-plugging should do the same. Having said that, the run-with setting impl is very clearcut however that it is intended to run *after* all cold-plug setup is complete. IOW, it is inherantly intending to have differnt behaviour for cold plug vs hotplug. There's a very real risk we'll cause regressions if we change how permissions are handled implicitly on any backends. With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :| ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] migration: cpr socket permissions fix 2025-11-21 16:07 ` Peter Xu 2025-11-21 16:54 ` Daniel P. Berrangé @ 2025-12-04 20:05 ` Chaney, Ben 2025-12-05 15:13 ` Peter Xu 1 sibling, 1 reply; 11+ messages in thread From: Chaney, Ben @ 2025-12-04 20:05 UTC (permalink / raw) To: Peter Xu, berrange@redhat.com Cc: farosas@suse.de, armbru@redhat.com, mark.kanda@oracle.com, qemu-devel@nongnu.org, Hunt, Joshua, Tottenham, Max, Hudson, Nick > Considering unix socket itself doesn't really have a UID attached to it, > it's only the unix path that needs a chmod(), meanwhile the mgmt of course > knows both the right UID (as specified in -run-with) and the path, would it > make sense if the mgmt chmod() after it starts dest QEMU? That'll reduce > the scope of impact to minimum. I like this solution, but it runs into the issue that the main channel socket is not created ahead of time, so there isn't an opportunity for the management layer to change it's permissions. The CPR socket is created ahead of time, so we could use this solution there. I'm not familiar with the history here. Do you know why the sockets are created at different times? Thanks, Ben ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] migration: cpr socket permissions fix 2025-12-04 20:05 ` Chaney, Ben @ 2025-12-05 15:13 ` Peter Xu 2025-12-08 19:32 ` Chaney, Ben 0 siblings, 1 reply; 11+ messages in thread From: Peter Xu @ 2025-12-05 15:13 UTC (permalink / raw) To: Chaney, Ben Cc: berrange@redhat.com, farosas@suse.de, armbru@redhat.com, mark.kanda@oracle.com, qemu-devel@nongnu.org, Hunt, Joshua, Tottenham, Max, Hudson, Nick On Thu, Dec 04, 2025 at 08:05:59PM +0000, Chaney, Ben wrote: > > Considering unix socket itself doesn't really have a UID attached to it, > > it's only the unix path that needs a chmod(), meanwhile the mgmt of course > > knows both the right UID (as specified in -run-with) and the path, would it > > make sense if the mgmt chmod() after it starts dest QEMU? That'll reduce > > the scope of impact to minimum. > > > I like this solution, but it runs into the issue that the main channel socket is not > created ahead of time, so there isn't an opportunity for the management layer > to change it's permissions. The CPR socket is created ahead of time, so we could > use this solution there. I'm not familiar with the history here. Do you know why > the sockets are created at different times? IIUC the cpr channel isn't created ahead of time either, it's still created a while after QEMU process start to run. It's just that I believe CPR needs to synchronously wait for the client to connect first and send data, before it can reach other part of QEMU logic to further create the main channel. It should look like this: qemu_init cpr_state_load cpr_transfer_input qio_net_listener_wait_client [1] qmp_x_exit_preconfig qmp_migrate_incoming [2] os_setup_post change_process_uid [3] So IIUC you're looking for [2] creating the other unix socket. Maybe you can stick with -incoming defer, then it'll be after step [3], which will inherit the modified uid, and mgmt doesn't need to bother monitoring. Thanks, -- Peter Xu ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] migration: cpr socket permissions fix 2025-12-05 15:13 ` Peter Xu @ 2025-12-08 19:32 ` Chaney, Ben 2025-12-09 18:54 ` Peter Xu 0 siblings, 1 reply; 11+ messages in thread From: Chaney, Ben @ 2025-12-08 19:32 UTC (permalink / raw) To: Peter Xu Cc: berrange@redhat.com, farosas@suse.de, armbru@redhat.com, mark.kanda@oracle.com, qemu-devel@nongnu.org, Hunt, Joshua, Tottenham, Max, Hudson, Nick On 12/5/25, 10:13 AM, "Peter Xu" <peterx@redhat.com <mailto:peterx@redhat.com>> wrote: > Maybe you can stick with -incoming defer, then it'll be after step [3], > which will inherit the modified uid, and mgmt doesn't need to bother > monitoring. I tried this approach, but It doesn't look like it is possible to create the cprsocket later with -incoming defer. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] migration: cpr socket permissions fix 2025-12-08 19:32 ` Chaney, Ben @ 2025-12-09 18:54 ` Peter Xu 2025-12-11 18:42 ` Chaney, Ben 0 siblings, 1 reply; 11+ messages in thread From: Peter Xu @ 2025-12-09 18:54 UTC (permalink / raw) To: Chaney, Ben Cc: berrange@redhat.com, farosas@suse.de, armbru@redhat.com, mark.kanda@oracle.com, qemu-devel@nongnu.org, Hunt, Joshua, Tottenham, Max, Hudson, Nick On Mon, Dec 08, 2025 at 07:32:41PM +0000, Chaney, Ben wrote: > > On 12/5/25, 10:13 AM, "Peter Xu" <peterx@redhat.com <mailto:peterx@redhat.com>> wrote: > > > > Maybe you can stick with -incoming defer, then it'll be after step [3], > > which will inherit the modified uid, and mgmt doesn't need to bother > > monitoring. > > I tried this approach, but It doesn't look like it is possible to create the > cprsocket later with -incoming defer. You'll still need to chmod for the cpr socket. "defer" will still help the main channel to be created with the uid provided. -- Peter Xu ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] migration: cpr socket permissions fix 2025-12-09 18:54 ` Peter Xu @ 2025-12-11 18:42 ` Chaney, Ben 2025-12-11 19:12 ` Peter Xu 0 siblings, 1 reply; 11+ messages in thread From: Chaney, Ben @ 2025-12-11 18:42 UTC (permalink / raw) To: Peter Xu Cc: berrange@redhat.com, farosas@suse.de, armbru@redhat.com, mark.kanda@oracle.com, qemu-devel@nongnu.org, Hunt, Joshua, Tottenham, Max, Hudson, Nick On 12/9/25, 1:55 PM, "Peter Xu" <peterx@redhat.com <mailto:peterx@redhat.com>> wrote: > On Mon, Dec 08, 2025 at 07:32:41PM +0000, Chaney, Ben wrote: > > > > On 12/5/25, 10:13 AM, "Peter Xu" <peterx@redhat.com <mailto:peterx@redhat.com> <mailto:peterx@redhat.com <mailto:peterx@redhat.com>>> wrote: > > > > > > > Maybe you can stick with -incoming defer, then it'll be after step [3], > > > which will inherit the modified uid, and mgmt doesn't need to bother > > > monitoring. > > > > I tried this approach, but It doesn't look like it is possible to create the > > cprsocket later with -incoming defer. > > > You'll still need to chmod for the cpr socket. "defer" will still help the > main channel to be created with the uid provided. Thanks for the pointers. I was able to get the incoming defer method working, but it has much worse performance than the other method. Would you be open to a solution where we chown only the migration sockets, or would that run into similar concerns? Thanks, Ben ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] migration: cpr socket permissions fix 2025-12-11 18:42 ` Chaney, Ben @ 2025-12-11 19:12 ` Peter Xu 2025-12-11 20:44 ` Chaney, Ben 0 siblings, 1 reply; 11+ messages in thread From: Peter Xu @ 2025-12-11 19:12 UTC (permalink / raw) To: Chaney, Ben Cc: berrange@redhat.com, farosas@suse.de, armbru@redhat.com, mark.kanda@oracle.com, qemu-devel@nongnu.org, Hunt, Joshua, Tottenham, Max, Hudson, Nick On Thu, Dec 11, 2025 at 06:42:05PM +0000, Chaney, Ben wrote: > > > On 12/9/25, 1:55 PM, "Peter Xu" <peterx@redhat.com <mailto:peterx@redhat.com>> wrote: > > > On Mon, Dec 08, 2025 at 07:32:41PM +0000, Chaney, Ben wrote: > > > > > > On 12/5/25, 10:13 AM, "Peter Xu" <peterx@redhat.com <mailto:peterx@redhat.com> <mailto:peterx@redhat.com <mailto:peterx@redhat.com>>> wrote: > > > > > > > > > > Maybe you can stick with -incoming defer, then it'll be after step [3], > > > > which will inherit the modified uid, and mgmt doesn't need to bother > > > > monitoring. > > > > > > I tried this approach, but It doesn't look like it is possible to create the > > > cprsocket later with -incoming defer. > > > > > > You'll still need to chmod for the cpr socket. "defer" will still help the > > main channel to be created with the uid provided. > > Thanks for the pointers. I was able to get the incoming defer method > working, but it has much worse performance than the other method. > > Would you be open to a solution where we chown only the migration > sockets, or would that run into similar concerns? We can evaluate, but before that, could you explain your current solution first? And, what is the performance you mentioned here that is worse? I at least didn't expect it to be downtime, because IIUC what your mgmt needs to do is to chmod on the cpr channel first (during which migration hasn't started), then chmod once more on the main channel after CPR channel migrated and before main channel migration happens (during which VM should be running on src), hence it should have nothing to do with downtime. Thanks, -- Peter Xu ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] migration: cpr socket permissions fix 2025-12-11 19:12 ` Peter Xu @ 2025-12-11 20:44 ` Chaney, Ben 2025-12-11 21:14 ` Peter Xu 0 siblings, 1 reply; 11+ messages in thread From: Chaney, Ben @ 2025-12-11 20:44 UTC (permalink / raw) To: Peter Xu Cc: berrange@redhat.com, farosas@suse.de, armbru@redhat.com, mark.kanda@oracle.com, qemu-devel@nongnu.org, Hunt, Joshua, Tottenham, Max, Hudson, Nick > On 12/11/25, 2:13 PM, "Peter Xu" <peterx@redhat.com <mailto:peterx@redhat.com>> wrote: > On Thu, Dec 11, 2025 at 06:42:05PM +0000, Chaney, Ben wrote: > > > > > > On 12/9/25, 1:55 PM, "Peter Xu" <peterx@redhat.com <mailto:peterx@redhat.com> <mailto:peterx@redhat.com <mailto:peterx@redhat.com>>> wrote: > > > > > > On Mon, Dec 08, 2025 at 07:32:41PM +0000, Chaney, Ben wrote: > > > > > > > On 12/5/25, 10:13 AM, "Peter Xu" <peterx@redhat.com <mailto:peterx@redhat.com> <mailto:peterx@redhat.com <mailto:peterx@redhat.com>> <mailto:peterx@redhat.com <mailto:peterx@redhat.com> <mailto:peterx@redhat.com <mailto:peterx@redhat.com>>>> wrote: > > > > > > > > > > > > > Maybe you can stick with -incoming defer, then it'll be after step [3], > > > > > which will inherit the modified uid, and mgmt doesn't need to bother > > > > > monitoring. > > > > > > > > I tried this approach, but It doesn't look like it is possible to create the > > > > cprsocket later with -incoming defer. > > > > > > > > > You'll still need to chmod for the cpr socket. "defer" will still help the > > > main channel to be created with the uid provided. > > > > Thanks for the pointers. I was able to get the incoming defer method > > working, but it has much worse performance than the other method. > > > > Would you be open to a solution where we chown only the migration > > sockets, or would that run into similar concerns? > > > We can evaluate, but before that, could you explain your current solution > first? > > > And, what is the performance you mentioned here that is worse? > > > I at least didn't expect it to be downtime, because IIUC what your mgmt > needs to do is to chmod on the cpr channel first (during which migration > hasn't started), then chmod once more on the main channel after CPR channel > migrated and before main channel migration happens (during which VM should > be running on src), hence it should have nothing to do with downtime. I wouldn't have expected this to affect downtime either, but it does increase the downtime by about 3.5 seconds (700-800ms to just over 4s). I am using the following setup to defer the creation of the main socket: qemu-system-x86_64 ... -incoming defer -incoming \ '{"channel-type": "cpr", "addr": { "transport": "socket", "type": "unix", "path": "cpr.sock"}}' chown $UID:$GID cpr.sock echo '{"execute":"qmp_capabilities"} {"execute": "query-status"} {"execute":"migrate-set-parameters", "arguments":{"mode":"cpr-transfer"}} {"execute": "migrate", "arguments": { "channels": [ {"channel-type": "main", "addr": { "transport": "socket", "type": "unix", "path": "main.sock"}}, {"channel-type": "cpr", "addr": { "transport": "socket", "type": "unix", "path": "cpr.sock"}}]}} {"execute": "query-status"} {"execute": "query-migrate"} ' | $SSH_COMMAND socat STDIO unix-connect:qemu_src.monitor echo '{"execute":"qmp_capabilities"} {"execute": "migrate-incoming", "arguments": { "channels": [ {"channel-type": "main", "addr": { "transport": "socket", "type": "unix", "path": "main.sock"}}]}} {"execute": "query-status"} {"execute": "query-migrate"} ' | $SSH_COMMAND socat STDIO unix-connect:qemu_dst.monitor The migration finishes as soon as the migrate-incoming command is issued. There is no opportunity to chown the main socket, but because it is being hot plugged it gets created with the appropriate permissions. I should also note that I am testing this in combination with the patch set for cpr transfer for tap devices, which makes the issue more pronounced in terms of network interruption, however the reported downtime increases by 3.5s regardless of if that patch set is applied or not. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] migration: cpr socket permissions fix 2025-12-11 20:44 ` Chaney, Ben @ 2025-12-11 21:14 ` Peter Xu 0 siblings, 0 replies; 11+ messages in thread From: Peter Xu @ 2025-12-11 21:14 UTC (permalink / raw) To: Chaney, Ben Cc: berrange@redhat.com, farosas@suse.de, armbru@redhat.com, mark.kanda@oracle.com, qemu-devel@nongnu.org, Hunt, Joshua, Tottenham, Max, Hudson, Nick On Thu, Dec 11, 2025 at 08:44:27PM +0000, Chaney, Ben wrote: > > > > On 12/11/25, 2:13 PM, "Peter Xu" <peterx@redhat.com <mailto:peterx@redhat.com>> wrote: > > > On Thu, Dec 11, 2025 at 06:42:05PM +0000, Chaney, Ben wrote: > > > > > > > > > On 12/9/25, 1:55 PM, "Peter Xu" <peterx@redhat.com <mailto:peterx@redhat.com> <mailto:peterx@redhat.com <mailto:peterx@redhat.com>>> wrote: > > > > > > > > On Mon, Dec 08, 2025 at 07:32:41PM +0000, Chaney, Ben wrote: > > > > > > > > > On 12/5/25, 10:13 AM, "Peter Xu" <peterx@redhat.com <mailto:peterx@redhat.com> <mailto:peterx@redhat.com <mailto:peterx@redhat.com>> <mailto:peterx@redhat.com <mailto:peterx@redhat.com> <mailto:peterx@redhat.com <mailto:peterx@redhat.com>>>> wrote: > > > > > > > > > > > > > > > > Maybe you can stick with -incoming defer, then it'll be after step [3], > > > > > > which will inherit the modified uid, and mgmt doesn't need to bother > > > > > > monitoring. > > > > > > > > > > I tried this approach, but It doesn't look like it is possible to create the > > > > > cprsocket later with -incoming defer. > > > > > > > > > > > > You'll still need to chmod for the cpr socket. "defer" will still help the > > > > main channel to be created with the uid provided. > > > > > > Thanks for the pointers. I was able to get the incoming defer method > > > working, but it has much worse performance than the other method. > > > > > > Would you be open to a solution where we chown only the migration > > > sockets, or would that run into similar concerns? > > > > > > We can evaluate, but before that, could you explain your current solution > > first? > > > > > > And, what is the performance you mentioned here that is worse? > > > > > > I at least didn't expect it to be downtime, because IIUC what your mgmt > > needs to do is to chmod on the cpr channel first (during which migration > > hasn't started), then chmod once more on the main channel after CPR channel > > migrated and before main channel migration happens (during which VM should > > be running on src), hence it should have nothing to do with downtime. > > I wouldn't have expected this to affect downtime either, but it does increase the > downtime by about 3.5 seconds (700-800ms to just over 4s). I am using the > following setup to defer the creation of the main socket: > > qemu-system-x86_64 ... -incoming defer -incoming \ > '{"channel-type": "cpr", "addr": { "transport": "socket", "type": "unix", "path": "cpr.sock"}}' > > chown $UID:$GID cpr.sock > > echo '{"execute":"qmp_capabilities"} > {"execute": "query-status"} > {"execute":"migrate-set-parameters", > "arguments":{"mode":"cpr-transfer"}} > {"execute": "migrate", "arguments": { "channels": [ > {"channel-type": "main", "addr": { "transport": "socket", "type": "unix", > "path": "main.sock"}}, > {"channel-type": "cpr", > "addr": { "transport": "socket", "type": "unix", > "path": "cpr.sock"}}]}} > > {"execute": "query-status"} > > {"execute": "query-migrate"} > ' | $SSH_COMMAND socat STDIO unix-connect:qemu_src.monitor > > echo '{"execute":"qmp_capabilities"} > {"execute": "migrate-incoming", "arguments": { "channels": [ > {"channel-type": "main", "addr": { "transport": "socket", "type": "unix", > "path": "main.sock"}}]}} > {"execute": "query-status"} > {"execute": "query-migrate"} > ' | $SSH_COMMAND socat STDIO unix-connect:qemu_dst.monitor > > The migration finishes as soon as the migrate-incoming command is issued. This really sounds weird, because this window should be the maximum downtime.. if it finished so fast, something is wrong. Could you spend some time investigate this problem? IMHO something was very off, a few seconds of downtime shouldn't be hard to chase. If we need to justify a chmod on top of migration channels, we still need to know why it's needed. Thanks, > There is no opportunity to chown the main socket, but because it is being > hot plugged it gets created with the appropriate permissions. > > I should also note that I am testing this in combination with the patch set for > cpr transfer for tap devices, which makes the issue more pronounced in terms > of network interruption, however the reported downtime increases by 3.5s > regardless of if that patch set is applied or not. -- Peter Xu ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-12-11 21:14 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-11-20 18:57 [PATCH] migration: cpr socket permissions fix Ben Chaney 2025-11-21 16:07 ` Peter Xu 2025-11-21 16:54 ` Daniel P. Berrangé 2025-12-04 20:05 ` Chaney, Ben 2025-12-05 15:13 ` Peter Xu 2025-12-08 19:32 ` Chaney, Ben 2025-12-09 18:54 ` Peter Xu 2025-12-11 18:42 ` Chaney, Ben 2025-12-11 19:12 ` Peter Xu 2025-12-11 20:44 ` Chaney, Ben 2025-12-11 21:14 ` Peter Xu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).