ALT Linux Team development discussions
 help / color / mirror / Atom feed
* [devel] GRUB partition-map patch (md raid1 support)
@ 2003-08-22 17:22 Sergey Vlasov
  2003-08-25  8:42 ` Alexander Bokovoy
  0 siblings, 1 reply; 2+ messages in thread
From: Sergey Vlasov @ 2003-08-22 17:22 UTC (permalink / raw)
  To: ALT Developers List


[-- Attachment #1.1: Type: text/plain, Size: 1549 bytes --]

Hello!

Я тут слегка похакал GRUB на предмет установки на RAID1 - вроде бы
работает. Патч на базе grub-0.93-alt1 (после всех прочих - там
получилась зависимость от предыдущих; на чистый не ляжет).

Сделано следующим образом: в /boot/grub/device.map можно писать записи
не только для дисков, но и для отдельных разделов:

(fd0)	/dev/fd0
(hd0)	/dev/hda
(hd1)	/dev/hdc
(hd0,0)	/dev/evms/md/md0
(hd1,0)	/dev/evms/md/md0

После этого /usr/sbin/grub для записи в раздел полезет в указанное
устройство (читать всё равно будет с /dev/hda и т.п. напрямую - там
специальная обработка только для записи). Это будет работать при
установке stage1 в первый сектор раздела (не в MBR - там на всех
дисках должен быть обычный код для загрузки с активного раздела). Т.е.
/boot/grub/install.sh будет такого вида:

grub --device-map=/boot/grub/device.map --batch <<EOF
install (hd0,0)/grub/stage1 d (hd0,0) (hd0,0)/grub/stage2 p (hd0,0)/grub/menu.lst
quit
EOF

savedefault в menu.lst использовать нельзя, т.к. это запишется только
на один диск.

bootloader-utils при установке ядра не срабатывает - "Can't convert
grub_partition" (ядро не заносится в menu.lst). К счастью, в случае
GRUB это не смертельно - при необходимости всё равно из его командной
строки можно загрузить что угодно.

Сделано сегодня, так что вполне вероятно наличие кучи багов :-)


PS: LILO за неделю надоел до невозможности :-)
    (да к тому же у нас он ещё не пропатчен для EVMS 2, так что всё
    равно пришлось менять загрузчик)

-- 
Sergey Vlasov

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: grub-0.93-alt-partition-map.patch --]
[-- Type: text/x-patch; name="grub-0.93-alt-partition-map.patch", Size: 8695 bytes --]

--- grub-0.93/stage2/disk_io.c.alt-partition-map	2003-08-22 19:48:46 +0400
+++ grub-0.93/stage2/disk_io.c	2003-08-22 19:48:46 +0400
@@ -344,7 +344,8 @@
 	 embed a Stage 1.5 into a partition instead of a MBR, use system
 	 calls directly instead of biosdisk, because of the bug in
 	 Linux. *sigh*  */
-      return write_to_partition (device_map, current_drive, current_partition,
+      return write_to_partition (device_map, partition_map,
+				 current_drive, current_partition,
 				 sector, sector_count, buf);
     }
   else
--- grub-0.93/stage2/shared.h.alt-partition-map	2003-08-22 19:48:46 +0400
+++ grub-0.93/stage2/shared.h	2003-08-22 19:48:46 +0400
@@ -588,6 +588,8 @@
 extern char **device_map;
 /* The filename which stores the information about a device map.  */
 extern char *device_map_file;
+/* The map between drive/partition numbers and UNIX device file names.  */
+extern struct partition_map_entry *partition_map;
 /* The array of geometries.  */
 extern struct geometry *disks;
 /* Assign DRIVE to a device name DEVICE.  */
--- grub-0.93/lib/device.c.alt-partition-map	2003-08-22 19:48:46 +0400
+++ grub-0.93/lib/device.c	2003-08-22 20:10:33 +0400
@@ -369,9 +369,27 @@
   return 1;
 }
 
+#ifdef __linux__
+/* Find device name for PARTITION on DRIVE in MAP. */
+static const char *
+find_device_for_partition (struct partition_map_entry *map,
+			   int drive, int partition)
+{
+  while (map)
+    {
+      if ((map->drive == drive) && (map->partition == partition))
+	return map->device_name;
+      map = map->next;
+    }
+
+  return NULL;
+}
+#endif /* __linux__ */
+
 /* Read mapping information from FP, and write it to MAP.  */
 static int
-read_device_map (FILE *fp, char **map, const char *map_file)
+read_device_map (FILE *fp, char **map, const char *map_file,
+		 struct partition_map_entry **partition_map)
 {
   static void show_error (int no, const char *msg)
     {
@@ -388,6 +406,9 @@
       char *ptr, *eptr;
       int drive;
       int is_floppy = 0;
+#ifdef __linux__
+      int partition = -1;
+#endif /* __linux__ */
       
       /* Increase the number of lines.  */
       line_number++;
@@ -431,6 +452,27 @@
       
       if (! is_floppy)
 	drive += 0x80;
+
+#ifdef __linux__
+      /* Check for a possible partition map entry.  */
+      if (*ptr == ',')
+	{
+	  if (is_floppy)
+	    {
+	      show_error (line_number,
+			  "Partitions on floppy drives are not allowed");
+	      return 0;
+	    }
+
+	  ptr++;
+	  partition = strtoul (ptr, &ptr, 10);
+	  if (partition < 0 || partition > 255) /* XXX: max value? */
+	    {
+	      show_error (line_number, "Bad partition number");
+	      return 0;
+	    }
+	}
+#endif /* __linux__ */
       
       if (*ptr != ')')
 	{
@@ -455,6 +497,35 @@
 	eptr++;
       *eptr = 0;
 
+#ifdef __linux__
+      if (partition != -1)
+	{
+	  struct partition_map_entry *new_entry;
+	  /* Multiple entries for a given partition is not allowed.  */
+	  if (find_device_for_partition (*partition_map, drive, partition))
+	    {
+	      show_error (line_number, "Duplicated entry found");
+	      return 0;
+	    }
+      
+	  /* Allocate a new partition map entry.  */
+	  new_entry = malloc (sizeof (struct partition_map_entry));
+	  assert (new_entry);
+      
+	  /* Fill the entry.  */
+	  new_entry->next = *partition_map;
+	  new_entry->drive = drive;
+	  new_entry->partition = partition;
+	  new_entry->device_name = strdup (ptr);
+	  assert (new_entry->device_name);
+      
+	  /* Place the new entry at the beginning of the list.  */
+	  *partition_map = new_entry;
+
+	  continue;
+	}
+#endif
+
       /* Multiple entries for a given drive is not allowed.  */
       if (map[drive])
 	{
@@ -476,7 +547,8 @@
    If it is zero, don't probe any floppy at all. If it is one, probe one
    floppy. If it is two, probe two floppies. And so on.  */
 int
-init_device_map (char ***map, const char *map_file, int floppy_disks)
+init_device_map (char ***map, struct partition_map_entry **partition_map,
+		 const char *map_file, int floppy_disks)
 {
   int i;
   int num_hd = 0;
@@ -501,7 +573,7 @@
 	{
 	  int ret;
 
-	  ret = read_device_map (fp, *map, map_file);
+	  ret = read_device_map (fp, *map, map_file, partition_map);
 	  fclose (fp);
 	  return ret;
 	}
@@ -651,7 +723,7 @@
 
 /* Restore the memory consumed for MAP.  */
 void
-restore_device_map (char **map)
+restore_device_map (char **map, struct partition_map_entry *partition_map)
 {
   int i;
 
@@ -660,6 +732,17 @@
       free (map[i]);
 
   free (map);
+
+#ifdef __linux__
+  while (partition_map)
+    {
+      struct partition_map_entry *next = partition_map->next;
+      if (partition_map->device_name)
+	free (partition_map->device_name);
+      free (partition_map);
+      partition_map = next;
+    }
+#endif /* __linux__ */
 }
 
 #ifdef __linux__
@@ -667,10 +750,12 @@
    a whole disk is not consistent with the one for a partition of the
    disk.  */
 int
-write_to_partition (char **map, int drive, int partition,
+write_to_partition (char **map, struct partition_map_entry *partition_map,
+		    int drive, int partition,
 		    int sector, int size, const char *buf)
 {
   char dev[PATH_MAX];	/* XXX */
+  const char *partition_dev;
   int fd;
   
   if ((partition & 0x00FF00) != 0x00FF00)
@@ -681,21 +766,31 @@
       return 1;
     }
   
-  assert (map[drive] != 0);
-  
-  strcpy (dev, map[drive]);
-  if (have_devfs ())
+  /* First try to find the entry in PARTITION_MAP.  */
+  partition_dev = find_device_for_partition (partition_map, drive,
+					     (partition >> 16) & 0xFF);
+  if (partition_dev)
     {
-      if (strcmp (dev + strlen(dev) - 5, "/disc") == 0)
-	strcpy (dev + strlen(dev) - 5, "/part");
+      strcpy (dev, partition_dev); /* XXX */
     }
+  else
+    {
+      assert (map[drive] != 0);
+  
+      strcpy (dev, map[drive]);
+      if (have_devfs ())
+	{
+	  if (strcmp (dev + strlen(dev) - 5, "/disc") == 0)
+	    strcpy (dev + strlen(dev) - 5, "/part");
+	}
 
-  sprintf (dev + strlen(dev), "%s%d", 
-	   /* Compaq smart and others */
-	   (strncmp(dev, "/dev/ida/", 9) == 0 ||
-	    strncmp(dev, "/dev/cciss/", 11) == 0 ||
-	    strncmp(dev, "/dev/rd/", 8) == 0) ? "p" : "",
-	   ((partition >> 16) & 0xFF) + 1);
+      sprintf (dev + strlen(dev), "%s%d", 
+	       /* Compaq smart and others */
+	       (strncmp(dev, "/dev/ida/", 9) == 0 ||
+		strncmp(dev, "/dev/cciss/", 11) == 0 ||
+		strncmp(dev, "/dev/rd/", 8) == 0) ? "p" : "",
+	       ((partition >> 16) & 0xFF) + 1);
+    }
   
   /* Open the partition.  */
   fd = open (dev, O_RDWR);
--- grub-0.93/lib/device.h.alt-partition-map	2000-08-08 20:41:55 +0400
+++ grub-0.93/lib/device.h	2003-08-22 19:48:46 +0400
@@ -32,15 +32,28 @@
 #define DEFAULT_HD_HEADS	128
 #define DEFAULT_HD_SECTORS	63
 
+struct partition_map_entry
+{
+  struct partition_map_entry *next;
+  int drive;
+  int partition;
+  char *device_name;
+};
+
 /* Function prototypes.  */
 extern void get_drive_geometry (struct geometry *geom, char **map, int drive);
 extern int check_device (const char *device);
-extern int init_device_map (char ***map, const char *map_file,
+extern int init_device_map (char ***map,
+			    struct partition_map_entry **partition_map,
+			    const char *map_file,
 			    int no_floppies);
-extern void restore_device_map (char **map);
+extern void restore_device_map (char **map,
+				struct partition_map_entry *partition_map);
 
 #ifdef __linux__
-extern int write_to_partition (char **map, int drive, int partition,
+extern int write_to_partition (char **map,
+			       struct partition_map_entry *partition_map,
+			       int drive, int partition,
 			       int offset, int size, const char *buf);
 #endif /* __linux__ */
 			       
--- grub-0.93/grub/asmstub.c.alt-partition-map	2003-08-22 19:48:46 +0400
+++ grub-0.93/grub/asmstub.c	2003-08-22 19:48:46 +0400
@@ -86,6 +86,9 @@
 /* The map between BIOS drives and UNIX device file names.  */
 char **device_map = 0;
 
+/* The map between drive/partition numbers and UNIX device file names.  */
+struct partition_map_entry *partition_map = 0;
+
 /* The jump buffer for exiting correctly.  */
 static jmp_buf env_for_exit;
 
@@ -153,7 +156,8 @@
   for (i = 0; i < NUM_DISKS; i++)
     disks[i].flags = -1;
 
-  if (! init_device_map (&device_map, device_map_file, floppy_disks))
+  if (! init_device_map (&device_map, &partition_map, device_map_file,
+			 floppy_disks))
     return 1;
   
   /* Check some invariants. */
@@ -211,8 +215,9 @@
     close (serial_fd);
   
   /* Release memory. */
-  restore_device_map (device_map);
+  restore_device_map (device_map, partition_map);
   device_map = 0;
+  partition_map = 0;
   free (disks);
   disks = 0;
   free (scratch);

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [devel] GRUB partition-map patch (md raid1 support)
  2003-08-22 17:22 [devel] GRUB partition-map patch (md raid1 support) Sergey Vlasov
@ 2003-08-25  8:42 ` Alexander Bokovoy
  0 siblings, 0 replies; 2+ messages in thread
