/*
* mdadm - manage Linux "md" devices aka RAID arrays.
*
- * Copyright (C) 2001-2002 Neil Brown <neilb@cse.unsw.edu.au>
+ * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de>
*
*
* This program is free software; you can redistribute it and/or modify
int Assemble(struct supertype *st, char *mddev, int mdfd,
mddev_ident_t ident, char *conffile,
- mddev_dev_t devlist,
+ mddev_dev_t devlist, char *backup_file,
int readonly, int runstop,
char *update,
int verbose, int force)
*
* If !uuidset and scan, look in conf-file for uuid
* If not found, give up
- * If !devlist and scan and uuidset, get list of devs from conf-file
+ * If !devlist and scan and uuidset, get list of devs from conf-file
*
* For each device:
* Check superblock - discard if bad
int chosen_drive;
int change = 0;
int inargv = 0;
- int start_partial_ok = force || devlist==NULL;
+ int start_partial_ok = (runstop >= 0) && (force || devlist==NULL);
unsigned int num_devs;
mddev_dev_t tmpdev;
struct mdinfo info;
- struct mddev_ident_s ident2;
char *avail;
int nextspare = 0;
fprintf( stderr, Name ": no RAID superblock on %s\n",
devname);
} else {
- tst->ss->getinfo_super(&info, &ident2, super);
+ tst->ss->getinfo_super(&info, super);
}
if (dfd >= 0) close(dfd);
continue;
}
if (ident->name[0] &&
- (!super || strncmp(ident2.name, ident->name, 32)!=0)) {
+ (!super || strncmp(info.name, ident->name, 32)!=0)) {
if ((inargv && verbose >= 0) || verbose > 0)
fprintf(stderr, Name ": %s has wrong name.\n",
devname);
st->ss->update_super(&info, super, update, devname, verbose);
dfd = dev_open(devname, O_RDWR|O_EXCL);
- if (dfd < 0)
+ if (dfd < 0)
fprintf(stderr, Name ": Cannot open %s for superblock update\n",
devname);
else if (st->ss->store_super(st, dfd, super))
devname);
if (dfd >= 0)
close(dfd);
+
+ if (strcmp(update, "uuid")==0 &&
+ ident->bitmap_fd)
+ bitmap_update_uuid(ident->bitmap_fd, info.uuid);
}
if (verbose > 0)
> devices[most_recent].events)
most_recent = devcnt;
}
- if (info.array.level == -4)
+ if (info.array.level == -4)
/* with multipath, the raid_disk from the superblock is meaningless */
i = devcnt;
else
return 1;
}
- st->ss->getinfo_super(&info, &ident2, first_super);
+ st->ss->getinfo_super(&info, first_super);
/* now we have some devices that might be suitable.
* I wonder how many
fprintf(stderr, Name ": No suitable drives found for %s\n", mddev);
return 1;
}
- st->ss->getinfo_super(&info, &ident2, super);
+ st->ss->getinfo_super(&info, super);
for (i=0; i<bestcnt; i++) {
int j = best[i];
unsigned int desired_state;
}
if (force && okcnt == info.array.raid_disks-1) {
/* FIXME check event count */
- change += st->ss->update_super(&info, super, "force",
+ change += st->ss->update_super(&info, super, "force",
devices[chosen_drive].devname, verbose);
}
* that was moved aside due to the reshape overwriting live data
* The code of doing this lives in Grow.c
*/
+#ifndef MDASSEMBLE
if (info.reshape_active) {
int err = 0;
int *fdlist = malloc(sizeof(int)* bestcnt);
fdlist[i] = -1;
}
if (!err)
- err = Grow_restart(st, &info, fdlist, bestcnt);
+ err = Grow_restart(st, &info, fdlist, bestcnt, backup_file);
while (i>0) {
i--;
if (fdlist[i]>=0) close(fdlist[i]);
return err;
}
}
+#endif
/* count number of in-sync devices according to the superblock.
* We must have this number to start the array without -s or -R
*/
inf.major_version = st->ss->major;
inf.minor_version = st->minor_version;
rv = ioctl(mdfd, SET_ARRAY_INFO, &inf);
- } else
+ } else
rv = ioctl(mdfd, SET_ARRAY_INFO, NULL);
if (rv) {
fprintf(stderr, Name ": SET_BITMAP_FILE failed.\n");
return 1;
}
+ } else if (ident->bitmap_file) {
+ /* From config file */
+ int bmfd = open(ident->bitmap_file, O_RDWR);
+ if (bmfd < 0) {
+ fprintf(stderr, Name ": Could not open bitmap file %s\n",
+ ident->bitmap_file);
+ return 1;
+ }
+ if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) {
+ fprintf(stderr, Name ": Failed to set bitmapfile for %s\n", mddev);
+ close(bmfd);
+ return 1;
+ }
+ close(bmfd);
}
-
+
/* First, add the raid disks, but add the chosen one last */
for (i=0; i<= bestcnt; i++) {
int j;
}
if (runstop == 1 ||
- (runstop == 0 &&
+ (runstop <= 0 &&
( enough(info.array.level, info.array.raid_disks, info.array.layout, avail, okcnt) &&
(okcnt >= req_cnt || start_partial_ok)
))) {
if (verbose >= 0) {
fprintf(stderr, Name ": %s has been started with %d drive%s",
mddev, okcnt, okcnt==1?"":"s");
- if (okcnt < info.array.raid_disks)
+ if (okcnt < info.array.raid_disks)
fprintf(stderr, " (out of %d)", info.array.raid_disks);
if (sparecnt)
fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
return 1;
}
if (runstop == -1) {
- fprintf(stderr, Name ": %s assembled from %d drive%s, but not started.\n",
+ fprintf(stderr, Name ": %s assembled from %d drive%s",
mddev, okcnt, okcnt==1?"":"s");
+ if (okcnt != info.array.raid_disks)
+ fprintf(stderr, " (out of %d)", info.array.raid_disks);
+ fprintf(stderr, ", but not started.\n");
return 0;
}
if (verbose >= 0) {