- Slightly tweak the udev rules to make sure we don't start arrays while
running in rc.sysinit...leave array starting to it instead - Modify mdadm to put its mapfile in /dev/md instead of /var/run/mdadm since at startup /var/run/mdadm is read-only by default and this breaks incremental assembly - Change how mdadm decides to assemble incremental devices using their preferred name or a random name to avoid possible conflicts when plugging a foreign array into a host
This commit is contained in:
parent
f37e19d541
commit
e4f4111870
192
mdadm-3.0-foreign.patch
Normal file
192
mdadm-3.0-foreign.patch
Normal file
@ -0,0 +1,192 @@
|
||||
--- mdadm-3.0-devel3/Incremental.c.foreign 2009-03-20 17:11:01.000000000 -0400
|
||||
+++ mdadm-3.0-devel3/Incremental.c 2009-03-20 17:11:39.000000000 -0400
|
||||
@@ -48,8 +48,10 @@ int Incremental(char *devname, int verbo
|
||||
* 2/ Find metadata, reject if none appropriate (check
|
||||
* version/name from args)
|
||||
* 3/ Check if there is a match in mdadm.conf
|
||||
- * 3a/ if not, check for homehost match. If no match, assemble as
|
||||
- * a 'foreign' array.
|
||||
+ * 3a/ Evalutate the quality of match and whether or not we have a
|
||||
+ * conf file at all, and make a decision about whether or not
|
||||
+ * to allow this array to keep its preferred name based upon
|
||||
+ * that
|
||||
* 4/ Determine device number.
|
||||
* - If in mdadm.conf with std name, use that
|
||||
* - UUID in /dev/md/mdadm.map use that
|
||||
@@ -78,7 +80,7 @@ int Incremental(char *devname, int verbo
|
||||
*/
|
||||
struct stat stb;
|
||||
struct mdinfo info;
|
||||
- struct mddev_ident_s *array_list, *match;
|
||||
+ struct mddev_ident_s *array_list, *match, *match_uuid, *match_name;
|
||||
char chosen_name[1024];
|
||||
int rv;
|
||||
struct map_ent *mp, *map = NULL;
|
||||
@@ -150,24 +152,37 @@ int Incremental(char *devname, int verbo
|
||||
|
||||
array_list = conf_get_ident(NULL);
|
||||
match = NULL;
|
||||
+ match_uuid = NULL;
|
||||
+ match_name = NULL;
|
||||
for (; array_list; array_list = array_list->next) {
|
||||
+ /* Check for matching uuid, then drop through to check and see
|
||||
+ * if we also have a matching name, and to catch cases of
|
||||
+ * matching names without a corresponding uuid match */
|
||||
if (array_list->uuid_set &&
|
||||
same_uuid(array_list->uuid, info.uuid, st->ss->swapuuid)
|
||||
- == 0) {
|
||||
- if (verbose >= 2 && array_list->devname)
|
||||
+ != 0)
|
||||
+ match_uuid = array_list;
|
||||
+ else if (array_list->uuid_set && verbose >= 2 &&
|
||||
+ array_list->devname)
|
||||
fprintf(stderr, Name
|
||||
": UUID differs from %s.\n",
|
||||
array_list->devname);
|
||||
- continue;
|
||||
- }
|
||||
+ /* If we match name now and the entry has a uuid, it *must*
|
||||
+ * match. If we match name, but the entry *doesn't* have
|
||||
+ * a uuid set, save it off separately so we can tell if we
|
||||
+ * matched uuid, name, or both, and if both, if they were
|
||||
+ * the same entry */
|
||||
if (array_list->name[0] &&
|
||||
- strcasecmp(array_list->name, info.name) != 0) {
|
||||
- if (verbose >= 2 && array_list->devname)
|
||||
+ strcasecmp(array_list->name, info.name) == 0)
|
||||
+ match_name = array_list;
|
||||
+ else if (array_list->name[0] && verbose >= 2 &&
|
||||
+ array_list->devname)
|
||||
fprintf(stderr, Name
|
||||
": Name differs from %s.\n",
|
||||
array_list->devname);
|
||||
+ if ((!match_uuid || match == match_uuid) &&
|
||||
+ (!match_name || match == match_name))
|
||||
continue;
|
||||
- }
|
||||
if (array_list->devices &&
|
||||
!match_oneof(array_list->devices, devname)) {
|
||||
if (verbose >= 2 && array_list->devname)
|
||||
@@ -197,7 +212,13 @@ int Incremental(char *devname, int verbo
|
||||
/* FIXME, should I check raid_disks and level too?? */
|
||||
|
||||
if (match) {
|
||||
- if (verbose >= 0) {
|
||||
+ if (match_uuid != match_name) {
|
||||
+ if (match_uuid->devname)
|
||||
+ fprintf(stderr, Name ": more than one "
|
||||
+ "match for %s, using the UUID "
|
||||
+ "match\n", match_uuid->devname);
|
||||
+ match = match_uuid;
|
||||
+ } else if (verbose >= 0) {
|
||||
if (match->devname && array_list->devname)
|
||||
fprintf(stderr, Name
|
||||
": we match both %s and %s - cannot decide which to use.\n",
|
||||
@@ -205,23 +226,54 @@ int Incremental(char *devname, int verbo
|
||||
else
|
||||
fprintf(stderr, Name
|
||||
": multiple lines in mdadm.conf match\n");
|
||||
+ return 2;
|
||||
}
|
||||
- return 2;
|
||||
}
|
||||
match = array_list;
|
||||
}
|
||||
|
||||
- /* 3a/ if not, check for homehost match. If no match, continue
|
||||
- * but don't trust the 'name' in the array. Thus a 'random' minor
|
||||
- * number will be assigned, and the device name will be based
|
||||
- * on that. */
|
||||
- if (match)
|
||||
+ /* 3a/ Decide if we got a good match, two matches, no matches, or a
|
||||
+ * likely foreign match. I dropped the homehost test entirely because
|
||||
+ * it didn't seem to add any value whatsoever above and beyond what
|
||||
+ * these tests can do. */
|
||||
+ if (match_uuid == match_name)
|
||||
+ /* found in conf, both name and uuid match */
|
||||
trustworthy = LOCAL;
|
||||
- else if (homehost == NULL ||
|
||||
- st->ss->match_home(st, homehost) != 1)
|
||||
+ else if (match_uuid && match_name)
|
||||
+ /* found both a name and a uuid match, but not on the same
|
||||
+ * entry, so use a random name and assume UUID match was
|
||||
+ * correct but has a bad name just in case the one that
|
||||
+ * would match the matching name shows up with both a
|
||||
+ * matching name and a matching UUID */
|
||||
trustworthy = FOREIGN;
|
||||
- else
|
||||
- trustworthy = LOCAL;
|
||||
+ else if (!match_uuid && match_name) {
|
||||
+ /* no uuid match, but name match */
|
||||
+ if (match_name->uuid_set)
|
||||
+ /* oops, name that matched had a uuid, it just wasn't
|
||||
+ * right, assume there is a local device with both
|
||||
+ * a matching name and uuid, so this needs a random
|
||||
+ * name */
|
||||
+ trustworthy = FOREIGN;
|
||||
+ else
|
||||
+ /* matched name, and the matching entry in conf file
|
||||
+ * didn't include a uuid, and this uuid never showed
|
||||
+ * up anywhere else in the conf file, so consider it
|
||||
+ * a soft match and allow it...although users should
|
||||
+ * *REALLY* include the uuid on array lines in the
|
||||
+ * conf file */
|
||||
+ trustworthy = LOCAL;
|
||||
+ } else { /* no match at all */
|
||||
+ if (!conf_exists())
|
||||
+ /* If we don't even have a conf file, this is foreign,
|
||||
+ * but also not likely to conflict with anything
|
||||
+ * local, so let it keep its preferred name */
|
||||
+ trustworthy = LOCAL;
|
||||
+ else
|
||||
+ /* We have a conf file, this didn't match any uuids
|
||||
+ * or names, so also not likely to conflict, let it
|
||||
+ * keep its own name */
|
||||
+ trustworthy = LOCAL;
|
||||
+ }
|
||||
|
||||
/* There are three possible sources for 'autof': command line,
|
||||
* ARRAY line in mdadm.conf, or CREATE line in mdadm.conf.
|
||||
--- mdadm-3.0-devel3/mdadm.h.foreign 2009-03-10 01:39:41.000000000 -0400
|
||||
+++ mdadm-3.0-devel3/mdadm.h 2009-03-20 17:11:01.000000000 -0400
|
||||
@@ -785,6 +785,7 @@ extern mddev_dev_t conf_get_devs(void);
|
||||
extern int conf_test_dev(char *devname);
|
||||
extern struct createinfo *conf_get_create_info(void);
|
||||
extern void set_conffile(char *file);
|
||||
+extern int conf_exists(void);
|
||||
extern char *conf_get_mailaddr(void);
|
||||
extern char *conf_get_mailfrom(void);
|
||||
extern char *conf_get_program(void);
|
||||
--- mdadm-3.0-devel3/config.c.foreign 2009-03-10 01:39:41.000000000 -0400
|
||||
+++ mdadm-3.0-devel3/config.c 2009-03-20 17:11:01.000000000 -0400
|
||||
@@ -637,7 +637,7 @@ void homehostline(char *line)
|
||||
}
|
||||
}
|
||||
|
||||
-
|
||||
+int exists = 0;
|
||||
int loaded = 0;
|
||||
|
||||
static char *conffile = NULL;
|
||||
@@ -683,6 +683,7 @@ void load_conffile(void)
|
||||
if (f == NULL)
|
||||
return;
|
||||
|
||||
+ exists = 1;
|
||||
loaded = 1;
|
||||
while ((line=conf_line(f))) {
|
||||
switch(match_keyword(line)) {
|
||||
@@ -718,6 +719,13 @@ void load_conffile(void)
|
||||
/* printf("got file\n"); */
|
||||
}
|
||||
|
||||
+int conf_exists(void)
|
||||
+{
|
||||
+ if (!loaded)
|
||||
+ load_conffile();
|
||||
+ return exists;
|
||||
+}
|
||||
+
|
||||
char *conf_get_mailaddr(void)
|
||||
{
|
||||
load_conffile();
|
127
mdadm-3.0-mapfile.patch
Normal file
127
mdadm-3.0-mapfile.patch
Normal file
@ -0,0 +1,127 @@
|
||||
--- mdadm-3.0-devel3/Incremental.c.dev 2009-03-20 13:19:35.000000000 -0400
|
||||
+++ mdadm-3.0-devel3/Incremental.c 2009-03-20 13:20:01.000000000 -0400
|
||||
@@ -52,7 +52,7 @@ int Incremental(char *devname, int verbo
|
||||
* a 'foreign' array.
|
||||
* 4/ Determine device number.
|
||||
* - If in mdadm.conf with std name, use that
|
||||
- * - UUID in /var/run/mdadm.map use that
|
||||
+ * - UUID in /dev/md/mdadm.map use that
|
||||
* - If name is suggestive, use that. unless in use with different uuid.
|
||||
* - Choose a free, high number.
|
||||
* - Use a partitioned device unless strong suggestion not to.
|
||||
@@ -67,7 +67,7 @@ int Incremental(char *devname, int verbo
|
||||
* - check one drive in array to make sure metadata is a reasonably
|
||||
* close match. Reject if not (e.g. different type)
|
||||
* - add the device
|
||||
- * 6/ Make sure /var/run/mdadm.map contains this array.
|
||||
+ * 6/ Make sure /dev/md/mdadm.map contains this array.
|
||||
* 7/ Is there enough devices to possibly start the array?
|
||||
* For a container, this means running Incremental_container.
|
||||
* 7a/ if not, finish with success.
|
||||
@@ -315,7 +315,7 @@ int Incremental(char *devname, int verbo
|
||||
}
|
||||
info.array.working_disks = 1;
|
||||
sysfs_free(sra);
|
||||
- /* 6/ Make sure /var/run/mdadm.map contains this array. */
|
||||
+ /* 6/ Make sure /dev/md/mdadm.map contains this array. */
|
||||
map_update(&map, fd2devnum(mdfd),
|
||||
info.text_version,
|
||||
info.uuid, chosen_name);
|
||||
--- mdadm-3.0-devel3/mapfile.c.dev 2009-03-20 13:16:27.000000000 -0400
|
||||
+++ mdadm-3.0-devel3/mapfile.c 2009-03-20 13:18:37.000000000 -0400
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * mapfile - manage /var/run/mdadm.map. Part of:
|
||||
+ * mapfile - manage /dev/md/mdadm.map. Part of:
|
||||
* mdadm - manage Linux "md" devices aka RAID arrays.
|
||||
*
|
||||
* Copyright (C) 2006 Neil Brown <neilb@suse.de>
|
||||
@@ -28,7 +28,7 @@
|
||||
* Australia
|
||||
*/
|
||||
|
||||
-/* /var/run/mdadm.map is used to track arrays being created in --incremental
|
||||
+/* /dev/md/mdadm.map is used to track arrays being created in --incremental
|
||||
* more. It particularly allows lookup from UUID to array device, but
|
||||
* also allows the array device name to be easily found.
|
||||
*
|
||||
@@ -50,9 +50,9 @@ int map_write(struct map_ent *mel)
|
||||
int err;
|
||||
int subdir = 1;
|
||||
|
||||
- f = fopen("/var/run/mdadm/map.new", "w");
|
||||
+ f = fopen("/dev/md/mdadm/map.new", "w");
|
||||
if (!f) {
|
||||
- f = fopen("/var/run/mdadm.map.new", "w");
|
||||
+ f = fopen("/dev/md/mdadm.map.new", "w");
|
||||
subdir = 0;
|
||||
}
|
||||
if (!f)
|
||||
@@ -74,17 +74,17 @@ int map_write(struct map_ent *mel)
|
||||
fclose(f);
|
||||
if (err) {
|
||||
if (subdir)
|
||||
- unlink("/var/run/mdadm/map.new");
|
||||
+ unlink("/dev/md/mdadm/map.new");
|
||||
else
|
||||
- unlink("/var/run/mdadm.map.new");
|
||||
+ unlink("/dev/md/mdadm.map.new");
|
||||
return 0;
|
||||
}
|
||||
if (subdir)
|
||||
- return rename("/var/run/mdadm/map.new",
|
||||
- "/var/run/mdadm/map") == 0;
|
||||
+ return rename("/dev/md/mdadm/map.new",
|
||||
+ "/dev/md/mdadm/map") == 0;
|
||||
else
|
||||
- return rename("/var/run/mdadm.map.new",
|
||||
- "/var/run/mdadm.map") == 0;
|
||||
+ return rename("/dev/md/mdadm.map.new",
|
||||
+ "/dev/md/mdadm.map") == 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,9 +93,9 @@ static int lsubdir = 0;
|
||||
int map_lock(struct map_ent **melp)
|
||||
{
|
||||
if (lfd < 0) {
|
||||
- lfd = open("/var/run/mdadm/map.lock", O_CREAT|O_RDWR, 0600);
|
||||
+ lfd = open("/dev/md/mdadm/map.lock", O_CREAT|O_RDWR, 0600);
|
||||
if (lfd < 0) {
|
||||
- lfd = open("/var/run/mdadm.map.lock", O_CREAT|O_RDWR, 0600);
|
||||
+ lfd = open("/dev/md/mdadm.map.lock", O_CREAT|O_RDWR, 0600);
|
||||
lsubdir = 0;
|
||||
} else
|
||||
lsubdir = 1;
|
||||
@@ -118,9 +118,9 @@ void map_unlock(struct map_ent **melp)
|
||||
if (lfd >= 0)
|
||||
close(lfd);
|
||||
if (lsubdir)
|
||||
- unlink("/var/run/mdadm/map.lock");
|
||||
+ unlink("/dev/md/mdadm/map.lock");
|
||||
else
|
||||
- unlink("/var/run/mdadm.map.lock");
|
||||
+ unlink("/dev/md/mdadm.map.lock");
|
||||
lfd = -1;
|
||||
}
|
||||
|
||||
@@ -149,15 +149,15 @@ void map_read(struct map_ent **melp)
|
||||
|
||||
*melp = NULL;
|
||||
|
||||
- f = fopen("/var/run/mdadm/map", "r");
|
||||
+ f = fopen("/dev/md/mdadm/map", "r");
|
||||
if (!f)
|
||||
- f = fopen("/var/run/mdadm.map", "r");
|
||||
+ f = fopen("/dev/md/mdadm.map", "r");
|
||||
if (!f) {
|
||||
RebuildMap();
|
||||
- f = fopen("/var/run/mdadm/map", "r");
|
||||
+ f = fopen("/dev/md/mdadm/map", "r");
|
||||
}
|
||||
if (!f)
|
||||
- f = fopen("/var/run/mdadm.map", "r");
|
||||
+ f = fopen("/dev/md/mdadm.map", "r");
|
||||
if (!f)
|
||||
return;
|
||||
|
@ -4,5 +4,5 @@
|
||||
|
||||
SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="linux_raid_member", \
|
||||
IMPORT{program}="/sbin/mdadm --examine --export $tempnode", \
|
||||
RUN+="/sbin/mdadm --incremental $env{DEVNAME}"
|
||||
RUN+="/bin/bash -c '[ ! -f /dev/.in_sysinit ] && mdadm -I $env{DEVNAME}'"
|
||||
|
||||
|
16
mdadm.spec
16
mdadm.spec
@ -1,7 +1,7 @@
|
||||
Summary: The mdadm program controls Linux md devices (software RAID arrays)
|
||||
Name: mdadm
|
||||
Version: 3.0
|
||||
Release: 0.devel3.2%{?dist}
|
||||
Release: 0.devel3.3%{?dist}
|
||||
Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}-devel3.tar.bz2
|
||||
Source1: mdmonitor.init
|
||||
Source2: raid-check
|
||||
@ -9,6 +9,8 @@ Source3: mdadm.rules
|
||||
Patch1: mdadm-2.5.2-static.patch
|
||||
Patch2: mdadm-3.0-cast.patch
|
||||
Patch3: mdadm-3.0-incremental.patch
|
||||
Patch4: mdadm-3.0-mapfile.patch
|
||||
Patch5: mdadm-3.0-foreign.patch
|
||||
URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/
|
||||
License: GPLv2+
|
||||
Group: System Environment/Base
|
||||
@ -32,6 +34,8 @@ file can be used to help with some common tasks.
|
||||
%patch1 -p1 -b .static
|
||||
%patch2 -p1 -b .cast
|
||||
%patch3 -p1 -b .incremental
|
||||
%patch4 -p1 -b .mapfile
|
||||
%patch5 -p1 -b .foreign
|
||||
|
||||
%build
|
||||
make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" SYSCONFDIR="%{_sysconfdir}" mdadm.static mdadm mdmon
|
||||
@ -83,6 +87,16 @@ fi
|
||||
%attr(0700,root,root) %dir /var/run/mdadm
|
||||
|
||||
%changelog
|
||||
* Fri Mar 20 2009 Doug Ledford <dledford@redhat.com> - 3.0-0.devel3.3
|
||||
- Slightly tweak the udev rules to make sure we don't start arrays
|
||||
while running in rc.sysinit...leave array starting to it instead
|
||||
- Modify mdadm to put its mapfile in /dev/md instead of /var/run/mdadm
|
||||
since at startup /var/run/mdadm is read-only by default and this
|
||||
breaks incremental assembly
|
||||
- Change how mdadm decides to assemble incremental devices using their
|
||||
preferred name or a random name to avoid possible conflicts when plugging
|
||||
a foreign array into a host
|
||||
|
||||
* Wed Mar 18 2009 Doug Ledford <dledford@redhat.com> - 3.0-0.devel3.2
|
||||
- Change around the mdadm udev rules we ship to avoid a udev file conflict
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user