2008-08-23 Bean <bean123ch@gmail.com>
* conf/common.rmk (grub_probe_SOURCES): Add disk/mdraid_linux.c. (grub_fstest_SOURCES): Add disk/raid5_recover.c, disk/raid6_recover.c, disk/mdraid_linux.c and disk/dmraid_nvidia.c and lib/crc.c. (pkglib_MODULES): Add raid5rec.mod, raid6rec.mod, mdraid.mod and dm_nv.mod. (raid5rec_mod_SOURCES): New macro. (raid5rec_mod_CFLAGS): Likewise. (raid5rec_mod_LDFLAGS): Likewise. (raid6rec_mod_SOURCES): Likewise. (raid6rec_mod_CFLAGS): Likewise. (raid6rec_mod_LDFLAGS): Likewise. (mdraid_mod_SOURCES): Likewise. (mdraid_mod_CFLAGS): Likewise. (mdraid_mod_LDFLAGS): Likewise. (dm_nv_mod_SOURCES): Likewise. (dm_nv_mod_CFLAGS): Likewise. (dm_nv_mod_LDFLAGS): Likewise. * conf/i386-pc.rmk (grub_setup_SOURCES): Add disk/mdraid_linux.c. (grub_emu_SOURCES): Add disk/raid5_recover.c, disk/raid6_recover.c, disk/mdraid_linux.c and disk/dmraid_nvidia.c. * conf/i386-coreboot.rmk (grub_emu_SOURCES): Add disk/raid5_recover.c, disk/raid6_recover.c, disk/mdraid_linux.c and disk/dmraid_nvidia.c. * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. * disk/raid5_recover.c: New file. * disk/raid6_recover.c: Likewise. * disk/mdraid_linux.c: Likewise. * disk/dmraid_nvidia.c: Likewise. * disk/i386/pc/biosdisk.c: Set total_sectors of cdrom device to ULONG_MAX. * disk/raid.c (grub_raid_open): Use the size of the smallest disk to calculate the size of raid device. (grub_raid_read): Simplify raid0 code. Support raid4, raid6 and four different layout of raid5. (grub_raid_scan_device): Remove code specific to mdraid. (grub_raid_list): New variable. (free_array): New function. (grub_raid_register): Likewise. (grub_raid_unregister): Likewise. (grub_raid_rescan): Likewise. (GRUB_MOD_INIT): Don't iterate device here. (GRUB_MOD_FINI): Use free_array to release resource. * include/grub/raid.h: Remove macro and structure specific to mdraid. (grub_raid5_recover_func_t): New function variable type. (grub_raid6_recover_func_t): Likewise. (grub_raid5_recover_func): New variable. (grub_raid6_recover_func): Likewise. (grub_raid_register): New function. (grub_raid_unregister): Likewise. (grub_raid_rescan): Likewise. (grub_raid_block_xor): Likewise. * util/grub-fstest.c: Add #include <grub/raid.h> and <grub/lib/crc.h>. (CMD_CRC): New macro. (part): Removed. (read_file): Handle device as well as file. (cmd_crc): New function. (fstest): Handle multiple disks. (options): Remove part, raw and long, add root and diskcount. (usage): Add crc, remove -p, -r, -l, add -r and -c. (main): Find the first non option entry and ignore subsequence options, add handling for the new options, support multiple disks. * util/grub-probe.c (probe): Add mdraid to abstraction_name.
This commit is contained in:
parent
29c1891563
commit
5ed20adcb9
24 changed files with 1877 additions and 635 deletions
|
@ -29,7 +29,9 @@
|
|||
#include <grub/term.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/raid.h>
|
||||
#include <grub/lib/hexdump.h>
|
||||
#include <grub/lib/crc.h>
|
||||
|
||||
#include <grub_fstest_init.h>
|
||||
|
||||
|
@ -136,12 +138,12 @@ grub_unregister_command (const char *name __attribute__ ((unused)))
|
|||
#define CMD_CP 2
|
||||
#define CMD_CMP 3
|
||||
#define CMD_HEX 4
|
||||
#define CMD_BLOCKLIST 5
|
||||
#define CMD_CRC 6
|
||||
#define CMD_BLOCKLIST 7
|
||||
|
||||
#define BUF_SIZE 32256
|
||||
|
||||
static grub_off_t skip, leng;
|
||||
static char *part;
|
||||
|
||||
static void
|
||||
read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len))
|
||||
|
@ -150,16 +152,53 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len))
|
|||
grub_file_t file;
|
||||
grub_off_t ofs, len;
|
||||
|
||||
file = grub_file_open (pathname);
|
||||
if (!file)
|
||||
if ((pathname[0] == '-') && (pathname[1] == 0))
|
||||
{
|
||||
grub_util_error ("cannot open file %s.\n", pathname);
|
||||
grub_device_t dev;
|
||||
|
||||
dev = grub_device_open (0);
|
||||
if ((! dev) || (! dev->disk))
|
||||
grub_util_error ("Can\'t open device.");
|
||||
|
||||
grub_util_info ("total sectors : %lld.",
|
||||
(unsigned long long) dev->disk->total_sectors);
|
||||
|
||||
if (! leng)
|
||||
leng = (dev->disk->total_sectors << GRUB_DISK_SECTOR_BITS) - skip;
|
||||
|
||||
while (leng)
|
||||
{
|
||||
grub_size_t len;
|
||||
|
||||
len = (leng > BUF_SIZE) ? BUF_SIZE : leng;
|
||||
|
||||
if (grub_disk_read (dev->disk, 0, skip, len, buf))
|
||||
grub_util_error ("Disk read fails at offset %lld, length %d.",
|
||||
skip, len);
|
||||
|
||||
if (hook (skip, buf, len))
|
||||
break;
|
||||
|
||||
skip += len;
|
||||
leng -= len;
|
||||
}
|
||||
|
||||
grub_device_close (dev);
|
||||
return;
|
||||
}
|
||||
|
||||
file = grub_file_open (pathname);
|
||||
if (!file)
|
||||
{
|
||||
grub_util_error ("cannot open file %s.", pathname);
|
||||
return;
|
||||
}
|
||||
|
||||
grub_util_info ("file size : %lld.", (unsigned long long) file->size);
|
||||
|
||||
if (skip > file->size)
|
||||
{
|
||||
grub_util_error ("invalid skip value %d.\n");
|
||||
grub_util_error ("invalid skip value %d.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -177,7 +216,7 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len))
|
|||
sz = grub_file_read (file, buf, (len > BUF_SIZE) ? BUF_SIZE : len);
|
||||
if (sz < 0)
|
||||
{
|
||||
grub_util_error ("read error at offset %llu.\n", ofs);
|
||||
grub_util_error ("read error at offset %llu.", ofs);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -203,17 +242,17 @@ cmd_cp (char *src, char *dest)
|
|||
|
||||
if ((int) fwrite (buf, 1, len, ff) != len)
|
||||
{
|
||||
grub_util_error ("write error.\n");
|
||||
grub_util_error ("write error.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ff = fopen (dest, "w");
|
||||
ff = fopen (dest, "wb");
|
||||
if (ff == NULL)
|
||||
{
|
||||
grub_util_error ("open error.\n");
|
||||
grub_util_error ("open error.");
|
||||
return;
|
||||
}
|
||||
read_file (src, cp_hook);
|
||||
|
@ -231,7 +270,7 @@ cmd_cmp (char *src, char *dest)
|
|||
{
|
||||
if ((int) fread (buf_1, 1, len, ff) != len)
|
||||
{
|
||||
grub_util_error ("read error at offset %llu.\n", ofs);
|
||||
grub_util_error ("read error at offset %llu.", ofs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -242,22 +281,22 @@ cmd_cmp (char *src, char *dest)
|
|||
for (i = 0; i < len; i++, ofs++)
|
||||
if (buf_1[i] != buf[i])
|
||||
{
|
||||
grub_util_error ("compare fail at offset %llu.\n", ofs);
|
||||
grub_util_error ("compare fail at offset %llu.", ofs);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ff = fopen (dest, "r");
|
||||
ff = fopen (dest, "rb");
|
||||
if (ff == NULL)
|
||||
{
|
||||
grub_util_error ("open error.\n");
|
||||
grub_util_error ("open error.");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((skip) && (fseeko (ff, skip, SEEK_SET)))
|
||||
grub_util_error ("seek error.\n");
|
||||
grub_util_error ("seek error.");
|
||||
|
||||
read_file (src, cmp_hook);
|
||||
fclose (ff);
|
||||
|
@ -277,28 +316,44 @@ cmd_hex (char *pathname)
|
|||
}
|
||||
|
||||
static void
|
||||
fstest (char *image_path, int cmd, int n, char **args)
|
||||
cmd_crc (char *pathname)
|
||||
{
|
||||
char host_file[7 + grub_strlen (image_path) + 1];
|
||||
char device_name[(part) ? (6 + grub_strlen (part)) : 5];
|
||||
char *argv[3] = { "-p", "loop", host_file };
|
||||
grub_uint32_t crc = 0;
|
||||
|
||||
auto int crc_hook (grub_off_t ofs, char *buf, int len);
|
||||
int crc_hook (grub_off_t ofs, char *buf, int len)
|
||||
{
|
||||
(void) ofs;
|
||||
|
||||
grub_sprintf (host_file, "(host)/%s", image_path);
|
||||
crc = grub_getcrc32 (crc, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (execute_command (&cmd_loopback, 3, argv))
|
||||
read_file (pathname, crc_hook);
|
||||
printf ("%08x\n", crc);
|
||||
}
|
||||
|
||||
static void
|
||||
fstest (char **images, int num_disks, int cmd, int n, char **args)
|
||||
{
|
||||
char host_file[128];
|
||||
char loop_name[8];
|
||||
char *argv[3] = { "-p", loop_name, host_file};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_disks; i++)
|
||||
{
|
||||
grub_util_error ("loopback command fails.\n");
|
||||
goto fail;
|
||||
if (grub_strlen (images[i]) + 7 > sizeof (host_file))
|
||||
grub_util_error ("Pathname %s too long.", images[i]);
|
||||
|
||||
grub_sprintf (loop_name, "loop%d", i);
|
||||
grub_sprintf (host_file, "(host)%s", images[i]);
|
||||
|
||||
if (execute_command (&cmd_loopback, 3, argv))
|
||||
grub_util_error ("loopback command fails.");
|
||||
}
|
||||
|
||||
if (part)
|
||||
grub_sprintf (device_name, "loop,%s", part);
|
||||
else
|
||||
grub_strcpy (device_name, "loop");
|
||||
|
||||
grub_env_set ("root", device_name);
|
||||
|
||||
grub_raid_rescan ();
|
||||
switch (cmd)
|
||||
{
|
||||
case CMD_LS:
|
||||
|
@ -313,29 +368,32 @@ fstest (char *image_path, int cmd, int n, char **args)
|
|||
case CMD_HEX:
|
||||
cmd_hex (args[0]);
|
||||
break;
|
||||
case CMD_CRC:
|
||||
cmd_crc (args[0]);
|
||||
break;
|
||||
case CMD_BLOCKLIST:
|
||||
execute_command (&cmd_blocklist, n, args);
|
||||
grub_printf ("\n");
|
||||
}
|
||||
|
||||
fail:
|
||||
|
||||
argv[0] = "-d";
|
||||
|
||||
execute_command (&cmd_loopback, 2, argv);
|
||||
for (i = 0; i < num_disks; i++)
|
||||
{
|
||||
grub_sprintf (loop_name, "loop%d", i);
|
||||
execute_command (&cmd_loopback, 2, argv);
|
||||
}
|
||||
}
|
||||
|
||||
static struct option options[] = {
|
||||
{"part", required_argument, 0, 'p'},
|
||||
{"root", required_argument, 0, 'r'},
|
||||
{"skip", required_argument, 0, 's'},
|
||||
{"length", required_argument, 0, 'n'},
|
||||
{"diskcount", required_argument, 0, 'c'},
|
||||
{"debug", required_argument, 0, 'd'},
|
||||
{"raw", no_argument, 0, 'r'},
|
||||
{"long", no_argument, 0, 'l'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -351,17 +409,17 @@ Usage: grub-fstest [OPTION]... IMAGE_PATH COMMANDS\n\
|
|||
Debug tool for filesystem driver.\n\
|
||||
\nCommands:\n\
|
||||
ls PATH list files in PATH\n\
|
||||
cp SRC DEST copy file to local system\n\
|
||||
cmp SRC DEST compare files\n\
|
||||
hex FILE hex dump FILE\n\
|
||||
cp FILE LOCAL copy FILE to local file LOCAL\n\
|
||||
cmp FILE LOCAL compare FILE with local file LOCAL\n\
|
||||
hex FILE Hex dump FILE\n\
|
||||
crc FILE Get crc32 checksum of FILE\n\
|
||||
blocklist FILE display blocklist of FILE\n\
|
||||
\nOptions:\n\
|
||||
-p, --part=NUM select partition NUM\n\
|
||||
-r, --root=DEVICE_NAME set root device\n\
|
||||
-s, --skip=N skip N bytes from output file\n\
|
||||
-n, --length=N handle N bytes in output file\n\
|
||||
-c, --diskcount=N N input files\n\
|
||||
-d, --debug=S Set debug environment variable\n\
|
||||
-r, --raw disable auto decompression\n\
|
||||
-l, --long show long directory list\n\
|
||||
-h, --help display this message and exit\n\
|
||||
-V, --version print version information and exit\n\
|
||||
-v, --verbose print verbose messages\n\
|
||||
|
@ -374,45 +432,66 @@ Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
|
|||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
char *image_path, *debug_str = 0;
|
||||
int cmd, is_raw = 0, is_long = 0;
|
||||
char *debug_str = 0, *root = 0, *default_root, *alloc_root;
|
||||
int i, cmd, num_opts, image_index, num_disks = 1;
|
||||
|
||||
progname = "grub-fstest";
|
||||
|
||||
/* Find the first non option entry. */
|
||||
for (num_opts = 1; num_opts < argc; num_opts++)
|
||||
if (argv[num_opts][0] == '-')
|
||||
{
|
||||
if ((argv[num_opts][2] == 0) && (num_opts < argc - 1) &&
|
||||
((argv[num_opts][1] == 'r') ||
|
||||
(argv[num_opts][1] == 's') ||
|
||||
(argv[num_opts][1] == 'n') ||
|
||||
(argv[num_opts][1] == 'c') ||
|
||||
(argv[num_opts][1] == 'd')))
|
||||
num_opts++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
/* Check for options. */
|
||||
while (1)
|
||||
{
|
||||
int c = getopt_long (argc, argv, "p:s:n:d:rlhVv", options, 0);
|
||||
int c = getopt_long (num_opts, argv, "r:s:n:c:d:hVv", options, 0);
|
||||
char *p;
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
else
|
||||
switch (c)
|
||||
{
|
||||
case 'p':
|
||||
part = optarg;
|
||||
case 'r':
|
||||
root = optarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
skip = grub_strtoul (optarg, NULL, 0);
|
||||
skip = grub_strtoul (optarg, &p, 0);
|
||||
if (*p == 's')
|
||||
skip <<= GRUB_DISK_SECTOR_BITS;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
leng = grub_strtoul (optarg, NULL, 0);
|
||||
leng = grub_strtoul (optarg, &p, 0);
|
||||
if (*p == 's')
|
||||
leng <<= GRUB_DISK_SECTOR_BITS;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
num_disks = grub_strtoul (optarg, NULL, 0);
|
||||
if (num_disks < 1)
|
||||
{
|
||||
fprintf (stderr, "Invalid disk count.\n");
|
||||
usage (1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
debug_str = optarg;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
is_raw = 1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
is_long = 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage (0);
|
||||
break;
|
||||
|
@ -432,52 +511,53 @@ main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
/* Obtain PATH. */
|
||||
if (optind >= argc)
|
||||
if (optind + num_disks - 1 >= argc)
|
||||
{
|
||||
fprintf (stderr, "No path is specified.\n");
|
||||
fprintf (stderr, "Not enough pathname.\n");
|
||||
usage (1);
|
||||
}
|
||||
|
||||
image_path = argv[optind];
|
||||
|
||||
if (*image_path != '/')
|
||||
{
|
||||
fprintf (stderr, "Must use absolute path.\n");
|
||||
usage (1);
|
||||
}
|
||||
|
||||
optind++;
|
||||
image_index = optind;
|
||||
for (i = 0; i < num_disks; i++, optind++)
|
||||
if (argv[optind][0] != '/')
|
||||
{
|
||||
fprintf (stderr, "Must use absolute path.\n");
|
||||
usage (1);
|
||||
}
|
||||
|
||||
cmd = 0;
|
||||
if (optind < argc)
|
||||
{
|
||||
int nparm = 1;
|
||||
int nparm = 0;
|
||||
|
||||
if (!grub_strcmp (argv[optind], "ls"))
|
||||
{
|
||||
cmd = CMD_LS;
|
||||
if (is_long)
|
||||
argv[optind--] = "-l";
|
||||
else
|
||||
nparm = 0;
|
||||
}
|
||||
{
|
||||
cmd = CMD_LS;
|
||||
}
|
||||
else if (!grub_strcmp (argv[optind], "cp"))
|
||||
{
|
||||
cmd = CMD_CP;
|
||||
nparm = 2;
|
||||
nparm = 2;
|
||||
}
|
||||
else if (!grub_strcmp (argv[optind], "cmp"))
|
||||
{
|
||||
cmd = CMD_CMP;
|
||||
nparm = 2;
|
||||
nparm = 2;
|
||||
}
|
||||
else if (!grub_strcmp (argv[optind], "hex"))
|
||||
{
|
||||
cmd = CMD_HEX;
|
||||
nparm = 1;
|
||||
}
|
||||
else if (!grub_strcmp (argv[optind], "crc"))
|
||||
{
|
||||
cmd = CMD_CRC;
|
||||
nparm = 1;
|
||||
}
|
||||
else if (!grub_strcmp (argv[optind], "blocklist"))
|
||||
{
|
||||
cmd = CMD_BLOCKLIST;
|
||||
nparm = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -503,14 +583,31 @@ main (int argc, char *argv[])
|
|||
/* Initialize all modules. */
|
||||
grub_init_all ();
|
||||
|
||||
if (is_raw)
|
||||
grub_env_set ("filehook", "0");
|
||||
|
||||
if (debug_str)
|
||||
grub_env_set ("debug", debug_str);
|
||||
|
||||
default_root = (num_disks == 1) ? "loop0" : "md0";
|
||||
alloc_root = 0;
|
||||
if (root)
|
||||
{
|
||||
if ((*root >= '0') && (*root <= '9'))
|
||||
{
|
||||
alloc_root = xmalloc (strlen (default_root) + strlen (root) + 2);
|
||||
|
||||
sprintf (alloc_root, "%s,%s", default_root, root);
|
||||
root = alloc_root;
|
||||
}
|
||||
}
|
||||
else
|
||||
root = default_root;
|
||||
|
||||
grub_env_set ("root", root);
|
||||
|
||||
if (alloc_root)
|
||||
free (alloc_root);
|
||||
|
||||
/* Do it. */
|
||||
fstest (image_path + 1, cmd, argc - optind, argv + optind);
|
||||
fstest (argv + image_index, num_disks, cmd, argc - optind, argv + optind);
|
||||
|
||||
/* Free resources. */
|
||||
grub_fini_all ();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue