> > It's 552 lines, so I'll go ahead and attach it here with the warning
> > that it is the 4th patch (of 4) to get applied in their .spec file (after
> > .include, .ebda and .cpqarray) and as such may not apply cleanly... it's
> > only got 8 chunks in it though, only the 3rd and 8th of which have
> > significant size...

[ Thursday, October 14, 1999 ] Alex H. Vandenham wrote:
> I believe that's the source rpm for lilo.  Where is the patch available. This
> is the second lilo raid patch I have seen and they're different.

I attached the patch (just like I said I would)... I'll include it in the
text of this message for you.

--- lilo.new/lilo.c.noraid      Tue Sep 21 23:58:01 1999
+++ lilo.new/lilo.c     Wed Sep 22 04:18:22 1999
@@ -24,11 +24,11 @@
 #include "cfg.h"
 #include "identify.h"
 #include "partition.h"
-
+#include "md-int.h"
 
 #define S2(x) #x
 #define S(x) S2(x)
-
+#define MAX_TOKEN 200
 
 static void show_other(int fd)
 {
@@ -227,15 +227,21 @@
 {
     char *name,*config_file,*reboot_arg,*identify,*ident_opt,*new_root;
     char *uninst_dev;
-    int query,more,version,uninstall,validate;
+    int query,more,version,uninstall,validate,do_md_install,pass;
     BOOT_SECTOR dummy;
     IMAGE_DESCR dummy2;
     struct stat st;
-    int fd;
+    int fd, md_fd;
+    md_array_info_t md_array_info;
+    md_disk_info_t md_disk_info;
+    char md_boot_name[MAX_TOKEN+1];
+    char md_boot_map[MAX_TOKEN+1];
+    DT_ENTRY md_disk;
+    DT_ENTRY *disk;
 
     config_file = DFL_CONFIG;
     reboot_arg = identify = ident_opt = new_root = uninst_dev = NULL;
-    query = version = uninstall = validate = 0;
+    pass = do_md_install = query = version = uninstall = validate = 0;
     name = *argv++;
     argc--;
     cfg_init(cf_options);
@@ -414,43 +420,117 @@
     }
     preload_dev_cache();
     if (identify) identify_image(identify,ident_opt);
-    if (uninstall)
-       bsect_uninstall(uninst_dev ? uninst_dev : cfg_get_strg(cf_options,
-         "boot"),cfg_get_strg(cf_options,"backup"),validate);
-    compact = cfg_get_flag(cf_options,"compact");
-    linear = cfg_get_flag(cf_options,"linear");
-    nowarn = cfg_get_flag(cf_options,"nowarn");
-    if (cfg_get_strg(cf_options,"verbose"))
-       verbose += to_number(cfg_get_strg(cf_options,"verbose"));
-    if (reboot_arg) {
-       map_patch_first(cfg_get_strg(cf_options,"map") ? cfg_get_strg(
-         cf_options,"map") : MAP_FILE,reboot_arg);
-       exit(0);
-    }
-    if (argc) usage(name);
-    geo_init(cfg_get_strg(cf_options,"disktab"));
-    if (query)
-       show_images(!cfg_get_strg(cf_options,"map") ? MAP_FILE :
-         cfg_get_strg(cf_options,"map"));
-    bsect_open(cfg_get_strg(cf_options,"boot"),cfg_get_strg(cf_options,"map") ?
-      cfg_get_strg(cf_options,"map") : MAP_FILE,cfg_get_strg(cf_options,
-      "install"),cfg_get_strg(cf_options,"delay") ? to_number(cfg_get_strg(
-      cf_options,"delay")) : 0,cfg_get_strg(cf_options,"timeout") ?
-      to_number(cfg_get_strg(cf_options,"timeout")) : -1);
-    if (more) {
-        cfg_init(cf_top);
-        if (cfg_parse(cf_top)) cfg_error("Syntax error");
-    }
-    if (!bsect_number()) die("No images have been defined.");
-    check_fallback();
-    if (!test)
-       if (cfg_get_strg(cf_options,"force-backup"))
-           bsect_update(cfg_get_strg(cf_options,"force-backup"),1);
-       else bsect_update(cfg_get_strg(cf_options,"backup"),0);
-    else {
-       bsect_cancel();
-       fprintf(stderr,"The boot sector and the map file have *NOT* been "
-         "altered.\n");
+    if (strncmp("/dev/md",cfg_get_strg(cf_options,"boot"),7) == 0) {
+       if ((md_fd=open(cfg_get_strg(cf_options,"boot"),O_NOACCESS)) < 0)
+           die("Unable to open %s",cfg_get_strg(cf_options,"boot"));
+       if (fstat(md_fd,&st) < 0)
+           die("Unable to stat %s",cfg_get_strg(cf_options,"boot"));
+       if (!S_ISBLK(st.st_mode))
+           die("%s is not a block device",cfg_get_strg(cf_options,"boot"));
+       if (ioctl(md_fd,GET_ARRAY_INFO,&md_array_info) < 0)
+           die("Unable to get RAID info on %s",cfg_get_strg(cf_options,"boot"));
+       if ((md_array_info.major_version == 0) && (md_array_info.minor_version < 90))
+           die("Raid versions < 0.90 are not supported");
+       if (md_array_info.level != 1)
+           die("Only RAID1 devices are supported as boot devices");
+       do_md_install = 1;
+       strcpy(md_boot_name,cfg_get_strg(cf_options,"boot"));
+       if (cfg_get_strg(cf_options,"map"))
+           strcpy(md_boot_map,cfg_get_strg(cf_options,"map"));
+       else
+           strcpy(md_boot_map,MAP_FILE);
+       md_disk.device = (MD_MAJOR << 8) | md_array_info.md_minor;
+       md_disk.bios = 0x80;
+       md_disk.next = disktab;
+       disktab = &md_disk;
+    }
+    while( (pass == 0) || (do_md_install && (pass < md_array_info.nr_disks)) ) {
+       if(do_md_install) {
+           GEOMETRY geo;
+           DEVICE dev;
+           int device,disk_fd;
+           char new_name[MAX_TOKEN+1];
+
+           if(pass > 0) {
+               close(fd);
+               cfg_init(cf_options);
+               fd = cfg_open(config_file);
+               more = cfg_parse(cf_options);
+           }
+           md_disk_info.number = pass;
+           if (ioctl(md_fd,GET_DISK_INFO,&md_disk_info) < 0)
+               die("main: GET_DISK_INFO: %s", strerror(errno));
+           device = (md_disk_info.major << 8) | md_disk_info.minor;
+           disk_fd = dev_open(&dev,device,O_NOACCESS);
+           if (md_disk_info.state == MD_DISK_FAULTY) {
+               printf("disk %s marked as faulty, skipping\n",dev.name);
+               pass++;
+               continue;
+           }
+           geo_query_dev(&geo,device,1);
+           disk = alloc_t(DT_ENTRY);
+           disk->bios = 0x80;
+           disk->device = device & 0xfff0;
+           disk->sectors = geo.sectors;
+           disk->heads = geo.heads;
+           disk->cylinders = geo.cylinders;
+           disk->start = geo.start;
+           disk->next = disktab;
+           disktab = disk;
+           if (cfg_get_strg(cf_options,"boot")) cfg_unset(cf_options,"boot");
+           if (cfg_get_strg(cf_options,"map")) cfg_unset(cf_options,"map");
+           strncpy(new_name,dev.name,8);
+           new_name[8] = '\0';
+           cfg_set(cf_options,"boot",new_name,NULL);
+           snprintf(new_name,MAX_TOKEN,"%s.%04x",md_boot_map,device);
+           cfg_set(cf_options,"map",new_name,NULL);
+           printf("boot = %s, map = %s\n", cfg_get_strg(cf_options,"boot"),
+               cfg_get_strg(cf_options,"map"));
+           md_disk.sectors = geo.sectors;
+           md_disk.heads = geo.heads;
+           md_disk.cylinders = geo.cylinders;
+           md_disk.start = geo.start;
+       }
+           
+       pass++;
+       if (uninstall)
+           bsect_uninstall(uninst_dev ? uninst_dev : cfg_get_strg(cf_options,
+             "boot"),cfg_get_strg(cf_options,"backup"),validate);
+       compact = cfg_get_flag(cf_options,"compact");
+       linear = cfg_get_flag(cf_options,"linear");
+       nowarn = cfg_get_flag(cf_options,"nowarn");
+       if (cfg_get_strg(cf_options,"verbose"))
+           verbose += to_number(cfg_get_strg(cf_options,"verbose"));
+       if (reboot_arg) {
+           map_patch_first(cfg_get_strg(cf_options,"map") ? cfg_get_strg(
+             cf_options,"map") : MAP_FILE,reboot_arg);
+           exit(0);
+       }
+       if (argc) usage(name);
+       geo_init(cfg_get_strg(cf_options,"disktab"));
+       if (query)
+           show_images(!cfg_get_strg(cf_options,"map") ? MAP_FILE :
+             cfg_get_strg(cf_options,"map"));
+       bsect_open(cfg_get_strg(cf_options,"boot"),cfg_get_strg(cf_options,"map") ?
+         cfg_get_strg(cf_options,"map") : MAP_FILE,cfg_get_strg(cf_options,
+         "install"),cfg_get_strg(cf_options,"delay") ? to_number(cfg_get_strg(
+         cf_options,"delay")) : 0,cfg_get_strg(cf_options,"timeout") ?
+         to_number(cfg_get_strg(cf_options,"timeout")) : -1);
+       if (more) {
+            cfg_init(cf_top);
+            if (cfg_parse(cf_top)) cfg_error("Syntax error");
+       }
+       if (!bsect_number()) die("No images have been defined.");
+       check_fallback();
+       if (!test)
+           if (cfg_get_strg(cf_options,"force-backup"))
+               bsect_update(cfg_get_strg(cf_options,"force-backup"),1);
+           else bsect_update(cfg_get_strg(cf_options,"backup"),0);
+       else {
+           bsect_cancel();
+           fprintf(stderr,"The boot sector and the map file have *NOT* been "
+             "altered.\n");
+       }
     }
     return 0;
 }
--- lilo.new/geometry.c.noraid  Wed Sep 22 00:55:32 1999
+++ lilo.new/geometry.c Wed Sep 22 03:13:29 1999
@@ -35,18 +35,9 @@
     struct stat st;
 } ST_BUF;
 
