Merge lp:~xnox/ubuntu/quantal/mdadm/merge into lp:~xnox/ubuntu/quantal/mdadm/quantal

Proposed by Dimitri John Ledkov
Status: Merged
Merge reported by: Dimitri John Ledkov
Merged at revision: not available
Proposed branch: lp:~xnox/ubuntu/quantal/mdadm/merge
Merge into: lp:~xnox/ubuntu/quantal/mdadm/quantal
Diff against target: 24674 lines (+7902/-9243)
110 files modified
.pc/applied-patches (+0/-3)
.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/Assemble.c (+0/-1650)
.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/ReadMe.c (+0/-602)
.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/config.c (+0/-1131)
.pc/debian-conffile-location.diff/Makefile (+287/-0)
.pc/debian-conffile-location.diff/ReadMe.c (+608/-0)
.pc/debian-conffile-location.diff/mdadm.8.in (+2899/-0)
.pc/debian-conffile-location.diff/mdadm.conf.5 (+581/-0)
.pc/debian-conffile-location.diff/mdassemble.8 (+65/-0)
.pc/debian-no-Werror.diff/Makefile (+287/-0)
.pc/debian/conffile-location.diff/Makefile (+0/-286)
.pc/debian/conffile-location.diff/ReadMe.c (+0/-602)
.pc/debian/conffile-location.diff/mdadm.8.in (+0/-2880)
.pc/debian/conffile-location.diff/mdadm.conf.5 (+0/-581)
.pc/debian/conffile-location.diff/mdassemble.8 (+0/-65)
.pc/debian/no-Werror.diff/Makefile (+0/-286)
.pc/sha1-includes.diff/sha1.h (+141/-0)
ANNOUNCE-3.2.4 (+144/-0)
ANNOUNCE-3.2.5 (+31/-0)
Assemble.c (+72/-23)
Create.c (+14/-4)
Detail.c (+8/-7)
Grow.c (+288/-84)
Incremental.c (+6/-8)
Makefile (+7/-6)
Manage.c (+94/-51)
Monitor.c (+19/-12)
ReadMe.c (+7/-1)
check.d/_numbers (+0/-1)
check.d/root_on_raid (+0/-35)
config.c (+6/-6)
debian/README.source (+0/-18)
debian/changelog (+102/-0)
debian/checkarray (+15/-0)
debian/control (+1/-1)
debian/initramfs/local-premount (+1/-0)
debian/mdadm.logcheck.ignore.server (+1/-1)
debian/patches/debian-conffile-location.diff (+126/-0)
debian/patches/debian-disable-udev-incr-assembly.diff (+27/-0)
debian/patches/debian-no-Werror.diff (+26/-0)
debian/patches/debian/conffile-location.diff (+0/-128)
debian/patches/debian/disable-udev-incr-assembly.diff (+0/-29)
debian/patches/debian/no-Werror.diff (+0/-28)
debian/patches/series (+4/-3)
debian/patches/sha1-includes.diff (+45/-0)
debian/po/ca.po (+7/-7)
debian/po/cs.po (+7/-7)
debian/po/da.po (+7/-7)
debian/po/de.po (+7/-7)
debian/po/es.po (+7/-7)
debian/po/eu.po (+7/-7)
debian/po/fi.po (+6/-6)
debian/po/fr.po (+7/-7)
debian/po/gl.po (+7/-7)
debian/po/it.po (+7/-7)
debian/po/ja.po (+7/-7)
debian/po/nl.po (+7/-7)
debian/po/pt.po (+7/-7)
debian/po/pt_BR.po (+39/-7)
debian/po/ru.po (+7/-7)
debian/po/sk.po (+7/-7)
debian/po/sv.po (+7/-7)
debian/po/templates.pot (+2/-2)
debian/po/vi.po (+7/-7)
debian/rules (+7/-17)
debian/source_mdadm.py (+5/-7)
inventory (+28/-26)
lib.c (+7/-2)
makedist (+4/-2)
managemon.c (+6/-0)
mapfile.c (+6/-11)
mdadm.8.in (+42/-23)
mdadm.c (+24/-6)
mdadm.conf-example (+1/-1)
mdadm.conf.5 (+1/-1)
mdadm.h (+38/-14)
mdadm.spec (+2/-2)
mdassemble.8 (+1/-1)
mdmon.8 (+13/-3)
mdmon.c (+48/-11)
mdopen.c (+1/-1)
monitor.c (+20/-16)
msg.c (+10/-0)
msg.h (+1/-0)
platform-intel.h (+1/-0)
sha1.c (+42/-49)
sha1.h (+64/-12)
super-ddf.c (+25/-16)
super-intel.c (+1159/-189)
super0.c (+18/-12)
super1.c (+169/-102)
sysfs.c (+13/-4)
test (+6/-5)
tests/00raid1 (+2/-2)
tests/05r1-bitmapfile (+3/-3)
tests/05r1-grow-external (+2/-2)
tests/05r1-grow-internal (+2/-2)
tests/05r1-grow-internal-1 (+2/-2)
tests/05r1-internalbitmap (+3/-3)
tests/05r1-internalbitmap-v1a (+3/-3)
tests/05r1-internalbitmap-v1b (+3/-3)
tests/05r1-internalbitmap-v1c (+3/-3)
tests/05r1-n3-bitmapfile (+3/-3)
tests/05r1-re-add (+2/-2)
tests/06wrmostly (+2/-2)
tests/07autoassemble (+4/-4)
tests/09imsm-assemble (+3/-3)
tests/09imsm-create-fail-rebuild (+1/-1)
tests/10ddf-create (+1/-1)
util.c (+30/-12)
To merge this branch: bzr merge lp:~xnox/ubuntu/quantal/mdadm/merge
Reviewer Review Type Date Requested Status
Dimitri John Ledkov Pending
Review via email: mp+110746@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.pc/applied-patches'
2--- .pc/applied-patches 1970-01-01 00:00:00 +0000
3+++ .pc/applied-patches 2012-06-18 08:55:05 +0000
4@@ -0,0 +1,4 @@
5+debian-conffile-location.diff
6+debian-no-Werror.diff
7+debian-changes-3.1.4-1+8efb9d1ubuntu4
8+sha1-includes.diff
9
10=== removed file '.pc/applied-patches'
11--- .pc/applied-patches 2012-05-22 16:40:37 +0000
12+++ .pc/applied-patches 1970-01-01 00:00:00 +0000
13@@ -1,3 +0,0 @@
14-debian/conffile-location.diff
15-debian/no-Werror.diff
16-debian-changes-3.1.4-1+8efb9d1ubuntu4
17
18=== removed directory '.pc/debian'
19=== added directory '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4'
20=== removed directory '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4'
21=== added file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/Assemble.c'
22--- .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/Assemble.c 1970-01-01 00:00:00 +0000
23+++ .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/Assemble.c 2012-06-18 08:55:05 +0000
24@@ -0,0 +1,1699 @@
25+/*
26+ * mdadm - manage Linux "md" devices aka RAID arrays.
27+ *
28+ * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
29+ *
30+ *
31+ * This program is free software; you can redistribute it and/or modify
32+ * it under the terms of the GNU General Public License as published by
33+ * the Free Software Foundation; either version 2 of the License, or
34+ * (at your option) any later version.
35+ *
36+ * This program is distributed in the hope that it will be useful,
37+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
38+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39+ * GNU General Public License for more details.
40+ *
41+ * You should have received a copy of the GNU General Public License
42+ * along with this program; if not, write to the Free Software
43+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
44+ *
45+ * Author: Neil Brown
46+ * Email: <neilb@suse.de>
47+ */
48+
49+#include "mdadm.h"
50+#include <ctype.h>
51+
52+static int name_matches(char *found, char *required, char *homehost)
53+{
54+ /* See if the name found matches the required name, possibly
55+ * prefixed with 'homehost'
56+ */
57+ char fnd[33];
58+
59+ strncpy(fnd, found, 32);
60+ fnd[32] = 0;
61+ if (strcmp(found, required)==0)
62+ return 1;
63+ if (homehost) {
64+ int l = strlen(homehost);
65+ if (l < 32 && fnd[l] == ':' &&
66+ strcmp(fnd+l+1, required)==0)
67+ return 1;
68+ }
69+ return 0;
70+}
71+
72+static int is_member_busy(char *metadata_version)
73+{
74+ /* check if the given member array is active */
75+ struct mdstat_ent *mdstat = mdstat_read(1, 0);
76+ struct mdstat_ent *ent;
77+ int busy = 0;
78+
79+ for (ent = mdstat; ent; ent = ent->next) {
80+ if (ent->metadata_version == NULL)
81+ continue;
82+ if (strncmp(ent->metadata_version, "external:", 9) != 0)
83+ continue;
84+ if (!is_subarray(&ent->metadata_version[9]))
85+ continue;
86+ /* Skip first char - it can be '/' or '-' */
87+ if (strcmp(&ent->metadata_version[10], metadata_version+1) == 0) {
88+ busy = 1;
89+ break;
90+ }
91+ }
92+ free_mdstat(mdstat);
93+
94+ return busy;
95+}
96+
97+static int ident_matches(struct mddev_ident *ident,
98+ struct mdinfo *content,
99+ struct supertype *tst,
100+ char *homehost,
101+ char *update, char *devname)
102+{
103+
104+ if (ident->uuid_set && (!update || strcmp(update, "uuid")!= 0) &&
105+ same_uuid(content->uuid, ident->uuid, tst->ss->swapuuid)==0 &&
106+ memcmp(content->uuid, uuid_zero, sizeof(int[4])) != 0) {
107+ if (devname)
108+ fprintf(stderr, Name ": %s has wrong uuid.\n",
109+ devname);
110+ return 0;
111+ }
112+ if (ident->name[0] && (!update || strcmp(update, "name")!= 0) &&
113+ name_matches(content->name, ident->name, homehost)==0) {
114+ if (devname)
115+ fprintf(stderr, Name ": %s has wrong name.\n",
116+ devname);
117+ return 0;
118+ }
119+ if (ident->super_minor != UnSet &&
120+ ident->super_minor != content->array.md_minor) {
121+ if (devname)
122+ fprintf(stderr, Name ": %s has wrong super-minor.\n",
123+ devname);
124+ return 0;
125+ }
126+ if (ident->level != UnSet &&
127+ ident->level != content->array.level) {
128+ if (devname)
129+ fprintf(stderr, Name ": %s has wrong raid level.\n",
130+ devname);
131+ return 0;
132+ }
133+ if (ident->raid_disks != UnSet &&
134+ ident->raid_disks!= content->array.raid_disks) {
135+ if (devname)
136+ fprintf(stderr, Name ": %s requires wrong number of drives.\n",
137+ devname);
138+ return 0;
139+ }
140+ if (ident->member && ident->member[0]) {
141+ /* content->text_version must match */
142+ char *s = strchr(content->text_version+1, '/');
143+ if (s == NULL) {
144+ if (devname)
145+ fprintf(stderr, Name ": %s is not a container and one is required.\n",
146+ devname);
147+ return 0;
148+ } else if (strcmp(ident->member, s+1) != 0) {
149+ if (devname)
150+ fprintf(stderr, Name ": skipping wrong member %s is %s\n",
151+ content->text_version, devname);
152+ return 0;
153+ }
154+ }
155+ return 1;
156+}
157+
158+
159+int Assemble(struct supertype *st, char *mddev,
160+ struct mddev_ident *ident,
161+ struct mddev_dev *devlist,
162+ char *backup_file, int invalid_backup,
163+ int readonly, int runstop,
164+ char *update, char *homehost, int require_homehost,
165+ int verbose, int force, int freeze_reshape)
166+{
167+ /*
168+ * The task of Assemble is to find a collection of
169+ * devices that should (according to their superblocks)
170+ * form an array, and to give this collection to the MD driver.
171+ * In Linux-2.4 and later, this involves submitting a
172+ * SET_ARRAY_INFO ioctl with no arg - to prepare
173+ * the array - and then submit a number of
174+ * ADD_NEW_DISK ioctls to add disks into
175+ * the array. Finally RUN_ARRAY might
176+ * be submitted to start the array.
177+ *
178+ * Much of the work of Assemble is in finding and/or
179+ * checking the disks to make sure they look right.
180+ *
181+ * If mddev is not set, then scan must be set and we
182+ * read through the config file for dev+uuid mapping
183+ * We recurse, setting mddev, for each device that
184+ * - isn't running
185+ * - has a valid uuid (or any uuid if !uuidset)
186+ *
187+ * If mddev is set, we try to determine state of md.
188+ * check version - must be at least 0.90.0
189+ * check kernel version. must be at least 2.4.
190+ * If not, we can possibly fall back on START_ARRAY
191+ * Try to GET_ARRAY_INFO.
192+ * If possible, give up
193+ * If not, try to STOP_ARRAY just to make sure
194+ *
195+ * If !uuidset and scan, look in conf-file for uuid
196+ * If not found, give up
197+ * If !devlist and scan and uuidset, get list of devs from conf-file
198+ *
199+ * For each device:
200+ * Check superblock - discard if bad
201+ * Check uuid (set if we don't have one) - discard if no match
202+ * Check superblock similarity if we have a superblock - discard if different
203+ * Record events, devicenum
204+ * This should give us a list of devices for the array
205+ * We should collect the most recent event number
206+ *
207+ * Count disks with recent enough event count
208+ * While force && !enough disks
209+ * Choose newest rejected disks, update event count
210+ * mark clean and rewrite superblock
211+ * If recent kernel:
212+ * SET_ARRAY_INFO
213+ * foreach device with recent events : ADD_NEW_DISK
214+ * if runstop == 1 || "enough" disks and runstop==0 -> RUN_ARRAY
215+ * If old kernel:
216+ * Check the device numbers in superblock are right
217+ * update superblock if any changes
218+ * START_ARRAY
219+ *
220+ */
221+ int mdfd;
222+ int clean;
223+ int auto_assem = (mddev == NULL && !ident->uuid_set &&
224+ ident->super_minor == UnSet && ident->name[0] == 0
225+ && (ident->container == NULL || ident->member == NULL));
226+ int old_linux = 0;
227+ int vers = vers; /* Keep gcc quite - it really is initialised */
228+ struct {
229+ char *devname;
230+ int uptodate; /* set once we decide that this device is as
231+ * recent as everything else in the array.
232+ */
233+ struct mdinfo i;
234+ } *devices;
235+ char *devmap;
236+ int *best = NULL; /* indexed by raid_disk */
237+ int bestcnt = 0;
238+ int devcnt = 0;
239+ unsigned int okcnt, sparecnt, rebuilding_cnt;
240+ unsigned int req_cnt;
241+ int i;
242+ int most_recent = 0;
243+ int chosen_drive;
244+ int change = 0;
245+ int inargv = 0;
246+ int report_missmatch;
247+#ifndef MDASSEMBLE
248+ int bitmap_done;
249+#endif
250+ int start_partial_ok = (runstop >= 0) &&
251+ (force || devlist==NULL || auto_assem);
252+ unsigned int num_devs;
253+ struct mddev_dev *tmpdev;
254+ struct mdinfo info;
255+ struct mdinfo *content = NULL;
256+ char *avail;
257+ int nextspare = 0;
258+ char *name = NULL;
259+ int trustworthy;
260+ char chosen_name[1024];
261+ struct domainlist *domains = NULL;
262+
263+ if (get_linux_version() < 2004000)
264+ old_linux = 1;
265+
266+ /*
267+ * If any subdevs are listed, then any that don't
268+ * match ident are discarded. Remainder must all match and
269+ * become the array.
270+ * If no subdevs, then we scan all devices in the config file, but
271+ * there must be something in the identity
272+ */
273+
274+ if (!devlist &&
275+ ident->uuid_set == 0 &&
276+ (ident->super_minor < 0 || ident->super_minor == UnSet) &&
277+ ident->name[0] == 0 &&
278+ (ident->container == NULL || ident->member == NULL) &&
279+ ident->devices == NULL) {
280+ fprintf(stderr, Name ": No identity information available for %s - cannot assemble.\n",
281+ mddev ? mddev : "further assembly");
282+ return 1;
283+ }
284+
285+ if (devlist == NULL)
286+ devlist = conf_get_devs();
287+ else if (mddev)
288+ inargv = 1;
289+
290+ report_missmatch = ((inargv && verbose >= 0) || verbose > 0);
291+ try_again:
292+ /* We come back here when doing auto-assembly and attempting some
293+ * set of devices failed. Those are now marked as ->used==2 and
294+ * we ignore them and try again
295+ */
296+
297+ tmpdev = devlist; num_devs = 0;
298+ while (tmpdev) {
299+ if (tmpdev->used)
300+ tmpdev->used = 2;
301+ else
302+ num_devs++;
303+ tmpdev = tmpdev->next;
304+ }
305+
306+ if (!st && ident->st) st = ident->st;
307+
308+ if (verbose>0)
309+ fprintf(stderr, Name ": looking for devices for %s\n",
310+ mddev ? mddev : "further assembly");
311+
312+ /* first walk the list of devices to find a consistent set
313+ * that match the criterea, if that is possible.
314+ * We flag the ones we like with 'used'.
315+ */
316+ for (tmpdev = devlist;
317+ tmpdev;
318+ tmpdev = tmpdev ? tmpdev->next : NULL) {
319+ char *devname = tmpdev->devname;
320+ int dfd;
321+ struct stat stb;
322+ struct supertype *tst;
323+ struct dev_policy *pol = NULL;
324+ int found_container = 0;
325+
326+ if (tmpdev->used > 1) continue;
327+
328+ if (ident->devices &&
329+ !match_oneof(ident->devices, devname)) {
330+ if (report_missmatch)
331+ fprintf(stderr, Name ": %s is not one of %s\n", devname, ident->devices);
332+ continue;
333+ }
334+
335+ tst = dup_super(st);
336+
337+ dfd = dev_open(devname, O_RDONLY);
338+ if (dfd < 0) {
339+ if (report_missmatch)
340+ fprintf(stderr, Name ": cannot open device %s: %s\n",
341+ devname, strerror(errno));
342+ tmpdev->used = 2;
343+ } else if (fstat(dfd, &stb)< 0) {
344+ /* Impossible! */
345+ fprintf(stderr, Name ": fstat failed for %s: %s\n",
346+ devname, strerror(errno));
347+ tmpdev->used = 2;
348+ } else if ((stb.st_mode & S_IFMT) != S_IFBLK) {
349+ fprintf(stderr, Name ": %s is not a block device.\n",
350+ devname);
351+ tmpdev->used = 2;
352+ } else if (must_be_container(dfd)) {
353+ if (st) {
354+ /* already found some components, this cannot
355+ * be another one.
356+ */
357+ if (report_missmatch)
358+ fprintf(stderr, Name ": %s is a container, but we are looking for components\n",
359+ devname);
360+ tmpdev->used = 2;
361+#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
362+ } if (!tst && (tst = super_by_fd(dfd, NULL)) == NULL) {
363+ if (report_missmatch)
364+ fprintf(stderr, Name ": not a recognisable container: %s\n",
365+ devname);
366+ tmpdev->used = 2;
367+#endif
368+ } else if (!tst->ss->load_container
369+ || tst->ss->load_container(tst, dfd, NULL)) {
370+ if (report_missmatch)
371+ fprintf(stderr, Name ": no correct container type: %s\n",
372+ devname);
373+ tmpdev->used = 2;
374+ } else if (auto_assem &&
375+ !conf_test_metadata(tst->ss->name, (pol = devnum_policy(stb.st_rdev)),
376+ tst->ss->match_home(tst, homehost) == 1)) {
377+ if (report_missmatch)
378+ fprintf(stderr, Name ": %s has metadata type %s for which "
379+ "auto-assembly is disabled\n",
380+ devname, tst->ss->name);
381+ tmpdev->used = 2;
382+ } else
383+ found_container = 1;
384+ } else {
385+ if (!tst && (tst = guess_super(dfd)) == NULL) {
386+ if (report_missmatch)
387+ fprintf(stderr, Name ": no recogniseable superblock on %s\n",
388+ devname);
389+ tmpdev->used = 2;
390+ } else if (tst->ss->load_super(tst,dfd, NULL)) {
391+ if (report_missmatch)
392+ fprintf(stderr, Name ": no RAID superblock on %s\n",
393+ devname);
394+ tmpdev->used = 2;
395+ } else if (tst->ss->compare_super == NULL) {
396+ if (report_missmatch)
397+ fprintf(stderr, Name ": Cannot assemble %s metadata on %s\n",
398+ tst->ss->name, devname);
399+ tmpdev->used = 2;
400+ } else if (auto_assem && st == NULL &&
401+ !conf_test_metadata(tst->ss->name, (pol = devnum_policy(stb.st_rdev)),
402+ tst->ss->match_home(tst, homehost) == 1)) {
403+ if (report_missmatch)
404+ fprintf(stderr, Name ": %s has metadata type %s for which "
405+ "auto-assembly is disabled\n",
406+ devname, tst->ss->name);
407+ tmpdev->used = 2;
408+ }
409+ }
410+ if (dfd >= 0) close(dfd);
411+ if (tmpdev->used == 2) {
412+ if (auto_assem || !inargv)
413+ /* Ignore unrecognised devices during auto-assembly */
414+ goto loop;
415+ if (ident->uuid_set || ident->name[0] ||
416+ ident->super_minor != UnSet)
417+ /* Ignore unrecognised device if looking for
418+ * specific array */
419+ goto loop;
420+
421+
422+ fprintf(stderr, Name ": %s has no superblock - assembly aborted\n",
423+ devname);
424+ if (st)
425+ st->ss->free_super(st);
426+ dev_policy_free(pol);
427+ domain_free(domains);
428+ return 1;
429+ }
430+
431+ if (found_container) {
432+ /* tmpdev is a container. We need to be either
433+ * looking for a member, or auto-assembling
434+ */
435+ /* should be safe to try an exclusive open now, we
436+ * have rejected anything that some other mdadm might
437+ * be looking at
438+ */
439+ dfd = dev_open(devname, O_RDONLY | O_EXCL);
440+ if (dfd < 0) {
441+ if (report_missmatch)
442+ fprintf(stderr, Name ": %s is busy - skipping\n", devname);
443+ goto loop;
444+ }
445+ close(dfd);
446+
447+ if (ident->container) {
448+ if (ident->container[0] == '/' &&
449+ !same_dev(ident->container, devname)) {
450+ if (report_missmatch)
451+ fprintf(stderr, Name ": %s is not the container required (%s)\n",
452+ devname, ident->container);
453+ goto loop;
454+ }
455+ if (ident->container[0] != '/') {
456+ /* we have a uuid */
457+ int uuid[4];
458+
459+ content = &info;
460+ tst->ss->getinfo_super(tst, content, NULL);
461+
462+ if (!parse_uuid(ident->container, uuid) ||
463+ !same_uuid(content->uuid, uuid, tst->ss->swapuuid)) {
464+ if (report_missmatch)
465+ fprintf(stderr, Name ": %s has wrong UUID to be required container\n",
466+ devname);
467+ goto loop;
468+ }
469+ }
470+ }
471+ /* It is worth looking inside this container.
472+ */
473+ if (verbose > 0)
474+ fprintf(stderr, Name ": looking in container %s\n",
475+ devname);
476+
477+ for (content = tst->ss->container_content(tst, NULL);
478+ content;
479+ content = content->next) {
480+
481+ if (!ident_matches(ident, content, tst,
482+ homehost, update,
483+ report_missmatch ? devname : NULL))
484+ /* message already printed */;
485+ else if (is_member_busy(content->text_version)) {
486+ if (report_missmatch)
487+ fprintf(stderr, Name ": member %s in %s is already assembled\n",
488+ content->text_version,
489+ devname);
490+ } else if (content->array.state & (1<<MD_SB_BLOCK_VOLUME)) {
491+ /* do not assemble arrays with unsupported configurations */
492+ fprintf(stderr, Name ": Cannot activate member %s in %s.\n",
493+ content->text_version,
494+ devname);
495+ } else
496+ break;
497+ }
498+ if (!content) {
499+ tmpdev->used = 2;
500+ goto loop; /* empty container */
501+ }
502+
503+ st = tst; tst = NULL;
504+ if (!auto_assem && inargv && tmpdev->next != NULL) {
505+ fprintf(stderr, Name ": %s is a container, but is not "
506+ "only device given: confused and aborting\n",
507+ devname);
508+ st->ss->free_super(st);
509+ dev_policy_free(pol);
510+ domain_free(domains);
511+ return 1;
512+ }
513+ if (verbose > 0)
514+ fprintf(stderr, Name ": found match on member %s in %s\n",
515+ content->text_version, devname);
516+
517+ /* make sure we finished the loop */
518+ tmpdev = NULL;
519+ goto loop;
520+ } else {
521+
522+ content = &info;
523+ tst->ss->getinfo_super(tst, content, NULL);
524+
525+ if (!ident_matches(ident, content, tst,
526+ homehost, update,
527+ report_missmatch ? devname : NULL))
528+ goto loop;
529+
530+ /* should be safe to try an exclusive open now, we
531+ * have rejected anything that some other mdadm might
532+ * be looking at
533+ */
534+ dfd = dev_open(devname, O_RDONLY | O_EXCL);
535+ if (dfd < 0) {
536+ if (report_missmatch)
537+ fprintf(stderr, Name ": %s is busy - skipping\n", devname);
538+ goto loop;
539+ }
540+ close(dfd);
541+
542+ if (st == NULL)
543+ st = dup_super(tst);
544+ if (st->minor_version == -1)
545+ st->minor_version = tst->minor_version;
546+
547+ if (memcmp(content->uuid, uuid_zero,
548+ sizeof(int[4])) == 0) {
549+ /* this is a floating spare. It cannot define
550+ * an array unless there are no more arrays of
551+ * this type to be found. It can be included
552+ * in an array of this type though.
553+ */
554+ tmpdev->used = 3;
555+ goto loop;
556+ }
557+
558+ if (st->ss != tst->ss ||
559+ st->minor_version != tst->minor_version ||
560+ st->ss->compare_super(st, tst) != 0) {
561+ /* Some mismatch. If exactly one array matches this host,
562+ * we can resolve on that one.
563+ * Or, if we are auto assembling, we just ignore the second
564+ * for now.
565+ */
566+ if (auto_assem)
567+ goto loop;
568+ if (homehost) {
569+ int first = st->ss->match_home(st, homehost);
570+ int last = tst->ss->match_home(tst, homehost);
571+ if (first != last &&
572+ (first == 1 || last == 1)) {
573+ /* We can do something */
574+ if (first) {/* just ignore this one */
575+ if (report_missmatch)
576+ fprintf(stderr, Name ": %s misses out due to wrong homehost\n",
577+ devname);
578+ goto loop;
579+ } else { /* reject all those sofar */
580+ struct mddev_dev *td;
581+ if (report_missmatch)
582+ fprintf(stderr, Name ": %s overrides previous devices due to good homehost\n",
583+ devname);
584+ for (td=devlist; td != tmpdev; td=td->next)
585+ if (td->used == 1)
586+ td->used = 0;
587+ tmpdev->used = 1;
588+ goto loop;
589+ }
590+ }
591+ }
592+ fprintf(stderr, Name ": superblock on %s doesn't match others - assembly aborted\n",
593+ devname);
594+ tst->ss->free_super(tst);
595+ st->ss->free_super(st);
596+ dev_policy_free(pol);
597+ domain_free(domains);
598+ return 1;
599+ }
600+ tmpdev->used = 1;
601+ }
602+ loop:
603+ /* Collect domain information from members only */
604+ if (tmpdev && tmpdev->used == 1) {
605+ if (!pol)
606+ pol = devnum_policy(stb.st_rdev);
607+ domain_merge(&domains, pol, tst?tst->ss->name:NULL);
608+ }
609+ dev_policy_free(pol);
610+ pol = NULL;
611+ if (tst)
612+ tst->ss->free_super(tst);
613+ }
614+
615+ /* Check if we found some imsm spares but no members */
616+ if ((auto_assem ||
617+ (ident->uuid_set &&
618+ memcmp(uuid_zero, ident->uuid,sizeof(uuid_zero)) == 0)) &&
619+ (!st || !st->sb))
620+ for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
621+ if (tmpdev->used != 3)
622+ continue;
623+ tmpdev->used = 1;
624+ content = &info;
625+
626+ if (!st->sb) {
627+ /* we need sb from one of the spares */
628+ int dfd = dev_open(tmpdev->devname, O_RDONLY);
629+ if (dfd < 0 ||
630+ st->ss->load_super(st, dfd, NULL))
631+ tmpdev->used = 2;
632+ if (dfd > 0)
633+ close(dfd);
634+ }
635+ }
636+
637+ /* Now reject spares that don't match domains of identified members */
638+ for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
639+ struct stat stb;
640+ if (tmpdev->used != 3)
641+ continue;
642+ if (stat(tmpdev->devname, &stb)< 0) {
643+ fprintf(stderr, Name ": fstat failed for %s: %s\n",
644+ tmpdev->devname, strerror(errno));
645+ tmpdev->used = 2;
646+ } else {
647+ struct dev_policy *pol = devnum_policy(stb.st_rdev);
648+ int dt = domain_test(domains, pol, NULL);
649+ if (inargv && dt != 0)
650+ /* take this spare as domains match
651+ * if there are any */
652+ tmpdev->used = 1;
653+ else if (!inargv && dt == 1)
654+ /* device wasn't explicitly listed, so need
655+ * explicit domain match - which we have */
656+ tmpdev->used = 1;
657+ else
658+ /* if domains don't match mark as unused */
659+ tmpdev->used = 0;
660+ dev_policy_free(pol);
661+ }
662+ }
663+ domain_free(domains);
664+
665+ if (!st || !st->sb || !content)
666+ return 2;
667+
668+ /* Now need to open the array device. Use create_mddev */
669+ if (content == &info)
670+ st->ss->getinfo_super(st, content, NULL);
671+
672+ trustworthy = FOREIGN;
673+ name = content->name;
674+ switch (st->ss->match_home(st, homehost)
675+ ?: st->ss->match_home(st, "any")) {
676+ case 1:
677+ trustworthy = LOCAL;
678+ name = strchr(content->name, ':');
679+ if (name)
680+ name++;
681+ else
682+ name = content->name;
683+ break;
684+ }
685+ if (!auto_assem)
686+ /* If the array is listed in mdadm.conf or on
687+ * command line, then we trust the name
688+ * even if the array doesn't look local
689+ */
690+ trustworthy = LOCAL;
691+
692+ if (name[0] == 0 &&
693+ content->array.level == LEVEL_CONTAINER) {
694+ name = content->text_version;
695+ trustworthy = METADATA;
696+ }
697+
698+ if (name[0] && trustworthy != LOCAL &&
699+ ! require_homehost &&
700+ conf_name_is_free(name))
701+ trustworthy = LOCAL;
702+
703+ if (trustworthy == LOCAL &&
704+ strchr(name, ':'))
705+ /* Ignore 'host:' prefix of name */
706+ name = strchr(name, ':')+1;
707+
708+ mdfd = create_mddev(mddev, name, ident->autof, trustworthy,
709+ chosen_name);
710+ if (mdfd < 0) {
711+ st->ss->free_super(st);
712+ if (auto_assem)
713+ goto try_again;
714+ return 1;
715+ }
716+ mddev = chosen_name;
717+ vers = md_get_version(mdfd);
718+ if (vers < 9000) {
719+ fprintf(stderr, Name ": Assemble requires driver version 0.90.0 or later.\n"
720+ " Upgrade your kernel or try --build\n");
721+ close(mdfd);
722+ return 1;
723+ }
724+ if (mddev_busy(fd2devnum(mdfd))) {
725+ fprintf(stderr, Name ": %s already active, cannot restart it!\n",
726+ mddev);
727+ for (tmpdev = devlist ;
728+ tmpdev && tmpdev->used != 1;
729+ tmpdev = tmpdev->next)
730+ ;
731+ if (tmpdev && auto_assem)
732+ fprintf(stderr, Name ": %s needed for %s...\n",
733+ mddev, tmpdev->devname);
734+ close(mdfd);
735+ mdfd = -3;
736+ st->ss->free_super(st);
737+ if (auto_assem)
738+ goto try_again;
739+ return 1;
740+ }
741+ ioctl(mdfd, STOP_ARRAY, NULL); /* just incase it was started but has no content */
742+
743+#ifndef MDASSEMBLE
744+ if (content != &info) {
745+ /* This is a member of a container. Try starting the array. */
746+ int err;
747+ err = assemble_container_content(st, mdfd, content, runstop,
748+ chosen_name, verbose,
749+ backup_file, freeze_reshape);
750+ close(mdfd);
751+ return err;
752+ }
753+ bitmap_done = 0;
754+#endif
755+ /* Ok, no bad inconsistancy, we can try updating etc */
756+ devices = malloc(num_devs * sizeof(*devices));
757+ devmap = calloc(num_devs * content->array.raid_disks, 1);
758+ for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) {
759+ char *devname = tmpdev->devname;
760+ struct stat stb;
761+ /* looks like a good enough match to update the super block if needed */
762+#ifndef MDASSEMBLE
763+ if (update) {
764+ int dfd;
765+ /* prepare useful information in info structures */
766+ struct stat stb2;
767+ struct supertype *tst;
768+ int err;
769+ fstat(mdfd, &stb2);
770+
771+ if (strcmp(update, "uuid")==0 &&
772+ !ident->uuid_set) {
773+ int rfd;
774+ if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
775+ read(rfd, ident->uuid, 16) != 16) {
776+ *(__u32*)(ident->uuid) = random();
777+ *(__u32*)(ident->uuid+1) = random();
778+ *(__u32*)(ident->uuid+2) = random();
779+ *(__u32*)(ident->uuid+3) = random();
780+ }
781+ if (rfd >= 0) close(rfd);
782+ }
783+ dfd = dev_open(devname, O_RDWR|O_EXCL);
784+
785+ tst = dup_super(st);
786+ if (dfd < 0 || tst->ss->load_super(tst, dfd, NULL) != 0) {
787+ fprintf(stderr, Name ": cannot re-read metadata from %s - aborting\n",
788+ devname);
789+ if (dfd >= 0)
790+ close(dfd);
791+ close(mdfd);
792+ free(devices);
793+ free(devmap);
794+ return 1;
795+ }
796+ tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
797+
798+ memcpy(content->uuid, ident->uuid, 16);
799+ strcpy(content->name, ident->name);
800+ content->array.md_minor = minor(stb2.st_rdev);
801+
802+ if (strcmp(update, "byteorder") == 0)
803+ err = 0;
804+ else
805+ err = tst->ss->update_super(tst, content, update,
806+ devname, verbose,
807+ ident->uuid_set,
808+ homehost);
809+ if (err < 0) {
810+ fprintf(stderr,
811+ Name ": --update=%s not understood"
812+ " for %s metadata\n",
813+ update, tst->ss->name);
814+ tst->ss->free_super(tst);
815+ free(tst);
816+ close(mdfd);
817+ close(dfd);
818+ free(devices);
819+ free(devmap);
820+ return 1;
821+ }
822+ if (strcmp(update, "uuid")==0 &&
823+ !ident->uuid_set) {
824+ ident->uuid_set = 1;
825+ memcpy(ident->uuid, content->uuid, 16);
826+ }
827+ if (tst->ss->store_super(tst, dfd))
828+ fprintf(stderr, Name ": Could not re-write superblock on %s.\n",
829+ devname);
830+ close(dfd);
831+
832+ if (strcmp(update, "uuid")==0 &&
833+ ident->bitmap_fd >= 0 && !bitmap_done) {
834+ if (bitmap_update_uuid(ident->bitmap_fd,
835+ content->uuid,
836+ tst->ss->swapuuid) != 0)
837+ fprintf(stderr, Name ": Could not update uuid on external bitmap.\n");
838+ else
839+ bitmap_done = 1;
840+ }
841+ tst->ss->free_super(tst);
842+ } else
843+#endif
844+ {
845+ struct supertype *tst = dup_super(st);
846+ int dfd;
847+ dfd = dev_open(devname, O_RDWR|O_EXCL);
848+
849+ if (dfd < 0 || tst->ss->load_super(tst, dfd, NULL) != 0) {
850+ fprintf(stderr, Name ": cannot re-read metadata from %s - aborting\n",
851+ devname);
852+ if (dfd >= 0)
853+ close(dfd);
854+ close(mdfd);
855+ free(devices);
856+ free(devmap);
857+ return 1;
858+ }
859+ tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
860+ tst->ss->free_super(tst);
861+ close(dfd);
862+ }
863+
864+ stat(devname, &stb);
865+
866+ if (verbose > 0)
867+ fprintf(stderr, Name ": %s is identified as a member of %s, slot %d.\n",
868+ devname, mddev, content->disk.raid_disk);
869+ devices[devcnt].devname = devname;
870+ devices[devcnt].uptodate = 0;
871+ devices[devcnt].i = *content;
872+ devices[devcnt].i.disk.major = major(stb.st_rdev);
873+ devices[devcnt].i.disk.minor = minor(stb.st_rdev);
874+ if (most_recent < devcnt) {
875+ if (devices[devcnt].i.events
876+ > devices[most_recent].i.events)
877+ most_recent = devcnt;
878+ }
879+ if (content->array.level == LEVEL_MULTIPATH)
880+ /* with multipath, the raid_disk from the superblock is meaningless */
881+ i = devcnt;
882+ else
883+ i = devices[devcnt].i.disk.raid_disk;
884+ if (i+1 == 0) {
885+ if (nextspare < content->array.raid_disks)
886+ nextspare = content->array.raid_disks;
887+ i = nextspare++;
888+ } else {
889+ if (i >= content->array.raid_disks &&
890+ i >= nextspare)
891+ nextspare = i+1;
892+ }
893+ if (i < 10000) {
894+ if (i >= bestcnt) {
895+ int newbestcnt = i+10;
896+ int *newbest = malloc(sizeof(int)*newbestcnt);
897+ int c;
898+ for (c=0; c < newbestcnt; c++)
899+ if (c < bestcnt)
900+ newbest[c] = best[c];
901+ else
902+ newbest[c] = -1;
903+ if (best)free(best);
904+ best = newbest;
905+ bestcnt = newbestcnt;
906+ }
907+ if (best[i] >=0 &&
908+ devices[best[i]].i.events
909+ == devices[devcnt].i.events
910+ && (devices[best[i]].i.disk.minor
911+ != devices[devcnt].i.disk.minor)
912+ && st->ss == &super0
913+ && content->array.level != LEVEL_MULTIPATH) {
914+ /* two different devices with identical superblock.
915+ * Could be a mis-detection caused by overlapping
916+ * partitions. fail-safe.
917+ */
918+ fprintf(stderr, Name ": WARNING %s and %s appear"
919+ " to have very similar superblocks.\n"
920+ " If they are really different, "
921+ "please --zero the superblock on one\n"
922+ " If they are the same or overlap,"
923+ " please remove one from %s.\n",
924+ devices[best[i]].devname, devname,
925+ inargv ? "the list" :
926+ "the\n DEVICE list in mdadm.conf"
927+ );
928+ close(mdfd);
929+ free(devices);
930+ free(devmap);
931+ return 1;
932+ }
933+ if (best[i] == -1
934+ || (devices[best[i]].i.events
935+ < devices[devcnt].i.events))
936+ best[i] = devcnt;
937+ }
938+ devcnt++;
939+ }
940+
941+ if (devcnt == 0) {
942+ fprintf(stderr, Name ": no devices found for %s\n",
943+ mddev);
944+ if (st)
945+ st->ss->free_super(st);
946+ close(mdfd);
947+ free(devices);
948+ free(devmap);
949+ return 1;
950+ }
951+
952+ if (update && strcmp(update, "byteorder")==0)
953+ st->minor_version = 90;
954+
955+ st->ss->getinfo_super(st, content, NULL);
956+ clean = content->array.state & 1;
957+
958+ /* now we have some devices that might be suitable.
959+ * I wonder how many
960+ */
961+ avail = malloc(content->array.raid_disks);
962+ memset(avail, 0, content->array.raid_disks);
963+ okcnt = 0;
964+ sparecnt=0;
965+ rebuilding_cnt=0;
966+ for (i=0; i< bestcnt; i++) {
967+ int j = best[i];
968+ int event_margin = 1; /* always allow a difference of '1'
969+ * like the kernel does
970+ */
971+ if (j < 0) continue;
972+ /* note: we ignore error flags in multipath arrays
973+ * as they don't make sense
974+ */
975+ if (content->array.level != LEVEL_MULTIPATH)
976+ if (!(devices[j].i.disk.state & (1<<MD_DISK_ACTIVE))) {
977+ if (!(devices[j].i.disk.state
978+ & (1<<MD_DISK_FAULTY))) {
979+ devices[j].uptodate = 1;
980+ sparecnt++;
981+ }
982+ continue;
983+ }
984+ /* If this device thinks that 'most_recent' has failed, then
985+ * we must reject this device.
986+ */
987+ if (j != most_recent &&
988+ content->array.raid_disks > 0 &&
989+ devices[most_recent].i.disk.raid_disk >= 0 &&
990+ devmap[j * content->array.raid_disks + devices[most_recent].i.disk.raid_disk] == 0) {
991+ if (verbose > -1)
992+ fprintf(stderr, Name ": ignoring %s as it reports %s as failed\n",
993+ devices[j].devname, devices[most_recent].devname);
994+ best[i] = -1;
995+ continue;
996+ }
997+ if (devices[j].i.events+event_margin >=
998+ devices[most_recent].i.events) {
999+ devices[j].uptodate = 1;
1000+ if (i < content->array.raid_disks) {
1001+ if (devices[j].i.recovery_start == MaxSector ||
1002+ (content->reshape_active &&
1003+ ((i >= content->array.raid_disks - content->delta_disks) ||
1004+ (i >= content->array.raid_disks - content->delta_disks - 1
1005+ && content->array.level == 4)))) {
1006+ okcnt++;
1007+ avail[i]=1;
1008+ } else
1009+ rebuilding_cnt++;
1010+ } else
1011+ sparecnt++;
1012+ }
1013+ }
1014+ free(devmap);
1015+ while (force &&
1016+ (!enough(content->array.level, content->array.raid_disks,
1017+ content->array.layout, 1,
1018+ avail)
1019+ ||
1020+ (content->reshape_active && content->delta_disks > 0 &&
1021+ !enough(content->array.level, (content->array.raid_disks
1022+ - content->delta_disks),
1023+ content->new_layout, 1,
1024+ avail)
1025+ ))) {
1026+ /* Choose the newest best drive which is
1027+ * not up-to-date, update the superblock
1028+ * and add it.
1029+ */
1030+ int fd;
1031+ struct supertype *tst;
1032+ unsigned long long current_events;
1033+ chosen_drive = -1;
1034+ for (i = 0; i < content->array.raid_disks && i < bestcnt; i++) {
1035+ int j = best[i];
1036+ if (j>=0 &&
1037+ !devices[j].uptodate &&
1038+ devices[j].i.recovery_start == MaxSector &&
1039+ (chosen_drive < 0 ||
1040+ devices[j].i.events
1041+ > devices[chosen_drive].i.events))
1042+ chosen_drive = j;
1043+ }
1044+ if (chosen_drive < 0)
1045+ break;
1046+ current_events = devices[chosen_drive].i.events;
1047+ add_another:
1048+ if (verbose >= 0)
1049+ fprintf(stderr, Name ": forcing event count in %s(%d) from %d upto %d\n",
1050+ devices[chosen_drive].devname,
1051+ devices[chosen_drive].i.disk.raid_disk,
1052+ (int)(devices[chosen_drive].i.events),
1053+ (int)(devices[most_recent].i.events));
1054+ fd = dev_open(devices[chosen_drive].devname, O_RDWR|O_EXCL);
1055+ if (fd < 0) {
1056+ fprintf(stderr, Name ": Couldn't open %s for write - not updating\n",
1057+ devices[chosen_drive].devname);
1058+ devices[chosen_drive].i.events = 0;
1059+ continue;
1060+ }
1061+ tst = dup_super(st);
1062+ if (tst->ss->load_super(tst,fd, NULL)) {
1063+ close(fd);
1064+ fprintf(stderr, Name ": RAID superblock disappeared from %s - not updating.\n",
1065+ devices[chosen_drive].devname);
1066+ devices[chosen_drive].i.events = 0;
1067+ continue;
1068+ }
1069+ content->events = devices[most_recent].i.events;
1070+ tst->ss->update_super(tst, content, "force-one",
1071+ devices[chosen_drive].devname, verbose,
1072+ 0, NULL);
1073+
1074+ if (tst->ss->store_super(tst, fd)) {
1075+ close(fd);
1076+ fprintf(stderr, Name ": Could not re-write superblock on %s\n",
1077+ devices[chosen_drive].devname);
1078+ devices[chosen_drive].i.events = 0;
1079+ tst->ss->free_super(tst);
1080+ continue;
1081+ }
1082+ close(fd);
1083+ devices[chosen_drive].i.events = devices[most_recent].i.events;
1084+ devices[chosen_drive].uptodate = 1;
1085+ avail[chosen_drive] = 1;
1086+ okcnt++;
1087+ tst->ss->free_super(tst);
1088+
1089+ /* If there are any other drives of the same vintage,
1090+ * add them in as well. We can't lose and we might gain
1091+ */
1092+ for (i = 0; i < content->array.raid_disks && i < bestcnt ; i++) {
1093+ int j = best[i];
1094+ if (j >= 0 &&
1095+ !devices[j].uptodate &&
1096+ devices[j].i.recovery_start == MaxSector &&
1097+ devices[j].i.events == current_events) {
1098+ chosen_drive = j;
1099+ goto add_another;
1100+ }
1101+ }
1102+ }
1103+
1104+ /* Now we want to look at the superblock which the kernel will base things on
1105+ * and compare the devices that we think are working with the devices that the
1106+ * superblock thinks are working.
1107+ * If there are differences and --force is given, then update this chosen
1108+ * superblock.
1109+ */
1110+ chosen_drive = -1;
1111+ st->ss->free_super(st);
1112+ for (i=0; chosen_drive < 0 && i<bestcnt; i++) {
1113+ int j = best[i];
1114+ int fd;
1115+
1116+ if (j<0)
1117+ continue;
1118+ if (!devices[j].uptodate)
1119+ continue;
1120+ if (devices[j].i.events < devices[most_recent].i.events)
1121+ continue;
1122+ chosen_drive = j;
1123+ if ((fd=dev_open(devices[j].devname, O_RDONLY|O_EXCL))< 0) {
1124+ fprintf(stderr, Name ": Cannot open %s: %s\n",
1125+ devices[j].devname, strerror(errno));
1126+ close(mdfd);
1127+ free(devices);
1128+ return 1;
1129+ }
1130+ if (st->ss->load_super(st,fd, NULL)) {
1131+ close(fd);
1132+ fprintf(stderr, Name ": RAID superblock has disappeared from %s\n",
1133+ devices[j].devname);
1134+ close(mdfd);
1135+ free(devices);
1136+ return 1;
1137+ }
1138+ close(fd);
1139+ }
1140+ if (st->sb == NULL) {
1141+ fprintf(stderr, Name ": No suitable drives found for %s\n", mddev);
1142+ close(mdfd);
1143+ free(devices);
1144+ return 1;
1145+ }
1146+ st->ss->getinfo_super(st, content, NULL);
1147+#ifndef MDASSEMBLE
1148+ sysfs_init(content, mdfd, 0);
1149+#endif
1150+ for (i=0; i<bestcnt; i++) {
1151+ int j = best[i];
1152+ unsigned int desired_state;
1153+
1154+ if (i < content->array.raid_disks)
1155+ desired_state = (1<<MD_DISK_ACTIVE) | (1<<MD_DISK_SYNC);
1156+ else
1157+ desired_state = 0;
1158+
1159+ if (j<0)
1160+ continue;
1161+ if (!devices[j].uptodate)
1162+ continue;
1163+
1164+ devices[j].i.disk.state = desired_state;
1165+ if (!(devices[j].i.array.state & 1))
1166+ clean = 0;
1167+
1168+ if (st->ss->update_super(st, &devices[j].i, "assemble", NULL,
1169+ verbose, 0, NULL)) {
1170+ if (force) {
1171+ if (verbose >= 0)
1172+ fprintf(stderr, Name ": "
1173+ "clearing FAULTY flag for device %d in %s for %s\n",
1174+ j, mddev, devices[j].devname);
1175+ change = 1;
1176+ } else {
1177+ if (verbose >= -1)
1178+ fprintf(stderr, Name ": "
1179+ "device %d in %s has wrong state in superblock, but %s seems ok\n",
1180+ i, mddev, devices[j].devname);
1181+ }
1182+ }
1183+#if 0
1184+ if (!(super.disks[i].i.disk.state & (1 << MD_DISK_FAULTY))) {
1185+ fprintf(stderr, Name ": devices %d of %s is not marked FAULTY in superblock, but cannot be found\n",
1186+ i, mddev);
1187+ }
1188+#endif
1189+ }
1190+ if (force && !clean &&
1191+ !enough(content->array.level, content->array.raid_disks,
1192+ content->array.layout, clean,
1193+ avail)) {
1194+ change += st->ss->update_super(st, content, "force-array",
1195+ devices[chosen_drive].devname, verbose,
1196+ 0, NULL);
1197+ clean = 1;
1198+ }
1199+
1200+ if (change) {
1201+ int fd;
1202+ fd = dev_open(devices[chosen_drive].devname, O_RDWR|O_EXCL);
1203+ if (fd < 0) {
1204+ fprintf(stderr, Name ": Could not open %s for write - cannot Assemble array.\n",
1205+ devices[chosen_drive].devname);
1206+ close(mdfd);
1207+ free(devices);
1208+ return 1;
1209+ }
1210+ if (st->ss->store_super(st, fd)) {
1211+ close(fd);
1212+ fprintf(stderr, Name ": Could not re-write superblock on %s\n",
1213+ devices[chosen_drive].devname);
1214+ close(mdfd);
1215+ free(devices);
1216+ return 1;
1217+ }
1218+ if (verbose >= 0)
1219+ fprintf(stderr, Name ": Marking array %s as 'clean'\n",
1220+ mddev);
1221+ close(fd);
1222+ }
1223+
1224+ /* If we are in the middle of a reshape we may need to restore saved data
1225+ * that was moved aside due to the reshape overwriting live data
1226+ * The code of doing this lives in Grow.c
1227+ */
1228+#ifndef MDASSEMBLE
1229+ if (content->reshape_active) {
1230+ int err = 0;
1231+ int *fdlist = malloc(sizeof(int)* bestcnt);
1232+ if (verbose > 0)
1233+ fprintf(stderr, Name ":%s has an active reshape - checking "
1234+ "if critical section needs to be restored\n",
1235+ chosen_name);
1236+ for (i=0; i<bestcnt; i++) {
1237+ int j = best[i];
1238+ if (j >= 0) {
1239+ fdlist[i] = dev_open(devices[j].devname, O_RDWR|O_EXCL);
1240+ if (fdlist[i] < 0) {
1241+ fprintf(stderr, Name ": Could not open %s for write - cannot Assemble array.\n",
1242+ devices[j].devname);
1243+ err = 1;
1244+ break;
1245+ }
1246+ } else
1247+ fdlist[i] = -1;
1248+ }
1249+ if (!err) {
1250+ if (st->ss->external && st->ss->recover_backup)
1251+ err = st->ss->recover_backup(st, content);
1252+ else
1253+ err = Grow_restart(st, content, fdlist, bestcnt,
1254+ backup_file, verbose > 0);
1255+ if (err && invalid_backup) {
1256+ if (verbose > 0)
1257+ fprintf(stderr, Name ": continuing"
1258+ " without restoring backup\n");
1259+ err = 0;
1260+ }
1261+ }
1262+ while (i>0) {
1263+ i--;
1264+ if (fdlist[i]>=0) close(fdlist[i]);
1265+ }
1266+ if (err) {
1267+ fprintf(stderr, Name ": Failed to restore critical section for reshape, sorry.\n");
1268+ if (backup_file == NULL)
1269+ fprintf(stderr," Possibly you needed to specify the --backup-file\n");
1270+ close(mdfd);
1271+ free(devices);
1272+ return err;
1273+ }
1274+ }
1275+#endif
1276+ /* count number of in-sync devices according to the superblock.
1277+ * We must have this number to start the array without -s or -R
1278+ */
1279+ req_cnt = content->array.working_disks;
1280+
1281+ /* Almost ready to actually *do* something */
1282+ if (!old_linux) {
1283+ int rv;
1284+
1285+ /* First, fill in the map, so that udev can find our name
1286+ * as soon as we become active.
1287+ */
1288+ map_update(NULL, fd2devnum(mdfd), content->text_version,
1289+ content->uuid, chosen_name);
1290+
1291+ rv = set_array_info(mdfd, st, content);
1292+ if (rv) {
1293+ fprintf(stderr, Name ": failed to set array info for %s: %s\n",
1294+ mddev, strerror(errno));
1295+ ioctl(mdfd, STOP_ARRAY, NULL);
1296+ close(mdfd);
1297+ free(devices);
1298+ return 1;
1299+ }
1300+ if (ident->bitmap_fd >= 0) {
1301+ if (ioctl(mdfd, SET_BITMAP_FILE, ident->bitmap_fd) != 0) {
1302+ fprintf(stderr, Name ": SET_BITMAP_FILE failed.\n");
1303+ ioctl(mdfd, STOP_ARRAY, NULL);
1304+ close(mdfd);
1305+ free(devices);
1306+ return 1;
1307+ }
1308+ } else if (ident->bitmap_file) {
1309+ /* From config file */
1310+ int bmfd = open(ident->bitmap_file, O_RDWR);
1311+ if (bmfd < 0) {
1312+ fprintf(stderr, Name ": Could not open bitmap file %s\n",
1313+ ident->bitmap_file);
1314+ ioctl(mdfd, STOP_ARRAY, NULL);
1315+ close(mdfd);
1316+ free(devices);
1317+ return 1;
1318+ }
1319+ if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) {
1320+ fprintf(stderr, Name ": Failed to set bitmapfile for %s\n", mddev);
1321+ close(bmfd);
1322+ ioctl(mdfd, STOP_ARRAY, NULL);
1323+ close(mdfd);
1324+ free(devices);
1325+ return 1;
1326+ }
1327+ close(bmfd);
1328+ }
1329+
1330+ /* First, add the raid disks, but add the chosen one last */
1331+ for (i=0; i<= bestcnt; i++) {
1332+ int j;
1333+ if (i < bestcnt) {
1334+ j = best[i];
1335+ if (j == chosen_drive)
1336+ continue;
1337+ } else
1338+ j = chosen_drive;
1339+
1340+ if (j >= 0 /* && devices[j].uptodate */) {
1341+ int dfd = dev_open(devices[j].devname,
1342+ O_RDWR|O_EXCL);
1343+ if (dfd >= 0) {
1344+ remove_partitions(dfd);
1345+ close(dfd);
1346+ }
1347+ rv = add_disk(mdfd, st, content, &devices[j].i);
1348+
1349+ if (rv) {
1350+ fprintf(stderr, Name ": failed to add "
1351+ "%s to %s: %s\n",
1352+ devices[j].devname,
1353+ mddev,
1354+ strerror(errno));
1355+ if (i < content->array.raid_disks
1356+ || i == bestcnt)
1357+ okcnt--;
1358+ else
1359+ sparecnt--;
1360+ } else if (verbose > 0)
1361+ fprintf(stderr, Name ": added %s "
1362+ "to %s as %d%s\n",
1363+ devices[j].devname, mddev,
1364+ devices[j].i.disk.raid_disk,
1365+ devices[j].uptodate?"":
1366+ " (possibly out of date)");
1367+ } else if (verbose > 0 && i < content->array.raid_disks)
1368+ fprintf(stderr, Name ": no uptodate device for "
1369+ "slot %d of %s\n",
1370+ i, mddev);
1371+ }
1372+
1373+ if (content->array.level == LEVEL_CONTAINER) {
1374+ if (verbose >= 0) {
1375+ fprintf(stderr, Name ": Container %s has been "
1376+ "assembled with %d drive%s",
1377+ mddev, okcnt+sparecnt, okcnt+sparecnt==1?"":"s");
1378+ if (okcnt < (unsigned)content->array.raid_disks)
1379+ fprintf(stderr, " (out of %d)",
1380+ content->array.raid_disks);
1381+ fprintf(stderr, "\n");
1382+ }
1383+ st->ss->free_super(st);
1384+ sysfs_uevent(content, "change");
1385+ wait_for(chosen_name, mdfd);
1386+ close(mdfd);
1387+ free(devices);
1388+ return 0;
1389+ }
1390+
1391+ if (runstop == 1 ||
1392+ (runstop <= 0 &&
1393+ ( enough(content->array.level, content->array.raid_disks,
1394+ content->array.layout, clean, avail) &&
1395+ (okcnt + rebuilding_cnt >= req_cnt || start_partial_ok)
1396+ ))) {
1397+ /* This array is good-to-go.
1398+ * If a reshape is in progress then we might need to
1399+ * continue monitoring it. In that case we start
1400+ * it read-only and let the grow code make it writable.
1401+ */
1402+ int rv;
1403+#ifndef MDASSEMBLE
1404+ if (content->reshape_active &&
1405+ content->delta_disks <= 0) {
1406+ rv = sysfs_set_str(content, NULL,
1407+ "array_state", "readonly");
1408+ if (rv == 0)
1409+ rv = Grow_continue(mdfd, st, content,
1410+ backup_file,
1411+ freeze_reshape);
1412+ } else
1413+#endif
1414+ rv = ioctl(mdfd, RUN_ARRAY, NULL);
1415+ if (rv == 0) {
1416+ if (verbose >= 0) {
1417+ fprintf(stderr, Name ": %s has been started with %d drive%s",
1418+ mddev, okcnt, okcnt==1?"":"s");
1419+ if (okcnt < (unsigned)content->array.raid_disks)
1420+ fprintf(stderr, " (out of %d)", content->array.raid_disks);
1421+ if (rebuilding_cnt)
1422+ fprintf(stderr, "%s %d rebuilding", sparecnt?",":" and", rebuilding_cnt);
1423+ if (sparecnt)
1424+ fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
1425+ fprintf(stderr, ".\n");
1426+ }
1427+ if (content->reshape_active &&
1428+ content->array.level >= 4 &&
1429+ content->array.level <= 6) {
1430+ /* might need to increase the size
1431+ * of the stripe cache - default is 256
1432+ */
1433+ if (256 < 4 * (content->array.chunk_size/4096)) {
1434+ struct mdinfo *sra = sysfs_read(mdfd, 0, 0);
1435+ if (sra)
1436+ sysfs_set_num(sra, NULL,
1437+ "stripe_cache_size",
1438+ (4 * content->array.chunk_size / 4096) + 1);
1439+ sysfs_free(sra);
1440+ }
1441+ }
1442+ if (okcnt < (unsigned)content->array.raid_disks) {
1443+ /* If any devices did not get added
1444+ * because the kernel rejected them based
1445+ * on event count, try adding them
1446+ * again providing the action policy is
1447+ * 're-add' or greater. The bitmap
1448+ * might allow them to be included, or
1449+ * they will become spares.
1450+ */
1451+ for (i = 0; i < bestcnt; i++) {
1452+ int j = best[i];
1453+ if (j >= 0 && !devices[j].uptodate) {
1454+ if (!disk_action_allows(&devices[j].i, st->ss->name, act_re_add))
1455+ continue;
1456+ rv = add_disk(mdfd, st, content,
1457+ &devices[j].i);
1458+ if (rv == 0 && verbose >= 0)
1459+ fprintf(stderr,
1460+ Name ": %s has been re-added.\n",
1461+ devices[j].devname);
1462+ }
1463+ }
1464+ }
1465+ wait_for(mddev, mdfd);
1466+ close(mdfd);
1467+ if (auto_assem) {
1468+ int usecs = 1;
1469+ /* There is a nasty race with 'mdadm --monitor'.
1470+ * If it opens this device before we close it,
1471+ * it gets an incomplete open on which IO
1472+ * doesn't work and the capacity is
1473+ * wrong.
1474+ * If we reopen (to check for layered devices)
1475+ * before --monitor closes, we loose.
1476+ *
1477+ * So: wait upto 1 second for there to be
1478+ * a non-zero capacity.
1479+ */
1480+ while (usecs < 1000) {
1481+ mdfd = open(mddev, O_RDONLY);
1482+ if (mdfd >= 0) {
1483+ unsigned long long size;
1484+ if (get_dev_size(mdfd, NULL, &size) &&
1485+ size > 0)
1486+ break;
1487+ close(mdfd);
1488+ }
1489+ usleep(usecs);
1490+ usecs <<= 1;
1491+ }
1492+ }
1493+ free(devices);
1494+ return 0;
1495+ }
1496+ fprintf(stderr, Name ": failed to RUN_ARRAY %s: %s\n",
1497+ mddev, strerror(errno));
1498+
1499+ if (!enough(content->array.level, content->array.raid_disks,
1500+ content->array.layout, 1, avail))
1501+ fprintf(stderr, Name ": Not enough devices to "
1502+ "start the array.\n");
1503+ else if (!enough(content->array.level,
1504+ content->array.raid_disks,
1505+ content->array.layout, clean,
1506+ avail))
1507+ fprintf(stderr, Name ": Not enough devices to "
1508+ "start the array while not clean "
1509+ "- consider --force.\n");
1510+
1511+ if (auto_assem)
1512+ ioctl(mdfd, STOP_ARRAY, NULL);
1513+ close(mdfd);
1514+ free(devices);
1515+ return 1;
1516+ }
1517+ if (runstop == -1) {
1518+ fprintf(stderr, Name ": %s assembled from %d drive%s",
1519+ mddev, okcnt, okcnt==1?"":"s");
1520+ if (okcnt != (unsigned)content->array.raid_disks)
1521+ fprintf(stderr, " (out of %d)", content->array.raid_disks);
1522+ fprintf(stderr, ", but not started.\n");
1523+ close(mdfd);
1524+ free(devices);
1525+ return 0;
1526+ }
1527+ if (verbose >= -1) {
1528+ fprintf(stderr, Name ": %s assembled from %d drive%s", mddev, okcnt, okcnt==1?"":"s");
1529+ if (rebuilding_cnt)
1530+ fprintf(stderr, "%s %d rebuilding", sparecnt?", ":" and ", rebuilding_cnt);
1531+ if (sparecnt)
1532+ fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
1533+ if (!enough(content->array.level, content->array.raid_disks,
1534+ content->array.layout, 1, avail))
1535+ fprintf(stderr, " - not enough to start the array.\n");
1536+ else if (!enough(content->array.level,
1537+ content->array.raid_disks,
1538+ content->array.layout, clean,
1539+ avail))
1540+ fprintf(stderr, " - not enough to start the "
1541+ "array while not clean - consider "
1542+ "--force.\n");
1543+ else {
1544+ if (req_cnt == (unsigned)content->array.raid_disks)
1545+ fprintf(stderr, " - need all %d to start it", req_cnt);
1546+ else
1547+ fprintf(stderr, " - need %d of %d to start", req_cnt, content->array.raid_disks);
1548+ fprintf(stderr, " (use --run to insist).\n");
1549+ }
1550+ }
1551+ if (auto_assem)
1552+ ioctl(mdfd, STOP_ARRAY, NULL);
1553+ close(mdfd);
1554+ free(devices);
1555+ return 1;
1556+ } else {
1557+ /* The "chosen_drive" is a good choice, and if necessary, the superblock has
1558+ * been updated to point to the current locations of devices.
1559+ * so we can just start the array
1560+ */
1561+ unsigned long dev;
1562+ dev = makedev(devices[chosen_drive].i.disk.major,
1563+ devices[chosen_drive].i.disk.minor);
1564+ if (ioctl(mdfd, START_ARRAY, dev)) {
1565+ fprintf(stderr, Name ": Cannot start array: %s\n",
1566+ strerror(errno));
1567+ }
1568+
1569+ }
1570+ close(mdfd);
1571+ free(devices);
1572+ return 0;
1573+}
1574+
1575+#ifndef MDASSEMBLE
1576+int assemble_container_content(struct supertype *st, int mdfd,
1577+ struct mdinfo *content, int runstop,
1578+ char *chosen_name, int verbose,
1579+ char *backup_file, int freeze_reshape)
1580+{
1581+ struct mdinfo *dev, *sra;
1582+ int working = 0, preexist = 0;
1583+ int expansion = 0;
1584+ struct map_ent *map = NULL;
1585+ int old_raid_disks;
1586+ int start_reshape;
1587+
1588+ sysfs_init(content, mdfd, 0);
1589+
1590+ sra = sysfs_read(mdfd, 0, GET_VERSION);
1591+ if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0)
1592+ if (sysfs_set_array(content, md_get_version(mdfd)) != 0) {
1593+ if (sra)
1594+ sysfs_free(sra);
1595+ return 1;
1596+ }
1597+
1598+ /* There are two types of reshape: container wide or sub-array specific
1599+ * Check if metadata requests blocking container wide reshapes
1600+ */
1601+ start_reshape = (content->reshape_active &&
1602+ !((content->reshape_active == CONTAINER_RESHAPE) &&
1603+ (content->array.state & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE))));
1604+
1605+ /* Block subarray here if it is under reshape now
1606+ * Do not allow for any changes in this array
1607+ */
1608+ if (st->ss->external && content->recovery_blocked && start_reshape)
1609+ block_subarray(content);
1610+
1611+ if (sra)
1612+ sysfs_free(sra);
1613+ old_raid_disks = content->array.raid_disks - content->delta_disks;
1614+ for (dev = content->devs; dev; dev = dev->next)
1615+ if (sysfs_add_disk(content, dev, 1) == 0) {
1616+ if (dev->disk.raid_disk >= old_raid_disks &&
1617+ content->reshape_active)
1618+ expansion++;
1619+ else
1620+ working++;
1621+ } else if (errno == EEXIST)
1622+ preexist++;
1623+ if (working + expansion == 0)
1624+ return 1;/* Nothing new, don't try to start */
1625+
1626+ map_update(&map, fd2devnum(mdfd),
1627+ content->text_version,
1628+ content->uuid, chosen_name);
1629+
1630+ if (runstop > 0 ||
1631+ (working + preexist + expansion) >=
1632+ content->array.working_disks) {
1633+ int err;
1634+
1635+ if (start_reshape) {
1636+ int spare = content->array.raid_disks + expansion;
1637+ if (restore_backup(st, content,
1638+ working,
1639+ spare, backup_file, verbose) == 1)
1640+ return 1;
1641+
1642+ err = sysfs_set_str(content, NULL,
1643+ "array_state", "readonly");
1644+ if (err)
1645+ return 1;
1646+
1647+ if (st->ss->external) {
1648+ if (!mdmon_running(st->container_dev))
1649+ start_mdmon(st->container_dev);
1650+ ping_monitor_by_id(st->container_dev);
1651+ if (mdmon_running(st->container_dev) &&
1652+ st->update_tail == NULL)
1653+ st->update_tail = &st->updates;
1654+ }
1655+
1656+ err = Grow_continue(mdfd, st, content, backup_file,
1657+ freeze_reshape);
1658+ } else switch(content->array.level) {
1659+ case LEVEL_LINEAR:
1660+ case LEVEL_MULTIPATH:
1661+ case 0:
1662+ err = sysfs_set_str(content, NULL, "array_state",
1663+ "active");
1664+ break;
1665+ default:
1666+ err = sysfs_set_str(content, NULL, "array_state",
1667+ "readonly");
1668+ /* start mdmon if needed. */
1669+ if (!err) {
1670+ if (!mdmon_running(st->container_dev))
1671+ start_mdmon(st->container_dev);
1672+ ping_monitor_by_id(st->container_dev);
1673+ }
1674+ break;
1675+ }
1676+ if (!err)
1677+ sysfs_set_safemode(content, content->safe_mode_delay);
1678+
1679+ /* Block subarray here if it is not reshaped now
1680+ * It has be blocked a little later to allow mdmon to switch in
1681+ * in to R/W state
1682+ */
1683+ if (st->ss->external && content->recovery_blocked &&
1684+ !start_reshape)
1685+ block_subarray(content);
1686+
1687+ if (verbose >= 0) {
1688+ if (err)
1689+ fprintf(stderr, Name
1690+ ": array %s now has %d device%s",
1691+ chosen_name, working + preexist,
1692+ working + preexist == 1 ? "":"s");
1693+ else
1694+ fprintf(stderr, Name
1695+ ": Started %s with %d device%s",
1696+ chosen_name, working + preexist,
1697+ working + preexist == 1 ? "":"s");
1698+ if (preexist)
1699+ fprintf(stderr, " (%d new)", working);
1700+ if (expansion)
1701+ fprintf(stderr, " ( + %d for expansion)",
1702+ expansion);
1703+ fprintf(stderr, "\n");
1704+ }
1705+ if (!err)
1706+ wait_for(chosen_name, mdfd);
1707+ return err;
1708+ /* FIXME should have an O_EXCL and wait for read-auto */
1709+ } else {
1710+ if (verbose >= 0) {
1711+ fprintf(stderr, Name
1712+ ": %s assembled with %d device%s",
1713+ chosen_name, preexist + working,
1714+ preexist + working == 1 ? "":"s");
1715+ if (preexist)
1716+ fprintf(stderr, " (%d new)", working);
1717+ fprintf(stderr, " but not started\n");
1718+ }
1719+ return 1;
1720+ }
1721+}
1722+#endif
1723+
1724
1725=== removed file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/Assemble.c'
1726--- .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/Assemble.c 2012-02-09 16:53:02 +0000
1727+++ .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/Assemble.c 1970-01-01 00:00:00 +0000
1728@@ -1,1650 +0,0 @@
1729-/*
1730- * mdadm - manage Linux "md" devices aka RAID arrays.
1731- *
1732- * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
1733- *
1734- *
1735- * This program is free software; you can redistribute it and/or modify
1736- * it under the terms of the GNU General Public License as published by
1737- * the Free Software Foundation; either version 2 of the License, or
1738- * (at your option) any later version.
1739- *
1740- * This program is distributed in the hope that it will be useful,
1741- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1742- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1743- * GNU General Public License for more details.
1744- *
1745- * You should have received a copy of the GNU General Public License
1746- * along with this program; if not, write to the Free Software
1747- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1748- *
1749- * Author: Neil Brown
1750- * Email: <neilb@suse.de>
1751- */
1752-
1753-#include "mdadm.h"
1754-#include <ctype.h>
1755-
1756-static int name_matches(char *found, char *required, char *homehost)
1757-{
1758- /* See if the name found matches the required name, possibly
1759- * prefixed with 'homehost'
1760- */
1761- char fnd[33];
1762-
1763- strncpy(fnd, found, 32);
1764- fnd[32] = 0;
1765- if (strcmp(found, required)==0)
1766- return 1;
1767- if (homehost) {
1768- int l = strlen(homehost);
1769- if (l < 32 && fnd[l] == ':' &&
1770- strcmp(fnd+l+1, required)==0)
1771- return 1;
1772- }
1773- return 0;
1774-}
1775-
1776-static int is_member_busy(char *metadata_version)
1777-{
1778- /* check if the given member array is active */
1779- struct mdstat_ent *mdstat = mdstat_read(1, 0);
1780- struct mdstat_ent *ent;
1781- int busy = 0;
1782-
1783- for (ent = mdstat; ent; ent = ent->next) {
1784- if (ent->metadata_version == NULL)
1785- continue;
1786- if (strncmp(ent->metadata_version, "external:", 9) != 0)
1787- continue;
1788- if (!is_subarray(&ent->metadata_version[9]))
1789- continue;
1790- /* Skip first char - it can be '/' or '-' */
1791- if (strcmp(&ent->metadata_version[10], metadata_version+1) == 0) {
1792- busy = 1;
1793- break;
1794- }
1795- }
1796- free_mdstat(mdstat);
1797-
1798- return busy;
1799-}
1800-
1801-static int ident_matches(struct mddev_ident *ident,
1802- struct mdinfo *content,
1803- struct supertype *tst,
1804- char *homehost,
1805- char *update, char *devname)
1806-{
1807-
1808- if (ident->uuid_set && (!update || strcmp(update, "uuid")!= 0) &&
1809- same_uuid(content->uuid, ident->uuid, tst->ss->swapuuid)==0 &&
1810- memcmp(content->uuid, uuid_zero, sizeof(int[4])) != 0) {
1811- if (devname)
1812- fprintf(stderr, Name ": %s has wrong uuid.\n",
1813- devname);
1814- return 0;
1815- }
1816- if (ident->name[0] && (!update || strcmp(update, "name")!= 0) &&
1817- name_matches(content->name, ident->name, homehost)==0) {
1818- if (devname)
1819- fprintf(stderr, Name ": %s has wrong name.\n",
1820- devname);
1821- return 0;
1822- }
1823- if (ident->super_minor != UnSet &&
1824- ident->super_minor != content->array.md_minor) {
1825- if (devname)
1826- fprintf(stderr, Name ": %s has wrong super-minor.\n",
1827- devname);
1828- return 0;
1829- }
1830- if (ident->level != UnSet &&
1831- ident->level != content->array.level) {
1832- if (devname)
1833- fprintf(stderr, Name ": %s has wrong raid level.\n",
1834- devname);
1835- return 0;
1836- }
1837- if (ident->raid_disks != UnSet &&
1838- ident->raid_disks!= content->array.raid_disks) {
1839- if (devname)
1840- fprintf(stderr, Name ": %s requires wrong number of drives.\n",
1841- devname);
1842- return 0;
1843- }
1844- if (ident->member && ident->member[0]) {
1845- /* content->text_version must match */
1846- char *s = strchr(content->text_version+1, '/');
1847- if (s == NULL) {
1848- if (devname)
1849- fprintf(stderr, Name ": %s is not a container and one is required.\n",
1850- devname);
1851- return 0;
1852- } else if (strcmp(ident->member, s+1) != 0) {
1853- if (devname)
1854- fprintf(stderr, Name ": skipping wrong member %s is %s\n",
1855- content->text_version, devname);
1856- return 0;
1857- }
1858- }
1859- return 1;
1860-}
1861-
1862-
1863-int Assemble(struct supertype *st, char *mddev,
1864- struct mddev_ident *ident,
1865- struct mddev_dev *devlist,
1866- char *backup_file, int invalid_backup,
1867- int readonly, int runstop,
1868- char *update, char *homehost, int require_homehost,
1869- int verbose, int force, int freeze_reshape)
1870-{
1871- /*
1872- * The task of Assemble is to find a collection of
1873- * devices that should (according to their superblocks)
1874- * form an array, and to give this collection to the MD driver.
1875- * In Linux-2.4 and later, this involves submitting a
1876- * SET_ARRAY_INFO ioctl with no arg - to prepare
1877- * the array - and then submit a number of
1878- * ADD_NEW_DISK ioctls to add disks into
1879- * the array. Finally RUN_ARRAY might
1880- * be submitted to start the array.
1881- *
1882- * Much of the work of Assemble is in finding and/or
1883- * checking the disks to make sure they look right.
1884- *
1885- * If mddev is not set, then scan must be set and we
1886- * read through the config file for dev+uuid mapping
1887- * We recurse, setting mddev, for each device that
1888- * - isn't running
1889- * - has a valid uuid (or any uuid if !uuidset)
1890- *
1891- * If mddev is set, we try to determine state of md.
1892- * check version - must be at least 0.90.0
1893- * check kernel version. must be at least 2.4.
1894- * If not, we can possibly fall back on START_ARRAY
1895- * Try to GET_ARRAY_INFO.
1896- * If possible, give up
1897- * If not, try to STOP_ARRAY just to make sure
1898- *
1899- * If !uuidset and scan, look in conf-file for uuid
1900- * If not found, give up
1901- * If !devlist and scan and uuidset, get list of devs from conf-file
1902- *
1903- * For each device:
1904- * Check superblock - discard if bad
1905- * Check uuid (set if we don't have one) - discard if no match
1906- * Check superblock similarity if we have a superblock - discard if different
1907- * Record events, devicenum
1908- * This should give us a list of devices for the array
1909- * We should collect the most recent event number
1910- *
1911- * Count disks with recent enough event count
1912- * While force && !enough disks
1913- * Choose newest rejected disks, update event count
1914- * mark clean and rewrite superblock
1915- * If recent kernel:
1916- * SET_ARRAY_INFO
1917- * foreach device with recent events : ADD_NEW_DISK
1918- * if runstop == 1 || "enough" disks and runstop==0 -> RUN_ARRAY
1919- * If old kernel:
1920- * Check the device numbers in superblock are right
1921- * update superblock if any changes
1922- * START_ARRAY
1923- *
1924- */
1925- int mdfd;
1926- int clean;
1927- int auto_assem = (mddev == NULL && !ident->uuid_set &&
1928- ident->super_minor == UnSet && ident->name[0] == 0
1929- && (ident->container == NULL || ident->member == NULL));
1930- int old_linux = 0;
1931- int vers = vers; /* Keep gcc quite - it really is initialised */
1932- struct {
1933- char *devname;
1934- int uptodate; /* set once we decide that this device is as
1935- * recent as everything else in the array.
1936- */
1937- struct mdinfo i;
1938- } *devices;
1939- char *devmap;
1940- int *best = NULL; /* indexed by raid_disk */
1941- int bestcnt = 0;
1942- int devcnt = 0;
1943- unsigned int okcnt, sparecnt, rebuilding_cnt;
1944- unsigned int req_cnt;
1945- int i;
1946- int most_recent = 0;
1947- int chosen_drive;
1948- int change = 0;
1949- int inargv = 0;
1950- int report_missmatch;
1951-#ifndef MDASSEMBLE
1952- int bitmap_done;
1953-#endif
1954- int start_partial_ok = (runstop >= 0) &&
1955- (force || devlist==NULL || auto_assem);
1956- unsigned int num_devs;
1957- struct mddev_dev *tmpdev;
1958- struct mdinfo info;
1959- struct mdinfo *content = NULL;
1960- char *avail;
1961- int nextspare = 0;
1962- char *name = NULL;
1963- int trustworthy;
1964- char chosen_name[1024];
1965- struct domainlist *domains = NULL;
1966-
1967- if (get_linux_version() < 2004000)
1968- old_linux = 1;
1969-
1970- /*
1971- * If any subdevs are listed, then any that don't
1972- * match ident are discarded. Remainder must all match and
1973- * become the array.
1974- * If no subdevs, then we scan all devices in the config file, but
1975- * there must be something in the identity
1976- */
1977-
1978- if (!devlist &&
1979- ident->uuid_set == 0 &&
1980- (ident->super_minor < 0 || ident->super_minor == UnSet) &&
1981- ident->name[0] == 0 &&
1982- (ident->container == NULL || ident->member == NULL) &&
1983- ident->devices == NULL) {
1984- fprintf(stderr, Name ": No identity information available for %s - cannot assemble.\n",
1985- mddev ? mddev : "further assembly");
1986- return 1;
1987- }
1988-
1989- if (devlist == NULL)
1990- devlist = conf_get_devs();
1991- else if (mddev)
1992- inargv = 1;
1993-
1994- report_missmatch = ((inargv && verbose >= 0) || verbose > 0);
1995- try_again:
1996- /* We come back here when doing auto-assembly and attempting some
1997- * set of devices failed. Those are now marked as ->used==2 and
1998- * we ignore them and try again
1999- */
2000-
2001- tmpdev = devlist; num_devs = 0;
2002- while (tmpdev) {
2003- if (tmpdev->used)
2004- tmpdev->used = 2;
2005- else
2006- num_devs++;
2007- tmpdev = tmpdev->next;
2008- }
2009-
2010- if (!st && ident->st) st = ident->st;
2011-
2012- if (verbose>0)
2013- fprintf(stderr, Name ": looking for devices for %s\n",
2014- mddev ? mddev : "further assembly");
2015-
2016- /* first walk the list of devices to find a consistent set
2017- * that match the criterea, if that is possible.
2018- * We flag the ones we like with 'used'.
2019- */
2020- for (tmpdev = devlist;
2021- tmpdev;
2022- tmpdev = tmpdev ? tmpdev->next : NULL) {
2023- char *devname = tmpdev->devname;
2024- int dfd;
2025- struct stat stb;
2026- struct supertype *tst;
2027- struct dev_policy *pol = NULL;
2028- int found_container = 0;
2029-
2030- if (tmpdev->used > 1) continue;
2031-
2032- if (ident->devices &&
2033- !match_oneof(ident->devices, devname)) {
2034- if (report_missmatch)
2035- fprintf(stderr, Name ": %s is not one of %s\n", devname, ident->devices);
2036- continue;
2037- }
2038-
2039- tst = dup_super(st);
2040-
2041- dfd = dev_open(devname, O_RDONLY|O_EXCL);
2042- if (dfd < 0) {
2043- if (report_missmatch)
2044- fprintf(stderr, Name ": cannot open device %s: %s\n",
2045- devname, strerror(errno));
2046- tmpdev->used = 2;
2047- } else if (fstat(dfd, &stb)< 0) {
2048- /* Impossible! */
2049- fprintf(stderr, Name ": fstat failed for %s: %s\n",
2050- devname, strerror(errno));
2051- tmpdev->used = 2;
2052- } else if ((stb.st_mode & S_IFMT) != S_IFBLK) {
2053- fprintf(stderr, Name ": %s is not a block device.\n",
2054- devname);
2055- tmpdev->used = 2;
2056- } else if (must_be_container(dfd)) {
2057- if (st) {
2058- /* already found some components, this cannot
2059- * be another one.
2060- */
2061- if (report_missmatch)
2062- fprintf(stderr, Name ": %s is a container, but we are looking for components\n",
2063- devname);
2064- tmpdev->used = 2;
2065-#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
2066- } if (!tst && (tst = super_by_fd(dfd, NULL)) == NULL) {
2067- if (report_missmatch)
2068- fprintf(stderr, Name ": not a recognisable container: %s\n",
2069- devname);
2070- tmpdev->used = 2;
2071-#endif
2072- } else if (!tst->ss->load_container
2073- || tst->ss->load_container(tst, dfd, NULL)) {
2074- if (report_missmatch)
2075- fprintf(stderr, Name ": no correct container type: %s\n",
2076- devname);
2077- tmpdev->used = 2;
2078- } else if (auto_assem &&
2079- !conf_test_metadata(tst->ss->name, (pol = devnum_policy(stb.st_rdev)),
2080- tst->ss->match_home(tst, homehost) == 1)) {
2081- if (report_missmatch)
2082- fprintf(stderr, Name ": %s has metadata type %s for which "
2083- "auto-assembly is disabled\n",
2084- devname, tst->ss->name);
2085- tmpdev->used = 2;
2086- } else
2087- found_container = 1;
2088- } else {
2089- if (!tst && (tst = guess_super(dfd)) == NULL) {
2090- if (report_missmatch)
2091- fprintf(stderr, Name ": no recogniseable superblock on %s\n",
2092- devname);
2093- tmpdev->used = 2;
2094- } else if (tst->ss->load_super(tst,dfd, NULL)) {
2095- if (report_missmatch)
2096- fprintf(stderr, Name ": no RAID superblock on %s\n",
2097- devname);
2098- tmpdev->used = 2;
2099- } else if (tst->ss->compare_super == NULL) {
2100- if (report_missmatch)
2101- fprintf(stderr, Name ": Cannot assemble %s metadata on %s\n",
2102- tst->ss->name, devname);
2103- tmpdev->used = 2;
2104- } else if (auto_assem && st == NULL &&
2105- !conf_test_metadata(tst->ss->name, (pol = devnum_policy(stb.st_rdev)),
2106- tst->ss->match_home(tst, homehost) == 1)) {
2107- if (report_missmatch)
2108- fprintf(stderr, Name ": %s has metadata type %s for which "
2109- "auto-assembly is disabled\n",
2110- devname, tst->ss->name);
2111- tmpdev->used = 2;
2112- }
2113- }
2114- if (dfd >= 0) close(dfd);
2115- if (tmpdev->used == 2) {
2116- if (auto_assem || !inargv)
2117- /* Ignore unrecognised devices during auto-assembly */
2118- goto loop;
2119- if (ident->uuid_set || ident->name[0] ||
2120- ident->super_minor != UnSet)
2121- /* Ignore unrecognised device if looking for
2122- * specific array */
2123- goto loop;
2124-
2125-
2126- fprintf(stderr, Name ": %s has no superblock - assembly aborted\n",
2127- devname);
2128- if (st)
2129- st->ss->free_super(st);
2130- dev_policy_free(pol);
2131- domain_free(domains);
2132- return 1;
2133- }
2134-
2135- if (found_container) {
2136- /* tmpdev is a container. We need to be either
2137- * looking for a member, or auto-assembling
2138- */
2139-
2140- if (ident->container) {
2141- if (ident->container[0] == '/' &&
2142- !same_dev(ident->container, devname)) {
2143- if (report_missmatch)
2144- fprintf(stderr, Name ": %s is not the container required (%s)\n",
2145- devname, ident->container);
2146- goto loop;
2147- }
2148- if (ident->container[0] != '/') {
2149- /* we have a uuid */
2150- int uuid[4];
2151-
2152- content = &info;
2153- tst->ss->getinfo_super(tst, content, NULL);
2154-
2155- if (!parse_uuid(ident->container, uuid) ||
2156- !same_uuid(content->uuid, uuid, tst->ss->swapuuid)) {
2157- if (report_missmatch)
2158- fprintf(stderr, Name ": %s has wrong UUID to be required container\n",
2159- devname);
2160- goto loop;
2161- }
2162- }
2163- }
2164- /* It is worth looking inside this container.
2165- */
2166- if (verbose > 0)
2167- fprintf(stderr, Name ": looking in container %s\n",
2168- devname);
2169-
2170- for (content = tst->ss->container_content(tst, NULL);
2171- content;
2172- content = content->next) {
2173-
2174- if (!ident_matches(ident, content, tst,
2175- homehost, update,
2176- report_missmatch ? devname : NULL))
2177- /* message already printed */;
2178- else if (is_member_busy(content->text_version)) {
2179- if (report_missmatch)
2180- fprintf(stderr, Name ": member %s in %s is already assembled\n",
2181- content->text_version,
2182- devname);
2183- } else if (content->array.state & (1<<MD_SB_BLOCK_VOLUME)) {
2184- /* do not assemble arrays with unsupported configurations */
2185- fprintf(stderr, Name ": Cannot activate member %s in %s.\n",
2186- content->text_version,
2187- devname);
2188- } else
2189- break;
2190- }
2191- if (!content) {
2192- tmpdev->used = 2;
2193- goto loop; /* empty container */
2194- }
2195-
2196- st = tst; tst = NULL;
2197- if (!auto_assem && inargv && tmpdev->next != NULL) {
2198- fprintf(stderr, Name ": %s is a container, but is not "
2199- "only device given: confused and aborting\n",
2200- devname);
2201- st->ss->free_super(st);
2202- dev_policy_free(pol);
2203- domain_free(domains);
2204- return 1;
2205- }
2206- if (verbose > 0)
2207- fprintf(stderr, Name ": found match on member %s in %s\n",
2208- content->text_version, devname);
2209-
2210- /* make sure we finished the loop */
2211- tmpdev = NULL;
2212- goto loop;
2213- } else {
2214-
2215- content = &info;
2216- tst->ss->getinfo_super(tst, content, NULL);
2217-
2218- if (!ident_matches(ident, content, tst,
2219- homehost, update,
2220- report_missmatch ? devname : NULL))
2221- goto loop;
2222-
2223- if (st == NULL)
2224- st = dup_super(tst);
2225- if (st->minor_version == -1)
2226- st->minor_version = tst->minor_version;
2227-
2228- if (memcmp(content->uuid, uuid_zero,
2229- sizeof(int[4])) == 0) {
2230- /* this is a floating spare. It cannot define
2231- * an array unless there are no more arrays of
2232- * this type to be found. It can be included
2233- * in an array of this type though.
2234- */
2235- tmpdev->used = 3;
2236- goto loop;
2237- }
2238-
2239- if (st->ss != tst->ss ||
2240- st->minor_version != tst->minor_version ||
2241- st->ss->compare_super(st, tst) != 0) {
2242- /* Some mismatch. If exactly one array matches this host,
2243- * we can resolve on that one.
2244- * Or, if we are auto assembling, we just ignore the second
2245- * for now.
2246- */
2247- if (auto_assem)
2248- goto loop;
2249- if (homehost) {
2250- int first = st->ss->match_home(st, homehost);
2251- int last = tst->ss->match_home(tst, homehost);
2252- if (first != last &&
2253- (first == 1 || last == 1)) {
2254- /* We can do something */
2255- if (first) {/* just ignore this one */
2256- if (report_missmatch)
2257- fprintf(stderr, Name ": %s misses out due to wrong homehost\n",
2258- devname);
2259- goto loop;
2260- } else { /* reject all those sofar */
2261- struct mddev_dev *td;
2262- if (report_missmatch)
2263- fprintf(stderr, Name ": %s overrides previous devices due to good homehost\n",
2264- devname);
2265- for (td=devlist; td != tmpdev; td=td->next)
2266- if (td->used == 1)
2267- td->used = 0;
2268- tmpdev->used = 1;
2269- goto loop;
2270- }
2271- }
2272- }
2273- fprintf(stderr, Name ": superblock on %s doesn't match others - assembly aborted\n",
2274- devname);
2275- tst->ss->free_super(tst);
2276- st->ss->free_super(st);
2277- dev_policy_free(pol);
2278- domain_free(domains);
2279- return 1;
2280- }
2281- tmpdev->used = 1;
2282- }
2283- loop:
2284- /* Collect domain information from members only */
2285- if (tmpdev && tmpdev->used == 1) {
2286- if (!pol)
2287- pol = devnum_policy(stb.st_rdev);
2288- domain_merge(&domains, pol, tst?tst->ss->name:NULL);
2289- }
2290- dev_policy_free(pol);
2291- pol = NULL;
2292- if (tst)
2293- tst->ss->free_super(tst);
2294- }
2295-
2296- /* Check if we found some imsm spares but no members */
2297- if ((auto_assem ||
2298- (ident->uuid_set &&
2299- memcmp(uuid_zero, ident->uuid,sizeof(uuid_zero)) == 0)) &&
2300- (!st || !st->sb))
2301- for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
2302- if (tmpdev->used != 3)
2303- continue;
2304- tmpdev->used = 1;
2305- content = &info;
2306-
2307- if (!st->sb) {
2308- /* we need sb from one of the spares */
2309- int dfd = dev_open(tmpdev->devname, O_RDONLY);
2310- if (dfd < 0 ||
2311- st->ss->load_super(st, dfd, NULL))
2312- tmpdev->used = 2;
2313- if (dfd > 0)
2314- close(dfd);
2315- }
2316- }
2317-
2318- /* Now reject spares that don't match domains of identified members */
2319- for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
2320- struct stat stb;
2321- if (tmpdev->used != 3)
2322- continue;
2323- if (stat(tmpdev->devname, &stb)< 0) {
2324- fprintf(stderr, Name ": fstat failed for %s: %s\n",
2325- tmpdev->devname, strerror(errno));
2326- tmpdev->used = 2;
2327- } else {
2328- struct dev_policy *pol = devnum_policy(stb.st_rdev);
2329- int dt = domain_test(domains, pol, NULL);
2330- if (inargv && dt != 0)
2331- /* take this spare as domains match
2332- * if there are any */
2333- tmpdev->used = 1;
2334- else if (!inargv && dt == 1)
2335- /* device wasn't explicitly listed, so need
2336- * explicit domain match - which we have */
2337- tmpdev->used = 1;
2338- else
2339- /* if domains don't match mark as unused */
2340- tmpdev->used = 0;
2341- dev_policy_free(pol);
2342- }
2343- }
2344- domain_free(domains);
2345-
2346- if (!st || !st->sb || !content)
2347- return 2;
2348-
2349- /* Now need to open the array device. Use create_mddev */
2350- if (content == &info)
2351- st->ss->getinfo_super(st, content, NULL);
2352-
2353- trustworthy = FOREIGN;
2354- name = content->name;
2355- switch (st->ss->match_home(st, homehost)
2356- ?: st->ss->match_home(st, "any")) {
2357- case 1:
2358- trustworthy = LOCAL;
2359- name = strchr(content->name, ':');
2360- if (name)
2361- name++;
2362- else
2363- name = content->name;
2364- break;
2365- }
2366- if (!auto_assem)
2367- /* If the array is listed in mdadm.conf or on
2368- * command line, then we trust the name
2369- * even if the array doesn't look local
2370- */
2371- trustworthy = LOCAL;
2372-
2373- if (name[0] == 0 &&
2374- content->array.level == LEVEL_CONTAINER) {
2375- name = content->text_version;
2376- trustworthy = METADATA;
2377- }
2378-
2379- if (name[0] && trustworthy != LOCAL &&
2380- ! require_homehost &&
2381- conf_name_is_free(name))
2382- trustworthy = LOCAL;
2383-
2384- if (trustworthy == LOCAL &&
2385- strchr(name, ':'))
2386- /* Ignore 'host:' prefix of name */
2387- name = strchr(name, ':')+1;
2388-
2389- mdfd = create_mddev(mddev, name, ident->autof, trustworthy,
2390- chosen_name);
2391- if (mdfd < 0) {
2392- st->ss->free_super(st);
2393- if (auto_assem)
2394- goto try_again;
2395- return 1;
2396- }
2397- mddev = chosen_name;
2398- vers = md_get_version(mdfd);
2399- if (vers < 9000) {
2400- fprintf(stderr, Name ": Assemble requires driver version 0.90.0 or later.\n"
2401- " Upgrade your kernel or try --build\n");
2402- close(mdfd);
2403- return 1;
2404- }
2405- if (mddev_busy(fd2devnum(mdfd))) {
2406- fprintf(stderr, Name ": %s already active, cannot restart it!\n",
2407- mddev);
2408- for (tmpdev = devlist ;
2409- tmpdev && tmpdev->used != 1;
2410- tmpdev = tmpdev->next)
2411- ;
2412- if (tmpdev && auto_assem)
2413- fprintf(stderr, Name ": %s needed for %s...\n",
2414- mddev, tmpdev->devname);
2415- close(mdfd);
2416- mdfd = -3;
2417- st->ss->free_super(st);
2418- if (auto_assem)
2419- goto try_again;
2420- return 1;
2421- }
2422- ioctl(mdfd, STOP_ARRAY, NULL); /* just incase it was started but has no content */
2423-
2424-#ifndef MDASSEMBLE
2425- if (content != &info) {
2426- /* This is a member of a container. Try starting the array. */
2427- int err;
2428- err = assemble_container_content(st, mdfd, content, runstop,
2429- chosen_name, verbose,
2430- backup_file, freeze_reshape);
2431- close(mdfd);
2432- return err;
2433- }
2434- bitmap_done = 0;
2435-#endif
2436- /* Ok, no bad inconsistancy, we can try updating etc */
2437- devices = malloc(num_devs * sizeof(*devices));
2438- devmap = calloc(num_devs * content->array.raid_disks, 1);
2439- for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) {
2440- char *devname = tmpdev->devname;
2441- struct stat stb;
2442- /* looks like a good enough match to update the super block if needed */
2443-#ifndef MDASSEMBLE
2444- if (update) {
2445- int dfd;
2446- /* prepare useful information in info structures */
2447- struct stat stb2;
2448- struct supertype *tst;
2449- int err;
2450- fstat(mdfd, &stb2);
2451-
2452- if (strcmp(update, "uuid")==0 &&
2453- !ident->uuid_set) {
2454- int rfd;
2455- if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
2456- read(rfd, ident->uuid, 16) != 16) {
2457- *(__u32*)(ident->uuid) = random();
2458- *(__u32*)(ident->uuid+1) = random();
2459- *(__u32*)(ident->uuid+2) = random();
2460- *(__u32*)(ident->uuid+3) = random();
2461- }
2462- if (rfd >= 0) close(rfd);
2463- }
2464- dfd = dev_open(devname, O_RDWR|O_EXCL);
2465-
2466- tst = dup_super(st);
2467- if (dfd < 0 || tst->ss->load_super(tst, dfd, NULL) != 0) {
2468- fprintf(stderr, Name ": cannot re-read metadata from %s - aborting\n",
2469- devname);
2470- if (dfd >= 0)
2471- close(dfd);
2472- close(mdfd);
2473- free(devices);
2474- free(devmap);
2475- return 1;
2476- }
2477- tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
2478-
2479- memcpy(content->uuid, ident->uuid, 16);
2480- strcpy(content->name, ident->name);
2481- content->array.md_minor = minor(stb2.st_rdev);
2482-
2483- if (strcmp(update, "byteorder") == 0)
2484- err = 0;
2485- else
2486- err = tst->ss->update_super(tst, content, update,
2487- devname, verbose,
2488- ident->uuid_set,
2489- homehost);
2490- if (err < 0) {
2491- fprintf(stderr,
2492- Name ": --update=%s not understood"
2493- " for %s metadata\n",
2494- update, tst->ss->name);
2495- tst->ss->free_super(tst);
2496- free(tst);
2497- close(mdfd);
2498- close(dfd);
2499- free(devices);
2500- free(devmap);
2501- return 1;
2502- }
2503- if (strcmp(update, "uuid")==0 &&
2504- !ident->uuid_set) {
2505- ident->uuid_set = 1;
2506- memcpy(ident->uuid, content->uuid, 16);
2507- }
2508- if (tst->ss->store_super(tst, dfd))
2509- fprintf(stderr, Name ": Could not re-write superblock on %s.\n",
2510- devname);
2511- close(dfd);
2512-
2513- if (strcmp(update, "uuid")==0 &&
2514- ident->bitmap_fd >= 0 && !bitmap_done) {
2515- if (bitmap_update_uuid(ident->bitmap_fd,
2516- content->uuid,
2517- tst->ss->swapuuid) != 0)
2518- fprintf(stderr, Name ": Could not update uuid on external bitmap.\n");
2519- else
2520- bitmap_done = 1;
2521- }
2522- tst->ss->free_super(tst);
2523- } else
2524-#endif
2525- {
2526- struct supertype *tst = dup_super(st);
2527- int dfd;
2528- dfd = dev_open(devname, O_RDWR|O_EXCL);
2529-
2530- if (dfd < 0 || tst->ss->load_super(tst, dfd, NULL) != 0) {
2531- fprintf(stderr, Name ": cannot re-read metadata from %s - aborting\n",
2532- devname);
2533- if (dfd >= 0)
2534- close(dfd);
2535- close(mdfd);
2536- free(devices);
2537- free(devmap);
2538- return 1;
2539- }
2540- tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
2541- tst->ss->free_super(tst);
2542- close(dfd);
2543- }
2544-
2545- stat(devname, &stb);
2546-
2547- if (verbose > 0)
2548- fprintf(stderr, Name ": %s is identified as a member of %s, slot %d.\n",
2549- devname, mddev, content->disk.raid_disk);
2550- devices[devcnt].devname = devname;
2551- devices[devcnt].uptodate = 0;
2552- devices[devcnt].i = *content;
2553- devices[devcnt].i.disk.major = major(stb.st_rdev);
2554- devices[devcnt].i.disk.minor = minor(stb.st_rdev);
2555- if (most_recent < devcnt) {
2556- if (devices[devcnt].i.events
2557- > devices[most_recent].i.events)
2558- most_recent = devcnt;
2559- }
2560- if (content->array.level == LEVEL_MULTIPATH)
2561- /* with multipath, the raid_disk from the superblock is meaningless */
2562- i = devcnt;
2563- else
2564- i = devices[devcnt].i.disk.raid_disk;
2565- if (i+1 == 0) {
2566- if (nextspare < content->array.raid_disks)
2567- nextspare = content->array.raid_disks;
2568- i = nextspare++;
2569- } else {
2570- if (i >= content->array.raid_disks &&
2571- i >= nextspare)
2572- nextspare = i+1;
2573- }
2574- if (i < 10000) {
2575- if (i >= bestcnt) {
2576- int newbestcnt = i+10;
2577- int *newbest = malloc(sizeof(int)*newbestcnt);
2578- int c;
2579- for (c=0; c < newbestcnt; c++)
2580- if (c < bestcnt)
2581- newbest[c] = best[c];
2582- else
2583- newbest[c] = -1;
2584- if (best)free(best);
2585- best = newbest;
2586- bestcnt = newbestcnt;
2587- }
2588- if (best[i] >=0 &&
2589- devices[best[i]].i.events
2590- == devices[devcnt].i.events
2591- && (devices[best[i]].i.disk.minor
2592- != devices[devcnt].i.disk.minor)
2593- && st->ss == &super0
2594- && content->array.level != LEVEL_MULTIPATH) {
2595- /* two different devices with identical superblock.
2596- * Could be a mis-detection caused by overlapping
2597- * partitions. fail-safe.
2598- */
2599- fprintf(stderr, Name ": WARNING %s and %s appear"
2600- " to have very similar superblocks.\n"
2601- " If they are really different, "
2602- "please --zero the superblock on one\n"
2603- " If they are the same or overlap,"
2604- " please remove one from %s.\n",
2605- devices[best[i]].devname, devname,
2606- inargv ? "the list" :
2607- "the\n DEVICE list in mdadm.conf"
2608- );
2609- close(mdfd);
2610- free(devices);
2611- free(devmap);
2612- return 1;
2613- }
2614- if (best[i] == -1
2615- || (devices[best[i]].i.events
2616- < devices[devcnt].i.events))
2617- best[i] = devcnt;
2618- }
2619- devcnt++;
2620- }
2621-
2622- if (devcnt == 0) {
2623- fprintf(stderr, Name ": no devices found for %s\n",
2624- mddev);
2625- if (st)
2626- st->ss->free_super(st);
2627- close(mdfd);
2628- free(devices);
2629- free(devmap);
2630- return 1;
2631- }
2632-
2633- if (update && strcmp(update, "byteorder")==0)
2634- st->minor_version = 90;
2635-
2636- st->ss->getinfo_super(st, content, NULL);
2637- clean = content->array.state & 1;
2638-
2639- /* now we have some devices that might be suitable.
2640- * I wonder how many
2641- */
2642- avail = malloc(content->array.raid_disks);
2643- memset(avail, 0, content->array.raid_disks);
2644- okcnt = 0;
2645- sparecnt=0;
2646- rebuilding_cnt=0;
2647- for (i=0; i< bestcnt; i++) {
2648- int j = best[i];
2649- int event_margin = 1; /* always allow a difference of '1'
2650- * like the kernel does
2651- */
2652- if (j < 0) continue;
2653- /* note: we ignore error flags in multipath arrays
2654- * as they don't make sense
2655- */
2656- if (content->array.level != LEVEL_MULTIPATH)
2657- if (!(devices[j].i.disk.state & (1<<MD_DISK_ACTIVE))) {
2658- if (!(devices[j].i.disk.state
2659- & (1<<MD_DISK_FAULTY))) {
2660- devices[j].uptodate = 1;
2661- sparecnt++;
2662- }
2663- continue;
2664- }
2665- /* If this devices thinks that 'most_recent' has failed, then
2666- * we must reject this device.
2667- */
2668- if (j != most_recent &&
2669- content->array.raid_disks > 0 &&
2670- devices[most_recent].i.disk.raid_disk >= 0 &&
2671- devmap[j * content->array.raid_disks + devices[most_recent].i.disk.raid_disk] == 0) {
2672- if (verbose > -1)
2673- fprintf(stderr, Name ": ignoring %s as it reports %s as failed\n",
2674- devices[j].devname, devices[most_recent].devname);
2675- best[i] = -1;
2676- continue;
2677- }
2678- if (devices[j].i.events+event_margin >=
2679- devices[most_recent].i.events) {
2680- devices[j].uptodate = 1;
2681- if (i < content->array.raid_disks) {
2682- if (devices[j].i.recovery_start == MaxSector ||
2683- (content->reshape_active &&
2684- j >= content->array.raid_disks - content->delta_disks)) {
2685- okcnt++;
2686- avail[i]=1;
2687- } else
2688- rebuilding_cnt++;
2689- } else
2690- sparecnt++;
2691- }
2692- }
2693- free(devmap);
2694- while (force && !enough(content->array.level, content->array.raid_disks,
2695- content->array.layout, 1,
2696- avail, okcnt)) {
2697- /* Choose the newest best drive which is
2698- * not up-to-date, update the superblock
2699- * and add it.
2700- */
2701- int fd;
2702- struct supertype *tst;
2703- unsigned long long current_events;
2704- chosen_drive = -1;
2705- for (i = 0; i < content->array.raid_disks && i < bestcnt; i++) {
2706- int j = best[i];
2707- if (j>=0 &&
2708- !devices[j].uptodate &&
2709- devices[j].i.recovery_start == MaxSector &&
2710- (chosen_drive < 0 ||
2711- devices[j].i.events
2712- > devices[chosen_drive].i.events))
2713- chosen_drive = j;
2714- }
2715- if (chosen_drive < 0)
2716- break;
2717- current_events = devices[chosen_drive].i.events;
2718- add_another:
2719- if (verbose >= 0)
2720- fprintf(stderr, Name ": forcing event count in %s(%d) from %d upto %d\n",
2721- devices[chosen_drive].devname,
2722- devices[chosen_drive].i.disk.raid_disk,
2723- (int)(devices[chosen_drive].i.events),
2724- (int)(devices[most_recent].i.events));
2725- fd = dev_open(devices[chosen_drive].devname, O_RDWR|O_EXCL);
2726- if (fd < 0) {
2727- fprintf(stderr, Name ": Couldn't open %s for write - not updating\n",
2728- devices[chosen_drive].devname);
2729- devices[chosen_drive].i.events = 0;
2730- continue;
2731- }
2732- tst = dup_super(st);
2733- if (tst->ss->load_super(tst,fd, NULL)) {
2734- close(fd);
2735- fprintf(stderr, Name ": RAID superblock disappeared from %s - not updating.\n",
2736- devices[chosen_drive].devname);
2737- devices[chosen_drive].i.events = 0;
2738- continue;
2739- }
2740- content->events = devices[most_recent].i.events;
2741- tst->ss->update_super(tst, content, "force-one",
2742- devices[chosen_drive].devname, verbose,
2743- 0, NULL);
2744-
2745- if (tst->ss->store_super(tst, fd)) {
2746- close(fd);
2747- fprintf(stderr, Name ": Could not re-write superblock on %s\n",
2748- devices[chosen_drive].devname);
2749- devices[chosen_drive].i.events = 0;
2750- tst->ss->free_super(tst);
2751- continue;
2752- }
2753- close(fd);
2754- devices[chosen_drive].i.events = devices[most_recent].i.events;
2755- devices[chosen_drive].uptodate = 1;
2756- avail[chosen_drive] = 1;
2757- okcnt++;
2758- tst->ss->free_super(tst);
2759-
2760- /* If there are any other drives of the same vintage,
2761- * add them in as well. We can't lose and we might gain
2762- */
2763- for (i = 0; i < content->array.raid_disks && i < bestcnt ; i++) {
2764- int j = best[i];
2765- if (j >= 0 &&
2766- !devices[j].uptodate &&
2767- devices[j].i.events == current_events) {
2768- chosen_drive = j;
2769- goto add_another;
2770- }
2771- }
2772- }
2773-
2774- /* Now we want to look at the superblock which the kernel will base things on
2775- * and compare the devices that we think are working with the devices that the
2776- * superblock thinks are working.
2777- * If there are differences and --force is given, then update this chosen
2778- * superblock.
2779- */
2780- chosen_drive = -1;
2781- st->ss->free_super(st);
2782- for (i=0; chosen_drive < 0 && i<bestcnt; i++) {
2783- int j = best[i];
2784- int fd;
2785-
2786- if (j<0)
2787- continue;
2788- if (!devices[j].uptodate)
2789- continue;
2790- if (devices[j].i.events < devices[most_recent].i.events)
2791- continue;
2792- chosen_drive = j;
2793- if ((fd=dev_open(devices[j].devname, O_RDONLY|O_EXCL))< 0) {
2794- fprintf(stderr, Name ": Cannot open %s: %s\n",
2795- devices[j].devname, strerror(errno));
2796- close(mdfd);
2797- free(devices);
2798- return 1;
2799- }
2800- if (st->ss->load_super(st,fd, NULL)) {
2801- close(fd);
2802- fprintf(stderr, Name ": RAID superblock has disappeared from %s\n",
2803- devices[j].devname);
2804- close(mdfd);
2805- free(devices);
2806- return 1;
2807- }
2808- close(fd);
2809- }
2810- if (st->sb == NULL) {
2811- fprintf(stderr, Name ": No suitable drives found for %s\n", mddev);
2812- close(mdfd);
2813- free(devices);
2814- return 1;
2815- }
2816- st->ss->getinfo_super(st, content, NULL);
2817-#ifndef MDASSEMBLE
2818- sysfs_init(content, mdfd, 0);
2819-#endif
2820- for (i=0; i<bestcnt; i++) {
2821- int j = best[i];
2822- unsigned int desired_state;
2823-
2824- if (i < content->array.raid_disks)
2825- desired_state = (1<<MD_DISK_ACTIVE) | (1<<MD_DISK_SYNC);
2826- else
2827- desired_state = 0;
2828-
2829- if (j<0)
2830- continue;
2831- if (!devices[j].uptodate)
2832- continue;
2833-
2834- devices[j].i.disk.state = desired_state;
2835- if (!(devices[j].i.array.state & 1))
2836- clean = 0;
2837-
2838- if (st->ss->update_super(st, &devices[j].i, "assemble", NULL,
2839- verbose, 0, NULL)) {
2840- if (force) {
2841- if (verbose >= 0)
2842- fprintf(stderr, Name ": "
2843- "clearing FAULTY flag for device %d in %s for %s\n",
2844- j, mddev, devices[j].devname);
2845- change = 1;
2846- } else {
2847- if (verbose >= -1)
2848- fprintf(stderr, Name ": "
2849- "device %d in %s has wrong state in superblock, but %s seems ok\n",
2850- i, mddev, devices[j].devname);
2851- }
2852- }
2853-#if 0
2854- if (!(super.disks[i].i.disk.state & (1 << MD_DISK_FAULTY))) {
2855- fprintf(stderr, Name ": devices %d of %s is not marked FAULTY in superblock, but cannot be found\n",
2856- i, mddev);
2857- }
2858-#endif
2859- }
2860- if (force && !clean &&
2861- !enough(content->array.level, content->array.raid_disks,
2862- content->array.layout, clean,
2863- avail, okcnt)) {
2864- change += st->ss->update_super(st, content, "force-array",
2865- devices[chosen_drive].devname, verbose,
2866- 0, NULL);
2867- clean = 1;
2868- }
2869-
2870- if (change) {
2871- int fd;
2872- fd = dev_open(devices[chosen_drive].devname, O_RDWR|O_EXCL);
2873- if (fd < 0) {
2874- fprintf(stderr, Name ": Could not open %s for write - cannot Assemble array.\n",
2875- devices[chosen_drive].devname);
2876- close(mdfd);
2877- free(devices);
2878- return 1;
2879- }
2880- if (st->ss->store_super(st, fd)) {
2881- close(fd);
2882- fprintf(stderr, Name ": Could not re-write superblock on %s\n",
2883- devices[chosen_drive].devname);
2884- close(mdfd);
2885- free(devices);
2886- return 1;
2887- }
2888- if (verbose >= 0)
2889- fprintf(stderr, Name ": Marking array %s as 'clean'\n",
2890- mddev);
2891- close(fd);
2892- }
2893-
2894- /* If we are in the middle of a reshape we may need to restore saved data
2895- * that was moved aside due to the reshape overwriting live data
2896- * The code of doing this lives in Grow.c
2897- */
2898-#ifndef MDASSEMBLE
2899- if (content->reshape_active) {
2900- int err = 0;
2901- int *fdlist = malloc(sizeof(int)* bestcnt);
2902- if (verbose > 0)
2903- fprintf(stderr, Name ":%s has an active reshape - checking "
2904- "if critical section needs to be restored\n",
2905- chosen_name);
2906- for (i=0; i<bestcnt; i++) {
2907- int j = best[i];
2908- if (j >= 0) {
2909- fdlist[i] = dev_open(devices[j].devname, O_RDWR|O_EXCL);
2910- if (fdlist[i] < 0) {
2911- fprintf(stderr, Name ": Could not open %s for write - cannot Assemble array.\n",
2912- devices[j].devname);
2913- err = 1;
2914- break;
2915- }
2916- } else
2917- fdlist[i] = -1;
2918- }
2919- if (!err) {
2920- if (st->ss->external && st->ss->recover_backup)
2921- err = st->ss->recover_backup(st, content);
2922- else
2923- err = Grow_restart(st, content, fdlist, bestcnt,
2924- backup_file, verbose > 0);
2925- if (err && invalid_backup) {
2926- if (verbose > 0)
2927- fprintf(stderr, Name ": continuing"
2928- " without restoring backup\n");
2929- err = 0;
2930- }
2931- }
2932- while (i>0) {
2933- i--;
2934- if (fdlist[i]>=0) close(fdlist[i]);
2935- }
2936- if (err) {
2937- fprintf(stderr, Name ": Failed to restore critical section for reshape, sorry.\n");
2938- if (backup_file == NULL)
2939- fprintf(stderr," Possibly you needed to specify the --backup-file\n");
2940- close(mdfd);
2941- free(devices);
2942- return err;
2943- }
2944- }
2945-#endif
2946- /* count number of in-sync devices according to the superblock.
2947- * We must have this number to start the array without -s or -R
2948- */
2949- req_cnt = content->array.working_disks;
2950-
2951- /* Almost ready to actually *do* something */
2952- if (!old_linux) {
2953- int rv;
2954-
2955- /* First, fill in the map, so that udev can find our name
2956- * as soon as we become active.
2957- */
2958- map_update(NULL, fd2devnum(mdfd), content->text_version,
2959- content->uuid, chosen_name);
2960-
2961- rv = set_array_info(mdfd, st, content);
2962- if (rv) {
2963- fprintf(stderr, Name ": failed to set array info for %s: %s\n",
2964- mddev, strerror(errno));
2965- ioctl(mdfd, STOP_ARRAY, NULL);
2966- close(mdfd);
2967- free(devices);
2968- return 1;
2969- }
2970- if (ident->bitmap_fd >= 0) {
2971- if (ioctl(mdfd, SET_BITMAP_FILE, ident->bitmap_fd) != 0) {
2972- fprintf(stderr, Name ": SET_BITMAP_FILE failed.\n");
2973- ioctl(mdfd, STOP_ARRAY, NULL);
2974- close(mdfd);
2975- free(devices);
2976- return 1;
2977- }
2978- } else if (ident->bitmap_file) {
2979- /* From config file */
2980- int bmfd = open(ident->bitmap_file, O_RDWR);
2981- if (bmfd < 0) {
2982- fprintf(stderr, Name ": Could not open bitmap file %s\n",
2983- ident->bitmap_file);
2984- ioctl(mdfd, STOP_ARRAY, NULL);
2985- close(mdfd);
2986- free(devices);
2987- return 1;
2988- }
2989- if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) {
2990- fprintf(stderr, Name ": Failed to set bitmapfile for %s\n", mddev);
2991- close(bmfd);
2992- ioctl(mdfd, STOP_ARRAY, NULL);
2993- close(mdfd);
2994- free(devices);
2995- return 1;
2996- }
2997- close(bmfd);
2998- }
2999-
3000- /* First, add the raid disks, but add the chosen one last */
3001- for (i=0; i<= bestcnt; i++) {
3002- int j;
3003- if (i < bestcnt) {
3004- j = best[i];
3005- if (j == chosen_drive)
3006- continue;
3007- } else
3008- j = chosen_drive;
3009-
3010- if (j >= 0 /* && devices[j].uptodate */) {
3011- int dfd = dev_open(devices[j].devname,
3012- O_RDWR|O_EXCL);
3013- if (dfd >= 0) {
3014- remove_partitions(dfd);
3015- close(dfd);
3016- }
3017- rv = add_disk(mdfd, st, content, &devices[j].i);
3018-
3019- if (rv) {
3020- fprintf(stderr, Name ": failed to add "
3021- "%s to %s: %s\n",
3022- devices[j].devname,
3023- mddev,
3024- strerror(errno));
3025- if (i < content->array.raid_disks
3026- || i == bestcnt)
3027- okcnt--;
3028- else
3029- sparecnt--;
3030- } else if (verbose > 0)
3031- fprintf(stderr, Name ": added %s "
3032- "to %s as %d\n",
3033- devices[j].devname, mddev,
3034- devices[j].i.disk.raid_disk);
3035- } else if (verbose > 0 && i < content->array.raid_disks)
3036- fprintf(stderr, Name ": no uptodate device for "
3037- "slot %d of %s\n",
3038- i, mddev);
3039- }
3040-
3041- if (content->array.level == LEVEL_CONTAINER) {
3042- if (verbose >= 0) {
3043- fprintf(stderr, Name ": Container %s has been "
3044- "assembled with %d drive%s",
3045- mddev, okcnt+sparecnt, okcnt+sparecnt==1?"":"s");
3046- if (okcnt < (unsigned)content->array.raid_disks)
3047- fprintf(stderr, " (out of %d)",
3048- content->array.raid_disks);
3049- fprintf(stderr, "\n");
3050- }
3051- st->ss->free_super(st);
3052- sysfs_uevent(content, "change");
3053- wait_for(chosen_name, mdfd);
3054- close(mdfd);
3055- free(devices);
3056- return 0;
3057- }
3058-
3059- if (runstop == 1 ||
3060- (runstop <= 0 &&
3061- ( enough(content->array.level, content->array.raid_disks,
3062- content->array.layout, clean, avail, okcnt) &&
3063- (okcnt + rebuilding_cnt >= req_cnt || start_partial_ok)
3064- ))) {
3065- /* This array is good-to-go.
3066- * If a reshape is in progress then we might need to
3067- * continue monitoring it. In that case we start
3068- * it read-only and let the grow code make it writable.
3069- */
3070- int rv;
3071-#ifndef MDASSEMBLE
3072- if (content->reshape_active &&
3073- content->delta_disks <= 0) {
3074- rv = sysfs_set_str(content, NULL,
3075- "array_state", "readonly");
3076- if (rv == 0)
3077- rv = Grow_continue(mdfd, st, content,
3078- backup_file,
3079- freeze_reshape);
3080- } else
3081-#endif
3082- rv = ioctl(mdfd, RUN_ARRAY, NULL);
3083- if (rv == 0) {
3084- if (verbose >= 0) {
3085- fprintf(stderr, Name ": %s has been started with %d drive%s",
3086- mddev, okcnt, okcnt==1?"":"s");
3087- if (okcnt < (unsigned)content->array.raid_disks)
3088- fprintf(stderr, " (out of %d)", content->array.raid_disks);
3089- if (rebuilding_cnt)
3090- fprintf(stderr, "%s %d rebuilding", sparecnt?",":" and", rebuilding_cnt);
3091- if (sparecnt)
3092- fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
3093- fprintf(stderr, ".\n");
3094- }
3095- if (content->reshape_active &&
3096- content->array.level >= 4 &&
3097- content->array.level <= 6) {
3098- /* might need to increase the size
3099- * of the stripe cache - default is 256
3100- */
3101- if (256 < 4 * (content->array.chunk_size/4096)) {
3102- struct mdinfo *sra = sysfs_read(mdfd, 0, 0);
3103- if (sra)
3104- sysfs_set_num(sra, NULL,
3105- "stripe_cache_size",
3106- (4 * content->array.chunk_size / 4096) + 1);
3107- sysfs_free(sra);
3108- }
3109- }
3110- if (okcnt < (unsigned)content->array.raid_disks) {
3111- /* If any devices did not get added
3112- * because the kernel rejected them based
3113- * on event count, try adding them
3114- * again providing the action policy is
3115- * 're-add' or greater. The bitmap
3116- * might allow them to be included, or
3117- * they will become spares.
3118- */
3119- for (i = 0; i < bestcnt; i++) {
3120- int j = best[i];
3121- if (j >= 0 && !devices[j].uptodate) {
3122- if (!disk_action_allows(&devices[j].i, st->ss->name, act_re_add))
3123- continue;
3124- rv = add_disk(mdfd, st, content,
3125- &devices[j].i);
3126- if (rv == 0 && verbose >= 0)
3127- fprintf(stderr,
3128- Name ": %s has been re-added.\n",
3129- devices[j].devname);
3130- }
3131- }
3132- }
3133- wait_for(mddev, mdfd);
3134- close(mdfd);
3135- if (auto_assem) {
3136- int usecs = 1;
3137- /* There is a nasty race with 'mdadm --monitor'.
3138- * If it opens this device before we close it,
3139- * it gets an incomplete open on which IO
3140- * doesn't work and the capacity is
3141- * wrong.
3142- * If we reopen (to check for layered devices)
3143- * before --monitor closes, we loose.
3144- *
3145- * So: wait upto 1 second for there to be
3146- * a non-zero capacity.
3147- */
3148- while (usecs < 1000) {
3149- mdfd = open(mddev, O_RDONLY);
3150- if (mdfd >= 0) {
3151- unsigned long long size;
3152- if (get_dev_size(mdfd, NULL, &size) &&
3153- size > 0)
3154- break;
3155- close(mdfd);
3156- }
3157- usleep(usecs);
3158- usecs <<= 1;
3159- }
3160- }
3161- free(devices);
3162- return 0;
3163- }
3164- fprintf(stderr, Name ": failed to RUN_ARRAY %s: %s\n",
3165- mddev, strerror(errno));
3166-
3167- if (!enough(content->array.level, content->array.raid_disks,
3168- content->array.layout, 1, avail, okcnt))
3169- fprintf(stderr, Name ": Not enough devices to "
3170- "start the array.\n");
3171- else if (!enough(content->array.level,
3172- content->array.raid_disks,
3173- content->array.layout, clean,
3174- avail, okcnt))
3175- fprintf(stderr, Name ": Not enough devices to "
3176- "start the array while not clean "
3177- "- consider --force.\n");
3178-
3179- if (auto_assem)
3180- ioctl(mdfd, STOP_ARRAY, NULL);
3181- close(mdfd);
3182- free(devices);
3183- return 1;
3184- }
3185- if (runstop == -1) {
3186- fprintf(stderr, Name ": %s assembled from %d drive%s",
3187- mddev, okcnt, okcnt==1?"":"s");
3188- if (okcnt != (unsigned)content->array.raid_disks)
3189- fprintf(stderr, " (out of %d)", content->array.raid_disks);
3190- fprintf(stderr, ", but not started.\n");
3191- close(mdfd);
3192- free(devices);
3193- return 0;
3194- }
3195- if (verbose >= -1) {
3196- fprintf(stderr, Name ": %s assembled from %d drive%s", mddev, okcnt, okcnt==1?"":"s");
3197- if (rebuilding_cnt)
3198- fprintf(stderr, "%s %d rebuilding", sparecnt?", ":" and ", rebuilding_cnt);
3199- if (sparecnt)
3200- fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
3201- if (!enough(content->array.level, content->array.raid_disks,
3202- content->array.layout, 1, avail, okcnt))
3203- fprintf(stderr, " - not enough to start the array.\n");
3204- else if (!enough(content->array.level,
3205- content->array.raid_disks,
3206- content->array.layout, clean,
3207- avail, okcnt))
3208- fprintf(stderr, " - not enough to start the "
3209- "array while not clean - consider "
3210- "--force.\n");
3211- else {
3212- if (req_cnt == (unsigned)content->array.raid_disks)
3213- fprintf(stderr, " - need all %d to start it", req_cnt);
3214- else
3215- fprintf(stderr, " - need %d of %d to start", req_cnt, content->array.raid_disks);
3216- fprintf(stderr, " (use --run to insist).\n");
3217- }
3218- }
3219- if (auto_assem)
3220- ioctl(mdfd, STOP_ARRAY, NULL);
3221- close(mdfd);
3222- free(devices);
3223- return 1;
3224- } else {
3225- /* The "chosen_drive" is a good choice, and if necessary, the superblock has
3226- * been updated to point to the current locations of devices.
3227- * so we can just start the array
3228- */
3229- unsigned long dev;
3230- dev = makedev(devices[chosen_drive].i.disk.major,
3231- devices[chosen_drive].i.disk.minor);
3232- if (ioctl(mdfd, START_ARRAY, dev)) {
3233- fprintf(stderr, Name ": Cannot start array: %s\n",
3234- strerror(errno));
3235- }
3236-
3237- }
3238- close(mdfd);
3239- free(devices);
3240- return 0;
3241-}
3242-
3243-#ifndef MDASSEMBLE
3244-int assemble_container_content(struct supertype *st, int mdfd,
3245- struct mdinfo *content, int runstop,
3246- char *chosen_name, int verbose,
3247- char *backup_file, int freeze_reshape)
3248-{
3249- struct mdinfo *dev, *sra;
3250- int working = 0, preexist = 0;
3251- int expansion = 0;
3252- struct map_ent *map = NULL;
3253- int old_raid_disks;
3254-
3255- sysfs_init(content, mdfd, 0);
3256-
3257- sra = sysfs_read(mdfd, 0, GET_VERSION);
3258- if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0)
3259- if (sysfs_set_array(content, md_get_version(mdfd)) != 0) {
3260- if (sra)
3261- sysfs_free(sra);
3262- return 1;
3263- }
3264-
3265- if (st->ss->external && content->recovery_blocked)
3266- block_subarray(content);
3267-
3268- if (sra)
3269- sysfs_free(sra);
3270- old_raid_disks = content->array.raid_disks - content->delta_disks;
3271- for (dev = content->devs; dev; dev = dev->next)
3272- if (sysfs_add_disk(content, dev, 1) == 0) {
3273- if (dev->disk.raid_disk >= old_raid_disks &&
3274- content->reshape_active)
3275- expansion++;
3276- else
3277- working++;
3278- } else if (errno == EEXIST)
3279- preexist++;
3280- if (working == 0)
3281- return 1;/* Nothing new, don't try to start */
3282-
3283- map_update(&map, fd2devnum(mdfd),
3284- content->text_version,
3285- content->uuid, chosen_name);
3286-
3287- if (runstop > 0 ||
3288- (working + preexist + expansion) >=
3289- content->array.working_disks) {
3290- int err;
3291- int start_reshape;
3292-
3293- /* There are two types of reshape: container wide or sub-array specific
3294- * Check if metadata requests blocking container wide reshapes
3295- */
3296- start_reshape = (content->reshape_active &&
3297- !((content->reshape_active == CONTAINER_RESHAPE) &&
3298- (content->array.state & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE))));
3299- if (start_reshape) {
3300- int spare = content->array.raid_disks + expansion;
3301- if (restore_backup(st, content,
3302- working,
3303- spare, backup_file, verbose) == 1)
3304- return 1;
3305-
3306- err = sysfs_set_str(content, NULL,
3307- "array_state", "readonly");
3308- if (err)
3309- return 1;
3310-
3311- if (st->ss->external) {
3312- if (!mdmon_running(st->container_dev))
3313- start_mdmon(st->container_dev);
3314- ping_monitor_by_id(st->container_dev);
3315- if (mdmon_running(st->container_dev) &&
3316- st->update_tail == NULL)
3317- st->update_tail = &st->updates;
3318- }
3319-
3320- err = Grow_continue(mdfd, st, content, backup_file,
3321- freeze_reshape);
3322- } else switch(content->array.level) {
3323- case LEVEL_LINEAR:
3324- case LEVEL_MULTIPATH:
3325- case 0:
3326- err = sysfs_set_str(content, NULL, "array_state",
3327- "active");
3328- break;
3329- default:
3330- err = sysfs_set_str(content, NULL, "array_state",
3331- "readonly");
3332- /* start mdmon if needed. */
3333- if (!err) {
3334- if (!mdmon_running(st->container_dev))
3335- start_mdmon(st->container_dev);
3336- ping_monitor_by_id(st->container_dev);
3337- }
3338- break;
3339- }
3340- if (!err)
3341- sysfs_set_safemode(content, content->safe_mode_delay);
3342- if (verbose >= 0) {
3343- if (err)
3344- fprintf(stderr, Name
3345- ": array %s now has %d device%s",
3346- chosen_name, working + preexist,
3347- working + preexist == 1 ? "":"s");
3348- else
3349- fprintf(stderr, Name
3350- ": Started %s with %d device%s",
3351- chosen_name, working + preexist,
3352- working + preexist == 1 ? "":"s");
3353- if (preexist)
3354- fprintf(stderr, " (%d new)", working);
3355- if (expansion)
3356- fprintf(stderr, " ( + %d for expansion)",
3357- expansion);
3358- fprintf(stderr, "\n");
3359- }
3360- if (!err)
3361- wait_for(chosen_name, mdfd);
3362- return err;
3363- /* FIXME should have an O_EXCL and wait for read-auto */
3364- } else {
3365- if (verbose >= 0) {
3366- fprintf(stderr, Name
3367- ": %s assembled with %d device%s",
3368- chosen_name, preexist + working,
3369- preexist + working == 1 ? "":"s");
3370- if (preexist)
3371- fprintf(stderr, " (%d new)", working);
3372- fprintf(stderr, " but not started\n");
3373- }
3374- return 1;
3375- }
3376-}
3377-#endif
3378-
3379
3380=== added file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/ReadMe.c'
3381--- .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/ReadMe.c 1970-01-01 00:00:00 +0000
3382+++ .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/ReadMe.c 2012-06-18 08:55:05 +0000
3383@@ -0,0 +1,608 @@
3384+/*
3385+ * mdadm - manage Linux "md" devices aka RAID arrays.
3386+ *
3387+ * Copyright (C) 2001-2010 Neil Brown <neilb@suse.de>
3388+ *
3389+ *
3390+ * This program is free software; you can redistribute it and/or modify
3391+ * it under the terms of the GNU General Public License as published by
3392+ * the Free Software Foundation; either version 2 of the License, or
3393+ * (at your option) any later version.
3394+ *
3395+ * This program is distributed in the hope that it will be useful,
3396+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3397+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3398+ * GNU General Public License for more details.
3399+ *
3400+ * You should have received a copy of the GNU General Public License
3401+ * along with this program; if not, write to the Free Software
3402+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3403+ *
3404+ * Author: Neil Brown
3405+ * Email: <neilb@suse.de>
3406+ */
3407+
3408+#include "mdadm.h"
3409+
3410+char Version[] = Name " - v3.2.5 - 18th May 2012\n";
3411+
3412+/*
3413+ * File: ReadMe.c
3414+ *
3415+ * This file contains general comments about the implementation
3416+ * and the various usage messages that can be displayed by mdadm
3417+ *
3418+ * mdadm is a single program that can be used to control Linux md devices.
3419+ * It is intended to provide all the functionality of the mdtools and
3420+ * raidtools but with a very different interface.
3421+ * mdadm can perform all functions without a configuration file.
3422+ * There is the option of using a configuration file, but not in the same
3423+ * way that raidtools uses one
3424+ * raidtools uses a configuration file to describe how to create a RAID
3425+ * array, and also uses this file partially to start a previously
3426+ * created RAID array. Further, raidtools requires the configuration
3427+ * file for such things as stopping a raid array which needs to know
3428+ * nothing about the array.
3429+ *
3430+ * The configuration file that can be used by mdadm lists two
3431+ * different things:
3432+ * 1/ a mapping from uuid to md device to identify which arrays are
3433+ * expect and what names (numbers) they should be given
3434+ * 2/ a list of devices that should be scanned for md sub-devices
3435+ *
3436+ *
3437+ */
3438+
3439+/*
3440+ * mdadm has 7 major modes of operation:
3441+ * 1/ Create
3442+ * This mode is used to create a new array with a superblock
3443+ * It can progress in several step create-add-add-run
3444+ * or it can all happen with one command
3445+ * 2/ Assemble
3446+ * This mode is used to assemble the parts of a previously created
3447+ * array into an active array. Components can be explicitly given
3448+ * or can be searched for. mdadm (optionally) check that the components
3449+ * do form a bona-fide array, and can, on request, fiddle superblock
3450+ * version numbers so as to assemble a faulty array.
3451+ * 3/ Build
3452+ * This is for building legacy arrays without superblocks
3453+ * 4/ Manage
3454+ * This is for doing something to one or more devices
3455+ * in an array, such as add,remove,fail.
3456+ * run/stop/readonly/readwrite are also available
3457+ * 5/ Misc
3458+ * This is for doing things to individual devices.
3459+ * They might be parts of an array so
3460+ * zero-superblock, examine might be appropriate
3461+ * They might be md arrays so
3462+ * run,stop,rw,ro,detail might be appropriate
3463+ * Also query will treat it as either
3464+ * 6/ Monitor
3465+ * This mode never exits but just monitors arrays and reports changes.
3466+ * 7/ Grow
3467+ * This mode allows for changing of key attributes of a raid array, such
3468+ * as size, number of devices, and possibly even layout.
3469+ * At the time if writing, there is only minimal support.
3470+ */
3471+
3472+char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
3473+char short_bitmap_options[]=
3474+ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
3475+char short_bitmap_auto_options[]=
3476+ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:";
3477+
3478+struct option long_options[] = {
3479+ {"manage", 0, 0, ManageOpt},
3480+ {"misc", 0, 0, MiscOpt},
3481+ {"assemble", 0, 0, 'A'},
3482+ {"build", 0, 0, 'B'},
3483+ {"create", 0, 0, 'C'},
3484+ {"detail", 0, 0, 'D'},
3485+ {"examine", 0, 0, 'E'},
3486+ {"follow", 0, 0, 'F'},
3487+ {"grow", 0, 0, 'G'},
3488+ {"incremental",0,0, 'I'},
3489+ {"zero-superblock", 0, 0, 'K'}, /* deliberately no a short_option */
3490+ {"query", 0, 0, 'Q'},
3491+ {"examine-bitmap", 0, 0, 'X'},
3492+ {"auto-detect", 0, 0, AutoDetect},
3493+ {"detail-platform", 0, 0, DetailPlatform},
3494+ {"kill-subarray", 1, 0, KillSubarray},
3495+ {"update-subarray", 1, 0, UpdateSubarray},
3496+ {"udev-rules", 2, 0, UdevRules},
3497+ {"offroot", 0, 0, OffRootOpt},
3498+
3499+ /* synonyms */
3500+ {"monitor", 0, 0, 'F'},
3501+
3502+ /* after those will normally come the name of the md device */
3503+ {"help", 0, 0, 'h'},
3504+ {"help-options",0,0, HelpOptions},
3505+ {"version", 0, 0, 'V'},
3506+ {"verbose", 0, 0, 'v'},
3507+ {"quiet", 0, 0, 'q'},
3508+
3509+ /* For create or build: */
3510+ {"chunk", 1, 0, ChunkSize},
3511+ {"rounding", 1, 0, ChunkSize}, /* for linear, chunk is really a
3512+ * rounding number */
3513+ {"level", 1, 0, 'l'}, /* 0,1,4,5,6,linear */
3514+ {"parity", 1, 0, Layout}, /* {left,right}-{a,}symmetric */
3515+ {"layout", 1, 0, Layout},
3516+ {"raid-disks",1, 0, 'n'},
3517+ {"raid-devices",1, 0, 'n'},
3518+ {"spare-disks",1,0, 'x'},
3519+ {"spare-devices",1,0, 'x'},
3520+ {"size", 1, 0, 'z'},
3521+ {"auto", 1, 0, Auto}, /* also for --assemble */
3522+ {"assume-clean",0,0, AssumeClean },
3523+ {"metadata", 1, 0, 'e'}, /* superblock format */
3524+ {"bitmap", 1, 0, Bitmap},
3525+ {"bitmap-chunk", 1, 0, BitmapChunk},
3526+ {"write-behind", 2, 0, WriteBehind},
3527+ {"write-mostly",0, 0, WriteMostly},
3528+ {"re-add", 0, 0, ReAdd},
3529+ {"homehost", 1, 0, HomeHost},
3530+ {"symlinks", 1, 0, Symlinks},
3531+
3532+ /* For assemble */
3533+ {"uuid", 1, 0, 'u'},
3534+ {"super-minor",1,0, SuperMinor},
3535+ {"name", 1, 0, 'N'},
3536+ {"config", 1, 0, ConfigFile},
3537+ {"scan", 0, 0, 's'},
3538+ {"force", 0, 0, Force},
3539+ {"update", 1, 0, 'U'},
3540+ {"freeze-reshape", 0, 0, FreezeReshape},
3541+
3542+ /* Management */
3543+ {"add", 0, 0, Add},
3544+ {"remove", 0, 0, Remove},
3545+ {"fail", 0, 0, Fail},
3546+ {"set-faulty",0, 0, Fail},
3547+ {"run", 0, 0, 'R'},
3548+ {"stop", 0, 0, 'S'},
3549+ {"readonly", 0, 0, 'o'},
3550+ {"readwrite", 0, 0, 'w'},
3551+ {"no-degraded",0,0, NoDegraded },
3552+ {"wait", 0, 0, WaitOpt},
3553+ {"wait-clean", 0, 0, Waitclean },
3554+
3555+ /* For Detail/Examine */
3556+ {"brief", 0, 0, Brief},
3557+ {"export", 0, 0, 'Y'},
3558+ {"sparc2.2", 0, 0, Sparc22},
3559+ {"test", 0, 0, 't'},
3560+ {"prefer", 1, 0, Prefer},
3561+
3562+ /* For Follow/monitor */
3563+ {"mail", 1, 0, EMail},
3564+ {"program", 1, 0, ProgramOpt},
3565+ {"alert", 1, 0, ProgramOpt},
3566+ {"increment", 1, 0, Increment},
3567+ {"delay", 1, 0, 'd'},
3568+ {"daemonise", 0, 0, Fork},
3569+ {"daemonize", 0, 0, Fork},
3570+ {"oneshot", 0, 0, '1'},
3571+ {"pid-file", 1, 0, 'i'},
3572+ {"syslog", 0, 0, 'y'},
3573+ {"no-sharing", 0, 0, NoSharing},
3574+
3575+ /* For Grow */
3576+ {"backup-file", 1,0, BackupFile},
3577+ {"invalid-backup",0,0,InvalidBackup},
3578+ {"array-size", 1, 0, 'Z'},
3579+ {"continue", 0, 0, Continue},
3580+
3581+ /* For Incremental */
3582+ {"rebuild-map", 0, 0, RebuildMapOpt},
3583+ {"path", 1, 0, IncrementalPath},
3584+
3585+ {0, 0, 0, 0}
3586+};
3587+
3588+char Usage[] =
3589+"Usage: mdadm --help\n"
3590+" for help\n"
3591+;
3592+
3593+char Help[] =
3594+"mdadm is used for building, managing, and monitoring\n"
3595+"Linux md devices (aka RAID arrays)\n"
3596+"Usage: mdadm --create device options...\n"
3597+" Create a new array from unused devices.\n"
3598+" mdadm --assemble device options...\n"
3599+" Assemble a previously created array.\n"
3600+" mdadm --build device options...\n"
3601+" Create or assemble an array without metadata.\n"
3602+" mdadm --manage device options...\n"
3603+" make changes to an existing array.\n"
3604+" mdadm --misc options... devices\n"
3605+" report on or modify various md related devices.\n"
3606+" mdadm --grow options device\n"
3607+" resize/reshape an active array\n"
3608+" mdadm --incremental device\n"
3609+" add/remove a device to/from an array as appropriate\n"
3610+" mdadm --monitor options...\n"
3611+" Monitor one or more array for significant changes.\n"
3612+" mdadm device options...\n"
3613+" Shorthand for --manage.\n"
3614+"Any parameter that does not start with '-' is treated as a device name\n"
3615+"or, for --examine-bitmap, a file name.\n"
3616+"The first such name is often the name of an md device. Subsequent\n"
3617+"names are often names of component devices.\n"
3618+"\n"
3619+" For detailed help on the above major modes use --help after the mode\n"
3620+" e.g.\n"
3621+" mdadm --assemble --help\n"
3622+" For general help on options use\n"
3623+" mdadm --help-options\n"
3624+;
3625+
3626+char OptionHelp[] =
3627+"Any parameter that does not start with '-' is treated as a device name\n"
3628+"or, for --examine-bitmap, a file name.\n"
3629+"The first such name is often the name of an md device. Subsequent\n"
3630+"names are often names of component devices.\n"
3631+"\n"
3632+"Some common options are:\n"
3633+" --help -h : General help message or, after above option,\n"
3634+" mode specific help message\n"
3635+" --help-options : This help message\n"
3636+" --version -V : Print version information for mdadm\n"
3637+" --verbose -v : Be more verbose about what is happening\n"
3638+" --quiet -q : Don't print un-necessary messages\n"
3639+" --brief -b : Be less verbose, more brief\n"
3640+" --export -Y : With --detail, use key=value format for easy\n"
3641+" import into environment\n"
3642+" --force -f : Override normal checks and be more forceful\n"
3643+"\n"
3644+" --assemble -A : Assemble an array\n"
3645+" --build -B : Build an array without metadata\n"
3646+" --create -C : Create a new array\n"
3647+" --detail -D : Display details of an array\n"
3648+" --examine -E : Examine superblock on an array component\n"
3649+" --examine-bitmap -X: Display the detail of a bitmap file\n"
3650+" --monitor -F : monitor (follow) some arrays\n"
3651+" --grow -G : resize/ reshape and array\n"
3652+" --incremental -I : add/remove a single device to/from an array as appropriate\n"
3653+" --query -Q : Display general information about how a\n"
3654+" device relates to the md driver\n"
3655+" --auto-detect : Start arrays auto-detected by the kernel\n"
3656+" --offroot : Set first character of argv[0] to @ to indicate the\n"
3657+" application was launched from initrd/initramfs and\n"
3658+" should not be shutdown by systemd as part of the\n"
3659+" regular shutdown process.\n"
3660+;
3661+/*
3662+"\n"
3663+" For create or build:\n"
3664+" --bitmap= -b : File to store bitmap in - may pre-exist for --build\n"
3665+" --chunk= -c : chunk size of kibibytes\n"
3666+" --rounding= : rounding factor for linear array (==chunk size)\n"
3667+" --level= -l : raid level: 0,1,4,5,6,linear,mp. 0 or linear for build\n"
3668+" --parity= -p : raid5/6 parity algorithm: {left,right}-{,a}symmetric\n"
3669+" --layout= : same as --parity\n"
3670+" --raid-devices= -n : number of active devices in array\n"
3671+" --spare-devices= -x: number of spares (eXtras) devices in initial array\n"
3672+" --size= -z : Size (in K) of each drive in RAID1/4/5/6/10 - optional\n"
3673+" --force -f : Honour devices as listed on command line. Don't\n"
3674+" : insert a missing drive for RAID5.\n"
3675+" --assume-clean : Assume the array is already in-sync. This is dangerous.\n"
3676+" --bitmap-chunk= : chunksize of bitmap in bitmap file (Kilobytes)\n"
3677+" --delay= -d : seconds between bitmap updates\n"
3678+" --write-behind= : number of simultaneous write-behind requests to allow (requires bitmap)\n"
3679+" --name= -N : Textual name for array - max 32 characters\n"
3680+"\n"
3681+" For assemble:\n"
3682+" --bitmap= -b : File to find bitmap information in\n"
3683+" --uuid= -u : uuid of array to assemble. Devices which don't\n"
3684+" have this uuid are excluded\n"
3685+" --super-minor= -m : minor number to look for in super-block when\n"
3686+" choosing devices to use.\n"
3687+" --name= -N : Array name to look for in super-block.\n"
3688+" --config= -c : config file\n"
3689+" --scan -s : scan config file for missing information\n"
3690+" --force -f : Assemble the array even if some superblocks appear out-of-date\n"
3691+" --update= -U : Update superblock: try '-A --update=?' for list of options.\n"
3692+" --no-degraded : Do not start any degraded arrays - default unless --scan.\n"
3693+"\n"
3694+" For detail or examine:\n"
3695+" --brief -b : Just print device name and UUID\n"
3696+"\n"
3697+" For follow/monitor:\n"
3698+" --mail= -m : Address to mail alerts of failure to\n"
3699+" --program= -p : Program to run when an event is detected\n"
3700+" --alert= : same as --program\n"
3701+" --delay= -d : seconds of delay between polling state. default=60\n"
3702+"\n"
3703+" General management:\n"
3704+" --add -a : add, or hotadd subsequent devices\n"
3705+" --remove -r : remove subsequent devices\n"
3706+" --fail -f : mark subsequent devices a faulty\n"
3707+" --set-faulty : same as --fail\n"
3708+" --run -R : start a partially built array\n"
3709+" --stop -S : deactivate array, releasing all resources\n"
3710+" --readonly -o : mark array as readonly\n"
3711+" --readwrite -w : mark array as readwrite\n"
3712+" --zero-superblock : erase the MD superblock from a device.\n"
3713+" --wait -W : wait for recovery/resync/reshape to finish.\n"
3714+;
3715+*/
3716+
3717+char Help_create[] =
3718+"Usage: mdadm --create device -chunk=X --level=Y --raid-devices=Z devices\n"
3719+"\n"
3720+" This usage will initialise a new md array, associate some\n"
3721+" devices with it, and activate the array. In order to create an\n"
3722+" array with some devices missing, use the special word 'missing' in\n"
3723+" place of the relevant device name.\n"
3724+"\n"
3725+" Before devices are added, they are checked to see if they already contain\n"
3726+" raid superblocks or filesystems. They are also checked to see if\n"
3727+" the variance in device size exceeds 1%.\n"
3728+" If any discrepancy is found, the user will be prompted for confirmation\n"
3729+" before the array is created. The presence of a '--run' can override this\n"
3730+" caution.\n"
3731+"\n"
3732+" If the --size option is given then only that many kilobytes of each\n"
3733+" device is used, no matter how big each device is.\n"
3734+" If no --size is given, the apparent size of the smallest drive given\n"
3735+" is used for raid level 1 and greater, and the full device is used for\n"
3736+" other levels.\n"
3737+"\n"
3738+" Options that are valid with --create (-C) are:\n"
3739+" --bitmap= : Create a bitmap for the array with the given filename\n"
3740+" --chunk= -c : chunk size of kibibytes\n"
3741+" --rounding= : rounding factor for linear array (==chunk size)\n"
3742+" --level= -l : raid level: 0,1,4,5,6,linear,multipath and synonyms\n"
3743+" --parity= -p : raid5/6 parity algorithm: {left,right}-{,a}symmetric\n"
3744+" --layout= : same as --parity\n"
3745+" --raid-devices= -n : number of active devices in array\n"
3746+" --spare-devices= -x: number of spares (eXtras) devices in initial array\n"
3747+" --size= -z : Size (in K) of each drive in RAID1/4/5/6/10 - optional\n"
3748+" --force -f : Honour devices as listed on command line. Don't\n"
3749+" : insert a missing drive for RAID5.\n"
3750+" --run -R : insist of running the array even if not all\n"
3751+" : devices are present or some look odd.\n"
3752+" --readonly -o : start the array readonly - not supported yet.\n"
3753+" --name= -N : Textual name for array - max 32 characters\n"
3754+" --bitmap-chunk= : bitmap chunksize in Kilobytes.\n"
3755+" --delay= -d : bitmap update delay in seconds.\n"
3756+"\n"
3757+;
3758+
3759+char Help_build[] =
3760+"Usage: mdadm --build device -chunk=X --level=Y --raid-devices=Z devices\n"
3761+"\n"
3762+" This usage is similar to --create. The difference is that it creates\n"
3763+" a legacy array without a superblock. With these arrays there is no\n"
3764+" different between initially creating the array and subsequently\n"
3765+" assembling the array, except that hopefully there is useful data\n"
3766+" there in the second case.\n"
3767+"\n"
3768+" The level may only be 0, raid0, or linear.\n"
3769+" All devices must be listed and the array will be started once complete.\n"
3770+" Options that are valid with --build (-B) are:\n"
3771+" --bitmap= : file to store/find bitmap information in.\n"
3772+" --chunk= -c : chunk size of kibibytes\n"
3773+" --rounding= : rounding factor for linear array (==chunk size)\n"
3774+" --level= -l : 0, raid0, or linear\n"
3775+" --raid-devices= -n : number of active devices in array\n"
3776+" --bitmap-chunk= : bitmap chunksize in Kilobytes.\n"
3777+" --delay= -d : bitmap update delay in seconds.\n"
3778+;
3779+
3780+char Help_assemble[] =
3781+"Usage: mdadm --assemble device options...\n"
3782+" mdadm --assemble --scan options...\n"
3783+"\n"
3784+"This usage assembles one or more raid arrays from pre-existing\n"
3785+"components.\n"
3786+"For each array, mdadm needs to know the md device, the identity of\n"
3787+"the array, and a number of sub devices. These can be found in a number\n"
3788+"of ways.\n"
3789+"\n"
3790+"The md device is either given on the command line or is found listed\n"
3791+"in the config file. The array identity is determined either from the\n"
3792+"--uuid or --super-minor commandline arguments, from the config file,\n"
3793+"or from the first component device on the command line.\n"
3794+"\n"
3795+"The different combinations of these are as follows:\n"
3796+" If the --scan option is not given, then only devices and identities\n"
3797+" listed on the command line are considered.\n"
3798+" The first device will be the array device, and the remainder will be\n"
3799+" examined when looking for components.\n"
3800+" If an explicit identity is given with --uuid or --super-minor, then\n"
3801+" only devices with a superblock which matches that identity is considered,\n"
3802+" otherwise every device listed is considered.\n"
3803+"\n"
3804+" If the --scan option is given, and no devices are listed, then\n"
3805+" every array listed in the config file is considered for assembly.\n"
3806+" The identity of candidate devices are determined from the config file.\n"
3807+"\n"
3808+" If the --scan option is given as well as one or more devices, then\n"
3809+" Those devices are md devices that are to be assembled. Their identity\n"
3810+" and components are determined from the config file.\n"
3811+"\n"
3812+" If mdadm can not find all of the components for an array, it will assemble\n"
3813+" it but not activate it unless --run or --scan is given. To preserve this\n"
3814+" behaviour even with --scan, add --no-degraded. Note that \"all of the\n"
3815+" components\" means as many as were present the last time the array was running\n"
3816+" as recorded in the superblock. If the array was already degraded, and\n"
3817+" the missing device is not a new problem, it will still be assembled. It\n"
3818+" is only newly missing devices that cause the array not to be started.\n"
3819+"\n"
3820+"Options that are valid with --assemble (-A) are:\n"
3821+" --bitmap= : bitmap file to use wit the array\n"
3822+" --uuid= -u : uuid of array to assemble. Devices which don't\n"
3823+" have this uuid are excluded\n"
3824+" --super-minor= -m : minor number to look for in super-block when\n"
3825+" choosing devices to use.\n"
3826+" --name= -N : Array name to look for in super-block.\n"
3827+" --config= -c : config file\n"
3828+" --scan -s : scan config file for missing information\n"
3829+" --run -R : Try to start the array even if not enough devices\n"
3830+" for a full array are present\n"
3831+" --force -f : Assemble the array even if some superblocks appear\n"
3832+" : out-of-date. This involves modifying the superblocks.\n"
3833+" --update= -U : Update superblock: try '-A --update=?' for option list.\n"
3834+" --no-degraded : Assemble but do not start degraded arrays.\n"
3835+;
3836+
3837+char Help_manage[] =
3838+"Usage: mdadm arraydevice options component devices...\n"
3839+"\n"
3840+"This usage is for managing the component devices within an array.\n"
3841+"The --manage option is not needed and is assumed if the first argument\n"
3842+"is a device name or a management option.\n"
3843+"The first device listed will be taken to be an md array device, and\n"
3844+"subsequent devices are (potential) components of that array.\n"
3845+"\n"
3846+"Options that are valid with management mode are:\n"
3847+" --add -a : hotadd subsequent devices to the array\n"
3848+" --remove -r : remove subsequent devices, which must not be active\n"
3849+" --fail -f : mark subsequent devices a faulty\n"
3850+" --set-faulty : same as --fail\n"
3851+" --run -R : start a partially built array\n"
3852+" --stop -S : deactivate array, releasing all resources\n"
3853+" --readonly -o : mark array as readonly\n"
3854+" --readwrite -w : mark array as readwrite\n"
3855+;
3856+
3857+char Help_misc[] =
3858+"Usage: mdadm misc_option devices...\n"
3859+"\n"
3860+"This usage is for performing some task on one or more devices, which\n"
3861+"may be arrays or components, depending on the task.\n"
3862+"The --misc option is not needed (though it is allowed) and is assumed\n"
3863+"if the first argument in a misc option.\n"
3864+"\n"
3865+"Options that are valid with the miscellaneous mode are:\n"
3866+" --query -Q : Display general information about how a\n"
3867+" device relates to the md driver\n"
3868+" --detail -D : Display details of an array\n"
3869+" --detail-platform : Display hardware/firmware details\n"
3870+" --examine -E : Examine superblock on an array component\n"
3871+" --examine-bitmap -X: Display contents of a bitmap file\n"
3872+" --zero-superblock : erase the MD superblock from a device.\n"
3873+" --run -R : start a partially built array\n"
3874+" --stop -S : deactivate array, releasing all resources\n"
3875+" --readonly -o : mark array as readonly\n"
3876+" --readwrite -w : mark array as readwrite\n"
3877+" --test -t : exit status 0 if ok, 1 if degrade, 2 if dead, 4 if missing\n"
3878+" --wait -W : wait for resync/rebuild/recovery to finish\n"
3879+;
3880+
3881+char Help_monitor[] =
3882+"Usage: mdadm --monitor options devices\n"
3883+"\n"
3884+"This usage causes mdadm to monitor a number of md arrays by periodically\n"
3885+"polling their status and acting on any changes.\n"
3886+"If any devices are listed then those devices are monitored, otherwise\n"
3887+"all devices listed in the config file are monitored.\n"
3888+"The address for mailing advisories to, and the program to handle\n"
3889+"each change can be specified in the config file or on the command line.\n"
3890+"If no mail address or program are specified, then mdadm reports all\n"
3891+"state changes to stdout.\n"
3892+"\n"
3893+"Options that are valid with the monitor (-F --follow) mode are:\n"
3894+" --mail= -m : Address to mail alerts of failure to\n"
3895+" --program= -p : Program to run when an event is detected\n"
3896+" --alert= : same as --program\n"
3897+" --syslog -y : Report alerts via syslog\n"
3898+" --increment= -r : Report RebuildNN events in the given increment. default=20\n"
3899+" --delay= -d : seconds of delay between polling state. default=60\n"
3900+" --config= -c : specify a different config file\n"
3901+" --scan -s : find mail-address/program in config file\n"
3902+" --daemonise -f : Fork and continue in child, parent exits\n"
3903+" --pid-file= -i : In daemon mode write pid to specified file instead of stdout\n"
3904+" --oneshot -1 : Check for degraded arrays, then exit\n"
3905+" --test -t : Generate a TestMessage event against each array at startup\n"
3906+;
3907+
3908+char Help_grow[] =
3909+"Usage: mdadm --grow device options\n"
3910+"\n"
3911+"This usage causes mdadm to attempt to reconfigure a running array.\n"
3912+"This is only possibly if the kernel being used supports a particular\n"
3913+"reconfiguration. This version supports changing the number of\n"
3914+"devices in a RAID1/5/6, changing the active size of all devices in\n"
3915+"a RAID1/4/5/6, adding or removing a write-intent bitmap, and changing\n"
3916+"the error mode for a 'FAULTY' array.\n"
3917+"\n"
3918+"Options that are valid with the grow (-G --grow) mode are:\n"
3919+" --level= -l : Tell mdadm what level the array is so that it can\n"
3920+" : interpret '--layout' properly.\n"
3921+" --layout= -p : For a FAULTY array, set/change the error mode.\n"
3922+" --size= -z : Change the active size of devices in an array.\n"
3923+" : This is useful if all devices have been replaced\n"
3924+" : with larger devices. Value is in Kilobytes, or\n"
3925+" : the special word 'max' meaning 'as large as possible'.\n"
3926+" --raid-devices= -n : Change the number of active devices in an array.\n"
3927+" --bitmap= -b : Add or remove a write-intent bitmap.\n"
3928+" --backup-file= file : A file on a differt device to store data for a\n"
3929+" : short time while increasing raid-devices on a\n"
3930+" : RAID4/5/6 array. Not needed when a spare is present.\n"
3931+" --array-size= -Z : Change visible size of array. This does not change\n"
3932+" : any data on the device, and is not stable across restarts.\n"
3933+;
3934+
3935+char Help_incr[] =
3936+"Usage: mdadm --incremental [-Rqrsf] device\n"
3937+"\n"
3938+"This usage allows for incremental assembly of md arrays. Devices can be\n"
3939+"added one at a time as they are discovered. Once an array has all expected\n"
3940+"devices, it will be started.\n"
3941+"\n"
3942+"Optionally, the process can be reversed by using the fail option.\n"
3943+"When fail mode is invoked, mdadm will see if the device belongs to an array\n"
3944+"and then both fail (if needed) and remove the device from that array.\n"
3945+"\n"
3946+"Options that are valid with incremental assembly (-I --incremental) are:\n"
3947+" --run -R : Run arrays as soon as a minimal number of devices are\n"
3948+" : present rather than waiting for all expected.\n"
3949+" --quiet -q : Don't print any information messages, just errors.\n"
3950+" --rebuild-map -r : Rebuild the 'map' file that mdadm uses for tracking\n"
3951+" : partial arrays.\n"
3952+" --scan -s : Use with -R to start any arrays that have the minimal\n"
3953+" : required number of devices, but are not yet started.\n"
3954+" --fail -f : First fail (if needed) and then remove device from\n"
3955+" : any array that it is a member of.\n"
3956+;
3957+
3958+char Help_config[] =
3959+"The /etc/mdadm/mdadm.conf config file:\n\n"
3960+" The config file contains, apart from blank lines and comment lines that\n"
3961+" start with a hash(#), four sorts of configuration lines: array lines, \n"
3962+" device lines, mailaddr lines and program lines.\n"
3963+" Each configuration line is constructed of a number of space separated\n"
3964+" words, and can be continued on subsequent physical lines by indenting\n"
3965+" those lines.\n"
3966+"\n"
3967+" A device line starts with the word 'device' and then has a number of words\n"
3968+" which identify devices. These words should be names of devices in the\n"
3969+" filesystem, and can contain wildcards. There can be multiple words or each\n"
3970+" device line, and multiple device lines. All devices so listed are checked\n"
3971+" for relevant super blocks when assembling arrays.\n"
3972+"\n"
3973+" An array line start with the word 'array'. This is followed by the name of\n"
3974+" the array device in the filesystem, e.g. '/dev/md2'. Subsequent words\n"
3975+" describe the identity of the array, used to recognise devices to include in the\n"
3976+" array. The identity can be given as a UUID with a word starting 'uuid=', or\n"
3977+" as a minor-number stored in the superblock using 'super-minor=', or as a list\n"
3978+" of devices. This is given as a comma separated list of names, possibly\n"
3979+" containing wildcards, preceded by 'devices='. If multiple critea are given,\n"
3980+" than a device must match all of them to be considered.\n"
3981+"\n"
3982+" A mailaddr line starts with the word 'mailaddr' and should contain exactly\n"
3983+" one Email address. 'mdadm --monitor --scan' will send alerts of failed drives\n"
3984+" to this Email address."
3985+"\n"
3986+" A program line starts with the word 'program' and should contain exactly\n"
3987+" one program name. 'mdadm --monitor --scan' will run this program when any\n"
3988+" event is detected.\n"
3989+"\n"
3990+;
3991+
3992
3993=== removed file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/ReadMe.c'
3994--- .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/ReadMe.c 2012-02-09 16:53:02 +0000
3995+++ .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/ReadMe.c 1970-01-01 00:00:00 +0000
3996@@ -1,602 +0,0 @@
3997-/*
3998- * mdadm - manage Linux "md" devices aka RAID arrays.
3999- *
4000- * Copyright (C) 2001-2010 Neil Brown <neilb@suse.de>
4001- *
4002- *
4003- * This program is free software; you can redistribute it and/or modify
4004- * it under the terms of the GNU General Public License as published by
4005- * the Free Software Foundation; either version 2 of the License, or
4006- * (at your option) any later version.
4007- *
4008- * This program is distributed in the hope that it will be useful,
4009- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4010- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4011- * GNU General Public License for more details.
4012- *
4013- * You should have received a copy of the GNU General Public License
4014- * along with this program; if not, write to the Free Software
4015- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4016- *
4017- * Author: Neil Brown
4018- * Email: <neilb@suse.de>
4019- */
4020-
4021-#include "mdadm.h"
4022-
4023-char Version[] = Name " - v3.2.3 - 23rd December 2011\n";
4024-
4025-/*
4026- * File: ReadMe.c
4027- *
4028- * This file contains general comments about the implementation
4029- * and the various usage messages that can be displayed by mdadm
4030- *
4031- * mdadm is a single program that can be used to control Linux md devices.
4032- * It is intended to provide all the functionality of the mdtools and
4033- * raidtools but with a very different interface.
4034- * mdadm can perform all functions without a configuration file.
4035- * There is the option of using a configuration file, but not in the same
4036- * way that raidtools uses one
4037- * raidtools uses a configuration file to describe how to create a RAID
4038- * array, and also uses this file partially to start a previously
4039- * created RAID array. Further, raidtools requires the configuration
4040- * file for such things as stopping a raid array which needs to know
4041- * nothing about the array.
4042- *
4043- * The configuration file that can be used by mdadm lists two
4044- * different things:
4045- * 1/ a mapping from uuid to md device to identify which arrays are
4046- * expect and what names (numbers) they should be given
4047- * 2/ a list of devices that should be scanned for md sub-devices
4048- *
4049- *
4050- */
4051-
4052-/*
4053- * mdadm has 7 major modes of operation:
4054- * 1/ Create
4055- * This mode is used to create a new array with a superblock
4056- * It can progress in several step create-add-add-run
4057- * or it can all happen with one command
4058- * 2/ Assemble
4059- * This mode is used to assemble the parts of a previously created
4060- * array into an active array. Components can be explicitly given
4061- * or can be searched for. mdadm (optionally) check that the components
4062- * do form a bona-fide array, and can, on request, fiddle superblock
4063- * version numbers so as to assemble a faulty array.
4064- * 3/ Build
4065- * This is for building legacy arrays without superblocks
4066- * 4/ Manage
4067- * This is for doing something to one or more devices
4068- * in an array, such as add,remove,fail.
4069- * run/stop/readonly/readwrite are also available
4070- * 5/ Misc
4071- * This is for doing things to individual devices.
4072- * They might be parts of an array so
4073- * zero-superblock, examine might be appropriate
4074- * They might be md arrays so
4075- * run,stop,rw,ro,detail might be appropriate
4076- * Also query will treat it as either
4077- * 6/ Monitor
4078- * This mode never exits but just monitors arrays and reports changes.
4079- * 7/ Grow
4080- * This mode allows for changing of key attributes of a raid array, such
4081- * as size, number of devices, and possibly even layout.
4082- * At the time if writing, there is only minimal support.
4083- */
4084-
4085-char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
4086-char short_bitmap_options[]=
4087- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
4088-char short_bitmap_auto_options[]=
4089- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:";
4090-
4091-struct option long_options[] = {
4092- {"manage", 0, 0, ManageOpt},
4093- {"misc", 0, 0, MiscOpt},
4094- {"assemble", 0, 0, 'A'},
4095- {"build", 0, 0, 'B'},
4096- {"create", 0, 0, 'C'},
4097- {"detail", 0, 0, 'D'},
4098- {"examine", 0, 0, 'E'},
4099- {"follow", 0, 0, 'F'},
4100- {"grow", 0, 0, 'G'},
4101- {"incremental",0,0, 'I'},
4102- {"zero-superblock", 0, 0, 'K'}, /* deliberately no a short_option */
4103- {"query", 0, 0, 'Q'},
4104- {"examine-bitmap", 0, 0, 'X'},
4105- {"auto-detect", 0, 0, AutoDetect},
4106- {"detail-platform", 0, 0, DetailPlatform},
4107- {"kill-subarray", 1, 0, KillSubarray},
4108- {"update-subarray", 1, 0, UpdateSubarray},
4109- {"udev-rules", 2, 0, UdevRules},
4110-
4111- /* synonyms */
4112- {"monitor", 0, 0, 'F'},
4113-
4114- /* after those will normally come the name of the md device */
4115- {"help", 0, 0, 'h'},
4116- {"help-options",0,0, HelpOptions},
4117- {"version", 0, 0, 'V'},
4118- {"verbose", 0, 0, 'v'},
4119- {"quiet", 0, 0, 'q'},
4120-
4121- /* For create or build: */
4122- {"chunk", 1, 0, ChunkSize},
4123- {"rounding", 1, 0, ChunkSize}, /* for linear, chunk is really a
4124- * rounding number */
4125- {"level", 1, 0, 'l'}, /* 0,1,4,5,6,linear */
4126- {"parity", 1, 0, Layout}, /* {left,right}-{a,}symmetric */
4127- {"layout", 1, 0, Layout},
4128- {"raid-disks",1, 0, 'n'},
4129- {"raid-devices",1, 0, 'n'},
4130- {"spare-disks",1,0, 'x'},
4131- {"spare-devices",1,0, 'x'},
4132- {"size", 1, 0, 'z'},
4133- {"auto", 1, 0, Auto}, /* also for --assemble */
4134- {"assume-clean",0,0, AssumeClean },
4135- {"metadata", 1, 0, 'e'}, /* superblock format */
4136- {"bitmap", 1, 0, Bitmap},
4137- {"bitmap-chunk", 1, 0, BitmapChunk},
4138- {"write-behind", 2, 0, WriteBehind},
4139- {"write-mostly",0, 0, WriteMostly},
4140- {"re-add", 0, 0, ReAdd},
4141- {"homehost", 1, 0, HomeHost},
4142- {"symlinks", 1, 0, Symlinks},
4143-
4144- /* For assemble */
4145- {"uuid", 1, 0, 'u'},
4146- {"super-minor",1,0, SuperMinor},
4147- {"name", 1, 0, 'N'},
4148- {"config", 1, 0, ConfigFile},
4149- {"scan", 0, 0, 's'},
4150- {"force", 0, 0, Force},
4151- {"update", 1, 0, 'U'},
4152- {"freeze-reshape", 0, 0, FreezeReshape},
4153-
4154- /* Management */
4155- {"add", 0, 0, Add},
4156- {"remove", 0, 0, Remove},
4157- {"fail", 0, 0, Fail},
4158- {"set-faulty",0, 0, Fail},
4159- {"run", 0, 0, 'R'},
4160- {"stop", 0, 0, 'S'},
4161- {"readonly", 0, 0, 'o'},
4162- {"readwrite", 0, 0, 'w'},
4163- {"no-degraded",0,0, NoDegraded },
4164- {"wait", 0, 0, WaitOpt},
4165- {"wait-clean", 0, 0, Waitclean },
4166-
4167- /* For Detail/Examine */
4168- {"brief", 0, 0, Brief},
4169- {"export", 0, 0, 'Y'},
4170- {"sparc2.2", 0, 0, Sparc22},
4171- {"test", 0, 0, 't'},
4172-
4173- /* For Follow/monitor */
4174- {"mail", 1, 0, EMail},
4175- {"program", 1, 0, ProgramOpt},
4176- {"alert", 1, 0, ProgramOpt},
4177- {"increment", 1, 0, Increment},
4178- {"delay", 1, 0, 'd'},
4179- {"daemonise", 0, 0, Fork},
4180- {"daemonize", 0, 0, Fork},
4181- {"oneshot", 0, 0, '1'},
4182- {"pid-file", 1, 0, 'i'},
4183- {"syslog", 0, 0, 'y'},
4184- {"no-sharing", 0, 0, NoSharing},
4185-
4186- /* For Grow */
4187- {"backup-file", 1,0, BackupFile},
4188- {"invalid-backup",0,0,InvalidBackup},
4189- {"array-size", 1, 0, 'Z'},
4190- {"continue", 0, 0, Continue},
4191-
4192- /* For Incremental */
4193- {"rebuild-map", 0, 0, RebuildMapOpt},
4194- {"path", 1, 0, IncrementalPath},
4195-
4196- {0, 0, 0, 0}
4197-};
4198-
4199-char Usage[] =
4200-"Usage: mdadm --help\n"
4201-" for help\n"
4202-;
4203-
4204-char Help[] =
4205-"mdadm is used for building, managing, and monitoring\n"
4206-"Linux md devices (aka RAID arrays)\n"
4207-"Usage: mdadm --create device options...\n"
4208-" Create a new array from unused devices.\n"
4209-" mdadm --assemble device options...\n"
4210-" Assemble a previously created array.\n"
4211-" mdadm --build device options...\n"
4212-" Create or assemble an array without metadata.\n"
4213-" mdadm --manage device options...\n"
4214-" make changes to an existing array.\n"
4215-" mdadm --misc options... devices\n"
4216-" report on or modify various md related devices.\n"
4217-" mdadm --grow options device\n"
4218-" resize/reshape an active array\n"
4219-" mdadm --incremental device\n"
4220-" add/remove a device to/from an array as appropriate\n"
4221-" mdadm --monitor options...\n"
4222-" Monitor one or more array for significant changes.\n"
4223-" mdadm device options...\n"
4224-" Shorthand for --manage.\n"
4225-"Any parameter that does not start with '-' is treated as a device name\n"
4226-"or, for --examine-bitmap, a file name.\n"
4227-"The first such name is often the name of an md device. Subsequent\n"
4228-"names are often names of component devices.\n"
4229-"\n"
4230-" For detailed help on the above major modes use --help after the mode\n"
4231-" e.g.\n"
4232-" mdadm --assemble --help\n"
4233-" For general help on options use\n"
4234-" mdadm --help-options\n"
4235-;
4236-
4237-char OptionHelp[] =
4238-"Any parameter that does not start with '-' is treated as a device name\n"
4239-"or, for --examine-bitmap, a file name.\n"
4240-"The first such name is often the name of an md device. Subsequent\n"
4241-"names are often names of component devices.\n"
4242-"\n"
4243-"Some common options are:\n"
4244-" --help -h : General help message or, after above option,\n"
4245-" mode specific help message\n"
4246-" --help-options : This help message\n"
4247-" --version -V : Print version information for mdadm\n"
4248-" --verbose -v : Be more verbose about what is happening\n"
4249-" --quiet -q : Don't print un-necessary messages\n"
4250-" --brief -b : Be less verbose, more brief\n"
4251-" --export -Y : With --detail, use key=value format for easy\n"
4252-" import into environment\n"
4253-" --force -f : Override normal checks and be more forceful\n"
4254-"\n"
4255-" --assemble -A : Assemble an array\n"
4256-" --build -B : Build an array without metadata\n"
4257-" --create -C : Create a new array\n"
4258-" --detail -D : Display details of an array\n"
4259-" --examine -E : Examine superblock on an array component\n"
4260-" --examine-bitmap -X: Display the detail of a bitmap file\n"
4261-" --monitor -F : monitor (follow) some arrays\n"
4262-" --grow -G : resize/ reshape and array\n"
4263-" --incremental -I : add/remove a single device to/from an array as appropriate\n"
4264-" --query -Q : Display general information about how a\n"
4265-" device relates to the md driver\n"
4266-" --auto-detect : Start arrays auto-detected by the kernel\n"
4267-;
4268-/*
4269-"\n"
4270-" For create or build:\n"
4271-" --bitmap= -b : File to store bitmap in - may pre-exist for --build\n"
4272-" --chunk= -c : chunk size of kibibytes\n"
4273-" --rounding= : rounding factor for linear array (==chunk size)\n"
4274-" --level= -l : raid level: 0,1,4,5,6,linear,mp. 0 or linear for build\n"
4275-" --parity= -p : raid5/6 parity algorithm: {left,right}-{,a}symmetric\n"
4276-" --layout= : same as --parity\n"
4277-" --raid-devices= -n : number of active devices in array\n"
4278-" --spare-devices= -x: number of spares (eXtras) devices in initial array\n"
4279-" --size= -z : Size (in K) of each drive in RAID1/4/5/6/10 - optional\n"
4280-" --force -f : Honour devices as listed on command line. Don't\n"
4281-" : insert a missing drive for RAID5.\n"
4282-" --assume-clean : Assume the array is already in-sync. This is dangerous.\n"
4283-" --bitmap-chunk= : chunksize of bitmap in bitmap file (Kilobytes)\n"
4284-" --delay= -d : seconds between bitmap updates\n"
4285-" --write-behind= : number of simultaneous write-behind requests to allow (requires bitmap)\n"
4286-" --name= -N : Textual name for array - max 32 characters\n"
4287-"\n"
4288-" For assemble:\n"
4289-" --bitmap= -b : File to find bitmap information in\n"
4290-" --uuid= -u : uuid of array to assemble. Devices which don't\n"
4291-" have this uuid are excluded\n"
4292-" --super-minor= -m : minor number to look for in super-block when\n"
4293-" choosing devices to use.\n"
4294-" --name= -N : Array name to look for in super-block.\n"
4295-" --config= -c : config file\n"
4296-" --scan -s : scan config file for missing information\n"
4297-" --force -f : Assemble the array even if some superblocks appear out-of-date\n"
4298-" --update= -U : Update superblock: try '-A --update=?' for list of options.\n"
4299-" --no-degraded : Do not start any degraded arrays - default unless --scan.\n"
4300-"\n"
4301-" For detail or examine:\n"
4302-" --brief -b : Just print device name and UUID\n"
4303-"\n"
4304-" For follow/monitor:\n"
4305-" --mail= -m : Address to mail alerts of failure to\n"
4306-" --program= -p : Program to run when an event is detected\n"
4307-" --alert= : same as --program\n"
4308-" --delay= -d : seconds of delay between polling state. default=60\n"
4309-"\n"
4310-" General management:\n"
4311-" --add -a : add, or hotadd subsequent devices\n"
4312-" --remove -r : remove subsequent devices\n"
4313-" --fail -f : mark subsequent devices a faulty\n"
4314-" --set-faulty : same as --fail\n"
4315-" --run -R : start a partially built array\n"
4316-" --stop -S : deactivate array, releasing all resources\n"
4317-" --readonly -o : mark array as readonly\n"
4318-" --readwrite -w : mark array as readwrite\n"
4319-" --zero-superblock : erase the MD superblock from a device.\n"
4320-" --wait -W : wait for recovery/resync/reshape to finish.\n"
4321-;
4322-*/
4323-
4324-char Help_create[] =
4325-"Usage: mdadm --create device -chunk=X --level=Y --raid-devices=Z devices\n"
4326-"\n"
4327-" This usage will initialise a new md array, associate some\n"
4328-" devices with it, and activate the array. In order to create an\n"
4329-" array with some devices missing, use the special word 'missing' in\n"
4330-" place of the relevant device name.\n"
4331-"\n"
4332-" Before devices are added, they are checked to see if they already contain\n"
4333-" raid superblocks or filesystems. They are also checked to see if\n"
4334-" the variance in device size exceeds 1%.\n"
4335-" If any discrepancy is found, the user will be prompted for confirmation\n"
4336-" before the array is created. The presence of a '--run' can override this\n"
4337-" caution.\n"
4338-"\n"
4339-" If the --size option is given then only that many kilobytes of each\n"
4340-" device is used, no matter how big each device is.\n"
4341-" If no --size is given, the apparent size of the smallest drive given\n"
4342-" is used for raid level 1 and greater, and the full device is used for\n"
4343-" other levels.\n"
4344-"\n"
4345-" Options that are valid with --create (-C) are:\n"
4346-" --bitmap= : Create a bitmap for the array with the given filename\n"
4347-" --chunk= -c : chunk size of kibibytes\n"
4348-" --rounding= : rounding factor for linear array (==chunk size)\n"
4349-" --level= -l : raid level: 0,1,4,5,6,linear,multipath and synonyms\n"
4350-" --parity= -p : raid5/6 parity algorithm: {left,right}-{,a}symmetric\n"
4351-" --layout= : same as --parity\n"
4352-" --raid-devices= -n : number of active devices in array\n"
4353-" --spare-devices= -x: number of spares (eXtras) devices in initial array\n"
4354-" --size= -z : Size (in K) of each drive in RAID1/4/5/6/10 - optional\n"
4355-" --force -f : Honour devices as listed on command line. Don't\n"
4356-" : insert a missing drive for RAID5.\n"
4357-" --run -R : insist of running the array even if not all\n"
4358-" : devices are present or some look odd.\n"
4359-" --readonly -o : start the array readonly - not supported yet.\n"
4360-" --name= -N : Textual name for array - max 32 characters\n"
4361-" --bitmap-chunk= : bitmap chunksize in Kilobytes.\n"
4362-" --delay= -d : bitmap update delay in seconds.\n"
4363-"\n"
4364-;
4365-
4366-char Help_build[] =
4367-"Usage: mdadm --build device -chunk=X --level=Y --raid-devices=Z devices\n"
4368-"\n"
4369-" This usage is similar to --create. The difference is that it creates\n"
4370-" a legacy array without a superblock. With these arrays there is no\n"
4371-" different between initially creating the array and subsequently\n"
4372-" assembling the array, except that hopefully there is useful data\n"
4373-" there in the second case.\n"
4374-"\n"
4375-" The level may only be 0, raid0, or linear.\n"
4376-" All devices must be listed and the array will be started once complete.\n"
4377-" Options that are valid with --build (-B) are:\n"
4378-" --bitmap= : file to store/find bitmap information in.\n"
4379-" --chunk= -c : chunk size of kibibytes\n"
4380-" --rounding= : rounding factor for linear array (==chunk size)\n"
4381-" --level= -l : 0, raid0, or linear\n"
4382-" --raid-devices= -n : number of active devices in array\n"
4383-" --bitmap-chunk= : bitmap chunksize in Kilobytes.\n"
4384-" --delay= -d : bitmap update delay in seconds.\n"
4385-;
4386-
4387-char Help_assemble[] =
4388-"Usage: mdadm --assemble device options...\n"
4389-" mdadm --assemble --scan options...\n"
4390-"\n"
4391-"This usage assembles one or more raid arrays from pre-existing\n"
4392-"components.\n"
4393-"For each array, mdadm needs to know the md device, the identity of\n"
4394-"the array, and a number of sub devices. These can be found in a number\n"
4395-"of ways.\n"
4396-"\n"
4397-"The md device is either given on the command line or is found listed\n"
4398-"in the config file. The array identity is determined either from the\n"
4399-"--uuid or --super-minor commandline arguments, from the config file,\n"
4400-"or from the first component device on the command line.\n"
4401-"\n"
4402-"The different combinations of these are as follows:\n"
4403-" If the --scan option is not given, then only devices and identities\n"
4404-" listed on the command line are considered.\n"
4405-" The first device will be the array device, and the remainder will be\n"
4406-" examined when looking for components.\n"
4407-" If an explicit identity is given with --uuid or --super-minor, then\n"
4408-" only devices with a superblock which matches that identity is considered,\n"
4409-" otherwise every device listed is considered.\n"
4410-"\n"
4411-" If the --scan option is given, and no devices are listed, then\n"
4412-" every array listed in the config file is considered for assembly.\n"
4413-" The identity of candidate devices are determined from the config file.\n"
4414-"\n"
4415-" If the --scan option is given as well as one or more devices, then\n"
4416-" Those devices are md devices that are to be assembled. Their identity\n"
4417-" and components are determined from the config file.\n"
4418-"\n"
4419-" If mdadm can not find all of the components for an array, it will assemble\n"
4420-" it but not activate it unless --run or --scan is given. To preserve this\n"
4421-" behaviour even with --scan, add --no-degraded. Note that \"all of the\n"
4422-" components\" means as many as were present the last time the array was running\n"
4423-" as recorded in the superblock. If the array was already degraded, and\n"
4424-" the missing device is not a new problem, it will still be assembled. It\n"
4425-" is only newly missing devices that cause the array not to be started.\n"
4426-"\n"
4427-"Options that are valid with --assemble (-A) are:\n"
4428-" --bitmap= : bitmap file to use wit the array\n"
4429-" --uuid= -u : uuid of array to assemble. Devices which don't\n"
4430-" have this uuid are excluded\n"
4431-" --super-minor= -m : minor number to look for in super-block when\n"
4432-" choosing devices to use.\n"
4433-" --name= -N : Array name to look for in super-block.\n"
4434-" --config= -c : config file\n"
4435-" --scan -s : scan config file for missing information\n"
4436-" --run -R : Try to start the array even if not enough devices\n"
4437-" for a full array are present\n"
4438-" --force -f : Assemble the array even if some superblocks appear\n"
4439-" : out-of-date. This involves modifying the superblocks.\n"
4440-" --update= -U : Update superblock: try '-A --update=?' for option list.\n"
4441-" --no-degraded : Assemble but do not start degraded arrays.\n"
4442-;
4443-
4444-char Help_manage[] =
4445-"Usage: mdadm arraydevice options component devices...\n"
4446-"\n"
4447-"This usage is for managing the component devices within an array.\n"
4448-"The --manage option is not needed and is assumed if the first argument\n"
4449-"is a device name or a management option.\n"
4450-"The first device listed will be taken to be an md array device, and\n"
4451-"subsequent devices are (potential) components of that array.\n"
4452-"\n"
4453-"Options that are valid with management mode are:\n"
4454-" --add -a : hotadd subsequent devices to the array\n"
4455-" --remove -r : remove subsequent devices, which must not be active\n"
4456-" --fail -f : mark subsequent devices a faulty\n"
4457-" --set-faulty : same as --fail\n"
4458-" --run -R : start a partially built array\n"
4459-" --stop -S : deactivate array, releasing all resources\n"
4460-" --readonly -o : mark array as readonly\n"
4461-" --readwrite -w : mark array as readwrite\n"
4462-;
4463-
4464-char Help_misc[] =
4465-"Usage: mdadm misc_option devices...\n"
4466-"\n"
4467-"This usage is for performing some task on one or more devices, which\n"
4468-"may be arrays or components, depending on the task.\n"
4469-"The --misc option is not needed (though it is allowed) and is assumed\n"
4470-"if the first argument in a misc option.\n"
4471-"\n"
4472-"Options that are valid with the miscellaneous mode are:\n"
4473-" --query -Q : Display general information about how a\n"
4474-" device relates to the md driver\n"
4475-" --detail -D : Display details of an array\n"
4476-" --detail-platform : Display hardware/firmware details\n"
4477-" --examine -E : Examine superblock on an array component\n"
4478-" --examine-bitmap -X: Display contents of a bitmap file\n"
4479-" --zero-superblock : erase the MD superblock from a device.\n"
4480-" --run -R : start a partially built array\n"
4481-" --stop -S : deactivate array, releasing all resources\n"
4482-" --readonly -o : mark array as readonly\n"
4483-" --readwrite -w : mark array as readwrite\n"
4484-" --test -t : exit status 0 if ok, 1 if degrade, 2 if dead, 4 if missing\n"
4485-" --wait -W : wait for resync/rebuild/recovery to finish\n"
4486-;
4487-
4488-char Help_monitor[] =
4489-"Usage: mdadm --monitor options devices\n"
4490-"\n"
4491-"This usage causes mdadm to monitor a number of md arrays by periodically\n"
4492-"polling their status and acting on any changes.\n"
4493-"If any devices are listed then those devices are monitored, otherwise\n"
4494-"all devices listed in the config file are monitored.\n"
4495-"The address for mailing advisories to, and the program to handle\n"
4496-"each change can be specified in the config file or on the command line.\n"
4497-"If no mail address or program are specified, then mdadm reports all\n"
4498-"state changes to stdout.\n"
4499-"\n"
4500-"Options that are valid with the monitor (-F --follow) mode are:\n"
4501-" --mail= -m : Address to mail alerts of failure to\n"
4502-" --program= -p : Program to run when an event is detected\n"
4503-" --alert= : same as --program\n"
4504-" --syslog -y : Report alerts via syslog\n"
4505-" --increment= -r : Report RebuildNN events in the given increment. default=20\n"
4506-" --delay= -d : seconds of delay between polling state. default=60\n"
4507-" --config= -c : specify a different config file\n"
4508-" --scan -s : find mail-address/program in config file\n"
4509-" --daemonise -f : Fork and continue in child, parent exits\n"
4510-" --pid-file= -i : In daemon mode write pid to specified file instead of stdout\n"
4511-" --oneshot -1 : Check for degraded arrays, then exit\n"
4512-" --test -t : Generate a TestMessage event against each array at startup\n"
4513-;
4514-
4515-char Help_grow[] =
4516-"Usage: mdadm --grow device options\n"
4517-"\n"
4518-"This usage causes mdadm to attempt to reconfigure a running array.\n"
4519-"This is only possibly if the kernel being used supports a particular\n"
4520-"reconfiguration. This version supports changing the number of\n"
4521-"devices in a RAID1/5/6, changing the active size of all devices in\n"
4522-"a RAID1/4/5/6, adding or removing a write-intent bitmap, and changing\n"
4523-"the error mode for a 'FAULTY' array.\n"
4524-"\n"
4525-"Options that are valid with the grow (-G --grow) mode are:\n"
4526-" --level= -l : Tell mdadm what level the array is so that it can\n"
4527-" : interpret '--layout' properly.\n"
4528-" --layout= -p : For a FAULTY array, set/change the error mode.\n"
4529-" --size= -z : Change the active size of devices in an array.\n"
4530-" : This is useful if all devices have been replaced\n"
4531-" : with larger devices. Value is in Kilobytes, or\n"
4532-" : the special word 'max' meaning 'as large as possible'.\n"
4533-" --raid-devices= -n : Change the number of active devices in an array.\n"
4534-" --bitmap= -b : Add or remove a write-intent bitmap.\n"
4535-" --backup-file= file : A file on a differt device to store data for a\n"
4536-" : short time while increasing raid-devices on a\n"
4537-" : RAID4/5/6 array. Not needed when a spare is present.\n"
4538-" --array-size= -Z : Change visible size of array. This does not change\n"
4539-" : any data on the device, and is not stable across restarts.\n"
4540-;
4541-
4542-char Help_incr[] =
4543-"Usage: mdadm --incremental [-Rqrsf] device\n"
4544-"\n"
4545-"This usage allows for incremental assembly of md arrays. Devices can be\n"
4546-"added one at a time as they are discovered. Once an array has all expected\n"
4547-"devices, it will be started.\n"
4548-"\n"
4549-"Optionally, the process can be reversed by using the fail option.\n"
4550-"When fail mode is invoked, mdadm will see if the device belongs to an array\n"
4551-"and then both fail (if needed) and remove the device from that array.\n"
4552-"\n"
4553-"Options that are valid with incremental assembly (-I --incremental) are:\n"
4554-" --run -R : Run arrays as soon as a minimal number of devices are\n"
4555-" : present rather than waiting for all expected.\n"
4556-" --quiet -q : Don't print any information messages, just errors.\n"
4557-" --rebuild-map -r : Rebuild the 'map' file that mdadm uses for tracking\n"
4558-" : partial arrays.\n"
4559-" --scan -s : Use with -R to start any arrays that have the minimal\n"
4560-" : required number of devices, but are not yet started.\n"
4561-" --fail -f : First fail (if needed) and then remove device from\n"
4562-" : any array that it is a member of.\n"
4563-;
4564-
4565-char Help_config[] =
4566-"The /etc/mdadm/mdadm.conf config file:\n\n"
4567-" The config file contains, apart from blank lines and comment lines that\n"
4568-" start with a hash(#), four sorts of configuration lines: array lines, \n"
4569-" device lines, mailaddr lines and program lines.\n"
4570-" Each configuration line is constructed of a number of space separated\n"
4571-" words, and can be continued on subsequent physical lines by indenting\n"
4572-" those lines.\n"
4573-"\n"
4574-" A device line starts with the word 'device' and then has a number of words\n"
4575-" which identify devices. These words should be names of devices in the\n"
4576-" filesystem, and can contain wildcards. There can be multiple words or each\n"
4577-" device line, and multiple device lines. All devices so listed are checked\n"
4578-" for relevant super blocks when assembling arrays.\n"
4579-"\n"
4580-" An array line start with the word 'array'. This is followed by the name of\n"
4581-" the array device in the filesystem, e.g. '/dev/md2'. Subsequent words\n"
4582-" describe the identity of the array, used to recognise devices to include in the\n"
4583-" array. The identity can be given as a UUID with a word starting 'uuid=', or\n"
4584-" as a minor-number stored in the superblock using 'super-minor=', or as a list\n"
4585-" of devices. This is given as a comma separated list of names, possibly\n"
4586-" containing wildcards, preceded by 'devices='. If multiple critea are given,\n"
4587-" than a device must match all of them to be considered.\n"
4588-"\n"
4589-" A mailaddr line starts with the word 'mailaddr' and should contain exactly\n"
4590-" one Email address. 'mdadm --monitor --scan' will send alerts of failed drives\n"
4591-" to this Email address."
4592-"\n"
4593-" A program line starts with the word 'program' and should contain exactly\n"
4594-" one program name. 'mdadm --monitor --scan' will run this program when any\n"
4595-" event is detected.\n"
4596-"\n"
4597-;
4598-
4599
4600=== added directory '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/check.d'
4601=== removed directory '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/check.d'
4602=== added file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/check.d/_numbers'
4603=== removed file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/check.d/_numbers'
4604=== added file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/check.d/root_on_raid'
4605=== removed file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/check.d/root_on_raid'
4606=== added file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/config.c'
4607--- .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/config.c 1970-01-01 00:00:00 +0000
4608+++ .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/config.c 2012-06-18 08:55:05 +0000
4609@@ -0,0 +1,1131 @@
4610+/*
4611+ * mdadm - manage Linux "md" devices aka RAID arrays.
4612+ *
4613+ * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
4614+ *
4615+ *
4616+ * This program is free software; you can redistribute it and/or modify
4617+ * it under the terms of the GNU General Public License as published by
4618+ * the Free Software Foundation; either version 2 of the License, or
4619+ * (at your option) any later version.
4620+ *
4621+ * This program is distributed in the hope that it will be useful,
4622+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4623+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4624+ * GNU General Public License for more details.
4625+ *
4626+ * You should have received a copy of the GNU General Public License
4627+ * along with this program; if not, write to the Free Software
4628+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4629+ *
4630+ * Author: Neil Brown
4631+ * Email: <neilb@suse.de>
4632+ */
4633+
4634+#include "mdadm.h"
4635+#include "dlink.h"
4636+#include <dirent.h>
4637+#include <glob.h>
4638+#include <fnmatch.h>
4639+#include <ctype.h>
4640+#include <pwd.h>
4641+#include <grp.h>
4642+
4643+/*
4644+ * Read the config file
4645+ *
4646+ * conf_get_uuids gets a list of devicename+uuid pairs
4647+ * conf_get_devs gets device names after expanding wildcards
4648+ *
4649+ * Each keeps the returned list and frees it when asked to make
4650+ * a new list.
4651+ *
4652+ * The format of the config file needs to be fairly extensible.
4653+ * Now, arrays only have names and uuids and devices merely are.
4654+ * But later arrays might want names, and devices might want superblock
4655+ * versions, and who knows what else.
4656+ * I like free format, abhore backslash line continuation, adore
4657+ * indentation for structure and am ok about # comments.
4658+ *
4659+ * So, each line that isn't blank or a #comment must either start
4660+ * with a key word, and not be indented, or must start with a
4661+ * non-key-word and must be indented.
4662+ *
4663+ * Keywords are DEVICE and ARRAY ... and several others.
4664+ * DEV{ICE} introduces some devices that might contain raid components.
4665+ * e.g.
4666+ * DEV style=0 /dev/sda* /dev/hd*
4667+ * DEV style=1 /dev/sd[b-f]*
4668+ * ARR{AY} describes an array giving md device and attributes like uuid=whatever
4669+ * e.g.
4670+ * ARRAY /dev/md0 uuid=whatever name=something
4671+ * Spaces separate words on each line. Quoting, with "" or '' protects them,
4672+ * but may not wrap over lines
4673+ *
4674+ */
4675+
4676+#ifndef CONFFILE
4677+#define CONFFILE "/etc/mdadm.conf"
4678+#endif
4679+#ifndef CONFFILE2
4680+/* for Debian compatibility .... */
4681+#define CONFFILE2 "/etc/mdadm/mdadm.conf"
4682+#endif
4683+char DefaultConfFile[] = CONFFILE;
4684+char DefaultAltConfFile[] = CONFFILE2;
4685+
4686+enum linetype { Devices, Array, Mailaddr, Mailfrom, Program, CreateDev,
4687+ Homehost, AutoMode, Policy, PartPolicy, LTEnd };
4688+char *keywords[] = {
4689+ [Devices] = "devices",
4690+ [Array] = "array",
4691+ [Mailaddr] = "mailaddr",
4692+ [Mailfrom] = "mailfrom",
4693+ [Program] = "program",
4694+ [CreateDev]= "create",
4695+ [Homehost] = "homehost",
4696+ [AutoMode] = "auto",
4697+ [Policy] = "policy",
4698+ [PartPolicy]="part-policy",
4699+ [LTEnd] = NULL
4700+};
4701+
4702+/*
4703+ * match_keyword returns an index into the keywords array, or -1 for no match
4704+ * case is ignored, and at least three characters must be given
4705+ */
4706+
4707+int match_keyword(char *word)
4708+{
4709+ int len = strlen(word);
4710+ int n;
4711+
4712+ if (len < 3) return -1;
4713+ for (n=0; keywords[n]; n++) {
4714+ if (strncasecmp(word, keywords[n], len)==0)
4715+ return n;
4716+ }
4717+ return -1;
4718+}
4719+
4720+/*
4721+ * conf_line reads one logical line from the conffile.
4722+ * It skips comments and continues until it finds a line that starts
4723+ * with a non blank/comment. This character is pushed back for the next call
4724+ * A doubly linked list of words is returned.
4725+ * the first word will be a keyword. Other words will have had quotes removed.
4726+ */
4727+
4728+char *conf_line(FILE *file)
4729+{
4730+ char *w;
4731+ char *list;
4732+
4733+ w = conf_word(file, 1);
4734+ if (w == NULL) return NULL;
4735+
4736+ list = dl_strdup(w);
4737+ free(w);
4738+ dl_init(list);
4739+
4740+ while ((w = conf_word(file,0))){
4741+ char *w2 = dl_strdup(w);
4742+ free(w);
4743+ dl_add(list, w2);
4744+ }
4745+/* printf("got a line\n");*/
4746+ return list;
4747+}
4748+
4749+void free_line(char *line)
4750+{
4751+ char *w;
4752+ for (w=dl_next(line); w != line; w=dl_next(line)) {
4753+ dl_del(w);
4754+ dl_free(w);
4755+ }
4756+ dl_free(line);
4757+}
4758+
4759+
4760+struct conf_dev {
4761+ struct conf_dev *next;
4762+ char *name;
4763+} *cdevlist = NULL;
4764+
4765+struct mddev_dev *load_partitions(void)
4766+{
4767+ FILE *f = fopen("/proc/partitions", "r");
4768+ char buf[1024];
4769+ struct mddev_dev *rv = NULL;
4770+ if (f == NULL) {
4771+ fprintf(stderr, Name ": cannot open /proc/partitions\n");
4772+ return NULL;
4773+ }
4774+ while (fgets(buf, 1024, f)) {
4775+ int major, minor;
4776+ char *name, *mp;
4777+ struct mddev_dev *d;
4778+
4779+ buf[1023] = '\0';
4780+ if (buf[0] != ' ')
4781+ continue;
4782+ major = strtoul(buf, &mp, 10);
4783+ if (mp == buf || *mp != ' ')
4784+ continue;
4785+ minor = strtoul(mp, NULL, 10);
4786+
4787+ name = map_dev(major, minor, 1);
4788+ if (!name)
4789+ continue;
4790+ d = malloc(sizeof(*d));
4791+ d->devname = strdup(name);
4792+ d->next = rv;
4793+ d->used = 0;
4794+ rv = d;
4795+ }
4796+ fclose(f);
4797+ return rv;
4798+}
4799+
4800+struct mddev_dev *load_containers(void)
4801+{
4802+ struct mdstat_ent *mdstat = mdstat_read(1, 0);
4803+ struct mdstat_ent *ent;
4804+ struct mddev_dev *d;
4805+ struct mddev_dev *rv = NULL;
4806+
4807+ if (!mdstat)
4808+ return NULL;
4809+
4810+ for (ent = mdstat; ent; ent = ent->next)
4811+ if (ent->metadata_version &&
4812+ strncmp(ent->metadata_version, "external:", 9) == 0 &&
4813+ !is_subarray(&ent->metadata_version[9])) {
4814+ d = malloc(sizeof(*d));
4815+ if (!d)
4816+ continue;
4817+ if (asprintf(&d->devname, "/dev/%s", ent->dev) < 0) {
4818+ free(d);
4819+ continue;
4820+ }
4821+ d->next = rv;
4822+ d->used = 0;
4823+ rv = d;
4824+ }
4825+ free_mdstat(mdstat);
4826+
4827+ return rv;
4828+}
4829+
4830+struct createinfo createinfo = {
4831+ .autof = 2, /* by default, create devices with standard names */
4832+ .symlinks = 1,
4833+#ifdef DEBIAN
4834+ .gid = 6, /* disk */
4835+ .mode = 0660,
4836+#else
4837+ .mode = 0600,
4838+#endif
4839+};
4840+
4841+int parse_auto(char *str, char *msg, int config)
4842+{
4843+ int autof;
4844+ if (str == NULL || *str == 0)
4845+ autof = 2;
4846+ else if (strcasecmp(str,"no")==0)
4847+ autof = 1;
4848+ else if (strcasecmp(str,"yes")==0)
4849+ autof = 2;
4850+ else if (strcasecmp(str,"md")==0)
4851+ autof = config?5:3;
4852+ else {
4853+ /* There might be digits, and maybe a hypen, at the end */
4854+ char *e = str + strlen(str);
4855+ int num = 4;
4856+ int len;
4857+ while (e > str && isdigit(e[-1]))
4858+ e--;
4859+ if (*e) {
4860+ num = atoi(e);
4861+ if (num <= 0) num = 1;
4862+ }
4863+ if (e > str && e[-1] == '-')
4864+ e--;
4865+ len = e - str;
4866+ if ((len == 2 && strncasecmp(str,"md",2)==0)) {
4867+ autof = config ? 5 : 3;
4868+ } else if ((len == 3 && strncasecmp(str,"yes",3)==0)) {
4869+ autof = 2;
4870+ } else if ((len == 3 && strncasecmp(str,"mdp",3)==0)) {
4871+ autof = config ? 6 : 4;
4872+ } else if ((len == 1 && strncasecmp(str,"p",1)==0) ||
4873+ (len >= 4 && strncasecmp(str,"part",4)==0)) {
4874+ autof = 6;
4875+ } else {
4876+ fprintf(stderr, Name ": %s arg of \"%s\" unrecognised: use no,yes,md,mdp,part\n"
4877+ " optionally followed by a number.\n",
4878+ msg, str);
4879+ exit(2);
4880+ }
4881+ autof |= num << 3;
4882+ }
4883+ return autof;
4884+}
4885+
4886+static void createline(char *line)
4887+{
4888+ char *w;
4889+ char *ep;
4890+
4891+ for (w=dl_next(line); w!=line; w=dl_next(w)) {
4892+ if (strncasecmp(w, "auto=", 5) == 0)
4893+ createinfo.autof = parse_auto(w+5, "auto=", 1);
4894+ else if (strncasecmp(w, "owner=", 6) == 0) {
4895+ if (w[6] == 0) {
4896+ fprintf(stderr, Name ": missing owner name\n");
4897+ continue;
4898+ }
4899+ createinfo.uid = strtoul(w+6, &ep, 10);
4900+ if (*ep != 0) {
4901+ struct passwd *pw;
4902+ /* must be a name */
4903+ pw = getpwnam(w+6);
4904+ if (pw)
4905+ createinfo.uid = pw->pw_uid;
4906+ else
4907+ fprintf(stderr, Name ": CREATE user %s not found\n", w+6);
4908+ }
4909+ } else if (strncasecmp(w, "group=", 6) == 0) {
4910+ if (w[6] == 0) {
4911+ fprintf(stderr, Name ": missing group name\n");
4912+ continue;
4913+ }
4914+ createinfo.gid = strtoul(w+6, &ep, 10);
4915+ if (*ep != 0) {
4916+ struct group *gr;
4917+ /* must be a name */
4918+ gr = getgrnam(w+6);
4919+ if (gr)
4920+ createinfo.gid = gr->gr_gid;
4921+ else
4922+ fprintf(stderr, Name ": CREATE group %s not found\n", w+6);
4923+ }
4924+ } else if (strncasecmp(w, "mode=", 5) == 0) {
4925+ if (w[5] == 0) {
4926+ fprintf(stderr, Name ": missing CREATE mode\n");
4927+ continue;
4928+ }
4929+ createinfo.mode = strtoul(w+5, &ep, 8);
4930+ if (*ep != 0) {
4931+ createinfo.mode = 0600;
4932+ fprintf(stderr, Name ": unrecognised CREATE mode %s\n",
4933+ w+5);
4934+ }
4935+ } else if (strncasecmp(w, "metadata=", 9) == 0) {
4936+ /* style of metadata to use by default */
4937+ int i;
4938+ for (i=0; superlist[i] && !createinfo.supertype; i++)
4939+ createinfo.supertype =
4940+ superlist[i]->match_metadata_desc(w+9);
4941+ if (!createinfo.supertype)
4942+ fprintf(stderr, Name ": metadata format %s unknown, ignoring\n",
4943+ w+9);
4944+ } else if (strncasecmp(w, "symlinks=yes", 12) == 0)
4945+ createinfo.symlinks = 1;
4946+ else if (strncasecmp(w, "symlinks=no", 11) == 0)
4947+ createinfo.symlinks = 0;
4948+ else {
4949+ fprintf(stderr, Name ": unrecognised word on CREATE line: %s\n",
4950+ w);
4951+ }
4952+ }
4953+}
4954+
4955+void devline(char *line)
4956+{
4957+ char *w;
4958+ struct conf_dev *cd;
4959+
4960+ for (w=dl_next(line); w != line; w=dl_next(w)) {
4961+ if (w[0] == '/' || strcasecmp(w, "partitions") == 0 ||
4962+ strcasecmp(w, "containers") == 0) {
4963+ cd = malloc(sizeof(*cd));
4964+ cd->name = strdup(w);
4965+ cd->next = cdevlist;
4966+ cdevlist = cd;
4967+ } else {
4968+ fprintf(stderr, Name ": unreconised word on DEVICE line: %s\n",
4969+ w);
4970+ }
4971+ }
4972+}
4973+
4974+struct mddev_ident *mddevlist = NULL;
4975+struct mddev_ident **mddevlp = &mddevlist;
4976+
4977+static int is_number(char *w)
4978+{
4979+ /* check if there are 1 or more digits and nothing else */
4980+ int digits = 0;
4981+ while (*w && isdigit(*w)) {
4982+ digits++;
4983+ w++;
4984+ }
4985+ return (digits && ! *w);
4986+}
4987+
4988+void arrayline(char *line)
4989+{
4990+ char *w;
4991+
4992+ struct mddev_ident mis;
4993+ struct mddev_ident *mi;
4994+
4995+ mis.uuid_set = 0;
4996+ mis.super_minor = UnSet;
4997+ mis.level = UnSet;
4998+ mis.raid_disks = UnSet;
4999+ mis.spare_disks = 0;
5000+ mis.devices = NULL;
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: