diff mbox series

[XEN,2/3] libxl: Probe QEMU for -run-with chroot=dir and use it

Message ID 20240827100328.23216-3-anthony.perard@vates.tech (mailing list archive)
State Superseded
Headers show
Series libxl: Implement QEMU command line probe | expand

Commit Message

Anthony PERARD Aug. 27, 2024, 10:03 a.m. UTC
QEMU 9.0 have removed "-chroot" command line option, which have been
deprecated since QEMU 8.1 in favor of "-run-with chroot=dir".

Look into the result of the QMP command "query-command-line-options"
to find out if "-run-with chroot=dir" is available. Then use it in
place of "-chroot".

Resolves: xen-project/xen#187
Signed-off-by: Anthony PERARD <anthony.perard@vates.tech>
---
 tools/libs/light/libxl_dm.c       | 78 +++++++++++++++++++++++++------
 tools/libs/light/libxl_internal.h |  5 ++
 2 files changed, 69 insertions(+), 14 deletions(-)

Comments

Jason Andryuk Aug. 27, 2024, 10:20 p.m. UTC | #1
On 2024-08-27 06:03, Anthony PERARD wrote:
> QEMU 9.0 have removed "-chroot" command line option, which have been
> deprecated since QEMU 8.1 in favor of "-run-with chroot=dir".
> 
> Look into the result of the QMP command "query-command-line-options"
> to find out if "-run-with chroot=dir" is available. Then use it in
> place of "-chroot".
> 
> Resolves: xen-project/xen#187
> Signed-off-by: Anthony PERARD <anthony.perard@vates.tech>

Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>

though one suggestion below.

> ---
>   tools/libs/light/libxl_dm.c       | 78 +++++++++++++++++++++++++------
>   tools/libs/light/libxl_internal.h |  5 ++
>   2 files changed, 69 insertions(+), 14 deletions(-)
> 
> diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c
> index 46babfed0b..298fbb84fe 100644
> --- a/tools/libs/light/libxl_dm.c
> +++ b/tools/libs/light/libxl_dm.c
> @@ -1183,11 +1183,12 @@ static int libxl__pre_open_qmp_socket(libxl__gc *gc, libxl_domid domid,
>   }
>   
>   static int libxl__build_device_model_args_new(libxl__gc *gc,
> -                                        const char *dm, int guest_domid,
> -                                        const libxl_domain_config *guest_config,
> -                                        char ***args, char ***envs,
> -                                        const libxl__domain_build_state *state,
> -                                        int *dm_state_fd)
> +    const char *dm, int guest_domid,
> +    const libxl_domain_config *guest_config,
> +    char ***args, char ***envs,
> +    const libxl__domain_build_state *state,
> +    const libxl__qemu_available_cmd_line *qemu_cmdline,

cmd_line/cmdline makes me think of command line strings. 
qemu_opts/qemu_cli_opts is a little more generic, to me at least.  But 
not a big deal if you want to keep it as is.

Thanks,
Jason