-typedef struct _dt_entry {
-    int device,bios;
-    int sectors;
-    int heads; /* 0 if inaccessible */
-    int cylinders;
-    int start;
-    struct _dt_entry *next;
-} DT_ENTRY;
 
-
-static DT_ENTRY *disktab = NULL;
-static int old_disktab = 0;
+DT_ENTRY *disktab = NULL;
+int old_disktab = 0;
 
 
 void geo_init(char *name)
@@ -260,7 +251,7 @@
 }
 
 
-static void geo_query_dev(GEOMETRY *geo,int device,int all)
+void geo_query_dev(GEOMETRY *geo,int device,int all)
 {
     DEVICE dev;
     int fd,get_all;
--- lilo.new/geometry.h.noraid  Wed Sep 22 00:56:06 1999
+++ lilo.new/geometry.h Wed Sep 22 03:12:23 1999
@@ -18,6 +18,17 @@
     int boot; /* non-zero after geo_open_boot */
 } GEOMETRY;
 
+typedef struct _dt_entry {
+    int device,bios;
+    int sectors;
+    int heads; /* 0 if inaccessible */
+    int cylinders;
+    int start;
+    struct _dt_entry *next;
+} DT_ENTRY;
+
+extern DT_ENTRY *disktab;
+
 void geo_init(char *name);
 
 /* Loads the disk geometry table. */
