grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Add grub-fstest cat subcommand


From: Colin Watson
Subject: [PATCH] Add grub-fstest cat subcommand
Date: Mon, 21 Mar 2011 18:17:48 +0000
User-agent: Mutt/1.5.20 (2009-06-14)

This would make it easier to use grub-fstest to inspect files in
filesystems supported by GRUB without needing to mount the device.  The
same thing can be done using the cp subcommand, but that requires a
temporary file which often isn't needed.  A cat subcommand is generally
more convenient.

For context: temporarily mounting filesystems in the context of an OS
installer or a tool such as os-prober can be problematic on Linux.  In
particular, if you want to inspect files on a journalled filesystem,
then you have three choices to the best of my knowledge:

  1) Just go ahead and mount it read-only.  This seems superficially
     sensible.  Unfortunately, Linux's journalling filesystem
     implementations will write to the block device anyway.  If the
     filesystem was hibernated, disaster will ensue.  (And, on
     principle, the kinds of places where I'm doing this kind of
     read-only mount, such as os-prober, should never write to the
     disk.)

  2) Mark the block device read-only using blockdev, to ensure that even
     journalling filesystems will never write to it.  This solves the
     hibernation problem, but has two other flaws.  If the journal needs
     recovery, mounting will fail when an ordinary read-only mount would
     succeed; and blockdev has system-wide effect, so this will
     interfere with anything unlucky enough to be trying to mount the
     filesystem for real at the same time.

  3) Create a device-mapper snapshot of the block device and operate on
     that.  Unfortunately, if the block device is not itself a
     device-mapper device, this increments the reference count of the
     block device such that you can't mount the filesystem on it
     ("/dev/foo already mounted or /mnt busy").

I'm thus getting increasingly tempted to use grub-fstest for this kind
of application wherever possible.  Of course we need a fallback for
architectures where GRUB doesn't yet work, but aside from that I suspect
that it would make things significantly more reliable.

2011-03-21  Colin Watson  <address@hidden>

        * util/grub-fstest.c (cmd_cat): New function.
        (fstest): Handle CMD_CAT.
        (options): Add cat.
        (argp_parser): Handle cat.

=== modified file 'util/grub-fstest.c'
--- util/grub-fstest.c  2010-09-20 18:09:31 +0000
+++ util/grub-fstest.c  2011-03-21 17:32:32 +0000
@@ -54,12 +54,15 @@ execute_command (char *name, int n, char
   return (cmd->func) (cmd, n, args);
 }
 
-#define CMD_LS          1
-#define CMD_CP          2
-#define CMD_CMP         3
-#define CMD_HEX         4
-#define CMD_CRC         6
-#define CMD_BLOCKLIST   7
+enum {
+  CMD_LS = 1,
+  CMD_CP,
+  CMD_CAT,
+  CMD_CMP,
+  CMD_HEX,
+  CMD_CRC,
+  CMD_BLOCKLIST
+};
 
 #define BUF_SIZE  32256
 
@@ -182,6 +185,26 @@ cmd_cp (char *src, char *dest)
 }
 
 static void
+cmd_cat (char *src)
+{
+  auto int cat_hook (grub_off_t ofs, char *buf, int len);
+  int cat_hook (grub_off_t ofs, char *buf, int len)
+  {
+    (void) ofs;
+
+    if ((int) fwrite (buf, 1, len, stdout) != len)
+      {
+       grub_util_error (_("write error"));
+       return 1;
+      }
+
+    return 0;
+  }
+
+  read_file (src, cat_hook);
+}
+
+static void
 cmd_cmp (char *src, char *dest)
 {
   FILE *ff;
@@ -312,6 +335,9 @@ fstest (int n, char **args)
     case CMD_CP:
       cmd_cp (args[0], args[1]);
       break;
+    case CMD_CAT:
+      cmd_cat (args[0]);
+      break;
     case CMD_CMP:
       cmd_cmp (args[0], args[1]);
       break;
@@ -347,6 +373,7 @@ static struct argp_option options[] = {
   {0,          0, 0      , OPTION_DOC, N_("Commands:"), 1},
   {N_("ls PATH"),  0, 0      , OPTION_DOC, N_("List files in PATH."), 1},
   {N_("cp FILE LOCAL"),  0, 0, OPTION_DOC, N_("Copy FILE to local file 
LOCAL."), 1},
+  {N_("cat FILE"), 0, 0      , OPTION_DOC, N_("Copy FILE to standard 
output."), 1},
   {N_("cmp FILE LOCAL"), 0, 0, OPTION_DOC, N_("Compare FILE with local file 
LOCAL."), 1},
   {N_("hex FILE"), 0, 0      , OPTION_DOC, N_("Hex dump FILE."), 1},
   {N_("crc FILE"), 0, 0     , OPTION_DOC, N_("Get crc32 checksum of FILE."), 
1},
@@ -459,6 +486,11 @@ argp_parser (int key, char *arg, struct
          cmd = CMD_CP;
           nparm = 2;
        }
+      else if (!grub_strcmp (arg, "cat"))
+       {
+         cmd = CMD_CAT;
+         nparm = 1;
+       }
       else if (!grub_strcmp (arg, "cmp"))
        {
          cmd = CMD_CMP;

-- 
Colin Watson                                       address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]