Merge branch 'master' into devel-3.1

This commit is contained in:
NeilBrown 2009-10-22 11:13:13 +11:00
commit 4a997737a1
20 changed files with 873 additions and 320 deletions

View File

@ -315,6 +315,9 @@ int Assemble(struct supertype *st, char *mddev,
}
/* It is worth looking inside this container.
*/
if (verbose > 0)
fprintf(stderr, Name ": looking in container %s\n",
devname);
next_member:
if (tmpdev->content)
content = tmpdev->content;
@ -405,6 +408,9 @@ int Assemble(struct supertype *st, char *mddev,
fprintf(stderr, Name ": member %s in %s is already assembled\n",
content->text_version,
devname);
skip:
if (tmpdev->content)
goto next_member;
tst->ss->free_super(tst);
tst = NULL;
content = NULL;
@ -412,6 +418,21 @@ int Assemble(struct supertype *st, char *mddev,
goto loop;
return 1;
}
if (ident->member && ident->member[0]) {
char *s = strchr(content->text_version+1, '/');
if (s == NULL) {
fprintf(stderr, Name ": badly formatted version: %s\n",
content->text_version);
goto skip;
}
if (strcmp(ident->member, s+1) != 0) {
if (report_missmatch)
fprintf(stderr,
Name ": skipping wrong member %s\n",
content->text_version);
goto skip;
}
}
st = tst; tst = NULL;
if (!auto_assem && tmpdev->next != NULL) {
fprintf(stderr, Name ": %s is a container, but is not "
@ -420,6 +441,9 @@ int Assemble(struct supertype *st, char *mddev,
st->ss->free_super(st);
return 1;
}
if (verbose > 0)
fprintf(stderr, Name ": found match on member %s in %s\n",
content->text_version, devname);
break;
}
if (st == NULL)
@ -565,6 +589,7 @@ int Assemble(struct supertype *st, char *mddev,
#endif
/* Ok, no bad inconsistancy, we can try updating etc */
bitmap_done = 0;
content->update_private = NULL;
for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) {
char *devname = tmpdev->devname;
struct stat stb;
@ -717,6 +742,8 @@ int Assemble(struct supertype *st, char *mddev,
}
devcnt++;
}
free(content->update_private);
content->update_private = NULL;
if (devcnt == 0) {
fprintf(stderr, Name ": no devices found for %s\n",

View File

@ -194,7 +194,12 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
st->ss->export_detail_super(st);
} else {
struct map_ent *mp, *map = NULL;
char nbuf[64];
mp = map_by_devnum(&map, fd2devnum(fd));
if (mp) {
__fname_from_uuid(mp->uuid, 0, nbuf, ':');
printf("MD_UUID=%s\n", nbuf+5);
}
if (mp && mp->path &&
strncmp(mp->path, "/dev/md/", 8) == 0)
printf("MD_DEVNAME=%s\n", mp->path+8);
@ -540,6 +545,7 @@ This is pretty boring
1, avail, avail_disks))
rv = 2;
free(disks);
out:
close(fd);
return rv;

View File

@ -140,7 +140,7 @@ static void remove_devices(int devnum, char *path)
strcpy(path2, path);
pe = path2 + strlen(path2);
} else
path = NULL;
path2 = path = NULL;
for (part = 0; part < 16; part++) {
if (part) {
@ -161,6 +161,7 @@ static void remove_devices(int devnum, char *path)
unlink(path2);
}
}
free(path2);
}
@ -649,6 +650,7 @@ int Manage_subdevs(char *devname, int fd,
disc.state |= (1<<MD_DISK_SYNC);
break;
}
free(used);
}
if (dv->writemostly == 1)
disc.state |= (1 << MD_DISK_WRITEMOSTLY);

View File

