There is currently no way to get a list of devices being found inside
an environment variable.

The GNU Boot project is a boot firmware distribution that currently
ships images with a deblobbed Coreboot, GRUB, and a hand-made GRUB
configuration.

Once installed, the GRUB provided by GNU Boot is supposed to try to
find the GRUB configuration of the (usually GNU/Linux) distribution
that is installed on the computer.

To do that GNU Boot images includes a hand-made GRUB configuration
that have hardcoded devices names like md/0 or ahci0, and that loop
over that and test if grub.cfg is found in hardcoded paths like
/grub.cfg, /boot/grub.cfg, etc.

But that cannot work for LVM2 volume that have names chosen by the
user or that differ between GNU/Linux distribution.

So having a '--set=VARNAME' option in 'ls' can enable to loop over
all the device found or even build a list of LVM devices like that:

    ls --set=devices
    for device in $devices ; do
        if regexp ^lvm/ $device ; then
           append lvmvol=" $device"
        fi
    done

Then the GRUB configuration shipped by GNU Boot would simply try the
various hardcoded location of grub.cfg and boot on the first one being
found.

Right now this change only adds the ability to list devices, it
doesn't support the '-l' option.

Listing devices inside a variable also doesn't add the parenthesis
around the devices as this makes the use of the result more easy to
deal with.

Signed-off-by: Denis 'GNUtoo' Carikli <gnu...@cyberdimension.org>
---
 grub-core/commands/ls.c | 69 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 58 insertions(+), 11 deletions(-)

diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c
index 6a1c7f5d3..113235781 100644
--- a/grub-core/commands/ls.c
+++ b/grub-core/commands/ls.c
@@ -37,31 +37,69 @@ GRUB_MOD_LICENSE ("GPLv3+");
 
 static const struct grub_arg_option options[] =
   {
+    {"set",             's', 0,
+     N_("Set a variable to return value."), N_("VARNAME"), ARG_TYPE_STRING},
     {"long", 'l', 0, N_("Show a long list with more detailed information."), 
0, 0},
     {"human-readable", 'h', 0, N_("Print sizes in a human readable format."), 
0, 0},
     {"all", 'a', 0, N_("List all files."), 0, 0},
     {0, 0, 0, 0, 0, 0}
   };
 
+/* Context for grub_ls_list_devices.  */
+struct grub_ls_list_devices_ctx
+{
+  int longlist;
+  char *varname;
+};
+
 /* Helper for grub_ls_list_devices.  */
 static int
 grub_ls_print_devices (const char *name, void *data)
 {
-  int *longlist = data;
+  struct grub_ls_list_devices_ctx *ctx = data;
 
-  if (*longlist)
-    grub_normal_print_device_info (name);
+  if (ctx->longlist)
+    {
+      if (ctx->varname)
+       {
+         grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "set and longlist");
+         return GRUB_ERR_NOT_IMPLEMENTED_YET;
+       }
+
+      grub_normal_print_device_info (name);
+      return 0;
+    }
+
+  if (ctx->varname)
+    {
+      if (grub_env_get(ctx->varname))
+       grub_env_append (ctx->varname, " ");
+      grub_env_append (ctx->varname, name);
+    }
   else
-    grub_printf ("(%s) ", name);
+    {
+      grub_printf ("(%s) ", name);
+    }
 
   return 0;
 }
 
 static grub_err_t
-grub_ls_list_devices (int longlist)
+grub_ls_list_devices (int longlist, char *varname)
 {
-  grub_device_iterate (grub_ls_print_devices, &longlist);
-  grub_xputs ("\n");
+  struct grub_ls_list_devices_ctx ctx = {
+    .longlist = longlist,
+    .varname = varname,
+  };
+
+  /* Clear the variable content to be able to append inside later on */
+  if (varname)
+    grub_env_unset(varname);
+
+  grub_device_iterate (grub_ls_print_devices, &ctx);
+
+  if (!varname)
+    grub_xputs ("\n");
 
 #if 0
   {
@@ -171,13 +209,20 @@ print_files_long (const char *filename, const struct 
grub_dirhook_info *info,
 }
 
 static grub_err_t
-grub_ls_list_files (char *dirname, int longlist, int all, int human)
+grub_ls_list_files (char *dirname, int longlist, int all, int human,
+                    char *varname)
 {
   char *device_name;
   grub_fs_t fs;
   const char *path;
   grub_device_t dev;
 
+  if (varname)
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "set and list files");
+      return GRUB_ERR_NOT_IMPLEMENTED_YET;
+    }
+
   device_name = grub_file_get_device_name (dirname);
   dev = grub_device_open (device_name);
   if (! dev)
@@ -278,11 +323,13 @@ grub_cmd_ls (grub_extcmd_context_t ctxt, int argc, char 
**args)
   int i;
 
   if (argc == 0)
-    grub_ls_list_devices (state[0].set);
+    grub_ls_list_devices (state[1].set,
+                         state[0].set ? state[0].arg : NULL);
   else
     for (i = 0; i < argc; i++)
-      grub_ls_list_files (args[i], state[0].set, state[2].set,
-                         state[1].set);
+      grub_ls_list_files (args[i], state[1].set, state[3].set,
+                         state[2].set,
+                         state[0].set ? state[0].arg : NULL);
 
   return 0;
 }
-- 
2.45.1


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to