X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=super1.c;h=28332cd2a2d6dff41d9880af7213c3e59e4afeaf;hb=1377730fc4bb94b9d4590782efb8d27edbc72a75;hp=77b5485d3dadb83abe1b1e6e7d112549719ebc9f;hpb=b578481ca382959da894ebdd91c5e5f45d50374d;p=thirdparty%2Fmdadm.git diff --git a/super1.c b/super1.c index 77b5485d..28332cd2 100644 --- a/super1.c +++ b/super1.c @@ -1,7 +1,7 @@ /* * mdadm - manage Linux "md" devices aka RAID arrays. * - * Copyright (C) 2001-2004 Neil Brown + * Copyright (C) 2001-2006 Neil Brown * * * This program is free software; you can redistribute it and/or modify @@ -136,7 +136,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) } #ifndef MDASSEMBLE -static void examine_super1(void *sbv) +static void examine_super1(void *sbv, char *homehost) { struct mdp_superblock_1 *sb = sbv; time_t atime; @@ -144,6 +144,7 @@ static void examine_super1(void *sbv) int faulty; int i; char *c; + int l = homehost ? strlen(homehost) : 0; printf(" Magic : %08x\n", __le32_to_cpu(sb->magic)); printf(" Version : %02d\n", 1); @@ -154,8 +155,12 @@ static void examine_super1(void *sbv) printf("%02x", sb->set_uuid[i]); } printf("\n"); - printf(" Name : %.32s\n", sb->set_name); - + printf(" Name : %.32s", sb->set_name); + if (l > 0 && l < 32 && + sb->set_name[l] == ':' && + strncmp(sb->set_name, homehost, l) == 0) + printf(" (local to host %s)", homehost); + printf("\n"); atime = __le64_to_cpu(sb->ctime) & 0xFFFFFFFFFFULL; printf(" Creation Time : %.24s\n", ctime(&atime)); c=map_num(pers, __le32_to_cpu(sb->level)); @@ -303,10 +308,20 @@ static void brief_examine_super1(void *sbv) { struct mdp_superblock_1 *sb = sbv; int i; + char *nm; + + nm = strchr(sb->set_name, ':'); + if (nm) + nm++; + else if (sb->set_name[0]) + nm = sb->set_name; + else + nm = "??"; char *c=map_num(pers, __le32_to_cpu(sb->level)); - printf("ARRAY /dev/?? level=%s metadata=1 num-devices=%d UUID=", + printf("ARRAY /dev/md/%s level=%s metadata=1 num-devices=%d UUID=", + nm, c?c:"-unknown-", sb->raid_disks); for (i=0; i<16; i++) { printf("%02x", sb->set_uuid[i]); @@ -317,13 +332,18 @@ static void brief_examine_super1(void *sbv) printf("\n"); } -static void detail_super1(void *sbv) +static void detail_super1(void *sbv, char *homehost) { struct mdp_superblock_1 *sb = sbv; int i; - - printf(" Name : %.32s\n", sb->set_name); - printf(" UUID : "); + int l = homehost ? strlen(homehost) : 0; + + printf(" Name : %.32s", sb->set_name); + if (l > 0 && l < 32 && + sb->set_name[l] == ':' && + strncmp(sb->set_name, homehost, l) == 0) + printf(" (local to host %s)", homehost); + printf("\n UUID : "); for (i=0; i<16; i++) { if ((i&3)==0 && i != 0) printf(":"); printf("%02x", sb->set_uuid[i]); @@ -347,6 +367,16 @@ static void brief_detail_super1(void *sbv) #endif +static int match_home1(void *sbv, char *homehost) +{ + struct mdp_superblock_1 *sb = sbv; + int l = homehost ? strlen(homehost) : 0; + + return (l > 0 && l < 32 && + sb->set_name[l] == ':' && + strncmp(sb->set_name, homehost, l) == 0); +} + static void uuid_from_super1(int uuid[4], void * sbv) { struct mdp_superblock_1 *super = sbv; @@ -424,7 +454,9 @@ static void getinfo_super1(struct mdinfo *info, void *sbv) info->array.working_disks = working; } -static int update_super1(struct mdinfo *info, void *sbv, char *update, char *devname, int verbose) +static int update_super1(struct mdinfo *info, void *sbv, char *update, + char *devname, int verbose, + int uuid_set, char *homehost) { /* NOTE: for 'assemble' and 'force' we need to return non-zero if any change was made. * For others, the return value is ignored. @@ -476,8 +508,38 @@ static int update_super1(struct mdinfo *info, void *sbv, char *update, char *dev /* make sure resync happens */ sb->resync_offset = ~0ULL; } - if (strcmp(update, "uuid") == 0) + if (strcmp(update, "uuid") == 0) { memcpy(sb->set_uuid, info->uuid, 16); + if (__le32_to_cpu(sb->feature_map)&MD_FEATURE_BITMAP_OFFSET) { + struct bitmap_super_s *bm; + bm = (struct bitmap_super_s*)(sbv+1024); + memcpy(bm->uuid, info->uuid, 16); + } + } + if (strcmp(update, "homehost") == 0 && + homehost) { + char *c; + update = "name"; + c = strchr(sb->set_name, ':'); + if (c) + strncpy(info->name, c+1, 31 - (c-sb->set_name)); + else + strncpy(info->name, sb->set_name, 32); + info->name[33] = 0; + } + if (strcmp(update, "name") == 0) { + if (info->name[0] == 0) + sprintf(info->name, "%d", info->array.md_minor); + memset(sb->set_name, 0, sizeof(sb->set_name)); + if (homehost && + strchr(info->name, ':') == NULL && + strlen(homehost)+1+strlen(info->name) < 32) { + strcpy(sb->set_name, homehost); + strcat(sb->set_name, ":"); + strcat(sb->set_name, info->name); + } else + strcpy(sb->set_name, info->name); + } if (strcmp(update, "_reshape_progress")==0) sb->reshape_position = __cpu_to_le64(info->reshape_progress); @@ -492,16 +554,20 @@ static __u64 event_super1(void *sbv) return __le64_to_cpu(sb->events); } -static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info, unsigned long long size, char *name) +static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info, + unsigned long long size, char *name, char *homehost) { struct mdp_superblock_1 *sb = malloc(1024 + sizeof(bitmap_super_t)); int spares; int rfd; + char defname[10]; memset(sb, 0, 1024); - if (info->major_version == -1) + if (info->major_version == -1) { /* zeroing superblock */ + *sbp = sb; return 0; + } spares = info->working_disks - info->active_disks; if (info->raid_disks + spares > 384) { @@ -510,7 +576,6 @@ static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info, return 0; } - sb->magic = __cpu_to_le32(MD_SB_MAGIC); sb->major_version = __cpu_to_le32(1); sb->feature_map = 0; @@ -525,8 +590,19 @@ static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info, } if (rfd >= 0) close(rfd); + if (name == NULL || *name == 0) { + sprintf(defname, "%d", info->md_minor); + name = defname; + } memset(sb->set_name, 0, 32); - strcpy(sb->set_name, name); + if (homehost && + strchr(name, ':')== NULL && + strlen(homehost)+1+strlen(name) < 32) { + strcpy(sb->set_name, homehost); + strcat(sb->set_name, ":"); + strcat(sb->set_name, name); + } else + strcpy(sb->set_name, name); sb->ctime = __cpu_to_le64((unsigned long long)time(0)); sb->level = __cpu_to_le32(info->level); @@ -569,6 +645,8 @@ static void add_to_super1(void *sbv, mdu_disk_info_t *dk) *rp = 0xfffe; } +static void locate_bitmap1(struct supertype *st, int fd, void *sbv); + static int store_super1(struct supertype *st, int fd, void *sbv) { struct mdp_superblock_1 *sb = sbv; @@ -632,6 +710,15 @@ static int store_super1(struct supertype *st, int fd, void *sbv) if (write(fd, sb, sbsize) != sbsize) return 4; + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { + struct bitmap_super_s *bm = (struct bitmap_super_s*) + (((char*)sb)+1024); + if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) { + locate_bitmap1(st, fd, sbv); + if (write(fd, bm, sizeof(*bm)) != sizeof(*bm)) + return 5; + } + } fsync(fd); return 0; } @@ -777,8 +864,8 @@ static int compare_super1(void **firstp, void *secondv) return 1; if (!first) { - first = malloc(1024); - memcpy(first, second, 1024); + first = malloc(1024+sizeof(bitmap_super_t)); + memcpy(first, second, 1024+sizeof(bitmap_super_t)); *firstp = first; return 0; } @@ -801,7 +888,8 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname) unsigned long long dsize; unsigned long long sb_offset; struct mdp_superblock_1 *super; - + int uuid[4]; + struct bitmap_super_s *bsb; if (st->ss == NULL) { @@ -860,7 +948,7 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname) /* * Calculate the position of the superblock. * It is always aligned to a 4K boundary and - * depeding on minor_version, it can be: + * depending on minor_version, it can be: * 0: At least 8K, but less than 12K, from end of device * 1: At start of device * 2: 4K from start of device. @@ -924,6 +1012,28 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname) return 2; } *sbp = super; + + /* Now check on the bitmap superblock */ + if ((__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) == 0) + return 0; + /* Read the bitmap superblock and make sure it looks + * valid. If it doesn't clear the bit. An --assemble --force + * should get that written out. + */ + locate_bitmap1(st, fd, super); + if (read(fd, ((char*)super)+1024, sizeof(struct bitmap_super_s)) + != sizeof(struct bitmap_super_s)) + goto no_bitmap; + + uuid_from_super1(uuid, super); + bsb = (struct bitmap_super_s *)(((char*)super)+1024); + if (__le32_to_cpu(bsb->magic) != BITMAP_MAGIC || + memcmp(bsb->uuid, uuid, 16) != 0) + goto no_bitmap; + return 0; + + no_bitmap: + super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) & ~1); return 0; } @@ -1041,7 +1151,7 @@ add_internal_bitmap1(struct supertype *st, void *sbv, } -void locate_bitmap1(struct supertype *st, int fd, void *sbv) +static void locate_bitmap1(struct supertype *st, int fd, void *sbv) { unsigned long long offset; struct mdp_superblock_1 *sb; @@ -1061,7 +1171,7 @@ void locate_bitmap1(struct supertype *st, int fd, void *sbv) lseek64(fd, offset<<9, 0); } -int write_bitmap1(struct supertype *st, int fd, void *sbv) +static int write_bitmap1(struct supertype *st, int fd, void *sbv) { struct mdp_superblock_1 *sb = sbv; bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+1024); @@ -1102,6 +1212,7 @@ struct superswitch super1 = { .detail_super = detail_super1, .brief_detail_super = brief_detail_super1, #endif + .match_home = match_home1, .uuid_from_super = uuid_from_super1, .getinfo_super = getinfo_super1, .update_super = update_super1,