> +    int *dm_state_fd)
>   {
>       const libxl_domain_create_info *c_info = &guest_config->c_info;
>       const libxl_domain_build_info *b_info = &guest_config->b_info;
Anthony PERARD Aug. 28, 2024, 2:42 p.m. UTC | #2
On Tue, Aug 27, 2024 at 06:20:42PM -0400, Jason Andryuk wrote:
> On 2024-08-27 06:03, Anthony PERARD wrote:
> > QEMU 9.0 have removed "-chroot" command line option, which have been
> > deprecated since QEMU 8.1 in favor of "-run-with chroot=dir".
> > 
> > Look into the result of the QMP command "query-command-line-options"
> > to find out if "-run-with chroot=dir" is available. Then use it in
> > place of "-chroot".
> > 
> > Resolves: xen-project/xen#187
> > Signed-off-by: Anthony PERARD <anthony.perard@vates.tech>
> 
> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
> 
> though one suggestion below.
> 
> > ---
> >   tools/libs/light/libxl_dm.c       | 78 +++++++++++++++++++++++++------
> >   tools/libs/light/libxl_internal.h |  5 ++
> >   2 files changed, 69 insertions(+), 14 deletions(-)
> > 
> > diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c
> > index 46babfed0b..298fbb84fe 100644
> > --- a/tools/libs/light/libxl_dm.c
> > +++ b/tools/libs/light/libxl_dm.c
> > @@ -1183,11 +1183,12 @@ static int libxl__pre_open_qmp_socket(libxl__gc *gc, libxl_domid domid,
> >   }
> >   static int libxl__build_device_model_args_new(libxl__gc *gc,
> > -                                        const char *dm, int guest_domid,
> > -                                        const libxl_domain_config *guest_config,
> > -                                        char ***args, char ***envs,
> > -                                        const libxl__domain_build_state *state,
> > -                                        int *dm_state_fd)
> > +    const char *dm, int guest_domid,
> > +    const libxl_domain_config *guest_config,
> > +    char ***args, char ***envs,
> > +    const libxl__domain_build_state *state,
> > +    const libxl__qemu_available_cmd_line *qemu_cmdline,
> 
> cmd_line/cmdline makes me think of command line strings.
> qemu_opts/qemu_cli_opts is a little more generic, to me at least.  But not a
> big deal if you want to keep it as is.

Yes, "opts" sounds better than "cmdline" in this context.

I'll rename "libxl__qemu_available_cmd_line" to
"libxl__qemu_available_opts".

And "qemu_cmdline" to "qemu_opts", both in the struct
libxl__dm_spawn_state and as argument of functions.

Thanks,
diff mbox series

Patch

diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c
index 46babfed0b..298fbb84fe 100644
--- a/tools/libs/light/libxl_dm.c
+++ b/tools/libs/light/libxl_dm.c
@@ -1183,11 +1183,12 @@  static int libxl__pre_open_qmp_socket(libxl__gc *gc, libxl_domid domid,
 }
 
 static int libxl__build_device_model_args_new(libxl__gc *gc,
-                                        const char *dm, int guest_domid,
-                                        const libxl_domain_config *guest_config,
-                                        char ***args, char ***envs,
-                                        const libxl__domain_build_state *state,
-                                        int *dm_state_fd)
+    const char *dm, int guest_domid,
+    const libxl_domain_config *guest_config,
+    char ***args, char ***envs,
+    const libxl__domain_build_state *state,
+    const libxl__qemu_available_cmd_line *qemu_cmdline,
+    int *dm_state_fd)
 {
     const libxl_domain_create_info *c_info = &guest_config->c_info;
     const libxl_domain_build_info *b_info = &guest_config->b_info;
@@ -1778,8 +1779,13 @@  static int libxl__build_device_model_args_new(libxl__gc *gc,
         }
 
         /* Add "-chroot [dir]" to command-line */
-        flexarray_append(dm_args, "-chroot");
-        flexarray_append(dm_args, chroot_dir);
+        if (qemu_cmdline->have_runwith_chroot) {
+            flexarray_append_pair(dm_args, "-run-with",
+                                  GCSPRINTF("chroot=%s", chroot_dir));
+        } else {
+            flexarray_append(dm_args, "-chroot");
+            flexarray_append(dm_args, chroot_dir);
+        }
     }
 
     if (state->saved_state) {
@@ -2059,11 +2065,12 @@  static int libxl__build_device_model_args_new(libxl__gc *gc,
 }
 
 static int libxl__build_device_model_args(libxl__gc *gc,
-                                        const char *dm, int guest_domid,
-                                        const libxl_domain_config *guest_config,
-                                        char ***args, char ***envs,
-                                        const libxl__domain_build_state *state,
-                                        int *dm_state_fd)
+    const char *dm, int guest_domid,
+    const libxl_domain_config *guest_config,
+    char ***args, char ***envs,
+    const libxl__domain_build_state *state,
+    const libxl__qemu_available_cmd_line *qemu_cmdline,
+    int *dm_state_fd)
 /* dm_state_fd may be NULL iff caller knows we are using stubdom
  * and therefore will be passing a filename rather than a fd. */
 {
@@ -2081,7 +2088,9 @@  static int libxl__build_device_model_args(libxl__gc *gc,
         return libxl__build_device_model_args_new(gc, dm,
                                                   guest_domid, guest_config,
                                                   args, envs,
-                                                  state, dm_state_fd);
+                                                  state,
+                                                  qemu_cmdline,
+                                                  dm_state_fd);
     default:
         LOGED(ERROR, guest_domid, "unknown device model version %d",
               guest_config->b_info.device_model_version);
@@ -2403,7 +2412,9 @@  void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss)
 
     ret = libxl__build_device_model_args(gc, "stubdom-dm", guest_domid,
                                          guest_config, &args, NULL,
-                                         d_state, NULL);
+                                         d_state,
+                                         &sdss->dm.qemu_cmdline,
+                                         NULL);
     if (ret) {
         ret = ERROR_FAIL;
         goto out;
@@ -3024,6 +3035,7 @@  static void device_model_probe_detached(libxl__egc *egc,
 static void device_model_probe_cmdline(libxl__egc *egc,
     libxl__ev_qmp *qmp, const libxl__json_object *response, int rc)
 {
+    EGC_GC;
     libxl__dm_spawn_state *dmss = CONTAINER_OF(qmp, *dmss, qmp);
 
     if (rc)
@@ -3033,6 +3045,43 @@  static void device_model_probe_cmdline(libxl__egc *egc,
      * query-command-line-options response:
      * [ { 'option': 'str', 'parameters': [{ 'name': 'str', ... }] } ]
      */
+    const libxl__json_object *option;
+    for (int i_option = 0;
+         (option = libxl__json_array_get(response, i_option));
+         i_option++) {
+        const libxl__json_object *o;
+        const char *opt_str;
+
+        o = libxl__json_map_get("option", option, JSON_STRING);
+        if (!o) {
+            rc = ERROR_QEMU_API;
+            goto out;
+        }
+        opt_str = libxl__json_object_get_string(o);
+
+        if (!strcmp("run-with", opt_str)) {
+            const libxl__json_object *params;
+            const libxl__json_object *item;
+
+            params = libxl__json_map_get("parameters", option, JSON_ARRAY);
+            for (int i = 0; (item = libxl__json_array_get(params, i)); i++) {
+                o = libxl__json_map_get("name", item, JSON_STRING);
+                if (!o) {
+                    rc = ERROR_QEMU_API;
+                    goto out;
+                }
+                if (!strcmp("chroot", libxl__json_object_get_string(o))) {
+                    dmss->qemu_cmdline.have_runwith_chroot = true;
+                }
+            }
+
+            /*
+             * No need to parse more options, we are only interested with
+             * -run-with at the moment.
+             */
+            break;
+        }
+    }
 
     qmp->callback = device_model_probe_quit;
     rc = libxl__ev_qmp_send(egc, qmp, "quit", NULL);
@@ -3113,6 +3162,7 @@  static void device_model_launch(libxl__egc *egc,
 
     rc = libxl__build_device_model_args(gc, dm, domid, guest_config,
                                           &args, &envs, state,
+                                          &dmss->qemu_cmdline,
                                           &dm_state_fd);
     if (rc)
         goto out;
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index e99adc56cb..df93d904c2 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -4142,6 +4142,10 @@  _hidden void libxl__add_nics(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
 /* First layer; wraps libxl__spawn_spawn. */
 
 typedef struct libxl__dm_spawn_state libxl__dm_spawn_state;
+typedef struct libxl__qemu_available_cmd_line libxl__qemu_available_cmd_line;
+struct libxl__qemu_available_cmd_line {
+    bool have_runwith_chroot;
+};
 
 typedef void libxl__dm_spawn_cb(libxl__egc *egc, libxl__dm_spawn_state*,
                                 int rc /* if !0, error was logged */);
@@ -4154,6 +4158,7 @@  struct libxl__dm_spawn_state {
     libxl__ev_qmp qmp;
     libxl__ev_time timeout;
     libxl__dm_resume_state dmrs;
+    libxl__qemu_available_cmd_line qemu_cmdline;
     const char *dm;
     /* filled in by user, must remain valid: */
     uint32_t guest_domid; /* domain being served */