From: Alexander Bokovoy @ 2003-08-25  8:42 UTC (permalink / raw)
  To: ALT Devel discussion list

On Fri, Aug 22, 2003 at 09:22:00PM +0400, Sergey Vlasov wrote:
> Hello!
> 
> Я тут слегка похакал GRUB на предмет установки на RAID1 - вроде бы
> работает. Патч на базе grub-0.93-alt1 (после всех прочих - там
> получилась зависимость от предыдущих; на чистый не ляжет).
> 
> Сделано следующим образом: в /boot/grub/device.map можно писать записи
> не только для дисков, но и для отдельных разделов:
> 
> (fd0)	/dev/fd0
> (hd0)	/dev/hda
> (hd1)	/dev/hdc
> (hd0,0)	/dev/evms/md/md0
> (hd1,0)	/dev/evms/md/md0
> 
> После этого /usr/sbin/grub для записи в раздел полезет в указанное
> устройство (читать всё равно будет с /dev/hda и т.п. напрямую - там
> специальная обработка только для записи). Это будет работать при
> установке stage1 в первый сектор раздела (не в MBR - там на всех
> дисках должен быть обычный код для загрузки с активного раздела). Т.е.
> /boot/grub/install.sh будет такого вида:
> 
> grub --device-map=/boot/grub/device.map --batch <<EOF
> install (hd0,0)/grub/stage1 d (hd0,0) (hd0,0)/grub/stage2 p (hd0,0)/grub/menu.lst
> quit
> EOF
> 
> savedefault в menu.lst использовать нельзя, т.к. это запишется только
> на один диск.
> 
> bootloader-utils при установке ядра не срабатывает - "Can't convert
> grub_partition" (ядро не заносится в menu.lst). К счастью, в случае
> GRUB это не смертельно - при необходимости всё равно из его командной
> строки можно загрузить что угодно.
> 
> Сделано сегодня, так что вполне вероятно наличие кучи багов :-)
> 
> 
> PS: LILO за неделю надоел до невозможности :-)
>     (да к тому же у нас он ещё не пропатчен для EVMS 2, так что всё
>     равно пришлось менять загрузчик)
Леша Котович работает над этим. У нас есть LILO с EVMS2, но оно пока не
тестировалось на системах с отсутствующим EVMS2 :)

-- 
/ Alexander Bokovoy
---
failed trials, system needs redesigned


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2003-08-25  8:42 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-22 17:22 [devel] GRUB partition-map patch (md raid1 support) Sergey Vlasov
2003-08-25  8:42 ` Alexander Bokovoy

ALT Linux Team development discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \
		devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru
	public-inbox-index devel

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://lore.altlinux.org/org.altlinux.lists.devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git