@ -33,14 +33,6 @@
static void alert(char *event, char *dev, char *disc, char *mailaddr, char *mailfrom,
char *cmd, int dosyslog);
static char *percentalerts[] = {
"RebuildStarted",
"Rebuild20",
"Rebuild40",
"Rebuild60",
"Rebuild80",
};
/* The largest number of disks current arrays can manage is 384
* This really should be dynamically, but that will have to wait
* At least it isn't MD_SB_DISKS.
@ -49,7 +41,7 @@ static char *percentalerts[] = {
int Monitor(mddev_dev_t devlist,
char *mailaddr, char *alert_cmd,
int period, int daemonise, int scan, int oneshot,
int dosyslog, int test, char* pidfile)
int dosyslog, int test, char* pidfile, int increments)
{
/*
* Every few seconds, scan every md device looking for changes
@ -77,8 +69,8 @@ int Monitor(mddev_dev_t devlist,
* An active device had a reverse transition
* RebuildStarted
* percent went from -1 to +ve
* Rebuild20 Rebuild40 Rebuild60 Rebuild80
* percent went from below to not-below that number
* RebuildNN
* percent went from below to not-below NN%
* DeviceDisappeared
* Couldn't access a device which was previously visible
*
@ -311,9 +303,17 @@ int Monitor(mddev_dev_t devlist,
if (mse &&
st->percent >= 0 &&
mse->percent >= 0 &&
(mse->percent / 20) > (st->percent / 20))
alert(percentalerts[mse->percent/20],
(mse->percent / increments) > (st->percent / increments)) {
char percentalert[15]; // "RebuildNN" (10 chars) or "RebuildStarted" (15 chars)
if((mse->percent / increments) == 0)
snprintf(percentalert, sizeof(percentalert), "RebuildStarted");
else
snprintf(percentalert, sizeof(percentalert), "Rebuild%02d", mse->percent);
alert(percentalert,
dev, NULL, mailaddr, mailfrom, alert_cmd, dosyslog);
}
if (mse &&
mse->percent == -1 &&

View File

@ -176,6 +176,7 @@ struct option long_options[] = {
{"mail", 1, 0, 'm'},
{"program", 1, 0, 'p'},
{"alert", 1, 0, 'p'},
{"increment", 1, 0, 'r'},
{"delay", 1, 0, 'd'},
{"daemonise", 0, 0, 'f'},
{"daemonize", 0, 0, 'f'},
@ -496,6 +497,7 @@ char Help_monitor[] =
" --mail= -m : Address to mail alerts of failure to\n"
" --program= -p : Program to run when an event is detected\n"
" --alert= : same as --program\n"
" --increment= -r : Report RebuildNN events in the given increment. default=20\n"
" --delay= -d : seconds of delay between polling state. default=60\n"
" --config= -c : specify a different config file\n"
" --scan -s : find mail-address/program in config file\n"

View File

@ -680,6 +680,12 @@ void do_manager(struct supertype *container)
read_sock(container);
if (container->sock < 0 || socket_hup_requested) {
/* If this fails, we hope it already exists
* pid file lives in /var/run/mdadm/mdXX.pid
*/
mkdir("/var", 0600);
mkdir("/var/run", 0600);
mkdir("/var/run/mdadm", 0600);
close(container->sock);
container->sock = make_control_sock(container->devname);
make_pidfile(container->devname, 0);

14
mdadm.8
View File

@ -309,7 +309,7 @@ says to get a list of array devices from
.BR /proc/mdstat .
.TP
.B \-e ", " \-\-metadata=
.BR \-e ", " \-\-metadata=
Declare the style of RAID metadata (superblock) to be used. The
default is 0.90 for
.BR \-\-create ,
@ -1261,6 +1261,12 @@ reduce this as the kernel alerts
.I mdadm
immediately when there is any change.
.TP
.BR \-r ", " \-\-increment
Give a percentage increment.
.I mdadm
will generate RebuildNN events with the given percentage increment.
.TP
.BR \-f ", " \-\-daemonise
Tell
@ -1859,8 +1865,10 @@ An md array started reconstruction. (syslog priority: Warning)
.BI Rebuild NN
Where
.I NN
is 20, 40, 60, or 80, this indicates that rebuild has passed that many
percentage of the total. (syslog priority: Warning)
is a two-digit number (ie. 05, 48). This indicates that rebuild
has passed that many percent of the total. The events are generated
with fixed increment since 0. Increment size may be specified with
a commandline option (default is 20). (syslog priority: Warning)
.TP
.B RebuildFinished

