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 <cjwat...@ubuntu.com> * 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 [cjwat...@ubuntu.com] _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel