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);
}