23
mdadm.c
View File

@ -91,6 +91,7 @@ int main(int argc, char *argv[])
int require_homehost = 1;
char *mailaddr = NULL;
char *program = NULL;
int increments = 20;
int delay = 0;
int daemonise = 0;
char *pidfile = NULL;
@ -714,6 +715,14 @@ int main(int argc, char *argv[])
program = optarg;
continue;
case O(MONITOR,'r'): /* rebuild increments */
increments = atoi(optarg);
if (increments>99 || increments<1) {
fprintf(stderr, Name ": please specify positive integer between 1 and 99 as rebuild increments.\n");
exit(2);
}
continue;
case O(MONITOR,'d'): /* delay in seconds */
case O(GROW, 'd'):
case O(BUILD,'d'): /* delay for bitmap updates */
@ -1270,11 +1279,18 @@ int main(int argc, char *argv[])
struct mdstat_ent *ms = mdstat_read(0, 1);
struct mdstat_ent *e;
struct map_ent *map = NULL;
int members;
int v = verbose>1?0:verbose+1;
for (members = 0; members <= 1; members++) {
for (e=ms ; e ; e=e->next) {
char *name;
struct map_ent *me;
int member = e->metadata_version &&
strncmp(e->metadata_version,
"external:/", 10) == 0;
if (members != member)
continue;
me = map_by_devnum(&map, e->devnum);
if (me && me->path
&& strcmp(me->path, "/unknown") != 0)
@ -1292,9 +1308,10 @@ int main(int argc, char *argv[])
export, test,
homehost);
else
rv |= WaitClean(name, v);
rv |= WaitClean(name, -1, v);
put_md_name(name);
}
}
free_mdstat(ms);
} else if (devmode == 'S' && scan) {
/* apply --stop to all devices in /proc/mdstat */
@ -1353,7 +1370,7 @@ int main(int argc, char *argv[])
case 'W':
rv |= Wait(dv->devname); continue;
case Waitclean:
rv |= WaitClean(dv->devname, verbose-quiet); continue;
rv |= WaitClean(dv->devname, -1, verbose-quiet); continue;
}
mdfd = open_mddev(dv->devname, 1);
if (mdfd>=0) {
@ -1393,7 +1410,7 @@ int main(int argc, char *argv[])
}
rv= Monitor(devlist, mailaddr, program,
delay?delay:60, daemonise, scan, oneshot,
dosyslog, test, pidfile);
dosyslog, test, pidfile, increments);
break;
case GROW:

10
mdadm.h
View File

