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:
bean 2008-08-23 14:51:19 +00:00
parent 29c1891563
commit 5ed20adcb9
24 changed files with 1877 additions and 635 deletions

View file

@ -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 ();