diff --git a/mdadm-3.0-foreign.patch b/mdadm-3.0-foreign.patch new file mode 100644 index 0000000..f2686fd --- /dev/null +++ b/mdadm-3.0-foreign.patch @@ -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(); diff --git a/mdadm-3.0-mapfile.patch b/mdadm-3.0-mapfile.patch new file mode 100644 index 0000000..9e75e4d --- /dev/null +++ b/mdadm-3.0-mapfile.patch @@ -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 +@@ -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; + diff --git a/mdadm.rules b/mdadm.rules index ed762da..39fd0cd 100644 --- a/mdadm.rules +++ b/mdadm.rules @@ -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}'" diff --git a/mdadm.spec b/mdadm.spec index 9f5b1ba..a4f8620 100644 --- a/mdadm.spec +++ b/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 - 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 - 3.0-0.devel3.2 - Change around the mdadm udev rules we ship to avoid a udev file conflict