Merge branch 'master' into devel-3.1
This commit is contained in:
commit
4a997737a1
27
Assemble.c
27
Assemble.c
|
@ -315,6 +315,9 @@ int Assemble(struct supertype *st, char *mddev,
|
||||||
}
|
}
|
||||||
/* It is worth looking inside this container.
|
/* It is worth looking inside this container.
|
||||||
*/
|
*/
|
||||||
|
if (verbose > 0)
|
||||||
|
fprintf(stderr, Name ": looking in container %s\n",
|
||||||
|
devname);
|
||||||
next_member:
|
next_member:
|
||||||
if (tmpdev->content)
|
if (tmpdev->content)
|
||||||
content = 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",
|
fprintf(stderr, Name ": member %s in %s is already assembled\n",
|
||||||
content->text_version,
|
content->text_version,
|
||||||
devname);
|
devname);
|
||||||
|
skip:
|
||||||
|
if (tmpdev->content)
|
||||||
|
goto next_member;
|
||||||
tst->ss->free_super(tst);
|
tst->ss->free_super(tst);
|
||||||
tst = NULL;
|
tst = NULL;
|
||||||
content = NULL;
|
content = NULL;
|
||||||
|
@ -412,6 +418,21 @@ int Assemble(struct supertype *st, char *mddev,
|
||||||
goto loop;
|
goto loop;
|
||||||
return 1;
|
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;
|
st = tst; tst = NULL;
|
||||||
if (!auto_assem && tmpdev->next != NULL) {
|
if (!auto_assem && tmpdev->next != NULL) {
|
||||||
fprintf(stderr, Name ": %s is a container, but is not "
|
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);
|
st->ss->free_super(st);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (verbose > 0)
|
||||||
|
fprintf(stderr, Name ": found match on member %s in %s\n",
|
||||||
|
content->text_version, devname);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (st == NULL)
|
if (st == NULL)
|
||||||
|
@ -565,6 +589,7 @@ int Assemble(struct supertype *st, char *mddev,
|
||||||
#endif
|
#endif
|
||||||
/* Ok, no bad inconsistancy, we can try updating etc */
|
/* Ok, no bad inconsistancy, we can try updating etc */
|
||||||
bitmap_done = 0;
|
bitmap_done = 0;
|
||||||
|
content->update_private = NULL;
|
||||||
for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) {
|
for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) {
|
||||||
char *devname = tmpdev->devname;
|
char *devname = tmpdev->devname;
|
||||||
struct stat stb;
|
struct stat stb;
|
||||||
|
@ -717,6 +742,8 @@ int Assemble(struct supertype *st, char *mddev,
|
||||||
}
|
}
|
||||||
devcnt++;
|
devcnt++;
|
||||||
}
|
}
|
||||||
|
free(content->update_private);
|
||||||
|
content->update_private = NULL;
|
||||||
|
|
||||||
if (devcnt == 0) {
|
if (devcnt == 0) {
|
||||||
fprintf(stderr, Name ": no devices found for %s\n",
|
fprintf(stderr, Name ": no devices found for %s\n",
|
||||||
|
|
6
Detail.c
6
Detail.c
|
@ -194,7 +194,12 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
|
||||||
st->ss->export_detail_super(st);
|
st->ss->export_detail_super(st);
|
||||||
} else {
|
} else {
|
||||||
struct map_ent *mp, *map = NULL;
|
struct map_ent *mp, *map = NULL;
|
||||||
|
char nbuf[64];
|
||||||
mp = map_by_devnum(&map, fd2devnum(fd));
|
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 &&
|
if (mp && mp->path &&
|
||||||
strncmp(mp->path, "/dev/md/", 8) == 0)
|
strncmp(mp->path, "/dev/md/", 8) == 0)
|
||||||
printf("MD_DEVNAME=%s\n", mp->path+8);
|
printf("MD_DEVNAME=%s\n", mp->path+8);
|
||||||
|
@ -540,6 +545,7 @@ This is pretty boring
|
||||||
1, avail, avail_disks))
|
1, avail, avail_disks))
|
||||||
rv = 2;
|
rv = 2;
|
||||||
|
|
||||||
|
free(disks);
|
||||||
out:
|
out:
|
||||||
close(fd);
|
close(fd);
|
||||||
return rv;
|
return rv;
|
||||||
|
|
4
Manage.c
4
Manage.c
|
@ -140,7 +140,7 @@ static void remove_devices(int devnum, char *path)
|
||||||
strcpy(path2, path);
|
strcpy(path2, path);
|
||||||
pe = path2 + strlen(path2);
|
pe = path2 + strlen(path2);
|
||||||
} else
|
} else
|
||||||
path = NULL;
|
path2 = path = NULL;
|
||||||
|
|
||||||
for (part = 0; part < 16; part++) {
|
for (part = 0; part < 16; part++) {
|
||||||
if (part) {
|
if (part) {
|
||||||
|
@ -161,6 +161,7 @@ static void remove_devices(int devnum, char *path)
|
||||||
unlink(path2);
|
unlink(path2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(path2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -649,6 +650,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||||
disc.state |= (1<<MD_DISK_SYNC);
|
disc.state |= (1<<MD_DISK_SYNC);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
free(used);
|
||||||
}
|
}
|
||||||
if (dv->writemostly == 1)
|
if (dv->writemostly == 1)
|
||||||
disc.state |= (1 << MD_DISK_WRITEMOSTLY);
|
disc.state |= (1 << MD_DISK_WRITEMOSTLY);
|
||||||
|
|
26
Monitor.c
26
Monitor.c
|
@ -33,14 +33,6 @@
|
||||||
static void alert(char *event, char *dev, char *disc, char *mailaddr, char *mailfrom,
|
static void alert(char *event, char *dev, char *disc, char *mailaddr, char *mailfrom,
|
||||||
char *cmd, int dosyslog);
|
char *cmd, int dosyslog);
|
||||||
|
|
||||||
static char *percentalerts[] = {
|
|
||||||
"RebuildStarted",
|
|
||||||
"Rebuild20",
|
|
||||||
"Rebuild40",
|
|
||||||
"Rebuild60",
|
|
||||||
"Rebuild80",
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The largest number of disks current arrays can manage is 384
|
/* The largest number of disks current arrays can manage is 384
|
||||||
* This really should be dynamically, but that will have to wait
|
* This really should be dynamically, but that will have to wait
|
||||||
* At least it isn't MD_SB_DISKS.
|
* At least it isn't MD_SB_DISKS.
|
||||||
|
@ -49,7 +41,7 @@ static char *percentalerts[] = {
|
||||||
int Monitor(mddev_dev_t devlist,
|
int Monitor(mddev_dev_t devlist,
|
||||||
char *mailaddr, char *alert_cmd,
|
char *mailaddr, char *alert_cmd,
|
||||||
int period, int daemonise, int scan, int oneshot,
|
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
|
* 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
|
* An active device had a reverse transition
|
||||||
* RebuildStarted
|
* RebuildStarted
|
||||||
* percent went from -1 to +ve
|
* percent went from -1 to +ve
|
||||||
* Rebuild20 Rebuild40 Rebuild60 Rebuild80
|
* RebuildNN
|
||||||
* percent went from below to not-below that number
|
* percent went from below to not-below NN%
|
||||||
* DeviceDisappeared
|
* DeviceDisappeared
|
||||||
* Couldn't access a device which was previously visible
|
* Couldn't access a device which was previously visible
|
||||||
*
|
*
|
||||||
|
@ -311,9 +303,17 @@ int Monitor(mddev_dev_t devlist,
|
||||||
if (mse &&
|
if (mse &&
|
||||||
st->percent >= 0 &&
|
st->percent >= 0 &&
|
||||||
mse->percent >= 0 &&
|
mse->percent >= 0 &&
|
||||||
(mse->percent / 20) > (st->percent / 20))
|
(mse->percent / increments) > (st->percent / increments)) {
|
||||||
alert(percentalerts[mse->percent/20],
|
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);
|
dev, NULL, mailaddr, mailfrom, alert_cmd, dosyslog);
|
||||||
|
}
|
||||||
|
|
||||||
if (mse &&
|
if (mse &&
|
||||||
mse->percent == -1 &&
|
mse->percent == -1 &&
|
||||||
|
|
2
ReadMe.c
2
ReadMe.c
|
@ -176,6 +176,7 @@ struct option long_options[] = {
|
||||||
{"mail", 1, 0, 'm'},
|
{"mail", 1, 0, 'm'},
|
||||||
{"program", 1, 0, 'p'},
|
{"program", 1, 0, 'p'},
|
||||||
{"alert", 1, 0, 'p'},
|
{"alert", 1, 0, 'p'},
|
||||||
|
{"increment", 1, 0, 'r'},
|
||||||
{"delay", 1, 0, 'd'},
|
{"delay", 1, 0, 'd'},
|
||||||
{"daemonise", 0, 0, 'f'},
|
{"daemonise", 0, 0, 'f'},
|
||||||
{"daemonize", 0, 0, 'f'},
|
{"daemonize", 0, 0, 'f'},
|
||||||
|
@ -496,6 +497,7 @@ char Help_monitor[] =
|
||||||
" --mail= -m : Address to mail alerts of failure to\n"
|
" --mail= -m : Address to mail alerts of failure to\n"
|
||||||
" --program= -p : Program to run when an event is detected\n"
|
" --program= -p : Program to run when an event is detected\n"
|
||||||
" --alert= : same as --program\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"
|
" --delay= -d : seconds of delay between polling state. default=60\n"
|
||||||
" --config= -c : specify a different config file\n"
|
" --config= -c : specify a different config file\n"
|
||||||
" --scan -s : find mail-address/program in config file\n"
|
" --scan -s : find mail-address/program in config file\n"
|
||||||
|
|
|
@ -680,6 +680,12 @@ void do_manager(struct supertype *container)
|
||||||
read_sock(container);
|
read_sock(container);
|
||||||
|
|
||||||
if (container->sock < 0 || socket_hup_requested) {
|
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);
|
close(container->sock);
|
||||||
container->sock = make_control_sock(container->devname);
|
container->sock = make_control_sock(container->devname);
|
||||||
make_pidfile(container->devname, 0);
|
make_pidfile(container->devname, 0);
|
||||||
|
|
14
mdadm.8
14
mdadm.8
|
@ -309,7 +309,7 @@ says to get a list of array devices from
|
||||||
.BR /proc/mdstat .
|
.BR /proc/mdstat .
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B \-e ", " \-\-metadata=
|
.BR \-e ", " \-\-metadata=
|
||||||
Declare the style of RAID metadata (superblock) to be used. The
|
Declare the style of RAID metadata (superblock) to be used. The
|
||||||
default is 0.90 for
|
default is 0.90 for
|
||||||
.BR \-\-create ,
|
.BR \-\-create ,
|
||||||
|
@ -1261,6 +1261,12 @@ reduce this as the kernel alerts
|
||||||
.I mdadm
|
.I mdadm
|
||||||
immediately when there is any change.
|
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
|
.TP
|
||||||
.BR \-f ", " \-\-daemonise
|
.BR \-f ", " \-\-daemonise
|
||||||
Tell
|
Tell
|
||||||
|
@ -1859,8 +1865,10 @@ An md array started reconstruction. (syslog priority: Warning)
|
||||||
.BI Rebuild NN
|
.BI Rebuild NN
|
||||||
Where
|
Where
|
||||||
.I NN
|
.I NN
|
||||||
is 20, 40, 60, or 80, this indicates that rebuild has passed that many
|
is a two-digit number (ie. 05, 48). This indicates that rebuild
|
||||||
percentage of the total. (syslog priority: Warning)
|
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
|
.TP
|
||||||
.B RebuildFinished
|
.B RebuildFinished
|
||||||
|
|
23
mdadm.c
23
mdadm.c
|
@ -91,6 +91,7 @@ int main(int argc, char *argv[])
|
||||||
int require_homehost = 1;
|
int require_homehost = 1;
|
||||||
char *mailaddr = NULL;
|
char *mailaddr = NULL;
|
||||||
char *program = NULL;
|
char *program = NULL;
|
||||||
|
int increments = 20;
|
||||||
int delay = 0;
|
int delay = 0;
|
||||||
int daemonise = 0;
|
int daemonise = 0;
|
||||||
char *pidfile = NULL;
|
char *pidfile = NULL;
|
||||||
|
@ -714,6 +715,14 @@ int main(int argc, char *argv[])
|
||||||
program = optarg;
|
program = optarg;
|
||||||
continue;
|
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(MONITOR,'d'): /* delay in seconds */
|
||||||
case O(GROW, 'd'):
|
case O(GROW, 'd'):
|
||||||
case O(BUILD,'d'): /* delay for bitmap updates */
|
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 *ms = mdstat_read(0, 1);
|
||||||
struct mdstat_ent *e;
|
struct mdstat_ent *e;
|
||||||
struct map_ent *map = NULL;
|
struct map_ent *map = NULL;
|
||||||
|
int members;
|
||||||
int v = verbose>1?0:verbose+1;
|
int v = verbose>1?0:verbose+1;
|
||||||
|
|
||||||
|
for (members = 0; members <= 1; members++) {
|
||||||
for (e=ms ; e ; e=e->next) {
|
for (e=ms ; e ; e=e->next) {
|
||||||
char *name;
|
char *name;
|
||||||
struct map_ent *me;
|
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);
|
me = map_by_devnum(&map, e->devnum);
|
||||||
if (me && me->path
|
if (me && me->path
|
||||||
&& strcmp(me->path, "/unknown") != 0)
|
&& strcmp(me->path, "/unknown") != 0)
|
||||||
|
@ -1292,9 +1308,10 @@ int main(int argc, char *argv[])
|
||||||
export, test,
|
export, test,
|
||||||
homehost);
|
homehost);
|
||||||
else
|
else
|
||||||
rv |= WaitClean(name, v);
|
rv |= WaitClean(name, -1, v);
|
||||||
put_md_name(name);
|
put_md_name(name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
free_mdstat(ms);
|
free_mdstat(ms);
|
||||||
} else if (devmode == 'S' && scan) {
|
} else if (devmode == 'S' && scan) {
|
||||||
/* apply --stop to all devices in /proc/mdstat */
|
/* apply --stop to all devices in /proc/mdstat */
|
||||||
|
@ -1353,7 +1370,7 @@ int main(int argc, char *argv[])
|
||||||
case 'W':
|
case 'W':
|
||||||
rv |= Wait(dv->devname); continue;
|
rv |= Wait(dv->devname); continue;
|
||||||
case Waitclean:
|
case Waitclean:
|
||||||
rv |= WaitClean(dv->devname, verbose-quiet); continue;
|
rv |= WaitClean(dv->devname, -1, verbose-quiet); continue;
|
||||||
}
|
}
|
||||||
mdfd = open_mddev(dv->devname, 1);
|
mdfd = open_mddev(dv->devname, 1);
|
||||||
if (mdfd>=0) {
|
if (mdfd>=0) {
|
||||||
|
@ -1393,7 +1410,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
rv= Monitor(devlist, mailaddr, program,
|
rv= Monitor(devlist, mailaddr, program,
|
||||||
delay?delay:60, daemonise, scan, oneshot,
|
delay?delay:60, daemonise, scan, oneshot,
|
||||||
dosyslog, test, pidfile);
|
dosyslog, test, pidfile, increments);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GROW:
|
case GROW:
|
||||||
|
|
10
mdadm.h
10
mdadm.h
|
@ -153,6 +153,11 @@ struct mdinfo {
|
||||||
int cache_size; /* size of raid456 stripe cache*/
|
int cache_size; /* size of raid456 stripe cache*/
|
||||||
int mismatch_cnt;
|
int mismatch_cnt;
|
||||||
char text_version[50];
|
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
|
int container_member; /* for assembling external-metatdata arrays
|
||||||
* This is to be used internally by metadata
|
* 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,
|
extern int Monitor(mddev_dev_t devlist,
|
||||||
char *mailaddr, char *alert_cmd,
|
char *mailaddr, char *alert_cmd,
|
||||||
int period, int daemonise, int scan, int oneshot,
|
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 Kill(char *dev, int force, int quiet, int noexcl);
|
||||||
extern int Wait(char *dev);
|
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,
|
extern int Incremental(char *devname, int verbose, int runstop,
|
||||||
struct supertype *st, char *homehost, int require_homehost,
|
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 const int uuid_match_any[4];
|
||||||
extern int same_uuid(int a[4], int b[4], int swapuuid);
|
extern int same_uuid(int a[4], int b[4], int swapuuid);
|
||||||
extern void copy_uuid(void *a, 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,
|
extern char *fname_from_uuid(struct supertype *st,
|
||||||
struct mdinfo *info, char *buf, char sep);
|
struct mdinfo *info, char *buf, char sep);
|
||||||
extern unsigned long calc_csum(void *super, int bytes);
|
extern unsigned long calc_csum(void *super, int bytes);
|
||||||
|
|
117
mdmon.c
117
mdmon.c
|
@ -113,6 +113,14 @@ static struct superswitch *find_metadata_methods(char *vers)
|
||||||
return NULL;
|
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)
|
int make_pidfile(char *devname, int o_excl)
|
||||||
{
|
{
|
||||||
|
@ -149,27 +157,30 @@ int is_container_member(struct mdstat_ent *mdstat, char *container)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_pidfile(char *devname);
|
pid_t devname2mdmon(char *devname)
|
||||||
static void try_kill_monitor(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];
|
char buf[100];
|
||||||
int fd;
|
int fd;
|
||||||
pid_t pid;
|
|
||||||
struct mdstat_ent *mdstat;
|
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 */
|
/* first rule of survival... don't off yourself */
|
||||||
if (pid == getpid())
|
if (pid == getpid())
|
||||||
return;
|
return;
|
||||||
|
@ -194,10 +205,9 @@ static void try_kill_monitor(char *devname)
|
||||||
for ( ; mdstat; mdstat = mdstat->next)
|
for ( ; mdstat; mdstat = mdstat->next)
|
||||||
if (is_container_member(mdstat, devname)) {
|
if (is_container_member(mdstat, devname)) {
|
||||||
sprintf(buf, "/dev/%s", mdstat->dev);
|
sprintf(buf, "/dev/%s", mdstat->dev);
|
||||||
WaitClean(buf, 0);
|
WaitClean(buf, sock, 0);
|
||||||
}
|
}
|
||||||
free_mdstat(mdstat);
|
free_mdstat(mdstat);
|
||||||
remove_pidfile(devname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_pidfile(char *devname)
|
void remove_pidfile(char *devname)
|
||||||
|
@ -355,9 +365,34 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot)
|
||||||
int pfd[2];
|
int pfd[2];
|
||||||
int status;
|
int status;
|
||||||
int ignore;
|
int ignore;
|
||||||
|
pid_t victim = -1;
|
||||||
|
int victim_sock = -1;
|
||||||
|
|
||||||
dprintf("starting mdmon for %s in %s\n",
|
dprintf("starting mdmon for %s in %s\n",
|
||||||
devname, switchroot ? : "/");
|
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);
|
mdfd = open_dev(devnum);
|
||||||
if (mdfd < 0) {
|
if (mdfd < 0) {
|
||||||
fprintf(stderr, "mdmon: %s: %s\n", devname,
|
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->devname = devname;
|
||||||
container->arrays = NULL;
|
container->arrays = NULL;
|
||||||
container->subarray[0] = 0;
|
container->subarray[0] = 0;
|
||||||
|
container->sock = -1;
|
||||||
|
|
||||||
if (!container->devname) {
|
if (!container->devname) {
|
||||||
fprintf(stderr, "mdmon: failed to allocate container name string\n");
|
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) {
|
if (switchroot) {
|
||||||
/* we assume we assume that /sys /proc /dev are available in
|
/* we assume we assume that /sys /proc /dev are available in
|
||||||
* the new root (see nash:setuproot)
|
* the new root
|
||||||
*
|
|
||||||
* kill any monitors in the current namespace and change
|
|
||||||
* to the new one
|
|
||||||
*/
|
*/
|
||||||
try_kill_monitor(container->devname);
|
victim = devname2mdmon(container->devname);
|
||||||
|
victim_sock = connect_monitor(container->devname);
|
||||||
if (chroot(switchroot) != 0) {
|
if (chroot(switchroot) != 0) {
|
||||||
fprintf(stderr, "mdmon: failed to chroot to '%s': %s\n",
|
fprintf(stderr, "mdmon: failed to chroot to '%s': %s\n",
|
||||||
switchroot, strerror(errno));
|
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("/");
|
ignore = chdir("/");
|
||||||
if (make_pidfile(container->devname, O_EXCL) < 0) {
|
if (victim < 0 && test_pidfile(container->devname) == 0) {
|
||||||
if (ping_monitor(container->devname) == 0) {
|
if (ping_monitor(container->devname) == 0) {
|
||||||
fprintf(stderr, "mdmon: %s already managed\n",
|
fprintf(stderr, "mdmon: %s already managed\n",
|
||||||
container->devname);
|
container->devname);
|
||||||
exit(3);
|
exit(3);
|
||||||
} else {
|
} else if (victim < 0)
|
||||||
int err;
|
victim = devname2mdmon(container->devname);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
container->sock = make_control_sock(container->devname);
|
|
||||||
|
|
||||||
if (container->ss->load_super(container, mdfd, devname)) {
|
if (container->ss->load_super(container, mdfd, devname)) {
|
||||||
fprintf(stderr, "mdmon: Cannot load metadata for %s\n",
|
fprintf(stderr, "mdmon: Cannot load metadata for %s\n",
|
||||||
devname);
|
devname);
|
||||||
|
@ -536,7 +545,7 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot)
|
||||||
ignore = dup(0);
|
ignore = dup(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mlockall(MCL_FUTURE);
|
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||||
|
|
||||||
if (clone_monitor(container) < 0) {
|
if (clone_monitor(container) < 0) {
|
||||||
fprintf(stderr, "mdmon: failed to start monitor process: %s\n",
|
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);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (victim > -1) {
|
||||||
|
try_kill_monitor(victim, container->devname, victim_sock);
|
||||||
|
close(victim_sock);
|
||||||
|
}
|
||||||
do_manager(container);
|
do_manager(container);
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
8
mdopen.c
8
mdopen.c
|
@ -43,7 +43,7 @@ void make_parts(char *dev, int cnt)
|
||||||
int odig = odig; /* quiet gcc -Os unitialized warning */
|
int odig = odig; /* quiet gcc -Os unitialized warning */
|
||||||
int i;
|
int i;
|
||||||
int nlen = strlen(dev) + 20;
|
int nlen = strlen(dev) + 20;
|
||||||
char *name = malloc(nlen);
|
char *name;
|
||||||
int dig = isdigit(dev[strlen(dev)-1]);
|
int dig = isdigit(dev[strlen(dev)-1]);
|
||||||
char orig[1024];
|
char orig[1024];
|
||||||
char sym[1024];
|
char sym[1024];
|
||||||
|
@ -52,6 +52,7 @@ void make_parts(char *dev, int cnt)
|
||||||
if (cnt==0) cnt=4;
|
if (cnt==0) cnt=4;
|
||||||
if (lstat(dev, &stb)!= 0)
|
if (lstat(dev, &stb)!= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (S_ISLNK(stb.st_mode)) {
|
if (S_ISLNK(stb.st_mode)) {
|
||||||
int len = readlink(dev, orig, sizeof(orig));
|
int len = readlink(dev, orig, sizeof(orig));
|
||||||
if (len < 0 || len > 1000)
|
if (len < 0 || len > 1000)
|
||||||
|
@ -63,6 +64,7 @@ void make_parts(char *dev, int cnt)
|
||||||
minor_num = minor(stb.st_rdev);
|
minor_num = minor(stb.st_rdev);
|
||||||
} else
|
} else
|
||||||
return;
|
return;
|
||||||
|
name = malloc(nlen);
|
||||||
for (i=1; i <= cnt ; i++) {
|
for (i=1; i <= cnt ; i++) {
|
||||||
struct stat stb2;
|
struct stat stb2;
|
||||||
snprintf(name, nlen, "%s%s%d", dev, dig?"p":"", i);
|
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)
|
if (err == 0 && stat(name, &stb2) == 0)
|
||||||
add_dev(name, &stb2, 0, NULL);
|
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 (dev) {
|
||||||
|
|
||||||
if (strncmp(dev, "/dev/md/", 8) == 0) {
|
if (strncmp(dev, "/dev/md/", 8) == 0) {
|
||||||
strcpy(cname, dev+8);
|
strcpy(cname, dev+8);
|
||||||
} else if (strncmp(dev, "/dev/", 5) == 0) {
|
} 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);
|
strcpy(chosen, dev);
|
||||||
else if (cname[0] == 0)
|
else if (cname[0] == 0)
|
||||||
strcpy(chosen, devname);
|
strcpy(chosen, devname);
|
||||||
|
|
14
msg.c
14
msg.c
|
@ -177,10 +177,8 @@ int connect_monitor(char *devname)
|
||||||
return sfd;
|
return sfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* give the monitor a chance to update the metadata */
|
int fping_monitor(int sfd)
|
||||||
int ping_monitor(char *devname)
|
|
||||||
{
|
{
|
||||||
int sfd = connect_monitor(devname);
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (sfd < 0)
|
if (sfd < 0)
|
||||||
|
@ -194,6 +192,16 @@ int ping_monitor(char *devname)
|
||||||
if (!err && wait_reply(sfd, 20) != 0)
|
if (!err && wait_reply(sfd, 20) != 0)
|
||||||
err = -1;
|
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);
|
close(sfd);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
1
msg.h
1
msg.h
|
@ -27,6 +27,7 @@ extern int ack(int fd, int tmo);
|
||||||
extern int wait_reply(int fd, int tmo);
|
extern int wait_reply(int fd, int tmo);
|
||||||
extern int connect_monitor(char *devname);
|
extern int connect_monitor(char *devname);
|
||||||
extern int ping_monitor(char *devname);
|
extern int ping_monitor(char *devname);
|
||||||
|
extern int fping_monitor(int sock);
|
||||||
extern int ping_manager(char *devname);
|
extern int ping_manager(char *devname);
|
||||||
|
|
||||||
#define MSG_MAX_LEN (4*1024*1024)
|
#define MSG_MAX_LEN (4*1024*1024)
|
||||||
|
|
27
super-ddf.c
27
super-ddf.c
|
@ -1589,13 +1589,8 @@ static int init_super_ddf(struct supertype *st,
|
||||||
struct phys_disk *pd;
|
struct phys_disk *pd;
|
||||||
struct virtual_disk *vd;
|
struct virtual_disk *vd;
|
||||||
|
|
||||||
if (!info) {
|
|
||||||
st->sb = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (st->sb)
|
if (st->sb)
|
||||||
return init_super_ddf_bvd(st, info, size, name, homehost,
|
return init_super_ddf_bvd(st, info, size, name, homehost, uuid);
|
||||||
uuid);
|
|
||||||
|
|
||||||
if (posix_memalign((void**)&ddf, 512, sizeof(*ddf)) != 0) {
|
if (posix_memalign((void**)&ddf, 512, sizeof(*ddf)) != 0) {
|
||||||
fprintf(stderr, Name ": %s could not allocate superblock\n", __func__);
|
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));
|
memset(ddf, 0, sizeof(*ddf));
|
||||||
ddf->dlist = NULL; /* no physical disks yet */
|
ddf->dlist = NULL; /* no physical disks yet */
|
||||||
ddf->conflist = NULL; /* No virtual 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
|
/* At least 32MB *must* be reserved for the ddf. So let's just
|
||||||
* start 32MB from the end, and put the primary header there.
|
* 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;
|
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;
|
unsigned long long dsize;
|
||||||
void *buf;
|
void *buf;
|
||||||
int rc;
|
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))
|
if (!get_dev_size(fd, NULL, &dsize))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -3627,7 +3638,7 @@ struct superswitch super_ddf = {
|
||||||
|
|
||||||
.load_super = load_super_ddf,
|
.load_super = load_super_ddf,
|
||||||
.init_super = init_super_ddf,
|
.init_super = init_super_ddf,
|
||||||
.store_super = store_zero_ddf,
|
.store_super = store_super_ddf,
|
||||||
.free_super = free_super_ddf,
|
.free_super = free_super_ddf,
|
||||||
.match_metadata_desc = match_metadata_desc_ddf,
|
.match_metadata_desc = match_metadata_desc_ddf,
|
||||||
.container_content = container_content_ddf,
|
.container_content = container_content_ddf,
|
||||||
|
|
805
super-intel.c
805
super-intel.c
File diff suppressed because it is too large
Load Diff
5
sysfs.c
5
sysfs.c
|
@ -792,7 +792,7 @@ int sysfs_unique_holder(int devnum, long rdev)
|
||||||
static char *clean_states[] = {
|
static char *clean_states[] = {
|
||||||
"clear", "inactive", "readonly", "read-auto", "clean", NULL };
|
"clear", "inactive", "readonly", "read-auto", "clean", NULL };
|
||||||
|
|
||||||
int WaitClean(char *dev, int verbose)
|
int WaitClean(char *dev, int sock, int verbose)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct mdinfo *mdi;
|
struct mdinfo *mdi;
|
||||||
|
@ -868,7 +868,8 @@ int WaitClean(char *dev, int verbose)
|
||||||
}
|
}
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
rv = 1;
|
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
|
/* we need to ping to close the window between array
|
||||||
* state transitioning to clean and the metadata being
|
* state transitioning to clean and the metadata being
|
||||||
* marked clean
|
* marked clean
|
||||||
|
|
|
@ -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
|
|
@ -55,8 +55,8 @@ mdadm -Ss
|
||||||
mdadm -Asc /var/tmp/mdadm.conf
|
mdadm -Asc /var/tmp/mdadm.conf
|
||||||
check nosync # This failed once. The raid5 was resyncing.
|
check nosync # This failed once. The raid5 was resyncing.
|
||||||
|
|
||||||
mdadm -Dbs > /tmp/mdadm.conf
|
mdadm -Dbs | sort > /tmp/mdadm.conf
|
||||||
diff /tmp/mdadm.conf /var/tmp/mdadm.conf
|
sort /var/tmp/mdadm.conf | diff /tmp/mdadm.conf -
|
||||||
mdadm -Ss
|
mdadm -Ss
|
||||||
|
|
||||||
# and now assemble fully incrementally.
|
# and now assemble fully incrementally.
|
||||||
|
@ -70,7 +70,7 @@ do
|
||||||
done
|
done
|
||||||
check nosync
|
check nosync
|
||||||
|
|
||||||
mdadm -Dbs > /tmp/mdadm.conf
|
mdadm -Dbs | sort > /tmp/mdadm.conf
|
||||||
diff /tmp/mdadm.conf /var/tmp/mdadm.conf
|
sort /var/tmp/mdadm.conf | diff /tmp/mdadm.conf -
|
||||||
mdadm -Ss
|
mdadm -Ss
|
||||||
rm /tmp/mdadm.conf /var/tmp/mdadm.conf
|
rm /tmp/mdadm.conf /var/tmp/mdadm.conf
|
||||||
|
|
|
@ -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
12
util.c
|
@ -336,17 +336,15 @@ void copy_uuid(void *a, int b[4], int swapuuid)
|
||||||
memcpy(a, b, 16);
|
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 i, j;
|
||||||
int id;
|
|
||||||
char uuid[16];
|
char uuid[16];
|
||||||
char *c = buf;
|
char *c = buf;
|
||||||
strcpy(c, "UUID-");
|
strcpy(c, "UUID-");
|
||||||
c += strlen(c);
|
c += strlen(c);
|
||||||
copy_uuid(uuid, info->uuid, st->ss->swapuuid);
|
copy_uuid(uuid, id, swap);
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
id = uuid[i];
|
|
||||||
if (i)
|
if (i)
|
||||||
*c++ = sep;
|
*c++ = sep;
|
||||||
for (j = 3; j >= 0; j--) {
|
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;
|
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
|
#ifndef MDASSEMBLE
|
||||||
|
|
Loading…
Reference in New Issue