Merge branch 'master' of git://github.com/djbw/mdadm
This commit is contained in:
commit
823f06865e
|
@ -320,6 +320,8 @@ int Assemble(struct supertype *st, char *mddev,
|
||||||
content = tmpdev->content;
|
content = tmpdev->content;
|
||||||
else
|
else
|
||||||
content = tst->ss->container_content(tst);
|
content = tst->ss->container_content(tst);
|
||||||
|
if (!content)
|
||||||
|
goto loop; /* empty container */
|
||||||
|
|
||||||
tmpdev->content = content->next;
|
tmpdev->content = content->next;
|
||||||
if (tmpdev->content == NULL)
|
if (tmpdev->content == NULL)
|
||||||
|
|
32
Create.c
32
Create.c
|
@ -792,7 +792,39 @@ int Create(struct supertype *st, char *mddev,
|
||||||
dv == moved_disk && dnum != insert_point) break;
|
dv == moved_disk && dnum != insert_point) break;
|
||||||
}
|
}
|
||||||
if (pass == 1) {
|
if (pass == 1) {
|
||||||
|
struct mdinfo info_new;
|
||||||
|
struct map_ent *me = NULL;
|
||||||
|
|
||||||
|
/* check to see if the uuid has changed due to these
|
||||||
|
* metadata changes, and if so update the member array
|
||||||
|
* and container uuid. Note ->write_init_super clears
|
||||||
|
* the subarray cursor such that ->getinfo_super once
|
||||||
|
* again returns container info.
|
||||||
|
*/
|
||||||
|
map_lock(&map);
|
||||||
|
st->ss->getinfo_super(st, &info_new);
|
||||||
|
if (st->ss->external && level != LEVEL_CONTAINER &&
|
||||||
|
!same_uuid(info_new.uuid, info.uuid, 0)) {
|
||||||
|
map_update(&map, fd2devnum(mdfd),
|
||||||
|
info_new.text_version,
|
||||||
|
info_new.uuid, chosen_name);
|
||||||
|
me = map_by_devnum(&map, st->container_dev);
|
||||||
|
}
|
||||||
|
|
||||||
st->ss->write_init_super(st);
|
st->ss->write_init_super(st);
|
||||||
|
|
||||||
|
/* update parent container uuid */
|
||||||
|
if (me) {
|
||||||
|
char *path = strdup(me->path);
|
||||||
|
|
||||||
|
st->ss->getinfo_super(st, &info_new);
|
||||||
|
map_update(&map, st->container_dev,
|
||||||
|
info_new.text_version,
|
||||||
|
info_new.uuid, path);
|
||||||
|
free(path);
|
||||||
|
}
|
||||||
|
map_unlock(&map);
|
||||||
|
|
||||||
flush_metadata_updates(st);
|
flush_metadata_updates(st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,10 +116,8 @@ int Examine(mddev_dev_t devlist, int brief, int export, int scan,
|
||||||
ap->st = st;
|
ap->st = st;
|
||||||
arrays = ap;
|
arrays = ap;
|
||||||
st->ss->getinfo_super(st, &ap->info);
|
st->ss->getinfo_super(st, &ap->info);
|
||||||
} else {
|
} else
|
||||||
st->ss->getinfo_super(st, &ap->info);
|
st->ss->getinfo_super(st, &ap->info);
|
||||||
st->ss->free_super(st);
|
|
||||||
}
|
|
||||||
if (!(ap->info.disk.state & (1<<MD_DISK_SYNC)))
|
if (!(ap->info.disk.state & (1<<MD_DISK_SYNC)))
|
||||||
ap->spares++;
|
ap->spares++;
|
||||||
d = dl_strdup(devlist->devname);
|
d = dl_strdup(devlist->devname);
|
||||||
|
|
32
mapfile.c
32
mapfile.c
|
@ -297,6 +297,34 @@ struct map_ent *map_by_name(struct map_ent **map, char *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* sets the proper subarray and container_dev according to the metadata
|
||||||
|
* version super_by_fd does this automatically, this routine is meant as
|
||||||
|
* a supplement for guess_super()
|
||||||
|
*/
|
||||||
|
static void set_member_info(struct supertype *st, struct mdstat_ent *ent)
|
||||||
|
{
|
||||||
|
char version[strlen(ent->metadata_version)+1];
|
||||||
|
|
||||||
|
st->subarray[0] = '\0';
|
||||||
|
|
||||||
|
if (strncmp(ent->metadata_version, "external:", 9) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
strcpy(version, ent->metadata_version);
|
||||||
|
|
||||||
|
if (is_subarray(&version[9])) {
|
||||||
|
char *subarray = strrchr(version, '/');
|
||||||
|
char *name = &version[10];
|
||||||
|
|
||||||
|
if (!subarray)
|
||||||
|
return;
|
||||||
|
*subarray++ = '\0';
|
||||||
|
|
||||||
|
st->container_dev = devname2devnum(name);
|
||||||
|
strncpy(st->subarray, subarray, sizeof(st->subarray));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RebuildMap(void)
|
void RebuildMap(void)
|
||||||
{
|
{
|
||||||
struct mdstat_ent *mdstat = mdstat_read(0, 0);
|
struct mdstat_ent *mdstat = mdstat_read(0, 0);
|
||||||
|
@ -337,8 +365,10 @@ void RebuildMap(void)
|
||||||
st = guess_super(dfd);
|
st = guess_super(dfd);
|
||||||
if ( st == NULL)
|
if ( st == NULL)
|
||||||
ok = -1;
|
ok = -1;
|
||||||
else
|
else {
|
||||||
|
set_member_info(st, md);
|
||||||
ok = st->ss->load_super(st, dfd, NULL);
|
ok = st->ss->load_super(st, dfd, NULL);
|
||||||
|
}
|
||||||
close(dfd);
|
close(dfd);
|
||||||
if (ok != 0)
|
if (ok != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
1
mdadm.h
1
mdadm.h
|
@ -848,6 +848,7 @@ extern int open_container(int fd);
|
||||||
extern int mdmon_running(int devnum);
|
extern int mdmon_running(int devnum);
|
||||||
extern int signal_mdmon(int devnum);
|
extern int signal_mdmon(int devnum);
|
||||||
extern int check_env(char *name);
|
extern int check_env(char *name);
|
||||||
|
extern __u32 random32(void);
|
||||||
extern int start_mdmon(int devnum);
|
extern int start_mdmon(int devnum);
|
||||||
|
|
||||||
extern char *devnum2devname(int num);
|
extern char *devnum2devname(int num);
|
||||||
|
|
|
@ -157,6 +157,7 @@ static int scan(const void *start, const void *end)
|
||||||
const struct imsm_orom *find_imsm_orom(void)
|
const struct imsm_orom *find_imsm_orom(void)
|
||||||
{
|
{
|
||||||
static int populated = 0;
|
static int populated = 0;
|
||||||
|
unsigned long align;
|
||||||
|
|
||||||
/* it's static data so we only need to read it once */
|
/* it's static data so we only need to read it once */
|
||||||
if (populated)
|
if (populated)
|
||||||
|
@ -184,7 +185,11 @@ const struct imsm_orom *find_imsm_orom(void)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* scan option-rom memory looking for an imsm signature */
|
/* scan option-rom memory looking for an imsm signature */
|
||||||
if (probe_roms_init() != 0)
|
if (check_env("IMSM_SAFE_OROM_SCAN"))
|
||||||
|
align = 2048;
|
||||||
|
else
|
||||||
|
align = 512;
|
||||||
|
if (probe_roms_init(align) != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
probe_roms();
|
probe_roms();
|
||||||
populated = scan_adapter_roms(scan);
|
populated = scan_adapter_roms(scan);
|
||||||
|
|
26
probe_roms.c
26
probe_roms.c
|
@ -32,6 +32,8 @@ static void *rom_mem = MAP_FAILED;
|
||||||
static int rom_fd = -1;
|
static int rom_fd = -1;
|
||||||
const static int rom_len = 0xf0000 - 0xc0000; /* option-rom memory region */
|
const static int rom_len = 0xf0000 - 0xc0000; /* option-rom memory region */
|
||||||
static int _sigbus;
|
static int _sigbus;
|
||||||
|
static unsigned long rom_align;
|
||||||
|
|
||||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||||
|
|
||||||
static void sigbus(int sig)
|
static void sigbus(int sig)
|
||||||
|
@ -76,11 +78,20 @@ void probe_roms_exit(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int probe_roms_init(void)
|
int probe_roms_init(unsigned long align)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
/* valid values are 2048 and 512. 512 is for PCI-3.0 compliant
|
||||||
|
* systems, or systems that do not have dangerous/legacy ISA
|
||||||
|
* devices. 2048 should always be safe
|
||||||
|
*/
|
||||||
|
if (align == 512 || align == 2048)
|
||||||
|
rom_align = align;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (signal(SIGBUS, sigbus) == SIG_ERR)
|
if (signal(SIGBUS, sigbus) == SIG_ERR)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
|
@ -208,6 +219,11 @@ int scan_adapter_roms(scan_fn fn)
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long align(unsigned long addr, unsigned long alignment)
|
||||||
|
{
|
||||||
|
return (addr + alignment - 1) & ~(alignment - 1);
|
||||||
|
}
|
||||||
|
|
||||||
void probe_roms(void)
|
void probe_roms(void)
|
||||||
{
|
{
|
||||||
const void *rom;
|
const void *rom;
|
||||||
|
@ -220,7 +236,7 @@ void probe_roms(void)
|
||||||
|
|
||||||
/* video rom */
|
/* video rom */
|
||||||
upper = adapter_rom_resources[0].start;
|
upper = adapter_rom_resources[0].start;
|
||||||
for (start = video_rom_resource.start; start < upper; start += 2048) {
|
for (start = video_rom_resource.start; start < upper; start += rom_align) {
|
||||||
rom = isa_bus_to_virt(start);
|
rom = isa_bus_to_virt(start);
|
||||||
if (!romsignature(rom))
|
if (!romsignature(rom))
|
||||||
continue;
|
continue;
|
||||||
|
@ -239,7 +255,7 @@ void probe_roms(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
|
start = align(video_rom_resource.end + 1, rom_align);
|
||||||
if (start < upper)
|
if (start < upper)
|
||||||
start = upper;
|
start = upper;
|
||||||
|
|
||||||
|
@ -255,7 +271,7 @@ void probe_roms(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for adapter roms on 2k boundaries */
|
/* check for adapter roms on 2k boundaries */
|
||||||
for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
|
for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += rom_align) {
|
||||||
rom = isa_bus_to_virt(start);
|
rom = isa_bus_to_virt(start);
|
||||||
if (!romsignature(rom))
|
if (!romsignature(rom))
|
||||||
continue;
|
continue;
|
||||||
|
@ -273,7 +289,7 @@ void probe_roms(void)
|
||||||
adapter_rom_resources[i].start = start;
|
adapter_rom_resources[i].start = start;
|
||||||
adapter_rom_resources[i].end = start + length - 1;
|
adapter_rom_resources[i].end = start + length - 1;
|
||||||
|
|
||||||
start = adapter_rom_resources[i++].end & ~2047UL;
|
start = adapter_rom_resources[i++].end & ~(rom_align - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void probe_roms_exit(void);
|
void probe_roms_exit(void);
|
||||||
int probe_roms_init(void);
|
int probe_roms_init(unsigned long align);
|
||||||
typedef int (*scan_fn)(const void *start, const void *end);
|
typedef int (*scan_fn)(const void *start, const void *end);
|
||||||
int scan_adapter_roms(scan_fn fn);
|
int scan_adapter_roms(scan_fn fn);
|
||||||
void probe_roms(void);
|
void probe_roms(void);
|
||||||
|
|
42
super-ddf.c
42
super-ddf.c
|
@ -762,6 +762,9 @@ static int load_ddf_local(int fd, struct ddf_super *super,
|
||||||
static int load_super_ddf_all(struct supertype *st, int fd,
|
static int load_super_ddf_all(struct supertype *st, int fd,
|
||||||
void **sbp, char *devname, int keep_fd);
|
void **sbp, char *devname, int keep_fd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void free_super_ddf(struct supertype *st);
|
||||||
|
|
||||||
static int load_super_ddf(struct supertype *st, int fd,
|
static int load_super_ddf(struct supertype *st, int fd,
|
||||||
char *devname)
|
char *devname)
|
||||||
{
|
{
|
||||||
|
@ -798,6 +801,8 @@ static int load_super_ddf(struct supertype *st, int fd,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_super_ddf(st);
|
||||||
|
|
||||||
if (posix_memalign((void**)&super, 512, sizeof(*super))!= 0) {
|
if (posix_memalign((void**)&super, 512, sizeof(*super))!= 0) {
|
||||||
fprintf(stderr, Name ": malloc of %zu failed.\n",
|
fprintf(stderr, Name ": malloc of %zu failed.\n",
|
||||||
sizeof(*super));
|
sizeof(*super));
|
||||||
|
@ -835,6 +840,18 @@ static int load_super_ddf(struct supertype *st, int fd,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (st->subarray[0]) {
|
||||||
|
struct vcl *v;
|
||||||
|
|
||||||
|
for (v = super->conflist; v; v = v->next)
|
||||||
|
if (v->vcnum == atoi(st->subarray))
|
||||||
|
super->currentconf = v;
|
||||||
|
if (!super->currentconf) {
|
||||||
|
free(super);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Should possibly check the sections .... */
|
/* Should possibly check the sections .... */
|
||||||
|
|
||||||
st->sb = super;
|
st->sb = super;
|
||||||
|
@ -1495,17 +1512,6 @@ static int update_super_ddf(struct supertype *st, struct mdinfo *info,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
__u32 random32(void)
|
|
||||||
{
|
|
||||||
__u32 rv;
|
|
||||||
int rfd = open("/dev/urandom", O_RDONLY);
|
|
||||||
if (rfd < 0 || read(rfd, &rv, 4) != 4)
|
|
||||||
rv = random();
|
|
||||||
if (rfd >= 0)
|
|
||||||
close(rfd);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void make_header_guid(char *guid)
|
static void make_header_guid(char *guid)
|
||||||
{
|
{
|
||||||
__u32 stamp;
|
__u32 stamp;
|
||||||
|
@ -2345,15 +2351,19 @@ static int __write_init_super_ddf(struct supertype *st, int do_close)
|
||||||
|
|
||||||
static int write_init_super_ddf(struct supertype *st)
|
static int write_init_super_ddf(struct supertype *st)
|
||||||
{
|
{
|
||||||
|
struct ddf_super *ddf = st->sb;
|
||||||
|
struct vcl *currentconf = ddf->currentconf;
|
||||||
|
|
||||||
|
/* we are done with currentconf reset it to point st at the container */
|
||||||
|
ddf->currentconf = NULL;
|
||||||
|
|
||||||
if (st->update_tail) {
|
if (st->update_tail) {
|
||||||
/* queue the virtual_disk and vd_config as metadata updates */
|
/* queue the virtual_disk and vd_config as metadata updates */
|
||||||
struct virtual_disk *vd;
|
struct virtual_disk *vd;
|
||||||
struct vd_config *vc;
|
struct vd_config *vc;
|
||||||
struct ddf_super *ddf = st->sb;
|
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (!ddf->currentconf) {
|
if (!currentconf) {
|
||||||
int len = (sizeof(struct phys_disk) +
|
int len = (sizeof(struct phys_disk) +
|
||||||
sizeof(struct phys_disk_entry));
|
sizeof(struct phys_disk_entry));
|
||||||
|
|
||||||
|
@ -2372,14 +2382,14 @@ static int write_init_super_ddf(struct supertype *st)
|
||||||
len = sizeof(struct virtual_disk) + sizeof(struct virtual_entry);
|
len = sizeof(struct virtual_disk) + sizeof(struct virtual_entry);
|
||||||
vd = malloc(len);
|
vd = malloc(len);
|
||||||
*vd = *ddf->virt;
|
*vd = *ddf->virt;
|
||||||
vd->entries[0] = ddf->virt->entries[ddf->currentconf->vcnum];
|
vd->entries[0] = ddf->virt->entries[currentconf->vcnum];
|
||||||
vd->populated_vdes = __cpu_to_be16(ddf->currentconf->vcnum);
|
vd->populated_vdes = __cpu_to_be16(currentconf->vcnum);
|
||||||
append_metadata_update(st, vd, len);
|
append_metadata_update(st, vd, len);
|
||||||
|
|
||||||
/* Then the vd_config */
|
/* Then the vd_config */
|
||||||
len = ddf->conf_rec_len * 512;
|
len = ddf->conf_rec_len * 512;
|
||||||
vc = malloc(len);
|
vc = malloc(len);
|
||||||
memcpy(vc, &ddf->currentconf->conf, len);
|
memcpy(vc, ¤tconf->conf, len);
|
||||||
append_metadata_update(st, vc, len);
|
append_metadata_update(st, vc, len);
|
||||||
|
|
||||||
/* FIXME I need to close the fds! */
|
/* FIXME I need to close the fds! */
|
||||||
|
|
102
super-intel.c
102
super-intel.c
|
@ -247,6 +247,7 @@ struct intel_super {
|
||||||
int creating_imsm; /* flag to indicate container creation */
|
int creating_imsm; /* flag to indicate container creation */
|
||||||
int current_vol; /* index of raid device undergoing creation */
|
int current_vol; /* index of raid device undergoing creation */
|
||||||
__u32 create_offset; /* common start for 'current_vol' */
|
__u32 create_offset; /* common start for 'current_vol' */
|
||||||
|
__u32 random; /* random data for seeding new family numbers */
|
||||||
struct intel_dev *devlist;
|
struct intel_dev *devlist;
|
||||||
struct dl {
|
struct dl {
|
||||||
struct dl *next;
|
struct dl *next;
|
||||||
|
@ -714,6 +715,7 @@ static void examine_super_imsm(struct supertype *st, char *homehost)
|
||||||
printf(" Magic : %s\n", str);
|
printf(" Magic : %s\n", str);
|
||||||
snprintf(str, strlen(MPB_VERSION_RAID0), "%s", get_imsm_version(mpb));
|
snprintf(str, strlen(MPB_VERSION_RAID0), "%s", get_imsm_version(mpb));
|
||||||
printf(" Version : %s\n", get_imsm_version(mpb));
|
printf(" Version : %s\n", get_imsm_version(mpb));
|
||||||
|
printf(" Orig Family : %08x\n", __le32_to_cpu(mpb->orig_family_num));
|
||||||
printf(" Family : %08x\n", __le32_to_cpu(mpb->family_num));
|
printf(" Family : %08x\n", __le32_to_cpu(mpb->family_num));
|
||||||
printf(" Generation : %08x\n", __le32_to_cpu(mpb->generation_num));
|
printf(" Generation : %08x\n", __le32_to_cpu(mpb->generation_num));
|
||||||
getinfo_super_imsm(st, &info);
|
getinfo_super_imsm(st, &info);
|
||||||
|
@ -763,8 +765,10 @@ static void brief_examine_super_imsm(struct supertype *st, int verbose)
|
||||||
struct intel_super *super = st->sb;
|
struct intel_super *super = st->sb;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!super->anchor->num_raid_devs)
|
if (!super->anchor->num_raid_devs) {
|
||||||
|
printf("ARRAY metadata=imsm\n");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
getinfo_super_imsm(st, &info);
|
getinfo_super_imsm(st, &info);
|
||||||
fname_from_uuid(st, &info, nbuf, ':');
|
fname_from_uuid(st, &info, nbuf, ':');
|
||||||
|
@ -1089,7 +1093,7 @@ static int match_home_imsm(struct supertype *st, char *homehost)
|
||||||
/* the imsm metadata format does not specify any host
|
/* the imsm metadata format does not specify any host
|
||||||
* identification information. We return -1 since we can never
|
* identification information. We return -1 since we can never
|
||||||
* confirm nor deny whether a given array is "meant" for this
|
* confirm nor deny whether a given array is "meant" for this
|
||||||
* host. We rely on compare_super and the 'family_num' field to
|
* host. We rely on compare_super and the 'family_num' fields to
|
||||||
* exclude member disks that do not belong, and we rely on
|
* exclude member disks that do not belong, and we rely on
|
||||||
* mdadm.conf to specify the arrays that should be assembled.
|
* mdadm.conf to specify the arrays that should be assembled.
|
||||||
* Auto-assembly may still pick up "foreign" arrays.
|
* Auto-assembly may still pick up "foreign" arrays.
|
||||||
|
@ -1117,7 +1121,7 @@ static void uuid_from_super_imsm(struct supertype *st, int uuid[4])
|
||||||
*/
|
*/
|
||||||
/* imsm does not track uuid's so we synthesis one using sha1 on
|
/* imsm does not track uuid's so we synthesis one using sha1 on
|
||||||
* - The signature (Which is constant for all imsm array, but no matter)
|
* - The signature (Which is constant for all imsm array, but no matter)
|
||||||
* - the family_num of the container
|
* - the orig_family_num of the container
|
||||||
* - the index number of the volume
|
* - the index number of the volume
|
||||||
* - the 'serial' number of the volume.
|
* - the 'serial' number of the volume.
|
||||||
* Hopefully these are all constant.
|
* Hopefully these are all constant.
|
||||||
|
@ -1127,10 +1131,18 @@ static void uuid_from_super_imsm(struct supertype *st, int uuid[4])
|
||||||
char buf[20];
|
char buf[20];
|
||||||
struct sha1_ctx ctx;
|
struct sha1_ctx ctx;
|
||||||
struct imsm_dev *dev = NULL;
|
struct imsm_dev *dev = NULL;
|
||||||
|
__u32 family_num;
|
||||||
|
|
||||||
|
/* some mdadm versions failed to set ->orig_family_num, in which
|
||||||
|
* case fall back to ->family_num. orig_family_num will be
|
||||||
|
* fixed up with the first metadata update.
|
||||||
|
*/
|
||||||
|
family_num = super->anchor->orig_family_num;
|
||||||
|
if (family_num == 0)
|
||||||
|
family_num = super->anchor->family_num;
|
||||||
sha1_init_ctx(&ctx);
|
sha1_init_ctx(&ctx);
|
||||||
sha1_process_bytes(super->anchor->sig, MPB_SIG_LEN, &ctx);
|
sha1_process_bytes(super->anchor->sig, MPB_SIG_LEN, &ctx);
|
||||||
sha1_process_bytes(&super->anchor->family_num, sizeof(__u32), &ctx);
|
sha1_process_bytes(&family_num, sizeof(__u32), &ctx);
|
||||||
if (super->current_vol >= 0)
|
if (super->current_vol >= 0)
|
||||||
dev = get_imsm_dev(super, super->current_vol);
|
dev = get_imsm_dev(super, super->current_vol);
|
||||||
if (dev) {
|
if (dev) {
|
||||||
|
@ -1256,7 +1268,11 @@ static void fixup_container_spare_uuid(struct mdinfo *inf)
|
||||||
struct supertype *_cst; /* container supertype */
|
struct supertype *_cst; /* container supertype */
|
||||||
|
|
||||||
_cst = array_list->st;
|
_cst = array_list->st;
|
||||||
|
if (_cst)
|
||||||
_sst = _cst->ss->match_metadata_desc(inf->text_version);
|
_sst = _cst->ss->match_metadata_desc(inf->text_version);
|
||||||
|
else
|
||||||
|
_sst = NULL;
|
||||||
|
|
||||||
if (_sst) {
|
if (_sst) {
|
||||||
memcpy(inf->uuid, array_list->uuid, sizeof(int[4]));
|
memcpy(inf->uuid, array_list->uuid, sizeof(int[4]));
|
||||||
free(_sst);
|
free(_sst);
|
||||||
|
@ -1438,7 +1454,8 @@ static int compare_super_imsm(struct supertype *st, struct supertype *tst)
|
||||||
*/
|
*/
|
||||||
if (first->anchor->num_raid_devs > 0 &&
|
if (first->anchor->num_raid_devs > 0 &&
|
||||||
sec->anchor->num_raid_devs > 0) {
|
sec->anchor->num_raid_devs > 0) {
|
||||||
if (first->anchor->family_num != sec->anchor->family_num)
|
if (first->anchor->orig_family_num != sec->anchor->orig_family_num ||
|
||||||
|
first->anchor->family_num != sec->anchor->family_num)
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1478,6 +1495,7 @@ static int compare_super_imsm(struct supertype *st, struct supertype *tst)
|
||||||
imsm_copy_dev(get_imsm_dev(first, i), get_imsm_dev(sec, i));
|
imsm_copy_dev(get_imsm_dev(first, i), get_imsm_dev(sec, i));
|
||||||
|
|
||||||
first->anchor->num_raid_devs = sec->anchor->num_raid_devs;
|
first->anchor->num_raid_devs = sec->anchor->num_raid_devs;
|
||||||
|
first->anchor->orig_family_num = sec->anchor->orig_family_num;
|
||||||
first->anchor->family_num = sec->anchor->family_num;
|
first->anchor->family_num = sec->anchor->family_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2167,9 +2185,11 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
|
||||||
if (st->subarray[0]) {
|
if (st->subarray[0]) {
|
||||||
if (atoi(st->subarray) <= super->anchor->num_raid_devs)
|
if (atoi(st->subarray) <= super->anchor->num_raid_devs)
|
||||||
super->current_vol = atoi(st->subarray);
|
super->current_vol = atoi(st->subarray);
|
||||||
else
|
else {
|
||||||
|
free_imsm(super);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
*sbp = super;
|
*sbp = super;
|
||||||
st->container_dev = devnum;
|
st->container_dev = devnum;
|
||||||
|
@ -2193,8 +2213,8 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname)
|
||||||
if (load_super_imsm_all(st, fd, &st->sb, devname, 1) == 0)
|
if (load_super_imsm_all(st, fd, &st->sb, devname, 1) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
if (st->subarray[0])
|
|
||||||
return 1; /* FIXME */
|
free_super_imsm(st);
|
||||||
|
|
||||||
super = alloc_super(0);
|
super = alloc_super(0);
|
||||||
if (!super) {
|
if (!super) {
|
||||||
|
@ -2215,6 +2235,15 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (st->subarray[0]) {
|
||||||
|
if (atoi(st->subarray) <= super->anchor->num_raid_devs)
|
||||||
|
super->current_vol = atoi(st->subarray);
|
||||||
|
else {
|
||||||
|
free_imsm(super);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
st->sb = super;
|
st->sb = super;
|
||||||
if (st->ss == NULL) {
|
if (st->ss == NULL) {
|
||||||
st->ss = &super_imsm;
|
st->ss = &super_imsm;
|
||||||
|
@ -2536,8 +2565,10 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
|
||||||
|
|
||||||
*_dev = *dev;
|
*_dev = *dev;
|
||||||
*_disk = dl->disk;
|
*_disk = dl->disk;
|
||||||
sum = __gen_imsm_checksum(mpb);
|
sum = random32();
|
||||||
|
sum += __gen_imsm_checksum(mpb);
|
||||||
mpb->family_num = __cpu_to_le32(sum);
|
mpb->family_num = __cpu_to_le32(sum);
|
||||||
|
mpb->orig_family_num = mpb->family_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2634,6 +2665,7 @@ static int write_super_imsm_spares(struct intel_super *super, int doclose)
|
||||||
mpb->disk[0] = d->disk;
|
mpb->disk[0] = d->disk;
|
||||||
sum = __gen_imsm_checksum(mpb);
|
sum = __gen_imsm_checksum(mpb);
|
||||||
mpb->family_num = __cpu_to_le32(sum);
|
mpb->family_num = __cpu_to_le32(sum);
|
||||||
|
mpb->orig_family_num = 0;
|
||||||
sum = __gen_imsm_checksum(mpb);
|
sum = __gen_imsm_checksum(mpb);
|
||||||
mpb->check_sum = __cpu_to_le32(sum);
|
mpb->check_sum = __cpu_to_le32(sum);
|
||||||
|
|
||||||
|
@ -2668,6 +2700,12 @@ static int write_super_imsm(struct intel_super *super, int doclose)
|
||||||
generation++;
|
generation++;
|
||||||
mpb->generation_num = __cpu_to_le32(generation);
|
mpb->generation_num = __cpu_to_le32(generation);
|
||||||
|
|
||||||
|
/* fix up cases where previous mdadm releases failed to set
|
||||||
|
* orig_family_num
|
||||||
|
*/
|
||||||
|
if (mpb->orig_family_num == 0)
|
||||||
|
mpb->orig_family_num = mpb->family_num;
|
||||||
|
|
||||||
mpb_size += sizeof(struct imsm_disk) * mpb->num_disks;
|
mpb_size += sizeof(struct imsm_disk) * mpb->num_disks;
|
||||||
for (d = super->disks; d; d = d->next) {
|
for (d = super->disks; d; d = d->next) {
|
||||||
if (d->index == -1)
|
if (d->index == -1)
|
||||||
|
@ -2711,17 +2749,16 @@ static int write_super_imsm(struct intel_super *super, int doclose)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int create_array(struct supertype *st)
|
static int create_array(struct supertype *st, int dev_idx)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
struct imsm_update_create_array *u;
|
struct imsm_update_create_array *u;
|
||||||
struct intel_super *super = st->sb;
|
struct intel_super *super = st->sb;
|
||||||
struct imsm_dev *dev = get_imsm_dev(super, super->current_vol);
|
struct imsm_dev *dev = get_imsm_dev(super, dev_idx);
|
||||||
struct imsm_map *map = get_imsm_map(dev, 0);
|
struct imsm_map *map = get_imsm_map(dev, 0);
|
||||||
struct disk_info *inf;
|
struct disk_info *inf;
|
||||||
struct imsm_disk *disk;
|
struct imsm_disk *disk;
|
||||||
int i;
|
int i;
|
||||||
int idx;
|
|
||||||
|
|
||||||
len = sizeof(*u) - sizeof(*dev) + sizeof_imsm_dev(dev, 0) +
|
len = sizeof(*u) - sizeof(*dev) + sizeof_imsm_dev(dev, 0) +
|
||||||
sizeof(*inf) * map->num_members;
|
sizeof(*inf) * map->num_members;
|
||||||
|
@ -2733,11 +2770,12 @@ static int create_array(struct supertype *st)
|
||||||
}
|
}
|
||||||
|
|
||||||
u->type = update_create_array;
|
u->type = update_create_array;
|
||||||
u->dev_idx = super->current_vol;
|
u->dev_idx = dev_idx;
|
||||||
imsm_copy_dev(&u->dev, dev);
|
imsm_copy_dev(&u->dev, dev);
|
||||||
inf = get_disk_info(u);
|
inf = get_disk_info(u);
|
||||||
for (i = 0; i < map->num_members; i++) {
|
for (i = 0; i < map->num_members; i++) {
|
||||||
idx = get_imsm_disk_idx(dev, i);
|
int idx = get_imsm_disk_idx(dev, i);
|
||||||
|
|
||||||
disk = get_imsm_disk(super, idx);
|
disk = get_imsm_disk(super, idx);
|
||||||
serialcpy(inf[i].serial, disk->serial);
|
serialcpy(inf[i].serial, disk->serial);
|
||||||
}
|
}
|
||||||
|
@ -2771,21 +2809,26 @@ static int _add_disk(struct supertype *st)
|
||||||
|
|
||||||
static int write_init_super_imsm(struct supertype *st)
|
static int write_init_super_imsm(struct supertype *st)
|
||||||
{
|
{
|
||||||
|
struct intel_super *super = st->sb;
|
||||||
|
int current_vol = super->current_vol;
|
||||||
|
|
||||||
|
/* we are done with current_vol reset it to point st at the container */
|
||||||
|
super->current_vol = -1;
|
||||||
|
|
||||||
if (st->update_tail) {
|
if (st->update_tail) {
|
||||||
/* queue the recently created array / added disk
|
/* queue the recently created array / added disk
|
||||||
* as a metadata update */
|
* as a metadata update */
|
||||||
struct intel_super *super = st->sb;
|
|
||||||
struct dl *d;
|
struct dl *d;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
/* determine if we are creating a volume or adding a disk */
|
/* determine if we are creating a volume or adding a disk */
|
||||||
if (super->current_vol < 0) {
|
if (current_vol < 0) {
|
||||||
/* in the add disk case we are running in mdmon
|
/* in the add disk case we are running in mdmon
|
||||||
* context, so don't close fd's
|
* context, so don't close fd's
|
||||||
*/
|
*/
|
||||||
return _add_disk(st);
|
return _add_disk(st);
|
||||||
} else
|
} else
|
||||||
rv = create_array(st);
|
rv = create_array(st, current_vol);
|
||||||
|
|
||||||
for (d = super->disks; d ; d = d->next) {
|
for (d = super->disks; d ; d = d->next) {
|
||||||
close(d->fd);
|
close(d->fd);
|
||||||
|
@ -3840,14 +3883,13 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot,
|
||||||
int idx = get_imsm_disk_idx(dev, slot);
|
int idx = get_imsm_disk_idx(dev, slot);
|
||||||
struct imsm_super *mpb = super->anchor;
|
struct imsm_super *mpb = super->anchor;
|
||||||
struct imsm_map *map;
|
struct imsm_map *map;
|
||||||
unsigned long long esize;
|
|
||||||
unsigned long long pos;
|
unsigned long long pos;
|
||||||
struct mdinfo *d;
|
struct mdinfo *d;
|
||||||
struct extent *ex;
|
struct extent *ex;
|
||||||
int i, j;
|
int i, j;
|
||||||
int found;
|
int found;
|
||||||
__u32 array_start;
|
__u32 array_start;
|
||||||
__u32 blocks;
|
__u32 array_end;
|
||||||
struct dl *dl;
|
struct dl *dl;
|
||||||
|
|
||||||
for (dl = super->disks; dl; dl = dl->next) {
|
for (dl = super->disks; dl; dl = dl->next) {
|
||||||
|
@ -3899,15 +3941,14 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot,
|
||||||
j = 0;
|
j = 0;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
array_start = __le32_to_cpu(map->pba_of_lba0);
|
array_start = __le32_to_cpu(map->pba_of_lba0);
|
||||||
blocks = __le32_to_cpu(map->blocks_per_member);
|
array_end = array_start +
|
||||||
|
__le32_to_cpu(map->blocks_per_member) - 1;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* check that we can start at pba_of_lba0 with
|
/* check that we can start at pba_of_lba0 with
|
||||||
* blocks_per_member of space
|
* blocks_per_member of space
|
||||||
*/
|
*/
|
||||||
esize = ex[j].start - pos;
|
if (array_start >= pos && array_end < ex[j].start) {
|
||||||
if (array_start >= pos &&
|
|
||||||
array_start + blocks < ex[j].start) {
|
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3921,9 +3962,8 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot,
|
||||||
|
|
||||||
free(ex);
|
free(ex);
|
||||||
if (i < mpb->num_raid_devs) {
|
if (i < mpb->num_raid_devs) {
|
||||||
dprintf("%x:%x does not have %u at %u\n",
|
dprintf("%x:%x does not have %u to %u available\n",
|
||||||
dl->major, dl->minor,
|
dl->major, dl->minor, array_start, array_end);
|
||||||
blocks, array_start);
|
|
||||||
/* No room */
|
/* No room */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -4025,6 +4065,7 @@ static struct mdinfo *imsm_activate_spare(struct active_array *a,
|
||||||
di->data_offset = __le32_to_cpu(map->pba_of_lba0);
|
di->data_offset = __le32_to_cpu(map->pba_of_lba0);
|
||||||
di->component_size = a->info.component_size;
|
di->component_size = a->info.component_size;
|
||||||
di->container_member = inst;
|
di->container_member = inst;
|
||||||
|
super->random = random32();
|
||||||
di->next = rv;
|
di->next = rv;
|
||||||
rv = di;
|
rv = di;
|
||||||
num_spares++;
|
num_spares++;
|
||||||
|
@ -4191,6 +4232,15 @@ static void imsm_process_update(struct supertype *st,
|
||||||
set_imsm_ord_tbl_ent(map, u->slot, dl->index);
|
set_imsm_ord_tbl_ent(map, u->slot, dl->index);
|
||||||
set_imsm_ord_tbl_ent(migr_map, u->slot, dl->index | IMSM_ORD_REBUILD);
|
set_imsm_ord_tbl_ent(migr_map, u->slot, dl->index | IMSM_ORD_REBUILD);
|
||||||
|
|
||||||
|
/* update the family_num to mark a new container
|
||||||
|
* generation, being careful to record the existing
|
||||||
|
* family_num in orig_family_num to clean up after
|
||||||
|
* earlier mdadm versions that neglected to set it.
|
||||||
|
*/
|
||||||
|
if (mpb->orig_family_num == 0)
|
||||||
|
mpb->orig_family_num = mpb->family_num;
|
||||||
|
mpb->family_num += super->random;
|
||||||
|
|
||||||
/* count arrays using the victim in the metadata */
|
/* count arrays using the victim in the metadata */
|
||||||
found = 0;
|
found = 0;
|
||||||
for (a = st->arrays; a ; a = a->next) {
|
for (a = st->arrays; a ; a = a->next) {
|
||||||
|
|
11
util.c
11
util.c
|
@ -1298,6 +1298,17 @@ int check_env(char *name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__u32 random32(void)
|
||||||
|
{
|
||||||
|
__u32 rv;
|
||||||
|
int rfd = open("/dev/urandom", O_RDONLY);
|
||||||
|
if (rfd < 0 || read(rfd, &rv, 4) != 4)
|
||||||
|
rv = random();
|
||||||
|
if (rfd >= 0)
|
||||||
|
close(rfd);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef MDASSEMBLE
|
#ifndef MDASSEMBLE
|
||||||
int flush_metadata_updates(struct supertype *st)
|
int flush_metadata_updates(struct supertype *st)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue