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.
|
||||
*/
|
||||
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",
|
||||
|
|
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);
|
||||
} 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;
|
||||
|
|
4
Manage.c
4
Manage.c
|
@ -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);
|
||||
|
|
26
Monitor.c
26
Monitor.c
|
@ -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 &&
|
||||
|
|
2
ReadMe.c
2
ReadMe.c
|
@ -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"
|
||||
|
|
|
@ -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
14
mdadm.8
|
@ -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
23
mdadm.c
|
@ -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
10
mdadm.h
|
@ -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
117
mdmon.c
|
@ -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);
|
||||
|
|
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 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
14
msg.c
|
@ -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
1
msg.h
|
@ -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)
|
||||
|
|
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 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,
|
||||
|
|
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[] = {
|
||||
"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
|
||||
|
|
|
@ -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
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue