grub-devel
[Top][All Lists]
Advanced

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

Re: Bug#461442: detection of other OSes in update-grub


From: Fabian Greffrath
Subject: Re: Bug#461442: detection of other OSes in update-grub
Date: Mon, 04 Feb 2008 09:43:58 +0100
User-agent: Thunderbird 2.0.0.9 (Windows/20071031)

Hi there,

Robert Millan schrieb:
If you want the former, feel free to send a patch to grub-devel.  For the
latter, look at my questions and send some feedback.

please find attached a patch that adds a new parameter '--device, -d' to grub-probe. If this parameter is set, grub-probe expects the given argument to be a block device. All of the '--target' parameters work with this option as well. If the '--device' parameter is not set, grub-probe will work as before. Furthermore I had to add a new public function to getroot.c that returns the given argument if it is a block device and returns NULL else. This was necessary, because else you could force grub-probe to print 'foobar' if run as 'grub-probe --target=device --device foobar'.

I consider this (i.e. adding a new option to grub-probe) a better solution than writing a separate tool only for this purpose.

The second file that I attached is the 30_os-prober script making use of the new grub-probe feature. Please note that the 'case ... in' part is only run if 'grub-probe --device' actually returns something usefull.

I am looking forward to your feedback.

Cheers,
Fabian

--
Dipl.-Phys. Fabian Greffrath

Ruhr-Universität Bochum
Lehrstuhl für Energieanlagen und Energieprozesstechnik (LEAT)
Universitätsstr. 150, IB 3/134
D-44780 Bochum

Telefon: +49 (0)234 / 32-26334
Fax:     +49 (0)234 / 32-14227
E-Mail:  address@hidden

diff -urNad grub2-1.95+20080201~/include/grub/util/getroot.h 
grub2-1.95+20080201/include/grub/util/getroot.h
--- grub2-1.95+20080201~/include/grub/util/getroot.h    2008-01-12 
16:11:56.000000000 +0100
+++ grub2-1.95+20080201/include/grub/util/getroot.h     2008-02-03 
18:14:11.000000000 +0100
@@ -29,5 +29,6 @@
 char *grub_get_prefix (const char *dir);
 int grub_util_get_dev_abstraction (const char *os_dev);
 char *grub_util_get_grub_dev (const char *os_dev);
+char *grub_util_check_block_device (const char *blk_dev);
 
 #endif /* ! GRUB_UTIL_GETROOT_HEADER */
diff -urNad grub2-1.95+20080201~/util/getroot.c 
grub2-1.95+20080201/util/getroot.c
--- grub2-1.95+20080201~/util/getroot.c 2008-01-12 16:11:56.000000000 +0100
+++ grub2-1.95+20080201/util/getroot.c  2008-02-03 21:56:29.000000000 +0100
@@ -327,3 +327,17 @@
 
   return grub_dev;
 }
+
+char *
+grub_util_check_block_device (const char *blk_dev)
+{
+  struct stat st;
+
+  if (stat (blk_dev, &st) < 0)
+    grub_util_error ("Cannot stat `%s'", blk_dev);
+
+  if (S_ISBLK (st.st_mode))
+    return strdup(blk_dev);
+  else
+    return 0;
+}
diff -urNad grub2-1.95+20080201~/util/grub-probe.c 
grub2-1.95+20080201/util/grub-probe.c
--- grub2-1.95+20080201~/util/grub-probe.c      2008-01-25 23:33:57.000000000 
+0100
+++ grub2-1.95+20080201/util/grub-probe.c       2008-02-03 19:30:50.000000000 
+0100
@@ -50,6 +50,7 @@
 };
 
 int print = PRINT_FS;
+unsigned int argument_is_device = 0;
 
 void
 grub_putchar (int c)
@@ -84,9 +85,18 @@
   int abstraction_type;
   grub_device_t dev = NULL;
   
-  device_name = grub_guess_root_device (path);
+  if (argument_is_device)
+    device_name = grub_util_check_block_device (path);
+  else
+    device_name = grub_guess_root_device (path);
+  
   if (! device_name)
