Eyal Lebedinsky wrote: > > I have two disks as raid on a BP6 (HPT366) and had one too many > lockups on hde+hdg, so I decided to move it down to hdb+hdd. > > I could not start the raid, it just complained that the disks > are not at the major/minor it expected it. > > The first message said that [21:00] is now hdb, then it said > that it cannot access [22:00] (naturally) so it removed a disk > from the array, then it said the array expects two disks but > only one was found. > > How do I tell it that the raid pair is just fine but it had to > be moved to a new location? > > I tried 'mkraid --upgrade' hoping it will reconfigure but no dice > (same errors as above). Attached is the program I ended up writing, which (I think) fixed the situation for me. Maybe someone who knows can create a nicer utility (safer too) from it. -- Eyal Lebedinsky ([EMAIL PROTECTED]) <http://samba.anu.edu.au/eyal/>
/* fixraid.c * * Last change: 26 Feb 2001 * Author: Eyal Lebedinsky ([EMAIL PROTECTED]) * * WARNING: * ======== * This is a very risky program, do not run it unless you fully * understand what it does! * * Fixes RAID superblock from one device to another. * * SB_DEV is the member to fix. What we fix is the definition of * the following member (here we fix /dev/hdb to point to /dev/hdd * instead of /dev/hdh). * * Get the superblock position (SB_SEEKPOS) from a (possibly failed) raidstart. * * Do not change SB_SEEKSTEP. * * Set old_0x280 to what the sb had before. (0x22:0x40 is /dev/hdh) * * Set new_0x280 to the new contents. (0x16:0x40 is /dev/hdd) */ #include <stdlib.h> #include <stdio.h> #define SB_DEV "/dev/hdb" /* device to fix */ #define SB_SEEKPOS 60051520L /* in K bytes */ #define SB_SEEKSTEP 1000000L /* in K bytes */ static unsigned char old_0x280[] = { 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, /* hdh: major */ 0x40, 0x00, 0x00, 0x00}; /* hdh: minor */ static unsigned char new_0x280[] = { 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, /* hdd: major */ 0x40, 0x00, 0x00, 0x00}; /* hdd: minor */ int main ( int argc, char **argv) { int doupdate; int rc; FILE *fin; long pos; long step; char sb[1024]; fprintf (stderr, "processing RAID superblock on %s at %ldK\n", SB_DEV, SB_SEEKPOS); if (argc < 2 || strcmp ("update please", argv[1])) { fprintf (stderr, "not updating - please ask nicely\n"); doupdate = 0; } else doupdate = 1; fin = fopen (SB_DEV, doupdate ? "r+" : "r"); if (NULL == fin) { fprintf (stderr, "open file failed\n"); return (1); } for (pos = SB_SEEKPOS; pos > 0; pos -= step) { step = pos >= SB_SEEKSTEP ? SB_SEEKSTEP : pos; rc = fseek (fin, step*1024L, SEEK_CUR); if (rc) { fprintf (stderr, "fseek +%ldK at -%ldK failed\n", step, pos); return (1); } } rc = fread (sb, 1024, 1, fin); if (1 != rc) { fprintf (stderr, "read failed\n"); return (1); } fprintf (stderr, "read superblock OK\n"); rc = fseek (fin, -1024L, SEEK_CUR); if (rc) { fprintf (stderr, "fseek back failed\n"); return (1); } if (!memcmp (sb+0x280, new_0x280, sizeof (new_0x280))) { fprintf (stderr, "superblock already updated\n"); return (1); } if (memcmp (sb+0x280, old_0x280, sizeof (old_0x280))) { fprintf (stderr, "superblock incorrect\n"); return (1); } fprintf (stderr, "superblock is OK\n"); memcpy (sb+0x280, new_0x280, sizeof (new_0x280)); if (doupdate) { rc = fwrite (sb, 1024, 1, fin); if (1 != rc) { fprintf (stderr, "write failed\n"); return (1); } fprintf (stderr, "superblock updated\n"); } fclose (fin); return (0); }