- Update to latest git repo (3.1.2 plus pending changes, fixes bz602457)
- Add in 64-md-raid.rules to compensate for it no longer being in udev (bz581905) - Remove mdadm.static as its no longer used in initrd creation
This commit is contained in:
parent
91d87d269f
commit
8808fe53de
@ -1,3 +1,4 @@
|
||||
mdadm-3.0.3.tar.bz2
|
||||
mdadm-3.1.1-gcd9a8b5.tar.bz2
|
||||
mdadm-3.1.2.tar.bz2
|
||||
mdadm-3.1.3-git07202010.tar.bz2
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 86983cce34645efb2b270a737d573e01eeee96e5 Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Wed, 24 Mar 2010 09:07:02 +1100
|
||||
Subject: [PATCH 1/6]
|
||||
|
||||
---
|
||||
util.c | 7 ++++++-
|
||||
1 files changed, 6 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/util.c b/util.c
|
||||
index d292a66..79d2b0f 100644
|
||||
--- a/util.c
|
||||
+++ b/util.c
|
||||
@@ -425,7 +425,12 @@ char *__fname_from_uuid(int id[4], int swap, char *buf, char sep)
|
||||
|
||||
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);
|
||||
+ // dirty hack to work around an issue with super1 superblocks...
|
||||
+ // super1 superblocks need swapuuid set in order for assembly to
|
||||
+ // work, but can't have it set if we want this printout to match
|
||||
+ // all the other uuid printouts in super1.c, so we force swapuuid
|
||||
+ // to 1 to make our printout match the rest of super1
|
||||
+ return __fname_from_uuid(info->uuid, (st->ss == &super1) ? 1 : st->ss->swapuuid, buf, sep);
|
||||
}
|
||||
|
||||
#ifndef MDASSEMBLE
|
||||
--
|
||||
1.6.6.1
|
||||
|
@ -1,28 +0,0 @@
|
||||
commit e750ad9d6fbd4e6606681a9c81b9a99994255940
|
||||
Author: Doug Ledford <dledford@redhat.com>
|
||||
Date: Thu Apr 8 17:34:47 2010 -0400
|
||||
|
||||
Don't even try to activate non-redundant array types unless all disks
|
||||
are present. This keeps arrays from getting marked as broken in
|
||||
the superblock and then permanently blocked from being assembled.
|
||||
|
||||
Signed-off-by: Doug Ledford <dledford@redhat.com>
|
||||
|
||||
diff --git a/Assemble.c b/Assemble.c
|
||||
index d059155..81178da 100644
|
||||
--- a/Assemble.c
|
||||
+++ b/Assemble.c
|
||||
@@ -1337,8 +1337,11 @@ int assemble_container_content(struct supertype *st, int mdfd,
|
||||
case LEVEL_LINEAR:
|
||||
case LEVEL_MULTIPATH:
|
||||
case 0:
|
||||
- err = sysfs_set_str(content, NULL, "array_state",
|
||||
- "active");
|
||||
+ if ((working + preexist) == content->array.raid_disks)
|
||||
+ err = sysfs_set_str(content, NULL,
|
||||
+ "array_state", "active");
|
||||
+ else
|
||||
+ err = 1;
|
||||
break;
|
||||
default:
|
||||
err = sysfs_set_str(content, NULL, "array_state",
|
@ -1,113 +0,0 @@
|
||||
commit b775cd39c498b0db4ca9f94bcc8615f59e534c7d
|
||||
Author: Doug Ledford <dledford@redhat.com>
|
||||
Date: Thu Apr 8 16:56:02 2010 -0400
|
||||
|
||||
Make Incremental container assembly behave like native array assembly
|
||||
|
||||
Signed-off-by: Doug Ledford <dledford@redhat.com>
|
||||
|
||||
diff --git a/Assemble.c b/Assemble.c
|
||||
index 1504f1f..d059155 100644
|
||||
--- a/Assemble.c
|
||||
+++ b/Assemble.c
|
||||
@@ -1327,8 +1327,10 @@ int assemble_container_content(struct supertype *st, int mdfd,
|
||||
content->text_version,
|
||||
content->uuid, chosen_name);
|
||||
|
||||
- if (runstop > 0 ||
|
||||
- (working + preexist) >= content->array.working_disks) {
|
||||
+ if ((runstop > 0 &&
|
||||
+ (working + preexist) >= content->array.working_disks) ||
|
||||
+ (runstop == 0 &&
|
||||
+ (working + preexist) == content->array.raid_disks)) {
|
||||
int err;
|
||||
|
||||
switch(content->array.level) {
|
||||
diff --git a/Incremental.c b/Incremental.c
|
||||
index d32a8e5..9d77d4d 100644
|
||||
--- a/Incremental.c
|
||||
+++ b/Incremental.c
|
||||
@@ -424,20 +424,21 @@ int Incremental(char *devname, int verbose, int runstop,
|
||||
sysfs_uevent(&info, "change");
|
||||
if (verbose >= 0)
|
||||
fprintf(stderr, Name
|
||||
- ": container %s now has %d devices\n",
|
||||
- chosen_name, info.array.working_disks);
|
||||
+ ": container %s now has %d out of %d devices\n",
|
||||
+ chosen_name, info.array.working_disks,
|
||||
+ info.array.raid_disks);
|
||||
wait_for(chosen_name, mdfd);
|
||||
close(mdfd);
|
||||
- if (runstop < 0)
|
||||
- return 0; /* don't try to assemble */
|
||||
- rv = Incremental(chosen_name, verbose, runstop,
|
||||
- NULL, homehost, require_homehost, autof);
|
||||
- if (rv == 1)
|
||||
- /* Don't fail the whole -I if a subarray didn't
|
||||
- * have enough devices to start yet
|
||||
+ if (runstop > 0 ||
|
||||
+ info.array.working_disks == info.array.raid_disks)
|
||||
+ /* The return value of our container assembly doesn't
|
||||
+ * depend on whether or not subarrays assembled
|
||||
+ * properly, so no need to preserve the return value
|
||||
+ * here.
|
||||
*/
|
||||
- rv = 0;
|
||||
- return rv;
|
||||
+ Incremental(chosen_name, verbose, runstop, NULL,
|
||||
+ homehost, require_homehost, autof);
|
||||
+ return 0;
|
||||
}
|
||||
avail = NULL;
|
||||
active_disks = count_active(st, mdfd, &avail, &info);
|
||||
@@ -666,6 +667,17 @@ int IncrementalScan(int verbose)
|
||||
|
||||
if (mdfd < 0)
|
||||
continue;
|
||||
+ if (strcmp("imsm",me->metadata) == 0) {
|
||||
+ /*
|
||||
+ * Just do a blind incremental assembly on the
|
||||
+ * container. If there's anything to be started,
|
||||
+ * we will, if it's already started, we'll silently
|
||||
+ * exit, if there's a problem, incremental will
|
||||
+ * catch it.
|
||||
+ */
|
||||
+ Incremental(me->path, verbose, 1, NULL, "<any>", 0, 1);
|
||||
+ continue;
|
||||
+ }
|
||||
if (ioctl(mdfd, GET_ARRAY_INFO, &array) == 0 ||
|
||||
errno != ENODEV) {
|
||||
close(mdfd);
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 999b970..7bcfcdb 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -1536,12 +1536,27 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
|
||||
if (super->current_vol >= 0) {
|
||||
getinfo_super_imsm_volume(st, info);
|
||||
return;
|
||||
+ } else {
|
||||
+ struct mdinfo vol_info;
|
||||
+
|
||||
+ super->current_vol = 0;
|
||||
+ getinfo_super_imsm_volume(st, &vol_info);
|
||||
+ super->current_vol = -1;
|
||||
+ info->array.raid_disks = vol_info.array.raid_disks;
|
||||
}
|
||||
|
||||
/* Set raid_disks to zero so that Assemble will always pull in valid
|
||||
* spares
|
||||
- */
|
||||
+ *
|
||||
+ * Note: my testing with assemble shows that it still works even
|
||||
+ * when we set the raid_disks to a proper setting. However, without
|
||||
+ * this it is impossible to tell when a container has the right
|
||||
+ * number of disks to start cleanly without violating layering
|
||||
+ * boundaries. So, not violating layering boundaries trumps spare
|
||||
+ * disk issues. Doug Ledford
|
||||
+ *
|
||||
info->array.raid_disks = 0;
|
||||
+ */
|
||||
info->array.level = LEVEL_CONTAINER;
|
||||
info->array.layout = 0;
|
||||
info->array.md_minor = -1;
|
@ -1,36 +0,0 @@
|
||||
commit ddda49f6daf481471334f5675fbc1fa149d83ad6
|
||||
Author: Doug Ledford <dledford@redhat.com>
|
||||
Date: Tue Apr 6 12:17:25 2010 -0400
|
||||
|
||||
Minor bug fix to incremental remove support
|
||||
|
||||
Signed-off-by: Doug Ledford <dledford@redhat.com>
|
||||
|
||||
diff --git a/Manage.c b/Manage.c
|
||||
index 6539eda..b15586b 100644
|
||||
--- a/Manage.c
|
||||
+++ b/Manage.c
|
||||
@@ -386,6 +386,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
|
||||
next = dv->next;
|
||||
jnext = 0;
|
||||
+ tfd = -1;
|
||||
|
||||
if (strcmp(dv->devname, "failed")==0 ||
|
||||
strcmp(dv->devname, "faulty")==0) {
|
||||
@@ -406,6 +407,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
stb.st_rdev = makedev(disc.major, disc.minor);
|
||||
next = dv;
|
||||
jnext = j+1;
|
||||
+ tfd = 0;
|
||||
sprintf(dvname,"%d:%d", disc.major, disc.minor);
|
||||
dnprintable = dvname;
|
||||
break;
|
||||
@@ -440,6 +442,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
stb.st_rdev = makedev(disc.major, disc.minor);
|
||||
next = dv;
|
||||
jnext = j+1;
|
||||
+ tfd = 0;
|
||||
dnprintable = dvname;
|
||||
break;
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
commit 1934c67fe5bc25a79393ad78e29bf9ef778bc701
|
||||
Author: Doug Ledford <dledford@redhat.com>
|
||||
Date: Tue Apr 6 23:02:47 2010 -0400
|
||||
|
||||
Only close lfd if we have an external metadata type since that's the only
|
||||
time we'll have it open.
|
||||
|
||||
If we weren't able to open the device file, assume the device is gone
|
||||
already and skip the sysfs_unique_holder test as it is guaranteed to
|
||||
fail.
|
||||
|
||||
Signed-off-by: Doug Ledford <dledford@redhat.com>
|
||||
|
||||
diff --git a/Manage.c b/Manage.c
|
||||
index b15586b..a690cfc 100644
|
||||
--- a/Manage.c
|
||||
+++ b/Manage.c
|
||||
@@ -811,6 +811,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
* rely on the 'detached' checks
|
||||
*/
|
||||
if (strcmp(dv->devname, "detached") == 0 ||
|
||||
+ tfd < 0 ||
|
||||
sysfs_unique_holder(dnum, stb.st_rdev))
|
||||
/* pass */;
|
||||
else {
|
||||
@@ -878,8 +879,8 @@ int Manage_subdevs(char *devname, int fd,
|
||||
|
||||
ping_manager(name);
|
||||
free(name);
|
||||
+ close(lfd);
|
||||
}
|
||||
- close(lfd);
|
||||
if (verbose >= 0)
|
||||
fprintf(stderr, Name ": hot removed %s\n",
|
||||
dnprintable);
|
@ -1,633 +0,0 @@
|
||||
From 8c43c776715301ff020639801a8b1b4716fdf745 Mon Sep 17 00:00:00 2001
|
||||
From: Doug Ledford <dledford@redhat.com>
|
||||
Date: Mon, 5 Apr 2010 12:32:08 -0400
|
||||
Subject: [PATCH 6/6] Initial implementation of incremental remove support
|
||||
|
||||
Signed-off-by: Doug Ledford <dledford@redhat.com>
|
||||
---
|
||||
Incremental.c | 36 ++++++++++++++++++
|
||||
Manage.c | 105 +++++++++++++++++++++++++++++++++++++--------------
|
||||
ReadMe.c | 21 +++++++---
|
||||
mdadm.8 | 23 ++++++++++-
|
||||
mdadm.c | 13 ++++++
|
||||
mdadm.h | 8 ++++
|
||||
mdstat.c | 90 +++++++++++++++++++++++++++++++++++++++++++-
|
||||
sysfs.c | 13 ++++--
|
||||
udev-md-raid.rules | 16 +++++---
|
||||
9 files changed, 274 insertions(+), 51 deletions(-)
|
||||
|
||||
diff --git a/Incremental.c b/Incremental.c
|
||||
index 7ad648a..d32a8e5 100644
|
||||
--- a/Incremental.c
|
||||
+++ b/Incremental.c
|
||||
@@ -843,3 +843,39 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
|
||||
map_unlock(&map);
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * IncrementalRemove - Attempt to see if the passed in device belongs to any
|
||||
+ * raid arrays, and if so first fail (if needed) and then remove the device.
|
||||
+ *
|
||||
+ * @devname - The device we want to remove
|
||||
+ *
|
||||
+ * Special note: We would like to just use Managedevs to fail/remove the
|
||||
+ * device, but unfortunately, by the time we are called via udev, the device
|
||||
+ * special file is already gone, and so we can't stat the device and se we
|
||||
+ * don't have the right rdev value to use in the ioctls. So, we use the
|
||||
+ * sysfs method of device removal instead, but since that's not gauranteed
|
||||
+ * to work depending on the version of kernel we run on, try to use the
|
||||
+ * ioctl method first and only fallback if we don't have a valid device
|
||||
+ * special file. That way we can support operation manually on older kernels
|
||||
+ * even if we won't be able to do this automatically via udev on older
|
||||
+ * kernels.
|
||||
+ */
|
||||
+int IncrementalRemove(char *devname, int verbose)
|
||||
+{
|
||||
+ char mddev[100] = "/dev/";
|
||||
+ int mdfd;
|
||||
+ struct mddev_dev_s devlist;
|
||||
+
|
||||
+ strncpy(mddev + 5, devname, sizeof(mddev) - 5);
|
||||
+ if (mdstat_check_active(mddev + 5))
|
||||
+ return 1;
|
||||
+ if ((mdfd = open_mddev(mddev, 0)) < 0)
|
||||
+ return 1;
|
||||
+ memset(&devlist, 0, sizeof(devlist));
|
||||
+ devlist.devname = devname;
|
||||
+ devlist.disposition = 'f';
|
||||
+ Manage_subdevs(mddev, mdfd, &devlist, verbose);
|
||||
+ devlist.disposition = 'r';
|
||||
+ return Manage_subdevs(mddev, mdfd, &devlist, verbose);
|
||||
+}
|
||||
diff --git a/Manage.c b/Manage.c
|
||||
index f848d8b..6539eda 100644
|
||||
--- a/Manage.c
|
||||
+++ b/Manage.c
|
||||
@@ -346,6 +346,9 @@ int Manage_subdevs(char *devname, int fd,
|
||||
mdu_disk_info_t disc;
|
||||
unsigned long long array_size;
|
||||
mddev_dev_t dv, next = NULL;
|
||||
+ struct mdinfo *mdi = NULL;
|
||||
+ struct mdinfo *dev = NULL;
|
||||
+ char sys_name[20] = "dev-";
|
||||
struct stat stb;
|
||||
int j, jnext = 0;
|
||||
int tfd;
|
||||
@@ -443,16 +446,43 @@ int Manage_subdevs(char *devname, int fd,
|
||||
if (jnext == 0)
|
||||
continue;
|
||||
} else {
|
||||
+ /*
|
||||
+ * For fail/remove operations, allow the disk
|
||||
+ * to be completely missing, use name matching
|
||||
+ * to a device in our sysfs entries to
|
||||
+ * suffice. For add we need a valid block device.
|
||||
+ * Leave this loop one of three ways:
|
||||
+ * 1) tfd < 0 and dev is set to our device
|
||||
+ * 2) tfd >= 0 and dev is NULL
|
||||
+ * 3) failed to find suitable device and return
|
||||
+ */
|
||||
j = 0;
|
||||
|
||||
tfd = dev_open(dv->devname, O_RDONLY);
|
||||
- if (tfd < 0 && dv->disposition == 'r' &&
|
||||
- lstat(dv->devname, &stb) == 0)
|
||||
- /* Be happy, the lstat worked, that is
|
||||
- * enough for --remove
|
||||
- */
|
||||
- ;
|
||||
- else {
|
||||
+ if (tfd < 0 && dv->disposition != 'a') {
|
||||
+ strcpy(&sys_name[4],
|
||||
+ strrchr(dv->devname, '/') + 1);
|
||||
+ mdi = sysfs_read(fd, 0,
|
||||
+ GET_DEVS | KEEP_GONE_DEVS);
|
||||
+ if (!mdi) {
|
||||
+ fprintf(stderr, Name ": can't open %s "
|
||||
+ "and can't read sysfs info\n",
|
||||
+ dv->devname);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ for (dev = mdi->devs; dev; dev = dev->next) {
|
||||
+ if (strcmp(sys_name, dev->sys_name))
|
||||
+ continue;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (!dev) {
|
||||
+ fprintf(stderr, Name ": can't open %s "
|
||||
+ "and %s not listed in sysfs\n",
|
||||
+ dv->devname, sys_name);
|
||||
+ sysfs_free(mdi);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ } else {
|
||||
if (tfd < 0 || fstat(tfd, &stb) != 0) {
|
||||
fprintf(stderr, Name ": cannot find %s: %s\n",
|
||||
dv->devname, strerror(errno));
|
||||
@@ -461,12 +491,12 @@ int Manage_subdevs(char *devname, int fd,
|
||||
return 1;
|
||||
}
|
||||
close(tfd);
|
||||
- }
|
||||
- if ((stb.st_mode & S_IFMT) != S_IFBLK) {
|
||||
- fprintf(stderr, Name ": %s is not a "
|
||||
- "block device.\n",
|
||||
- dv->devname);
|
||||
- return 1;
|
||||
+ if ((stb.st_mode & S_IFMT) != S_IFBLK) {
|
||||
+ fprintf(stderr, Name ": %s is not a "
|
||||
+ "block device.\n",
|
||||
+ dv->devname);
|
||||
+ return 1;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
switch(dv->disposition){
|
||||
@@ -790,26 +820,36 @@ int Manage_subdevs(char *devname, int fd,
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
- /* FIXME check that it is a current member */
|
||||
- err = ioctl(fd, HOT_REMOVE_DISK, (unsigned long)stb.st_rdev);
|
||||
- if (err && errno == ENODEV) {
|
||||
+ /* stb.st_rdev is only valid if we have a tfd that
|
||||
+ * does not indicate an error on attempt to open
|
||||
+ * the devname
|
||||
+ */
|
||||
+ if (tfd >= 0)
|
||||
+ err = ioctl(fd, HOT_REMOVE_DISK,
|
||||
+ (unsigned long)stb.st_rdev);
|
||||
+ if (tfd < 0 || (err && errno == ENODEV)) {
|
||||
/* Old kernels rejected this if no personality
|
||||
* registered */
|
||||
- struct mdinfo *sra = sysfs_read(fd, 0, GET_DEVS);
|
||||
- struct mdinfo *dv = NULL;
|
||||
- if (sra)
|
||||
- dv = sra->devs;
|
||||
- for ( ; dv ; dv=dv->next)
|
||||
- if (dv->disk.major == major(stb.st_rdev) &&
|
||||
- dv->disk.minor == minor(stb.st_rdev))
|
||||
+ if (!mdi) {
|
||||
+ strcpy(&sys_name[4],
|
||||
+ strrchr(dv->devname, '/') + 1);
|
||||
+ mdi = sysfs_read(fd, 0, GET_DEVS |
|
||||
+ KEEP_GONE_DEVS);
|
||||
+ if (mdi)
|
||||
+ dev = mdi->devs;
|
||||
+ for ( ; dev ; dev=dev->next) {
|
||||
+ if (strcmp(sys_name, dev->sys_name))
|
||||
+ continue;
|
||||
break;
|
||||
- if (dv)
|
||||
- err = sysfs_set_str(sra, dv,
|
||||
+ }
|
||||
+ }
|
||||
+ if (dev)
|
||||
+ err = sysfs_set_str(mdi, dev,
|
||||
"state", "remove");
|
||||
else
|
||||
err = -1;
|
||||
- if (sra)
|
||||
- sysfs_free(sra);
|
||||
+ if (mdi)
|
||||
+ sysfs_free(mdi);
|
||||
}
|
||||
if (err) {
|
||||
fprintf(stderr, Name ": hot remove failed "
|
||||
@@ -844,11 +884,18 @@ int Manage_subdevs(char *devname, int fd,
|
||||
|
||||
case 'f': /* set faulty */
|
||||
/* FIXME check current member */
|
||||
- if (ioctl(fd, SET_DISK_FAULTY, (unsigned long) stb.st_rdev)) {
|
||||
+ if ((tfd >= 0 && ioctl(fd, SET_DISK_FAULTY,
|
||||
+ (unsigned long) stb.st_rdev)) ||
|
||||
+ (tfd < 0 && sysfs_set_str(mdi, dev, "state",
|
||||
+ "faulty"))) {
|
||||
fprintf(stderr, Name ": set device faulty failed for %s: %s\n",
|
||||
dnprintable, strerror(errno));
|
||||
+ if (mdi)
|
||||
+ sysfs_free(mdi);
|
||||
return 1;
|
||||
- }
|
||||
+ }
|
||||
+ if (mdi)
|
||||
+ sysfs_free(mdi);
|
||||
if (verbose >= 0)
|
||||
fprintf(stderr, Name ": set %s faulty in %s\n",
|
||||
dnprintable, devname);
|
||||
diff --git a/ReadMe.c b/ReadMe.c
|
||||
index 9d5a211..fd216ec 100644
|
||||
--- a/ReadMe.c
|
||||
+++ b/ReadMe.c
|
||||
@@ -86,11 +86,12 @@ char Version[] = Name " - v3.1.2 - 10th March 2010\n";
|
||||
* At the time if writing, there is only minimal support.
|
||||
*/
|
||||
|
||||
-char short_options[]="-ABCDEFGIQhVXWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
|
||||
+char short_options[]=
|
||||
+ "-ABCDEFGIQhVXWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
|
||||
char short_bitmap_options[]=
|
||||
- "-ABCDEFGIQhVXWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
|
||||
+ "-ABCDEFGIQhVXWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
|
||||
char short_bitmap_auto_options[]=
|
||||
- "-ABCDEFGIQhVXWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:";
|
||||
+ "-ABCDEFGIQhVXWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:";
|
||||
|
||||
struct option long_options[] = {
|
||||
{"manage", 0, 0, '@'},
|
||||
@@ -213,7 +214,7 @@ char Help[] =
|
||||
" mdadm --grow options device\n"
|
||||
" resize/reshape an active array\n"
|
||||
" mdadm --incremental device\n"
|
||||
-" add a device to an array as appropriate\n"
|
||||
+" add/remove a device to/from an array as appropriate\n"
|
||||
" mdadm --monitor options...\n"
|
||||
" Monitor one or more array for significant changes.\n"
|
||||
" mdadm device options...\n"
|
||||
@@ -535,20 +536,26 @@ char Help_grow[] =
|
||||
;
|
||||
|
||||
char Help_incr[] =
|
||||
-"Usage: mdadm --incremental [-Rqrs] device\n"
|
||||
+"Usage: mdadm --incremental [-Rqrsf] device\n"
|
||||
"\n"
|
||||
"This usage allows for incremental assembly of md arrays. Devices can be\n"
|
||||
"added one at a time as they are discovered. Once an array has all expected\n"
|
||||
"devices, it will be started.\n"
|
||||
"\n"
|
||||
-"Options that are valid with incremental assembly (-I --incremental) more are:\n"
|
||||
-" --run -R : run arrays as soon as a minimal number of devices are\n"
|
||||
+"Optionally, the process can be reversed by using the fail option.\n"
|
||||
+"When fail mode is invoked, mdadm will see if the device belongs to an array\n"
|
||||
+"and then both fail (if needed) and remove the device from that array.\n"
|
||||
+"\n"
|
||||
+"Options that are valid with incremental assembly (-I --incremental) are:\n"
|
||||
+" --run -R : Run arrays as soon as a minimal number of devices are\n"
|
||||
" : present rather than waiting for all expected.\n"
|
||||
" --quiet -q : Don't print any information messages, just errors.\n"
|
||||
" --rebuild -r : Rebuild the 'map' file that mdadm uses for tracking\n"
|
||||
" : partial arrays.\n"
|
||||
" --scan -s : Use with -R to start any arrays that have the minimal\n"
|
||||
" : required number of devices, but are not yet started.\n"
|
||||
+" --fail -f : First fail (if needed) and then remove device from\n"
|
||||
+" : any array that it is a member of.\n"
|
||||
;
|
||||
|
||||
char Help_config[] =
|
||||
diff --git a/mdadm.8 b/mdadm.8
|
||||
index 4edfc41..eaf9155 100644
|
||||
--- a/mdadm.8
|
||||
+++ b/mdadm.8
|
||||
@@ -135,7 +135,11 @@ This provides a convenient interface to a
|
||||
.I hot-plug
|
||||
system. As each device is detected,
|
||||
.I mdadm
|
||||
-has a chance to include it in some array as appropriate.
|
||||
+has a chance to include it in some array as appropriate. Optionally,
|
||||
+with the
|
||||
+.I \-\-fail
|
||||
+flag is passed in then we will remove the device from any active array
|
||||
+instead of adding it.
|
||||
|
||||
If a
|
||||
.B CONTAINER
|
||||
@@ -189,7 +193,7 @@ Change the size or shape of an active array.
|
||||
|
||||
.TP
|
||||
.BR \-I ", " \-\-incremental
|
||||
-Add a single device into an appropriate array, and possibly start the array.
|
||||
+Add/remove a single device to/from an appropriate array, and possibly start the array.
|
||||
|
||||
.TP
|
||||
.B \-\-auto-detect
|
||||
@@ -1235,6 +1239,12 @@ in
|
||||
.B mdadm.conf
|
||||
as requiring an external bitmap, that bitmap will be attached first.
|
||||
|
||||
+.TP
|
||||
+.BR \-\-fail ", " \-f
|
||||
+This allows the hot-plug system to remove devices that have fully disappeared
|
||||
+from the kernel. It will first fail and then remove the device from any
|
||||
+array it belongs to.
|
||||
+
|
||||
.SH For Monitor mode:
|
||||
.TP
|
||||
.BR \-m ", " \-\-mail
|
||||
@@ -2141,6 +2151,10 @@ Usage:
|
||||
.I component-device
|
||||
.HP 12
|
||||
Usage:
|
||||
+.B mdadm \-\-incremental \-\-fail
|
||||
+.I component-device
|
||||
+.HP 12
|
||||
+Usage:
|
||||
.B mdadm \-\-incremental \-\-rebuild
|
||||
.HP 12
|
||||
Usage:
|
||||
@@ -2153,6 +2167,11 @@ passed to
|
||||
.B "mdadm \-\-incremental"
|
||||
to be conditionally added to an appropriate array.
|
||||
|
||||
+Conversely, it can also be used with the
|
||||
+.B \-\-fail
|
||||
+flag to do just the opposite and find whatever array a particular device
|
||||
+is part of and remove the device from the array.
|
||||
+
|
||||
If the device passed is a
|
||||
.B CONTAINER
|
||||
device created by a previous call to
|
||||
diff --git a/mdadm.c b/mdadm.c
|
||||
index d5e34c0..cd6fd8f 100644
|
||||
--- a/mdadm.c
|
||||
+++ b/mdadm.c
|
||||
@@ -124,6 +124,7 @@ int main(int argc, char *argv[])
|
||||
ident.name[0] = 0;
|
||||
ident.container = NULL;
|
||||
ident.member = NULL;
|
||||
+ ident.member_index = -1;
|
||||
|
||||
while ((option_index = -1) ,
|
||||
(opt=getopt_long(argc, argv,
|
||||
@@ -774,6 +775,9 @@ int main(int argc, char *argv[])
|
||||
devmode = 'r';
|
||||
continue;
|
||||
case O(MANAGE,'f'): /* set faulty */
|
||||
+ case O(INCREMENTAL,'f'): /* r for incremental is taken, use f
|
||||
+ * even though we will both fail and
|
||||
+ * remove the device */
|
||||
devmode = 'f';
|
||||
continue;
|
||||
case O(INCREMENTAL,'R'):
|
||||
@@ -1517,6 +1521,11 @@ int main(int argc, char *argv[])
|
||||
": --incremental --scan meaningless without --run.\n");
|
||||
break;
|
||||
}
|
||||
+ if (devmode == 'f') {
|
||||
+ fprintf(stderr, Name
|
||||
+ ": --incremental --scan --fail not supported.\n");
|
||||
+ break;
|
||||
+ }
|
||||
rv = IncrementalScan(verbose);
|
||||
}
|
||||
if (!devlist) {
|
||||
@@ -1533,6 +1542,10 @@ int main(int argc, char *argv[])
|
||||
rv = 1;
|
||||
break;
|
||||
}
|
||||
+ if (devmode == 'f') {
|
||||
+ rv = IncrementalRemove(devlist->devname, verbose-quiet);
|
||||
+ break;
|
||||
+ }
|
||||
rv = Incremental(devlist->devname, verbose-quiet, runstop,
|
||||
ss, homehost, require_homehost, autof);
|
||||
break;
|
||||
diff --git a/mdadm.h b/mdadm.h
|
||||
index d8ab85f..c113d0f 100644
|
||||
--- a/mdadm.h
|
||||
+++ b/mdadm.h
|
||||
@@ -315,6 +315,7 @@ typedef struct mddev_ident_s {
|
||||
* of some other entry.
|
||||
*/
|
||||
char *member; /* subarray within a container */
|
||||
+ int member_index; /* subarray index within a container */
|
||||
|
||||
struct mddev_ident_s *next;
|
||||
union {
|
||||
@@ -355,6 +356,10 @@ struct mdstat_ent {
|
||||
int raid_disks;
|
||||
int chunk_size;
|
||||
char * metadata_version;
|
||||
+ struct dev_member {
|
||||
+ char *name;
|
||||
+ struct dev_member *next;
|
||||
+ } *members;
|
||||
struct mdstat_ent *next;
|
||||
};
|
||||
|
||||
@@ -363,6 +368,7 @@ extern void free_mdstat(struct mdstat_ent *ms);
|
||||
extern void mdstat_wait(int seconds);
|
||||
extern void mdstat_wait_fd(int fd, const sigset_t *sigmask);
|
||||
extern int mddev_busy(int devnum);
|
||||
+extern int mdstat_check_active(char *devname);
|
||||
|
||||
struct map_ent {
|
||||
struct map_ent *next;
|
||||
@@ -404,6 +410,7 @@ enum sysfs_read_flags {
|
||||
GET_STATE = (1 << 13),
|
||||
GET_ERROR = (1 << 14),
|
||||
SKIP_GONE_DEVS = (1 << 15),
|
||||
+ KEEP_GONE_DEVS = (1 << 16),
|
||||
};
|
||||
|
||||
/* If fd >= 0, get the array it is open on,
|
||||
@@ -817,6 +824,7 @@ extern int Incremental_container(struct supertype *st, char *devname,
|
||||
int trustworthy);
|
||||
extern void RebuildMap(void);
|
||||
extern int IncrementalScan(int verbose);
|
||||
+extern int IncrementalRemove(char *devname, int verbose);
|
||||
|
||||
extern int CreateBitmap(char *filename, int force, char uuid[16],
|
||||
unsigned long chunksize, unsigned long daemon_sleep,
|
||||
diff --git a/mdstat.c b/mdstat.c
|
||||
index 4a9f370..81d2212 100644
|
||||
--- a/mdstat.c
|
||||
+++ b/mdstat.c
|
||||
@@ -83,6 +83,45 @@
|
||||
#include <sys/select.h>
|
||||
#include <ctype.h>
|
||||
|
||||
+static void free_member_devnames(struct dev_member **m)
|
||||
+{
|
||||
+ struct dev_member *t;
|
||||
+ if (!*m)
|
||||
+ return;
|
||||
+ while(*m) {
|
||||
+ t = *m;
|
||||
+ *m = (*m)->next;
|
||||
+ if (t->name)
|
||||
+ free(t->name);
|
||||
+ free(t);
|
||||
+ }
|
||||
+ *m = NULL;
|
||||
+}
|
||||
+
|
||||
+static struct dev_member *add_member_devname(struct dev_member **m, char *name)
|
||||
+{
|
||||
+ struct dev_member *new;
|
||||
+ char *t;
|
||||
+
|
||||
+ if (!m || !name)
|
||||
+ return NULL;
|
||||
+
|
||||
+ new = malloc(sizeof(*new));
|
||||
+ if (!new)
|
||||
+ return NULL;
|
||||
+ if ((t = strchr(name, '[')) == NULL)
|
||||
+ {
|
||||
+ /* not a device */
|
||||
+ free(new);
|
||||
+ return *m;
|
||||
+ }
|
||||
+ new->name = strndup(name, t - name);
|
||||
+ new->next = *m;
|
||||
+ *m = new;
|
||||
+
|
||||
+ return new;
|
||||
+}
|
||||
+
|
||||
void free_mdstat(struct mdstat_ent *ms)
|
||||
{
|
||||
while (ms) {
|
||||
@@ -91,6 +130,7 @@ void free_mdstat(struct mdstat_ent *ms)
|
||||
if (ms->level) free(ms->level);
|
||||
if (ms->pattern) free(ms->pattern);
|
||||
if (ms->metadata_version) free(ms->metadata_version);
|
||||
+ if (ms->members) free_member_devnames(&ms->members);
|
||||
t = ms;
|
||||
ms = ms->next;
|
||||
free(t);
|
||||
@@ -159,6 +199,7 @@ struct mdstat_ent *mdstat_read(int hold, int start)
|
||||
ent->raid_disks = 0;
|
||||
ent->chunk_size = 0;
|
||||
ent->devcnt = 0;
|
||||
+ ent->members = NULL;
|
||||
|
||||
ent->dev = strdup(line);
|
||||
ent->devnum = devnum;
|
||||
@@ -170,15 +211,23 @@ struct mdstat_ent *mdstat_read(int hold, int start)
|
||||
ent->active = 1;
|
||||
else if (strcmp(w, "inactive")==0)
|
||||
ent->active = 0;
|
||||
- else if (ent->active >=0 &&
|
||||
+ else if (ent->active > 0 &&
|
||||
ent->level == NULL &&
|
||||
w[0] != '(' /*readonly*/) {
|
||||
ent->level = strdup(w);
|
||||
in_devs = 1;
|
||||
} else if (in_devs && strcmp(w, "blocks")==0)
|
||||
in_devs = 0;
|
||||
- else if (in_devs) {
|
||||
+ else if (in_devs || (ent->active == 0 && w[0] != '(' &&
|
||||
+ w[l - 1] == ')')) {
|
||||
+ if (isdigit(w[0]))
|
||||
+ continue;
|
||||
+ in_devs = 1;
|
||||
ent->devcnt++;
|
||||
+ if (!add_member_devname(&ent->members, w)) {
|
||||
+ free_mdstat(ent);
|
||||
+ break;
|
||||
+ }
|
||||
if (strncmp(w, "md", 2)==0) {
|
||||
/* This has an md device as a component.
|
||||
* If that device is already in the
|
||||
@@ -310,3 +359,40 @@ int mddev_busy(int devnum)
|
||||
free_mdstat(mdstat);
|
||||
return me != NULL;
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * Finds name of the active array holding this device
|
||||
+ * @param[in] devname name of member device
|
||||
+ * @param[out] devname name of array
|
||||
+ *
|
||||
+ * @return found (0), or
|
||||
+ * not found, failure (1)
|
||||
+ */
|
||||
+
|
||||
+int mdstat_check_active(char *devname)
|
||||
+{
|
||||
+ struct mdstat_ent *mdstat = mdstat_read(0, 0);
|
||||
+ struct mdstat_ent *ent;
|
||||
+ char *name;
|
||||
+
|
||||
+ if (!devname)
|
||||
+ return 1;
|
||||
+ name = strrchr(devname, '/');
|
||||
+ if (name++ == NULL)
|
||||
+ return 1;
|
||||
+
|
||||
+ for (ent = mdstat; ent; ent = ent->next) {
|
||||
+ struct dev_member *m;
|
||||
+ if (ent->active && (strstr(ent->metadata_version,"imsm") ||
|
||||
+ strstr(ent->metadata_version,"ddf")))
|
||||
+ /* only return container matches, not subarrays */
|
||||
+ continue;
|
||||
+ for (m = ent->members; m; m = m->next) {
|
||||
+ if (!strcmp(m->name, name)) {
|
||||
+ strcpy(devname, ent->dev);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
diff --git a/sysfs.c b/sysfs.c
|
||||
index ebf9d8a..65dd848 100644
|
||||
--- a/sysfs.c
|
||||
+++ b/sysfs.c
|
||||
@@ -273,13 +273,16 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
|
||||
|
||||
strcpy(dbase, "block/dev");
|
||||
if (load_sys(fname, buf)) {
|
||||
- free(dev);
|
||||
- if (options & SKIP_GONE_DEVS)
|
||||
+ if (options & SKIP_GONE_DEVS) {
|
||||
+ free(dev);
|
||||
continue;
|
||||
- else
|
||||
+ } else if (options & KEEP_GONE_DEVS) {
|
||||
+ dev->disk.major = dev->disk.minor = -1;
|
||||
+ } else
|
||||
goto abort;
|
||||
- }
|
||||
- sscanf(buf, "%d:%d", &dev->disk.major, &dev->disk.minor);
|
||||
+ } else
|
||||
+ sscanf(buf, "%d:%d", &dev->disk.major,
|
||||
+ &dev->disk.minor);
|
||||
|
||||
/* special case check for block devices that can go 'offline' */
|
||||
if (options & SKIP_GONE_DEVS) {
|
||||
diff --git a/udev-md-raid.rules b/udev-md-raid.rules
|
||||
index c9a4f0e..aff14fa 100644
|
||||
--- a/udev-md-raid.rules
|
||||
+++ b/udev-md-raid.rules
|
||||
@@ -1,17 +1,16 @@
|
||||
# do not edit this file, it will be overwritten on update
|
||||
|
||||
SUBSYSTEM!="block", GOTO="md_end"
|
||||
-ACTION!="add|change", GOTO="md_end"
|
||||
+ACTION!="add|change|remove", GOTO="md_end"
|
||||
+ACTION=="remove", GOTO="md_remove"
|
||||
ACTION=="change", GOTO="md_no_incr"
|
||||
|
||||
-# import data from a raid member and activate it
|
||||
-#ENV{ID_FS_TYPE}=="linux_raid_member", IMPORT{program}="/sbin/mdadm --examine --export $tempnode", RUN+="/sbin/mdadm --incremental $env{DEVNAME}"
|
||||
-# import data from a raid set
|
||||
+# we are adding a raid member, activate it
|
||||
+ENV{ID_FS_TYPE}=="linux_raid_member", RUN+="/sbin/mdadm -I $env{DEVNAME}"
|
||||
LABEL="md_no_incr"
|
||||
KERNEL!="md*", GOTO="md_end"
|
||||
|
||||
-# partitions have no md/{array_state,metadata_version}, but should not
|
||||
-# for that reason be ignored.
|
||||
+# partitions have no md/{array_state,metadata_version}
|
||||
ENV{DEVTYPE}=="partition", GOTO="md_ignore_state"
|
||||
|
||||
# container devices have a metadata version of e.g. 'external:ddf' and
|
||||
@@ -32,7 +31,12 @@ ENV{DEVTYPE}=="partition", ENV{MD_DEVNAME}=="*[0-9]", SYMLINK+="md/$env{MD_DEVNA
|
||||
|
||||
IMPORT{program}="/sbin/blkid -o udev -p $tempnode"
|
||||
OPTIONS+="link_priority=100"
|
||||
+OPTIONS+="watch"
|
||||
ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
|
||||
ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
|
||||
+GOTO="md_end"
|
||||
+
|
||||
+LABEL="md_remove"
|
||||
+ENV{ID_FS_TYPE}=="linux_raid_member", RUN+="/sbin/mdadm -If $env{DEVNAME}"
|
||||
|
||||
LABEL="md_end"
|
||||
--
|
||||
1.6.6.1
|
||||
|
@ -1,265 +0,0 @@
|
||||
From df3e08eaa7ee07528968bb7152dfaaeebd3c97cb Mon Sep 17 00:00:00 2001
|
||||
From: Doug Ledford <dledford@redhat.com>
|
||||
Date: Fri, 2 Apr 2010 10:53:47 -0400
|
||||
Subject: [PATCH 5/6] Fix all the confusion over directories once and for all. We now have
|
||||
3 directory definitions: mdmon directory for its pid and sock files,
|
||||
mdmonitor directory which is for the mdadm monitor mode pid file and
|
||||
can only be passed in via command line, and the directory for the
|
||||
mdadm map file. Only the mdadm map file still hunts multiple locations,
|
||||
and the number of locations has been reduced to /var/run and the
|
||||
compile time specified location. I could see lowering that to just
|
||||
1 location, but I didn't do that with this patch.
|
||||
|
||||
Signed-off-by: Doug Ledford <dledford@redhat.com>
|
||||
---
|
||||
Makefile | 18 +++++++++---------
|
||||
mapfile.c | 18 ++++++++----------
|
||||
mdadm.h | 41 +++++++++++++++++++++--------------------
|
||||
mdmon.c | 28 ++++++----------------------
|
||||
msg.c | 2 +-
|
||||
util.c | 4 +---
|
||||
6 files changed, 46 insertions(+), 65 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 2aafad0..30e52a7 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -58,16 +58,16 @@ CONFFILE = $(SYSCONFDIR)/mdadm.conf
|
||||
CONFFILE2 = $(SYSCONFDIR)/mdadm/mdadm.conf
|
||||
MAILCMD =/usr/sbin/sendmail -t
|
||||
CONFFILEFLAGS = -DCONFFILE=\"$(CONFFILE)\" -DCONFFILE2=\"$(CONFFILE2)\"
|
||||
-# ALT_RUN should be somewhere that persists across the pivotroot
|
||||
-# from early boot to late boot.
|
||||
+# Both MAP_DIR and MDMON_DIR should be somewhere that persists across the
|
||||
+# pivotroot from early boot to late boot.
|
||||
# If you don't have /lib/init/rw you might want to use /dev/.something
|
||||
-# e.g. make ALT_RUN=/dev/.mdadm
|
||||
-ALT_RUN = /lib/init/rw
|
||||
-ALT_MAPFILE = map
|
||||
-VAR_RUN = /var/run
|
||||
-ALTFLAGS = -DALT_RUN=\"$(ALT_RUN)\" -DALT_MAPFILE=\"$(ALT_MAPFILE)\"
|
||||
-VARFLAGS = -DVAR_RUN=\"$(VAR_RUN)\"
|
||||
-CFLAGS = $(CWFLAGS) $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\" $(CONFFILEFLAGS) $(ALTFLAGS) $(VARFLAGS)
|
||||
+# e.g. make MAP_DIR=/dev/.mdadm
|
||||
+MAP_DIR = /lib/init/rw/mdadm
|
||||
+MAP_FILE = map
|
||||
+MDMON_DIR = /lib/init/rw/mdmon
|
||||
+DIRFLAGS = -DMAP_DIR=\"$(MAP_DIR)\" -DMAP_FILE=\"$(MAP_FILE)\"
|
||||
+DIRFLAGS += -DMDMON_DIR=\"$(MDMON_DIR)\"
|
||||
+CFLAGS = $(CWFLAGS) $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\" $(CONFFILEFLAGS) $(DIRFLAGS)
|
||||
|
||||
# If you want a static binary, you might uncomment these
|
||||
# LDFLAGS = -static
|
||||
diff --git a/mapfile.c b/mapfile.c
|
||||
index d47fde1..f4339db 100644
|
||||
--- a/mapfile.c
|
||||
+++ b/mapfile.c
|
||||
@@ -52,28 +52,26 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#define mapnames(base) { base, base ".new", base ".lock"}
|
||||
-char *mapname[3][3] = {
|
||||
- mapnames(VAR_RUN "/map"),
|
||||
- mapnames("/var/run/mdadm.map"),
|
||||
- mapnames(ALT_RUN "/" ALT_MAPFILE)
|
||||
+char *mapname[2][3] = {
|
||||
+ mapnames(MAP_DIR "/" MAP_FILE),
|
||||
+ mapnames("/var/run/mdadm.map")
|
||||
};
|
||||
-char *mapdir[3] = { VAR_RUN, NULL, ALT_RUN };
|
||||
+char *mapdir[2] = { MAP_DIR, NULL };
|
||||
|
||||
-int mapmode[3] = { O_RDONLY, O_RDWR|O_CREAT, O_RDWR|O_CREAT | O_TRUNC };
|
||||
+int mapmode[3] = { O_RDONLY, O_RDWR|O_CREAT, O_RDWR|O_CREAT|O_TRUNC };
|
||||
char *mapsmode[3] = { "r", "w", "w"};
|
||||
|
||||
FILE *open_map(int modenum, int *choice)
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0 ; i < 3 ; i++) {
|
||||
+ for (i = 0 ; i < 2 ; i++) {
|
||||
int fd;
|
||||
- if ((mapmode[modenum] & O_CREAT) &&
|
||||
- mapdir[modenum])
|
||||
+ if ((mapmode[modenum] & O_CREAT) && mapdir[i])
|
||||
/* Attempt to create directory, don't worry about
|
||||
* failure.
|
||||
*/
|
||||
- mkdir(mapdir[modenum], 0755);
|
||||
+ mkdir(mapdir[i], 0755);
|
||||
fd = open(mapname[i][modenum], mapmode[modenum], 0600);
|
||||
if (fd >= 0) {
|
||||
*choice = i;
|
||||
diff --git a/mdadm.h b/mdadm.h
|
||||
index 0386129..d8ab85f 100644
|
||||
--- a/mdadm.h
|
||||
+++ b/mdadm.h
|
||||
@@ -68,28 +68,30 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
|
||||
#define DEFAULT_BITMAP_DELAY 5
|
||||
#define DEFAULT_MAX_WRITE_BEHIND 256
|
||||
|
||||
-/* VAR_RUN is where pid and socket files used for communicating
|
||||
- * with mdmon normally live. It should be /var/run, but if
|
||||
- * it is too hard to remount /var/run as read-only rather than
|
||||
- * unmounting it at shutdown time, then it should be
|
||||
- * redefined to some place that comfortably persists until
|
||||
- * final shutdown, possibly in /dev if that is a tmpfs.
|
||||
- * Note: VAR_RUN does not need to be writable at shutdown,
|
||||
- * only during boot when "mdmon --takeover" is run.
|
||||
- */
|
||||
-#ifndef VAR_RUN
|
||||
-#define VAR_RUN "/var/run/mdadm"
|
||||
-#endif /* VAR_RUN */
|
||||
-/* ALT_RUN should be somewhere that persists across the pivotroot
|
||||
+/* MAP_DIR should be somewhere that persists across the pivotroot
|
||||
* from early boot to late boot.
|
||||
* If you don't have /lib/init/rw you might want to use /dev/.something
|
||||
*/
|
||||
-#ifndef ALT_RUN
|
||||
-#define ALT_RUN "/lib/init/rw/mdadm"
|
||||
-#endif /* ALT_RUN */
|
||||
-#ifndef ALT_MAPFILE
|
||||
-#define ALT_MAPFILE "map"
|
||||
-#endif /* ALT_MAPFILE */
|
||||
+#ifndef MAP_DIR
|
||||
+#define MAP_DIR "/lib/init/rw/mdadm"
|
||||
+#endif /* MAP_DIR */
|
||||
+/* MAP_FILE is what we name the map file we put in MAP_DIR, in case you
|
||||
+ * want something other than the default of "map"
|
||||
+ */
|
||||
+#ifndef MAP_FILE
|
||||
+#define MAP_FILE "map"
|
||||
+#endif /* MAP_FILE */
|
||||
+/* MDMON_DIR is where pid and socket files used for communicating
|
||||
+ * with mdmon normally live. It *should* be /var/run, but when
|
||||
+ * mdmon is needed at early boot then it needs to write there prior
|
||||
+ * to /var/run being mounted read/write, and it also then needs to
|
||||
+ * persist beyond when /var/run is mounter read-only. So, to be
|
||||
+ * safe, the default is somewhere that is read/write early in the
|
||||
+ * boot process and stays up as long as possible during shutdown.
|
||||
+ */
|
||||
+#ifndef MDMON_DIR
|
||||
+#define MDMON_DIR "/lib/init/rw/mdmon"
|
||||
+#endif /* MDMON_DIR */
|
||||
|
||||
#include "md_u.h"
|
||||
#include "md_p.h"
|
||||
@@ -910,7 +912,6 @@ extern int create_mddev(char *dev, char *name, int autof, int trustworthy,
|
||||
extern int open_mddev(char *dev, int report_errors);
|
||||
extern int open_container(int fd);
|
||||
|
||||
-extern char *pid_dir;
|
||||
extern int mdmon_running(int devnum);
|
||||
extern int mdmon_pid(int devnum);
|
||||
extern int check_env(char *name);
|
||||
diff --git a/mdmon.c b/mdmon.c
|
||||
index 69c320e..cbb72cc 100644
|
||||
--- a/mdmon.c
|
||||
+++ b/mdmon.c
|
||||
@@ -120,10 +120,10 @@ static int make_pidfile(char *devname)
|
||||
int fd;
|
||||
int n;
|
||||
|
||||
- if (mkdir(pid_dir, 0700) < 0 &&
|
||||
+ if (mkdir(MDMON_DIR, 0755) < 0 &&
|
||||
errno != EEXIST)
|
||||
return -errno;
|
||||
- sprintf(path, "%s/%s.pid", pid_dir, devname);
|
||||
+ sprintf(path, "%s/%s.pid", MDMON_DIR, devname);
|
||||
|
||||
fd = open(path, O_RDWR|O_CREAT|O_EXCL, 0600);
|
||||
if (fd < 0)
|
||||
@@ -189,13 +189,10 @@ void remove_pidfile(char *devname)
|
||||
{
|
||||
char buf[100];
|
||||
|
||||
- sprintf(buf, "%s/%s.pid", pid_dir, devname);
|
||||
+ sprintf(buf, "%s/%s.pid", MDMON_DIR, devname);
|
||||
unlink(buf);
|
||||
- sprintf(buf, "%s/%s.sock", pid_dir, devname);
|
||||
+ sprintf(buf, "%s/%s.sock", MDMON_DIR, devname);
|
||||
unlink(buf);
|
||||
- if (strcmp(pid_dir, ALT_RUN) == 0)
|
||||
- /* try to clean up when we are finished with this dir */
|
||||
- rmdir(pid_dir);
|
||||
}
|
||||
|
||||
static int make_control_sock(char *devname)
|
||||
@@ -208,7 +205,7 @@ static int make_control_sock(char *devname)
|
||||
if (sigterm)
|
||||
return -1;
|
||||
|
||||
- sprintf(path, "%s/%s.sock", pid_dir, devname);
|
||||
+ sprintf(path, "%s/%s.sock", MDMON_DIR, devname);
|
||||
unlink(path);
|
||||
sfd = socket(PF_LOCAL, SOCK_STREAM, 0);
|
||||
if (sfd < 0)
|
||||
@@ -445,12 +442,7 @@ static int mdmon(char *devname, int devnum, int must_fork, int takeover)
|
||||
act.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &act, NULL);
|
||||
|
||||
- pid_dir = VAR_RUN;
|
||||
victim = mdmon_pid(container->devnum);
|
||||
- if (victim < 0) {
|
||||
- pid_dir = ALT_RUN;
|
||||
- victim = mdmon_pid(container->devnum);
|
||||
- }
|
||||
if (victim >= 0)
|
||||
victim_sock = connect_monitor(container->devname);
|
||||
|
||||
@@ -474,16 +466,8 @@ static int mdmon(char *devname, int devnum, int must_fork, int takeover)
|
||||
*/
|
||||
if (victim > 0)
|
||||
remove_pidfile(devname);
|
||||
- pid_dir = VAR_RUN;
|
||||
if (make_pidfile(devname) < 0) {
|
||||
- /* Try the alternate */
|
||||
- pid_dir = ALT_RUN;
|
||||
- if (make_pidfile(devname) < 0) {
|
||||
- fprintf(stderr, "mdmon: Neither %s nor %s are writable\n"
|
||||
- " cannot create .pid or .sock files. Aborting\n",
|
||||
- VAR_RUN, ALT_RUN);
|
||||
- exit(3);
|
||||
- }
|
||||
+ exit(3);
|
||||
}
|
||||
container->sock = make_control_sock(devname);
|
||||
|
||||
diff --git a/msg.c b/msg.c
|
||||
index d2d8445..aabfa8f 100644
|
||||
--- a/msg.c
|
||||
+++ b/msg.c
|
||||
@@ -147,7 +147,7 @@ int connect_monitor(char *devname)
|
||||
int pos;
|
||||
char *c;
|
||||
|
||||
- pos = sprintf(path, "%s/", pid_dir);
|
||||
+ pos = sprintf(path, "%s/", MDMON_DIR);
|
||||
if (is_subarray(devname)) {
|
||||
devname++;
|
||||
c = strchr(devname, '/');
|
||||
diff --git a/util.c b/util.c
|
||||
index 79d2b0f..bdb19f9 100644
|
||||
--- a/util.c
|
||||
+++ b/util.c
|
||||
@@ -1499,15 +1499,13 @@ int fd2devnum(int fd)
|
||||
return NoMdDev;
|
||||
}
|
||||
|
||||
-char *pid_dir = VAR_RUN;
|
||||
-
|
||||
int mdmon_pid(int devnum)
|
||||
{
|
||||
char path[100];
|
||||
char pid[10];
|
||||
int fd;
|
||||
int n;
|
||||
- sprintf(path, "%s/%s.pid", pid_dir, devnum2devname(devnum));
|
||||
+ sprintf(path, "%s/%s.pid", MDMON_DIR, devnum2devname(devnum));
|
||||
fd = open(path, O_RDONLY | O_NOATIME, 0);
|
||||
|
||||
if (fd < 0)
|
||||
--
|
||||
1.6.6.1
|
||||
|
@ -1,80 +0,0 @@
|
||||
From 435b90e7d41a17f35a984112cace471c975906f4 Mon Sep 17 00:00:00 2001
|
||||
From: Doug Ledford <dledford@redhat.com>
|
||||
Date: Tue, 16 Mar 2010 23:00:11 -0400
|
||||
Subject: [PATCH 2/6] Create directory to contain mapfile (Assuming parent exists and
|
||||
filesystem is writable).
|
||||
This particularly keeps udev happy if VAR_RUN is set to /dev/md.
|
||||
|
||||
Signed-off-by: Doug Ledford <dledford@redhat.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
mapfile.c | 17 +++++++++++++----
|
||||
mdmon.c | 2 +-
|
||||
2 files changed, 14 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/mapfile.c b/mapfile.c
|
||||
index 366ebe3..89187ac 100644
|
||||
--- a/mapfile.c
|
||||
+++ b/mapfile.c
|
||||
@@ -29,7 +29,7 @@
|
||||
*/
|
||||
|
||||
/* /var/run/mdadm.map is used to track arrays being created in --incremental
|
||||
- * more. It particularly allows lookup from UUID to array device, but
|
||||
+ * mode. It particularly allows lookup from UUID to array device, but
|
||||
* also allows the array device name to be easily found.
|
||||
*
|
||||
* The map file is line based with space separated fields. The fields are:
|
||||
@@ -42,8 +42,8 @@
|
||||
* However /var/run may not exist or be writable in early boot. And if
|
||||
* no-one has created /var/run/mdadm, we still want to survive.
|
||||
* So possible locations are:
|
||||
- * /var/run/mdadm/map /var/run/mdadm.map /dev/.mdadm.map
|
||||
- * the last, because udev requires a writable /dev very early.
|
||||
+ * /var/run/mdadm/map /var/run/mdadm.map /lib/initrw/madam/map
|
||||
+ * The last can easily be change at compile to e.g. somewhere in /dev.
|
||||
* We read from the first one that exists and write to the first
|
||||
* one that we can.
|
||||
*/
|
||||
@@ -57,6 +57,7 @@ char *mapname[3][3] = {
|
||||
mapnames("/var/run/mdadm.map"),
|
||||
mapnames(ALT_RUN "/map")
|
||||
};
|
||||
+char *mapdir[3] = { VAR_RUN, NULL, ALT_RUN };
|
||||
|
||||
int mapmode[3] = { O_RDONLY, O_RDWR|O_CREAT, O_RDWR|O_CREAT | O_TRUNC };
|
||||
char *mapsmode[3] = { "r", "w", "w"};
|
||||
@@ -64,8 +65,16 @@ char *mapsmode[3] = { "r", "w", "w"};
|
||||
FILE *open_map(int modenum, int *choice)
|
||||
{
|
||||
int i;
|
||||
+
|
||||
for (i = 0 ; i < 3 ; i++) {
|
||||
- int fd = open(mapname[i][modenum], mapmode[modenum], 0600);
|
||||
+ int fd;
|
||||
+ if ((mapmode[modenum] & O_CREAT) &&
|
||||
+ mapdir[modenum])
|
||||
+ /* Attempt to create directory, don't worry about
|
||||
+ * failure.
|
||||
+ */
|
||||
+ mkdir(mapdir[modenum], 0755);
|
||||
+ fd = open(mapname[i][modenum], mapmode[modenum], 0600);
|
||||
if (fd >= 0) {
|
||||
*choice = i;
|
||||
return fdopen(fd, mapsmode[modenum]);
|
||||
diff --git a/mdmon.c b/mdmon.c
|
||||
index 961aa77..69c320e 100644
|
||||
--- a/mdmon.c
|
||||
+++ b/mdmon.c
|
||||
@@ -120,7 +120,7 @@ static int make_pidfile(char *devname)
|
||||
int fd;
|
||||
int n;
|
||||
|
||||
- if (mkdir(pid_dir, 0600) < 0 &&
|
||||
+ if (mkdir(pid_dir, 0700) < 0 &&
|
||||
errno != EEXIST)
|
||||
return -errno;
|
||||
sprintf(path, "%s/%s.pid", pid_dir, devname);
|
||||
--
|
||||
1.6.6.1
|
||||
|
@ -1,58 +0,0 @@
|
||||
From e259df4e63f553c1271fa7d7612c110d2518e572 Mon Sep 17 00:00:00 2001
|
||||
From: Doug Ledford <dledford@redhat.com>
|
||||
Date: Wed, 17 Mar 2010 10:52:22 -0400
|
||||
Subject: [PATCH 3/6] mapfile: if we putting the mapfile in a custom location via ALT_RUN, allow
|
||||
a custom filename too.
|
||||
|
||||
Signed-off-by: Doug Ledford <dledford@redhat.com>
|
||||
---
|
||||
Makefile | 3 ++-
|
||||
mapfile.c | 2 +-
|
||||
mdadm.h | 3 +++
|
||||
3 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 1035ea8..2aafad0 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -63,8 +63,9 @@ CONFFILEFLAGS = -DCONFFILE=\"$(CONFFILE)\" -DCONFFILE2=\"$(CONFFILE2)\"
|
||||
# If you don't have /lib/init/rw you might want to use /dev/.something
|
||||
# e.g. make ALT_RUN=/dev/.mdadm
|
||||
ALT_RUN = /lib/init/rw
|
||||
+ALT_MAPFILE = map
|
||||
VAR_RUN = /var/run
|
||||
-ALTFLAGS = -DALT_RUN=\"$(ALT_RUN)\"
|
||||
+ALTFLAGS = -DALT_RUN=\"$(ALT_RUN)\" -DALT_MAPFILE=\"$(ALT_MAPFILE)\"
|
||||
VARFLAGS = -DVAR_RUN=\"$(VAR_RUN)\"
|
||||
CFLAGS = $(CWFLAGS) $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\" $(CONFFILEFLAGS) $(ALTFLAGS) $(VARFLAGS)
|
||||
|
||||
diff --git a/mapfile.c b/mapfile.c
|
||||
index 89187ac..74f7256 100644
|
||||
--- a/mapfile.c
|
||||
+++ b/mapfile.c
|
||||
@@ -55,7 +55,7 @@
|
||||
char *mapname[3][3] = {
|
||||
mapnames(VAR_RUN "/map"),
|
||||
mapnames("/var/run/mdadm.map"),
|
||||
- mapnames(ALT_RUN "/map")
|
||||
+ mapnames(ALT_RUN "/" ALT_MAPFILE)
|
||||
};
|
||||
char *mapdir[3] = { VAR_RUN, NULL, ALT_RUN };
|
||||
|
||||
diff --git a/mdadm.h b/mdadm.h
|
||||
index 362b66b..0386129 100644
|
||||
--- a/mdadm.h
|
||||
+++ b/mdadm.h
|
||||
@@ -87,6 +87,9 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
|
||||
#ifndef ALT_RUN
|
||||
#define ALT_RUN "/lib/init/rw/mdadm"
|
||||
#endif /* ALT_RUN */
|
||||
+#ifndef ALT_MAPFILE
|
||||
+#define ALT_MAPFILE "map"
|
||||
+#endif /* ALT_MAPFILE */
|
||||
|
||||
#include "md_u.h"
|
||||
#include "md_p.h"
|
||||
--
|
||||
1.6.6.1
|
||||
|
@ -1,21 +0,0 @@
|
||||
commit 995511f26e8d661d32d1c3fc42a08960989d1e6d
|
||||
Author: Doug Ledford <dledford@redhat.com>
|
||||
Date: Tue Apr 6 14:04:30 2010 -0400
|
||||
|
||||
powerpc compile fix
|
||||
|
||||
Signed-off-by: Doug Ledford <dledford@redhat.com>
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index a196ca3..999b970 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -697,7 +697,7 @@ static void print_imsm_dev(struct imsm_dev *dev, char *uuid, int disk_idx)
|
||||
printf(" <-- %s", map_state_str[map->map_state]);
|
||||
printf("\n Checkpoint : %u (%llu)",
|
||||
__le32_to_cpu(dev->vol.curr_migr_unit),
|
||||
- blocks_per_migr_unit(dev));
|
||||
+ (unsigned long long)blocks_per_migr_unit(dev));
|
||||
}
|
||||
printf("\n");
|
||||
printf(" Dirty State : %s\n", dev->vol.dirty ? "dirty" : "clean");
|
@ -1,38 +0,0 @@
|
||||
From 7bf59f5c16d928d3826fdf0c406d1aac5775e78b Mon Sep 17 00:00:00 2001
|
||||
From: Doug Ledford <dledford@redhat.com>
|
||||
Date: Wed, 17 Mar 2010 09:28:07 -0400
|
||||
Subject: [PATCH 4/6] Only signal a udev change event if we actually write a mapfile in RebuildMap
|
||||
|
||||
Signed-off-by: Doug Ledford <dledford@redhat.com>
|
||||
---
|
||||
mapfile.c | 14 ++++++++------
|
||||
1 files changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/mapfile.c b/mapfile.c
|
||||
index 74f7256..d47fde1 100644
|
||||
--- a/mapfile.c
|
||||
+++ b/mapfile.c
|
||||
@@ -471,12 +471,14 @@ void RebuildMap(void)
|
||||
}
|
||||
sysfs_free(sra);
|
||||
}
|
||||
- map_write(map);
|
||||
+ /* Only trigger a change if we wrote a new map file */
|
||||
+ if (map_write(map))
|
||||
+ for (md = mdstat ; md ; md = md->next) {
|
||||
+ struct mdinfo *sra = sysfs_read(-1, md->devnum,
|
||||
+ GET_VERSION);
|
||||
+ sysfs_uevent(sra, "change");
|
||||
+ sysfs_free(sra);
|
||||
+ }
|
||||
map_free(map);
|
||||
- for (md = mdstat ; md ; md = md->next) {
|
||||
- struct mdinfo *sra = sysfs_read(-1, md->devnum, GET_VERSION);
|
||||
- sysfs_uevent(sra, "change");
|
||||
- sysfs_free(sra);
|
||||
- }
|
||||
free_mdstat(mdstat);
|
||||
}
|
||||
--
|
||||
1.6.6.1
|
||||
|
11
mdadm-3.1.3-read.patch
Normal file
11
mdadm-3.1.3-read.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- mdadm-3.1.3-git07202010/Grow.c.read 2010-07-20 12:18:12.000000000 -0400
|
||||
+++ mdadm-3.1.3-git07202010/Grow.c 2010-07-20 12:55:26.816805170 -0400
|
||||
@@ -1820,7 +1820,7 @@ int Grow_restart(struct supertype *st, s
|
||||
}
|
||||
/* There should be a duplicate backup superblock 4k before here */
|
||||
if (lseek64(fd, -4096, 1) < 0 ||
|
||||
- read(fd, &bsb2, 4096) != 4096)
|
||||
+ read(fd, &bsb2, sizeof(bsb2)) != sizeof(bsb2))
|
||||
goto second_fail; /* Cannot find leading superblock */
|
||||
if (bsb.magic[15] == '1')
|
||||
bsbsize = offsetof(struct mdp_backup_super, pad1);
|
@ -7,6 +7,7 @@ Source1: mdmonitor.init
|
||||
Source2: raid-check
|
||||
Source3: mdadm.rules
|
||||
Source4: mdadm-raid-check-sysconfig
|
||||
Patch0: mdadm-3.1.3-read.patch
|
||||
Patch20: mdadm-2.5.2-static.patch
|
||||
URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/
|
||||
License: GPLv2+
|
||||
@ -28,6 +29,7 @@ file can be used to help with some common tasks.
|
||||
|
||||
%prep
|
||||
%setup -q -n mdadm-3.1.3-git07202010
|
||||
%patch0 -p1 -b .read
|
||||
%patch20 -p1 -b .static
|
||||
|
||||
%build
|
||||
|
Loading…
Reference in New Issue
Block a user