@@ -59,5 +70,10 @@
 
 /* lseeks in the file associated with GEO for the sector at address ADDR.
    Returns a non-zero integer on success, zero on failure. */
+
+void geo_query_dev(GEOMETRY *geo,int device,int all);
+
+/* opens the specified device and gets the geometry information.  That
+   information is then stored in *geo */
 
 #endif
--- lilo.new/md-int.h.noraid    Wed Sep 22 13:06:36 1999
+++ lilo.new/md-int.h   Tue Sep 21 22:57:41 1999
@@ -0,0 +1,290 @@
+/*
+   md.h : Multiple Devices driver for Linux
+          Copyright (C) 1994-96 Marc ZYNGIER
+         <[EMAIL PROTECTED]> or
+         <[EMAIL PROTECTED]>
+         
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+   
+   You should have received a copy of the GNU General Public License
+   (for example /usr/src/linux/COPYING); if not, write to the Free
+   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
+*/
+
+#ifndef MD_INT_H
+#define MD_INT_H
+
+/* don't include the kernel RAID header! */
+#define _MD_H
+
+typedef unsigned int md_u32;
+typedef unsigned short md_u16;
+typedef unsigned char md_u8;
+
+#include <linux/major.h>
+#include <sys/ioctl.h>
+
+/*
+ * Different major versions are not compatible.
+ * Different minor versions are only downward compatible.
+ * Different patchlevel versions are downward and upward compatible.
+ */
+
+struct md_version {
+       int major;
+       int minor;
+       int patchlevel;
+};
+
+/*
+ * default readahead
+ */
+#define MD_READAHEAD   (256 * 1024)
+
+/* These are the ioctls for md versions < 0.50 */
+#define REGISTER_MD_DEV                _IO (MD_MAJOR, 1)
+#define START_MD               _IO (MD_MAJOR, 2)
+#define STOP_MD                _IO (MD_MAJOR, 3)
+
+/* status */
+#define RAID_VERSION            _IOR (MD_MAJOR, 0x10, struct md_version)
+#define GET_ARRAY_INFO          _IOR (MD_MAJOR, 0x11, md_array_info_t)
+#define GET_DISK_INFO           _IOR (MD_MAJOR, 0x12, md_disk_info_t)
+#define PRINT_RAID_DEBUG        _IO (MD_MAJOR, 0x13)
+
+/* configuration */
+#define CLEAR_ARRAY             _IO (MD_MAJOR, 0x20)
+#define ADD_NEW_DISK            _IOW (MD_MAJOR, 0x21, md_disk_info_t)
+#define HOT_REMOVE_DISK         _IO (MD_MAJOR, 0x22)
+#define SET_ARRAY_INFO          _IOW (MD_MAJOR, 0x23, md_array_info_t)
+#define SET_DISK_INFO           _IO (MD_MAJOR, 0x24)
+#define WRITE_RAID_INFO         _IO (MD_MAJOR, 0x25)
+#define UNPROTECT_ARRAY         _IO (MD_MAJOR, 0x26)
+#define PROTECT_ARRAY           _IO (MD_MAJOR, 0x27)
+#define HOT_ADD_DISK            _IO (MD_MAJOR, 0x28)
+
+/* usage */
+#define RUN_ARRAY               _IOW (MD_MAJOR, 0x30, struct md_param)
+#define START_ARRAY             _IO (MD_MAJOR, 0x31)
+#define STOP_ARRAY              _IO (MD_MAJOR, 0x32)
+#define STOP_ARRAY_RO           _IO (MD_MAJOR, 0x33)
+#define RESTART_ARRAY_RW        _IO (MD_MAJOR, 0x34)
+
+
+/* for raid < 0.50 only */
+#define MD_PERSONALITY_SHIFT   16
+
+#define MD_RESERVED       0UL
+#define LINEAR            1UL
+#define STRIPED           2UL
+#define RAID0             STRIPED
+#define RAID1             3UL
+#define RAID5             4UL
+#define TRANSLUCENT       5UL
+#define LVM               6UL
+#define MAX_PERSONALITY   7UL
+
+/*
+ * MD superblock.
+ *
+ * The MD superblock maintains some statistics on each MD configuration.
+ * Each real device in the MD set contains it near the end of the device.
+ * Some of the ideas are copied from the ext2fs implementation.
+ *
+ * We currently use 4096 bytes as follows:
+ *
+ *     word offset     function
+ *
+ *        0  -    31   Constant generic MD device information.
+ *        32  -    63   Generic state information.
+ *       64  -   127   Personality specific information.
+ *      128  -   511   12 32-words descriptors of the disks in the raid set.
+ *      512  -   911   Reserved.
+ *      912  -  1023   Disk specific descriptor.
+ */
+
+/*
+ * If x is the real device size in bytes, we return an apparent size of:
+ *
+ *     y = (x & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES
+ *
+ * and place the 4kB superblock at offset y.
+ */
+#define MD_RESERVED_BYTES              (64 * 1024)
+#define MD_RESERVED_SECTORS            (MD_RESERVED_BYTES / 512)
+#define MD_RESERVED_BLOCKS             (MD_RESERVED_BYTES / BLOCK_SIZE)
+
+#define MD_NEW_SIZE_SECTORS(x)         ((x & ~(MD_RESERVED_SECTORS - 1)) - 
+MD_RESERVED_SECTORS)
+#define MD_NEW_SIZE_BLOCKS(x)          ((x & ~(MD_RESERVED_BLOCKS - 1)) - 
+MD_RESERVED_BLOCKS)
+
+#define MD_SB_BYTES                    4096
+#define MD_SB_WORDS                    (MD_SB_BYTES / 4)
+#define MD_SB_BLOCKS                   (MD_SB_BYTES / BLOCK_SIZE)
+#define MD_SB_SECTORS                  (MD_SB_BYTES / 512)
+
+/*
+ * The following are counted in 32-bit words
+ */
+#define        MD_SB_GENERIC_OFFSET            0
+#define MD_SB_PERSONALITY_OFFSET       64
+#define MD_SB_DISKS_OFFSET             128
+#define MD_SB_DESCRIPTOR_OFFSET                992
+
+#define MD_SB_GENERIC_CONSTANT_WORDS   32
+#define MD_SB_GENERIC_STATE_WORDS      32
+#define MD_SB_GENERIC_WORDS            (MD_SB_GENERIC_CONSTANT_WORDS + 
+MD_SB_GENERIC_STATE_WORDS)
+#define MD_SB_PERSONALITY_WORDS                64
+#define MD_SB_DISKS_WORDS              384
+#define MD_SB_DESCRIPTOR_WORDS         32
+#define MD_SB_RESERVED_WORDS           (1024 - MD_SB_GENERIC_WORDS - 
+MD_SB_PERSONALITY_WORDS - MD_SB_DISKS_WORDS - MD_SB_DESCRIPTOR_WORDS)
+#define MD_SB_EQUAL_WORDS              (MD_SB_GENERIC_WORDS + MD_SB_PERSONALITY_WORDS 
++ MD_SB_DISKS_WORDS)
+#define MD_SB_DISKS                    (MD_SB_DISKS_WORDS / MD_SB_DESCRIPTOR_WORDS)
+
+/*
+ * Device "operational" state bits
+ */
+#define MD_DISK_FAULTY         0 /* disk is faulty / operational */
+#define MD_DISK_ACTIVE         1 /* disk is running or spare disk */
+#define MD_DISK_SYNC           2 /* disk is in sync with the raid set */
+
+typedef struct md_device_descriptor_s {
+       md_u32 number;          /* 0 Device number in the entire set          */
+       md_u32 major;           /* 1 Device major number                      */
+       md_u32 minor;           /* 2 Device minor number                      */
+       md_u32 raid_disk;       /* 3 The role of the device in the raid set   */
+       md_u32 state;           /* 4 Operational state                        */
+       md_u32 reserved[MD_SB_DESCRIPTOR_WORDS - 5];
+} md_descriptor_t;
+
+#define MD_SB_MAGIC            0xa92b4efc
+
+/*
+ * Superblock state bits
+ */
+#define MD_SB_CLEAN            0
+#define MD_SB_ERRORS           1
+
+typedef struct md_superblock_s {
+       /*
+        * Constant generic information
+        */
+       md_u32 md_magic;                /*  0 MD identifier                           
+*/
+       md_u32 major_version;   /*  1 major version to which the set conforms */
+       md_u32 minor_version;   /*  2 minor version ...                       */
+       md_u32 patch_version;   /*  3 patchlevel version ...                  */
+       md_u32 gvalid_words;    /*  4 Number of used words in this section    */
+       md_u32 set_magic;       /*  5 Raid set identifier                     */
+       md_u32 ctime;           /*  6 Creation time                           */
+       md_u32 level;           /*  7 Raid personality                        */
+       md_u32 size;            /*  8 Apparent size of each individual disk   */
+       md_u32 nr_disks;        /*  9 total disks in the raid set             */
+       md_u32 raid_disks;      /* 10 disks in a fully functional raid set    */
+       md_u32 md_minor;        /* 11 preferred MD minor device number        */
+       md_u32 gstate_creserved[MD_SB_GENERIC_CONSTANT_WORDS - 12];
+
+       /*
+        * Generic state information
+        */
+       md_u32 utime;           /*  0 Superblock update time                  */
+       md_u32 state;           /*  1 State bits (clean, ...)                 */
+       md_u32 active_disks;    /*  2 Number of currently active disks        */
+       md_u32 working_disks;   /*  3 Number of working disks                 */
+       md_u32 failed_disks;    /*  4 Number of failed disks                  */
+       md_u32 spare_disks;     /*  5 Number of spare disks                   */
+       md_u32 gstate_sreserved[MD_SB_GENERIC_STATE_WORDS - 6];
+
+       /*
+        * Personality information
+        */
+       md_u32 layout;          /*  0 the array's physical layout             */
+       md_u32 chunk_size;      /*  1 chunk size in bytes                     */
+       md_u32 pstate_reserved[MD_SB_PERSONALITY_WORDS - 2];
+
+       /*
+        * Disks information
+        */
+       md_descriptor_t disks[MD_SB_DISKS];
+
+       /*
+        * Reserved
+        */
+       md_u32 reserved[MD_SB_RESERVED_WORDS];
+
+       /*
+        * Active descriptor
+        */
+       md_descriptor_t descriptor;
+
+} md_superblock_t;
+
+/*
+ * options passed in raidstart:
+ */
+
+#define MAX_CHUNK_SIZE (4096*1024)
+
+struct md_param
+{
+       int                     personality;    /* 1,2,3,4 */
+       int                     chunk_size;     /* in bytes */
+       int                     max_fault;      /* unused for now */
+};
+
+typedef struct md_array_info_s {
+       /*
+        * Generic constant information
+        */
+       md_u32 major_version;
+       md_u32 minor_version;
+       md_u32 patch_version;
+       md_u32 ctime;
+       md_u32 level;
+       md_u32 size;
+       md_u32 nr_disks;
+       md_u32 raid_disks;
+       md_u32 md_minor;
+       md_u32 not_persistent;
+
+       /*
+        * Generic state information
+        */
+       md_u32 utime;           /*  0 Superblock update time                  */
+       md_u32 state;           /*  1 State bits (clean, ...)                 */
+       md_u32 active_disks;    /*  2 Number of currently active disks        */
+       md_u32 working_disks;   /*  3 Number of working disks                 */
+       md_u32 failed_disks;    /*  4 Number of failed disks                  */
+       md_u32 spare_disks;     /*  5 Number of spare disks                   */
+
+       /*
+        * Personality information
+        */
+       md_u32 layout;          /*  0 the array's physical layout             */
+       md_u32 chunk_size;      /*  1 chunk size in bytes                     */
+
+} md_array_info_t;
+
+typedef struct md_disk_info_s {
+       /*
+        * configuration/status of one particular disk
+        */
+       md_u32 number;
+       md_u32 major;
+       md_u32 minor;
+       md_u32 raid_disk;
+       md_u32 state;
+
+} md_disk_info_t;
+
+
+/*
+ * Supported RAID5 algorithms
+ */
+#define RAID5_ALGORITHM_LEFT_ASYMMETRIC                0
+#define RAID5_ALGORITHM_RIGHT_ASYMMETRIC       1
+#define RAID5_ALGORITHM_LEFT_SYMMETRIC         2
+#define RAID5_ALGORITHM_RIGHT_SYMMETRIC                3
+
+#endif _MD_H

Reply via email to