]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super0.c
Give useful message if raid4/5/6 cannot be started because it is not clean and is...
[thirdparty/mdadm.git] / super0.c
index da6671d26fb1eb4ef65e38deafcce49ed11dce35..d2338a9d2d689a8518d318b7830a992497307390 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -191,6 +191,8 @@ static void examine_super0(void *sbv, char *homehost)
        case 0:
        case 4:
        case 5:
+       case 6:
+       case 10:
                printf("     Chunk Size : %dK\n", sb->chunk_size/1024);
                break;
        case -1:
@@ -230,13 +232,8 @@ static void brief_examine_super0(void *sbv)
        mdp_super_t *sb = sbv;
        char *c=map_num(pers, sb->level);
        char devname[20];
-       struct stat stb;
 
        sprintf(devname, "/dev/md%d", sb->md_minor);
-       if (stat(devname, &stb) != 0) {
-               /* /dev/mdX doesn't exist, so use /dev/md/X */
-               sprintf(devname, "/dev/md/%d", sb->md_minor);
-       }
 
        printf("ARRAY %s level=%s num-devices=%d UUID=",
               devname,
@@ -323,6 +320,7 @@ static void getinfo_super0(struct mdinfo *info, void *sbv)
        info->array.ctime = sb->ctime;
        info->array.utime = sb->utime;
        info->array.chunk_size = sb->chunk_size;
+       info->array.state = sb->state;
        info->component_size = sb->size*2;
 
        info->disk.state = sb->this_disk.state;
@@ -414,13 +412,21 @@ static int update_super0(struct mdinfo *info, void *sbv, char *update,
                        } else if (i >= sb->raid_disks && sb->disks[i].number == 0)
                                sb->disks[i].state = 0;
        }
-       if (strcmp(update, "force")==0) {
+       if (strcmp(update, "force-one")==0) {
+               /* Not enough devices for a working array, so
+                * bring this one up-to-date.
+                */
                __u32 ehi = sb->events_hi, elo = sb->events_lo;
                sb->events_hi = (info->events>>32) & 0xFFFFFFFF;
                sb->events_lo = (info->events) & 0xFFFFFFFF;
                if (sb->events_hi != ehi ||
                    sb->events_lo != elo)
                        rv = 1;
+       }
+       if (strcmp(update, "force-array")==0) {
+               /* degraded array and 'force' requested, so
+                * maybe need to mark it 'clean'
+                */
                if ((sb->level == 5 || sb->level == 4 || sb->level == 6) &&
                    (sb->state & (1 << MD_SB_CLEAN)) == 0) {
                        /* need to force clean */
@@ -437,16 +443,6 @@ static int update_super0(struct mdinfo *info, void *sbv, char *update,
                        rv = 1;
                }
        }
-       if (strcmp(update, "newdev") == 0) {
-               int d = info->disk.number;
-               memset(&sb->disks[d], 0, sizeof(sb->disks[d]));
-               sb->disks[d].number = d;
-               sb->disks[d].major = info->disk.major;
-               sb->disks[d].minor = info->disk.minor;
-               sb->disks[d].raid_disk = info->disk.raid_disk;
-               sb->disks[d].state = info->disk.state;
-               sb->this_disk = sb->disks[d];
-       }
        if (strcmp(update, "grow") == 0) {
                sb->raid_disks = info->array.raid_disks;
                sb->nr_disks = info->array.nr_disks;
@@ -498,12 +494,6 @@ static int update_super0(struct mdinfo *info, void *sbv, char *update,
        return rv;
 }
 
-static __u64 event_super0(void *sbv)
-{
-       mdp_super_t *sb = sbv;
-       return md_event(sb);
-}
-
 /*
  * For verion-0 superblock, the homehost is 'stored' in the
  * uuid.  8 bytes for a hash of the host leaving 8 bytes
@@ -838,7 +828,10 @@ static __u64 avail_size0(struct supertype *st, __u64 devsize)
        return MD_NEW_SIZE_SECTORS(devsize);
 }
 
-static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, unsigned long long size, int may_change, int major)
+static int add_internal_bitmap0(struct supertype *st, void *sbv, int *chunkp,
+                               int delay, int write_behind,
+                               unsigned long long size, int may_change,
+                               int major)
 {
        /*
         * The bitmap comes immediately after the superblock and must be 60K in size
@@ -849,6 +842,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int
        unsigned long long bits;
        unsigned long long max_bits = 60*1024*8;
        unsigned long long min_chunk;
+       int chunk = *chunkp;
        mdp_super_t *sb = sbv;
        bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MD_SB_BYTES);
 
@@ -874,7 +868,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int
        bms->daemon_sleep = __cpu_to_le32(delay);
        bms->sync_size = __cpu_to_le64(size);
        bms->write_behind = __cpu_to_le32(write_behind);
-
+       *chunkp = chunk;
        return 1;
 }
 
@@ -972,7 +966,6 @@ struct superswitch super0 = {
        .uuid_from_super = uuid_from_super0,
        .getinfo_super = getinfo_super0,
        .update_super = update_super0,
-       .event_super = event_super0,
        .init_super = init_super0,
        .add_to_super = add_to_super0,
        .store_super = store_super0,