-    grub_util_error ("cannot find a device for %s.\n", path);
+    {
+      if (argument_is_device)
+        grub_util_error ("%s is not a block device.\n", path);
+      else
+        grub_util_error ("cannot find a device for %s.\n", path);
+    }
 
   if (print == PRINT_DEVICE)
     {
@@ -201,6 +211,7 @@
 
 static struct option options[] =
   {
+    {"device", no_argument, 0, 'd'},
     {"device-map", required_argument, 0, 'm'},
     {"target", required_argument, 0, 't'},
     {"help", no_argument, 0, 'h'},
@@ -217,10 +228,11 @@
             "Try ``grub-probe --help'' for more information.\n");
   else
     printf ("\
-Usage: grub-probe [OPTION]... PATH\n\
+Usage: grub-probe [OPTION]... [PATH|DEVICE]\n\
 \n\
-Probe device information for a given path.\n\
+Probe device information for a given path or device.\n\
 \n\
+  -d, --device              given argument is a system device, not a path\n\
   -m, --device-map=FILE     use FILE as the device map [default=%s]\n\
   -t, --target=(fs|drive|device|partmap|abstraction)\n\
                             print filesystem module, GRUB drive, system 
device, partition map module or abstraction module [default=fs]\n\
@@ -246,13 +258,17 @@
   /* Check for options.  */
   while (1)
     {
-      int c = getopt_long (argc, argv, "m:t:hVv", options, 0);
+      int c = getopt_long (argc, argv, "dm:t:hVv", options, 0);
       
       if (c == -1)
        break;
       else
        switch (c)
          {
+         case 'd':
+           argument_is_device = 1;
+           break;
+
          case 'm':
            if (dev_map)
              free (dev_map);
#! /bin/sh -e

# update-grub helper script.
# <insert copyright and license blurb here>

if [ -x "`which os-prober 2>/dev/null`" ] ; then
  OSPROBED="`os-prober | tr ' ' '|' | paste -s -d ' '`"
fi

if [ -n "${OSPROBED}" ] ; then
  for OS in ${OSPROBED} ; do
    DEVICE="`echo ${OS} | cut -d ':' -f 1`"
    LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '|' ' '`"
    LABEL="`echo ${OS} | cut -d ':' -f 3 | tr '|' ' '`"
    BOOT="`echo ${OS} | cut -d ':' -f 4`"

    if [ -z "${LONGNAME}" ] ; then
      LONGNAME="${LABEL}"
    fi

    echo "Found ${LONGNAME} on ${DEVICE}" >&2
    
    TESTDEVICE="`grub-probe --target=device $0`"
    if [ -n "`grub-probe --target=drive --device ${TESTDEVICE} 2>/dev/null`" ] 
; then
      case "${BOOT}" in
        chain)
          CHAINROOT="`grub-probe --target=drive --device ${DEVICE}`"

          cat << EOF
menuentry "${LONGNAME} (on ${DEVICE})" {
        set root=${CHAINROOT}
        chainloader +1
}
EOF
        ;;
        linux)
          if [ -x "`which linux-boot-prober 2>/dev/null`" ] ; then
            LINUXPROBED="`linux-boot-prober ${DEVICE} | tr ' ' '|' | paste -s 
-d ' '`"
          fi

          if [ -n "${LINUXPROBED}" ] ; then
            for LINUX in ${LINUXPROBED} ; do
              LROOT="`echo ${LINUX} | cut -d ':' -f 1`"
              LBOOT="`echo ${LINUX} | cut -d ':' -f 2`"
              LLABEL="`echo ${LINUX} | cut -d ':' -f 3 | tr '|' ' '`"
              LKERNEL="`echo ${LINUX} | cut -d ':' -f 4`"
              LINITRD="`echo ${LINUX} | cut -d ':' -f 5`"
              LPARAMS="`echo ${LINUX} | cut -d ':' -f 6 | tr '|' ' '`"

              LINUXROOT="`grub-probe --target=drive --device ${LBOOT}`"

              if [ -z "${LLABEL}" ] ; then
                LLABEL="${LONGNAME}"
              fi

              cat << EOF
menuentry "${LLABEL} (on ${DEVICE})" {
        set root=${LINUXROOT}
        linux ${LKERNEL} ${LPARAMS}
EOF
              if [ -n "${LINITRD}" ] ; then
                cat << EOF
        initrd ${LINITRD}
EOF
              fi
              cat << EOF
}
EOF
            done
          fi
        ;;
        hurd)
          # not yet...
        ;;
        *)
        ;;
      esac
    fi
  done
fi

reply via email to

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