@ -153,6 +153,11 @@ struct mdinfo {
int cache_size; /* size of raid456 stripe cache*/
int mismatch_cnt;
char text_version[50];
void *update_private; /* for passing metadata-format
* specific update data
* between successive calls to
* update_super()
*/
int container_member; /* for assembling external-metatdata arrays
* This is to be used internally by metadata
@ -749,11 +754,11 @@ extern int Examine(mddev_dev_t devlist, int brief, int export, int scan,
extern int Monitor(mddev_dev_t devlist,
char *mailaddr, char *alert_cmd,
int period, int daemonise, int scan, int oneshot,
int dosyslog, int test, char *pidfile);
int dosyslog, int test, char *pidfile, int increments);
extern int Kill(char *dev, int force, int quiet, int noexcl);
extern int Wait(char *dev);
extern int WaitClean(char *dev, int verbose);
extern int WaitClean(char *dev, int sock, int verbose);
extern int Incremental(char *devname, int verbose, int runstop,
struct supertype *st, char *homehost, int require_homehost,
@ -813,6 +818,7 @@ extern void uuid_from_super(int uuid[4], mdp_super_t *super);
extern const int uuid_match_any[4];
extern int same_uuid(int a[4], int b[4], int swapuuid);
extern void copy_uuid(void *a, int b[4], int swapuuid);
extern char *__fname_from_uuid(int id[4], int swap, char *buf, char sep);
extern char *fname_from_uuid(struct supertype *st,
struct mdinfo *info, char *buf, char sep);
extern unsigned long calc_csum(void *super, int bytes);

117
mdmon.c
View File

@ -113,6 +113,14 @@ static struct superswitch *find_metadata_methods(char *vers)
return NULL;
}
static int test_pidfile(char *devname)
{
char path[100];
struct stat st;
sprintf(path, "/var/run/mdadm/%s.pid", devname);
return stat(path, &st);
}
int make_pidfile(char *devname, int o_excl)
{
@ -149,27 +157,30 @@ int is_container_member(struct mdstat_ent *mdstat, char *container)
return 1;
}
void remove_pidfile(char *devname);
static void try_kill_monitor(char *devname)
pid_t devname2mdmon(char *devname)
{
char buf[100];
pid_t pid = -1;
int fd;
sprintf(buf, "/var/run/mdadm/%s.pid", devname);
fd = open(buf, O_RDONLY|O_NOATIME);
if (fd < 0)
return -1;
if (read(fd, buf, sizeof(buf)) > 0)
sscanf(buf, "%d\n", &pid);
close(fd);
return pid;
}
static void try_kill_monitor(pid_t pid, char *devname, int sock)
{
char buf[100];
int fd;
pid_t pid;
struct mdstat_ent *mdstat;
sprintf(buf, "/var/run/mdadm/%s.pid", devname);
fd = open(buf, O_RDONLY);
if (fd < 0)
return;
if (read(fd, buf, sizeof(buf)) < 0) {
close(fd);
return;
}
close(fd);
pid = strtoul(buf, NULL, 10);
/* first rule of survival... don't off yourself */
if (pid == getpid())
return;
@ -194,10 +205,9 @@ static void try_kill_monitor(char *devname)
for ( ; mdstat; mdstat = mdstat->next)
if (is_container_member(mdstat, devname)) {
sprintf(buf, "/dev/%s", mdstat->dev);
WaitClean(buf, 0);
WaitClean(buf, sock, 0);
}
free_mdstat(mdstat);
remove_pidfile(devname);
}
void remove_pidfile(char *devname)
@ -355,9 +365,34 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot)
int pfd[2];
int status;
int ignore;
pid_t victim = -1;
int victim_sock = -1;
dprintf("starting mdmon for %s in %s\n",
devname, switchroot ? : "/");
/* try to spawn mdmon instances from the target file system */
if (switchroot && strcmp(switchroot, "/") != 0) {
char path[1024];
pid_t pid;
sprintf(path, "%s/sbin/mdmon", switchroot);
switch (fork()) {
case 0:
execl(path, "mdmon", devname, NULL);
exit(1);
case -1:
return 1;
default:
pid = wait(&status);
if (pid > -1 && WIFEXITED(status) &&
WEXITSTATUS(status) == 0)
return 0;
else
return 1;
}
}
mdfd = open_dev(devnum);
if (mdfd < 0) {
fprintf(stderr, "mdmon: %s: %s\n", devname,
@ -400,6 +435,7 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot)
container->devname = devname;
container->arrays = NULL;
container->subarray[0] = 0;
container->sock = -1;
if (!container->devname) {
fprintf(stderr, "mdmon: failed to allocate container name string\n");
@ -464,12 +500,10 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot)
if (switchroot) {
/* we assume we assume that /sys /proc /dev are available in
* the new root (see nash:setuproot)
*
* kill any monitors in the current namespace and change
* to the new one
* the new root
*/
try_kill_monitor(container->devname);
victim = devname2mdmon(container->devname);
victim_sock = connect_monitor(container->devname);
if (chroot(switchroot) != 0) {
fprintf(stderr, "mdmon: failed to chroot to '%s': %s\n",
switchroot, strerror(errno));
@ -477,40 +511,15 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot)
}
}
/* If this fails, we hope it already exists
* pid file lives in /var/run/mdadm/mdXX.pid
*/
mkdir("/var", 0600);
mkdir("/var/run", 0600);
mkdir("/var/run/mdadm", 0600);
ignore = chdir("/");
if (make_pidfile(container->devname, O_EXCL) < 0) {
if (victim < 0 && test_pidfile(container->devname) == 0) {
if (ping_monitor(container->devname) == 0) {
fprintf(stderr, "mdmon: %s already managed\n",
container->devname);
exit(3);
} else {
int err;
/* cleanup the old monitor, this one is taking over */
try_kill_monitor(container->devname);
err = make_pidfile(container->devname, 0);
if (err < 0) {
fprintf(stderr, "mdmon: %s Cannot create pidfile\n",
container->devname);
if (err == -EROFS) {
/* FIXME implement a mechanism to
* prevent duplicate monitor instances
*/
fprintf(stderr,
"mdmon: continuing on read-only file system\n");
} else
exit(3);
}
}
} else if (victim < 0)
victim = devname2mdmon(container->devname);
}
container->sock = make_control_sock(container->devname);
if (container->ss->load_super(container, mdfd, devname)) {
fprintf(stderr, "mdmon: Cannot load metadata for %s\n",
devname);
@ -536,7 +545,7 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot)
ignore = dup(0);
#endif
mlockall(MCL_FUTURE);
mlockall(MCL_CURRENT | MCL_FUTURE);
if (clone_monitor(container) < 0) {
fprintf(stderr, "mdmon: failed to start monitor process: %s\n",
@ -544,6 +553,10 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot)
exit(2);
}
if (victim > -1) {
try_kill_monitor(victim, container->devname, victim_sock);
close(victim_sock);
}
do_manager(container);
exit(0);

