From: Sergey Vlasov <vsu@altlinux.ru> To: ALT Developers List <devel@altlinux.ru> Subject: [devel] GRUB partition-map patch (md raid1 support) Date: Fri, 22 Aug 2003 21:22:00 +0400 Message-ID: <20030822212200.215ac7c2.vsu@altlinux.ru> (raw) [-- 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 --]
next reply other threads:[~2003-08-22 17:22 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2003-08-22 17:22 Sergey Vlasov [this message] 2003-08-25 8:42 ` Alexander Bokovoy
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20030822212200.215ac7c2.vsu@altlinux.ru \ --to=vsu@altlinux.ru \ --cc=devel@altlinux.ru \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
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