+2010-09-16 Colin Watson <cjwatson@ubuntu.com>
+
+ Support RAID on virtio devices, and others.
+
+ * grub-core/kern/emu/getroot.c [__MINGW32__] (find_root_device):
+ Rename to ...
+ [__MINGW32__] (grub_find_device): ... this.
+ [! __MINGW32__ && ! __CYGWIN__] (find_root_device): Rename to ...
+ [! __MINGW32__ && ! __CYGWIN__] (grub_find_device): ... this. Use a
+ reasonable default if dir is NULL.
+ [! __MINGW32__ && __CYGWIN__] (find_cygwin_root_device): Rename to
+ ...
+ [! __MINGW32__ && __CYGWIN__] (grub_find_device): ... this.
+ (grub_guess_root_device): Update callers.
+ * include/grub/emu/getroot.h (grub_find_device): Add prototype.
+
+ * util/raid.c (grub_util_getdiskname): Remove.
+ (grub_util_raid_getmembers): Use grub_find_device rather than
+ grub_util_getdiskname.
+
2010-09-16 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (serial): Remove obsolete comment about GRUB
#ifdef __MINGW32__
-static char *
-find_root_device (const char *dir __attribute__ ((unused)),
+char *
+grub_find_device (const char *dir __attribute__ ((unused)),
dev_t dev __attribute__ ((unused)))
{
return 0;
#elif ! defined(__CYGWIN__)
-static char *
-find_root_device (const char *dir, dev_t dev)
+char *
+grub_find_device (const char *dir, dev_t dev)
{
DIR *dp;
char *saved_cwd;
struct dirent *ent;
+ if (! dir)
+ {
+#ifdef __CYGWIN__
+ return NULL;
+#else
+ dir = "/dev";
+#endif
+ }
+
dp = opendir (dir);
if (! dp)
return 0;
/* Find it recursively. */
char *res;
- res = find_root_device (ent->d_name, dev);
+ res = grub_find_device (ent->d_name, dev);
if (res)
{
return serial;
}
-static char *
-find_cygwin_root_device (const char *path, dev_t dev)
+char *
+grub_find_device (const char *path, dev_t dev)
{
/* No root device for /cygdrive. */
if (dev == (DEV_CYGDRIVE_MAJOR << 16))
/* Cygwin returns the partition serial number in stat.st_dev.
This is never identical to the device number of the emulated
- /dev/sdXN device, so above find_root_device () does not work.
+ /dev/sdXN device, so above grub_find_device () does not work.
Search the partition with the same serial in boot sector instead. */
char devpath[sizeof ("/dev/sda15") + 13]; /* Size + Paranoia. */
int d;
#ifdef __CYGWIN__
/* Cygwin specific function. */
- os_dev = find_cygwin_root_device (dir, st.st_dev);
+ os_dev = grub_find_device (dir, st.st_dev);
#else
/* This might be truly slow, but is there any better way? */
- os_dev = find_root_device ("/dev", st.st_dev);
+ os_dev = grub_find_device ("/dev", st.st_dev);
#endif
#endif /* !__GNU__ */
#ifndef GRUB_UTIL_GETROOT_HEADER
#define GRUB_UTIL_GETROOT_HEADER 1
+#include <sys/types.h>
+
enum grub_dev_abstraction_types {
GRUB_DEV_ABSTRACTION_NONE,
GRUB_DEV_ABSTRACTION_LVM,
GRUB_DEV_ABSTRACTION_RAID,
};
+char *grub_find_device (const char *dir, dev_t dev);
char *grub_guess_root_device (const char *dir);
int grub_util_get_dev_abstraction (const char *os_dev);
char *grub_util_get_grub_dev (const char *os_dev);
#include <grub/emu/misc.h>
#include <grub/util/misc.h>
#include <grub/util/raid.h>
+#include <grub/emu/getroot.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
+#include <sys/types.h>
#include <linux/types.h>
#include <linux/major.h>
#include <linux/raid/md_p.h>
#include <linux/raid/md_u.h>
-static char *
-grub_util_getdiskname (int major, int minor)
-{
- char *name = xmalloc (15);
-
- if (major == LOOP_MAJOR)
- sprintf (name, "/dev/loop%d", minor);
- else if (major == IDE0_MAJOR)
- sprintf (name, "/dev/hd%c", 'a' + minor / 64);
- else if (major == IDE1_MAJOR)
- sprintf (name, "/dev/hd%c", 'c' + minor / 64);
- else if (major == IDE2_MAJOR)
- sprintf (name, "/dev/hd%c", 'e' + minor / 64);
- else if (major == IDE3_MAJOR)
- sprintf (name, "/dev/hd%c", 'g' + minor / 64);
- else if (major == SCSI_DISK0_MAJOR)
- sprintf (name, "/dev/sd%c", 'a' + minor / 16);
- else
- grub_util_error ("unknown device number: %d, %d", major, minor);
-
- return name;
-}
-
char **
grub_util_raid_getmembers (char *name)
{
if (disk.state & (1 << MD_DISK_ACTIVE))
{
- devicelist[j] = grub_util_getdiskname (disk.major, disk.minor);
+ devicelist[j] = grub_find_device (NULL,
+ makedev (disk.major, disk.minor));
j++;
}
}