View File

@ -43,7 +43,7 @@ void make_parts(char *dev, int cnt)
int odig = odig; /* quiet gcc -Os unitialized warning */
int i;
int nlen = strlen(dev) + 20;
char *name = malloc(nlen);
char *name;
int dig = isdigit(dev[strlen(dev)-1]);
char orig[1024];
char sym[1024];
@ -52,6 +52,7 @@ void make_parts(char *dev, int cnt)
if (cnt==0) cnt=4;
if (lstat(dev, &stb)!= 0)
return;
if (S_ISLNK(stb.st_mode)) {
int len = readlink(dev, orig, sizeof(orig));
if (len < 0 || len > 1000)
@ -63,6 +64,7 @@ void make_parts(char *dev, int cnt)
minor_num = minor(stb.st_rdev);
} else
return;
name = malloc(nlen);
for (i=1; i <= cnt ; i++) {
struct stat stb2;
snprintf(name, nlen, "%s%s%d", dev, dig?"p":"", i);
@ -92,6 +94,7 @@ void make_parts(char *dev, int cnt)
if (err == 0 && stat(name, &stb2) == 0)
add_dev(name, &stb2, 0, NULL);
}
free(name);
}
@ -156,7 +159,6 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
if (dev) {
if (strncmp(dev, "/dev/md/", 8) == 0) {
strcpy(cname, dev+8);
} else if (strncmp(dev, "/dev/", 5) == 0) {
@ -307,7 +309,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
}
}
if (dev)
if (dev && dev[0] == '/')
strcpy(chosen, dev);
else if (cname[0] == 0)
strcpy(chosen, devname);

14
msg.c
View File

@ -177,10 +177,8 @@ int connect_monitor(char *devname)
return sfd;
}
/* give the monitor a chance to update the metadata */
int ping_monitor(char *devname)
int fping_monitor(int sfd)
{
int sfd = connect_monitor(devname);
int err = 0;
if (sfd < 0)
@ -194,6 +192,16 @@ int ping_monitor(char *devname)
if (!err && wait_reply(sfd, 20) != 0)
err = -1;
return err;
}
/* give the monitor a chance to update the metadata */
int ping_monitor(char *devname)
{
int sfd = connect_monitor(devname);
int err = fping_monitor(sfd);
close(sfd);
return err;
}

1
msg.h
View File

@ -27,6 +27,7 @@ extern int ack(int fd, int tmo);
extern int wait_reply(int fd, int tmo);
extern int connect_monitor(char *devname);
extern int ping_monitor(char *devname);
extern int fping_monitor(int sock);
extern int ping_manager(char *devname);
#define MSG_MAX_LEN (4*1024*1024)

View File

@ -1589,13 +1589,8 @@ static int init_super_ddf(struct supertype *st,
struct phys_disk *pd;
struct virtual_disk *vd;
if (!info) {
st->sb = NULL;
return 0;
}
if (st->sb)
return init_super_ddf_bvd(st, info, size, name, homehost,
uuid);
return init_super_ddf_bvd(st, info, size, name, homehost, uuid);
if (posix_memalign((void**)&ddf, 512, sizeof(*ddf)) != 0) {
fprintf(stderr, Name ": %s could not allocate superblock\n", __func__);
@ -1604,6 +1599,12 @@ static int init_super_ddf(struct supertype *st,
memset(ddf, 0, sizeof(*ddf));
ddf->dlist = NULL; /* no physical disks yet */
ddf->conflist = NULL; /* No virtual disks yet */
st->sb = ddf;
if (info == NULL) {
/* zeroing superblock */
return 0;
}
/* At least 32MB *must* be reserved for the ddf. So let's just
* start 32MB from the end, and put the primary header there.
@ -2971,12 +2972,22 @@ static struct mdinfo *container_content_ddf(struct supertype *st)
return rest;
}
static int store_zero_ddf(struct supertype *st, int fd)
static int store_super_ddf(struct supertype *st, int fd)
{
struct ddf_super *ddf = st->sb;
unsigned long long dsize;
void *buf;
int rc;
if (!ddf)
return 1;
/* ->dlist and ->conflist will be set for updates, currently not
* supported
*/
if (ddf->dlist || ddf->conflist)
return 1;
if (!get_dev_size(fd, NULL, &dsize))
return 1;
@ -3627,7 +3638,7 @@ struct superswitch super_ddf = {
.load_super = load_super_ddf,
.init_super = init_super_ddf,
.store_super = store_zero_ddf,
.store_super = store_super_ddf,
.free_super = free_super_ddf,
.match_metadata_desc = match_metadata_desc_ddf,
.container_content = container_content_ddf,

File diff suppressed because it is too large Load Diff

View File

@ -792,7 +792,7 @@ int sysfs_unique_holder(int devnum, long rdev)
static char *clean_states[] = {
"clear", "inactive", "readonly", "read-auto", "clean", NULL };
int WaitClean(char *dev, int verbose)
int WaitClean(char *dev, int sock, int verbose)
{
int fd;
struct mdinfo *mdi;
@ -868,7 +868,8 @@ int WaitClean(char *dev, int verbose)
}
if (rv < 0)
rv = 1;
else if (ping_monitor(mdi->text_version) == 0) {
else if (fping_monitor(sock) == 0 ||
ping_monitor(mdi->text_version) == 0) {
/* we need to ping to close the window between array
* state transitioning to clean and the metadata being
* marked clean

46
tests/09imsm-assemble Normal file
View File

@ -0,0 +1,46 @@
# validate the prodigal member disk scenario i.e. a former container
# member is returned after having been rebuilt on another system
num_disks=4
size=$((10*1024))
mdadm -CR $container -e imsm -n $num_disks $dev0 $dev1 $dev2 $dev3
mdadm -CR $member $dev0 $dev2 -n 2 -l 1 -z $size
mdadm --wait $member
mdadm -Ss
# make dev0 and dev1 a new rebuild family
mdadm -A $container $dev0 $dev1
mdadm -I $container
mdadm --wait ${member}_0
mdadm -Ss
# make dev2 and dev3 a new rebuild family
mdadm -A $container $dev2 $dev3
mdadm -I $container
mdadm --wait ${member}_0
mdadm -Ss
# reassemble and make sure one of the families falls out
mdadm -A $container $dev0 $dev1 $dev2 $dev3
mdadm -I $container
testdev ${member}_0 1 $size 1
if mdadm --remove $container $dev0 ; then
# the dev[23] family won
imsm_check_removal $container $dev1
imsm_check_hold $container $dev2
imsm_check_hold $container $dev3
else
# the dev[01] family won
imsm_check_hold $container $dev1
imsm_check_removal $container $dev2
imsm_check_removal $container $dev3
fi
mdadm -Ss
# reassemble with a new id for the dev[23] family
mdadm -A $container $dev0 $dev1
mdadm -I $container
mdadm -A ${container}2 $dev2 $dev3 --update=uuid
mdadm -I ${container}2
testdev ${member}_0 1 $size 1
testdev ${member}_1 1 $size 1

View File

@ -55,8 +55,8 @@ mdadm -Ss
mdadm -Asc /var/tmp/mdadm.conf
check nosync # This failed once. The raid5 was resyncing.
mdadm -Dbs > /tmp/mdadm.conf
diff /tmp/mdadm.conf /var/tmp/mdadm.conf
mdadm -Dbs | sort > /tmp/mdadm.conf
sort /var/tmp/mdadm.conf | diff /tmp/mdadm.conf -
mdadm -Ss
# and now assemble fully incrementally.
@ -70,7 +70,7 @@ do
done
check nosync
mdadm -Dbs > /tmp/mdadm.conf
diff /tmp/mdadm.conf /var/tmp/mdadm.conf
mdadm -Dbs | sort > /tmp/mdadm.conf
sort /var/tmp/mdadm.conf | diff /tmp/mdadm.conf -
mdadm -Ss
rm /tmp/mdadm.conf /var/tmp/mdadm.conf

32
tests/env-09imsm-assemble Normal file
View File

@ -0,0 +1,32 @@
imsm_check_hold() {
if mdadm --remove $1 $2; then
echo "$2 removal from $1 should have been blocked" >&2
cat /proc/mdstat >&2
mdadm -E $2
exit 1
fi
}
imsm_check_removal() {
if ! mdadm --remove $1 $2 ; then
echo "$2 removal from $1 should have succeeded" >&2
cat /proc/mdstat >&2
mdadm -E $2
exit 1
fi
}
setup_env() {
export IMSM_DEVNAME_AS_SERIAL=1
export IMSM_TEST_OROM=1
container=/dev/md/container
member=/dev/md/vol0
}
reset_env() {
unset IMSM_DEVNAME_AS_SERIAL
unset IMSM_TEST_OROM
unset imsm_check
unset container
unset member
}

12
util.c
View File

@ -336,17 +336,15 @@ void copy_uuid(void *a, int b[4], int swapuuid)
memcpy(a, b, 16);
}
char *fname_from_uuid(struct supertype *st, struct mdinfo *info, char *buf, char sep)
char *__fname_from_uuid(int id[4], int swap, char *buf, char sep)
{
int i, j;
int id;
char uuid[16];
char *c = buf;
strcpy(c, "UUID-");
c += strlen(c);
copy_uuid(uuid, info->uuid, st->ss->swapuuid);
copy_uuid(uuid, id, swap);
for (i = 0; i < 4; i++) {
id = uuid[i];
if (i)
*c++ = sep;
for (j = 3; j >= 0; j--) {
@ -355,6 +353,12 @@ char *fname_from_uuid(struct supertype *st, struct mdinfo *info, char *buf, char
}
}
return buf;
}
char *fname_from_uuid(struct supertype *st, struct mdinfo *info, char *buf, char sep)
{
return __fname_from_uuid(info->uuid, st->ss->swapuuid, buf, sep);
}
#ifndef MDASSEMBLE