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
=== added file '.pc/applied-patches'
--- .pc/applied-patches 1970-01-01 00:00:00 +0000
+++ .pc/applied-patches 2012-06-18 08:55:05 +0000
@@ -0,0 +1,4 @@
1debian-conffile-location.diff
2debian-no-Werror.diff
3debian-changes-3.1.4-1+8efb9d1ubuntu4
4sha1-includes.diff
05
=== removed file '.pc/applied-patches'
--- .pc/applied-patches 2012-05-22 16:40:37 +0000
+++ .pc/applied-patches 1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
1debian/conffile-location.diff
2debian/no-Werror.diff
3debian-changes-3.1.4-1+8efb9d1ubuntu4
40
=== removed directory '.pc/debian'
=== added directory '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4'
=== removed directory '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4'
=== added file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/Assemble.c'
--- .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/Assemble.c 1970-01-01 00:00:00 +0000
+++ .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/Assemble.c 2012-06-18 08:55:05 +0000
@@ -0,0 +1,1699 @@
1/*
2 * mdadm - manage Linux "md" devices aka RAID arrays.
3 *
4 * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Author: Neil Brown
22 * Email: <neilb@suse.de>
23 */
24
25#include "mdadm.h"
26#include <ctype.h>
27
28static int name_matches(char *found, char *required, char *homehost)
29{
30 /* See if the name found matches the required name, possibly
31 * prefixed with 'homehost'
32 */
33 char fnd[33];
34
35 strncpy(fnd, found, 32);
36 fnd[32] = 0;
37 if (strcmp(found, required)==0)
38 return 1;
39 if (homehost) {
40 int l = strlen(homehost);
41 if (l < 32 && fnd[l] == ':' &&
42 strcmp(fnd+l+1, required)==0)
43 return 1;
44 }
45 return 0;
46}
47
48static int is_member_busy(char *metadata_version)
49{
50 /* check if the given member array is active */
51 struct mdstat_ent *mdstat = mdstat_read(1, 0);
52 struct mdstat_ent *ent;
53 int busy = 0;
54
55 for (ent = mdstat; ent; ent = ent->next) {
56 if (ent->metadata_version == NULL)
57 continue;
58 if (strncmp(ent->metadata_version, "external:", 9) != 0)
59 continue;
60 if (!is_subarray(&ent->metadata_version[9]))
61 continue;
62 /* Skip first char - it can be '/' or '-' */
63 if (strcmp(&ent->metadata_version[10], metadata_version+1) == 0) {
64 busy = 1;
65 break;
66 }
67 }
68 free_mdstat(mdstat);
69
70 return busy;
71}
72
73static int ident_matches(struct mddev_ident *ident,
74 struct mdinfo *content,
75 struct supertype *tst,
76 char *homehost,
77 char *update, char *devname)
78{
79
80 if (ident->uuid_set && (!update || strcmp(update, "uuid")!= 0) &&
81 same_uuid(content->uuid, ident->uuid, tst->ss->swapuuid)==0 &&
82 memcmp(content->uuid, uuid_zero, sizeof(int[4])) != 0) {
83 if (devname)
84 fprintf(stderr, Name ": %s has wrong uuid.\n",
85 devname);
86 return 0;
87 }
88 if (ident->name[0] && (!update || strcmp(update, "name")!= 0) &&
89 name_matches(content->name, ident->name, homehost)==0) {
90 if (devname)
91 fprintf(stderr, Name ": %s has wrong name.\n",
92 devname);
93 return 0;
94 }
95 if (ident->super_minor != UnSet &&
96 ident->super_minor != content->array.md_minor) {
97 if (devname)
98 fprintf(stderr, Name ": %s has wrong super-minor.\n",
99 devname);
100 return 0;
101 }
102 if (ident->level != UnSet &&
103 ident->level != content->array.level) {
104 if (devname)
105 fprintf(stderr, Name ": %s has wrong raid level.\n",
106 devname);
107 return 0;
108 }
109 if (ident->raid_disks != UnSet &&
110 ident->raid_disks!= content->array.raid_disks) {
111 if (devname)
112 fprintf(stderr, Name ": %s requires wrong number of drives.\n",
113 devname);
114 return 0;
115 }
116 if (ident->member && ident->member[0]) {
117 /* content->text_version must match */
118 char *s = strchr(content->text_version+1, '/');
119 if (s == NULL) {
120 if (devname)
121 fprintf(stderr, Name ": %s is not a container and one is required.\n",
122 devname);
123 return 0;
124 } else if (strcmp(ident->member, s+1) != 0) {
125 if (devname)
126 fprintf(stderr, Name ": skipping wrong member %s is %s\n",
127 content->text_version, devname);
128 return 0;
129 }
130 }
131 return 1;
132}
133
134
135int Assemble(struct supertype *st, char *mddev,
136 struct mddev_ident *ident,
137 struct mddev_dev *devlist,
138 char *backup_file, int invalid_backup,
139 int readonly, int runstop,
140 char *update, char *homehost, int require_homehost,
141 int verbose, int force, int freeze_reshape)
142{
143 /*
144 * The task of Assemble is to find a collection of
145 * devices that should (according to their superblocks)
146 * form an array, and to give this collection to the MD driver.
147 * In Linux-2.4 and later, this involves submitting a
148 * SET_ARRAY_INFO ioctl with no arg - to prepare
149 * the array - and then submit a number of
150 * ADD_NEW_DISK ioctls to add disks into
151 * the array. Finally RUN_ARRAY might
152 * be submitted to start the array.
153 *
154 * Much of the work of Assemble is in finding and/or
155 * checking the disks to make sure they look right.
156 *
157 * If mddev is not set, then scan must be set and we
158 * read through the config file for dev+uuid mapping
159 * We recurse, setting mddev, for each device that
160 * - isn't running
161 * - has a valid uuid (or any uuid if !uuidset)
162 *
163 * If mddev is set, we try to determine state of md.
164 * check version - must be at least 0.90.0
165 * check kernel version. must be at least 2.4.
166 * If not, we can possibly fall back on START_ARRAY
167 * Try to GET_ARRAY_INFO.
168 * If possible, give up
169 * If not, try to STOP_ARRAY just to make sure
170 *
171 * If !uuidset and scan, look in conf-file for uuid
172 * If not found, give up
173 * If !devlist and scan and uuidset, get list of devs from conf-file
174 *
175 * For each device:
176 * Check superblock - discard if bad
177 * Check uuid (set if we don't have one) - discard if no match
178 * Check superblock similarity if we have a superblock - discard if different
179 * Record events, devicenum
180 * This should give us a list of devices for the array
181 * We should collect the most recent event number
182 *
183 * Count disks with recent enough event count
184 * While force && !enough disks
185 * Choose newest rejected disks, update event count
186 * mark clean and rewrite superblock
187 * If recent kernel:
188 * SET_ARRAY_INFO
189 * foreach device with recent events : ADD_NEW_DISK
190 * if runstop == 1 || "enough" disks and runstop==0 -> RUN_ARRAY
191 * If old kernel:
192 * Check the device numbers in superblock are right
193 * update superblock if any changes
194 * START_ARRAY
195 *
196 */
197 int mdfd;
198 int clean;
199 int auto_assem = (mddev == NULL && !ident->uuid_set &&
200 ident->super_minor == UnSet && ident->name[0] == 0
201 && (ident->container == NULL || ident->member == NULL));
202 int old_linux = 0;
203 int vers = vers; /* Keep gcc quite - it really is initialised */
204 struct {
205 char *devname;
206 int uptodate; /* set once we decide that this device is as
207 * recent as everything else in the array.
208 */
209 struct mdinfo i;
210 } *devices;
211 char *devmap;
212 int *best = NULL; /* indexed by raid_disk */
213 int bestcnt = 0;
214 int devcnt = 0;
215 unsigned int okcnt, sparecnt, rebuilding_cnt;
216 unsigned int req_cnt;
217 int i;
218 int most_recent = 0;
219 int chosen_drive;
220 int change = 0;
221 int inargv = 0;
222 int report_missmatch;
223#ifndef MDASSEMBLE
224 int bitmap_done;
225#endif
226 int start_partial_ok = (runstop >= 0) &&
227 (force || devlist==NULL || auto_assem);
228 unsigned int num_devs;
229 struct mddev_dev *tmpdev;
230 struct mdinfo info;
231 struct mdinfo *content = NULL;
232 char *avail;
233 int nextspare = 0;
234 char *name = NULL;
235 int trustworthy;
236 char chosen_name[1024];
237 struct domainlist *domains = NULL;
238
239 if (get_linux_version() < 2004000)
240 old_linux = 1;
241
242 /*
243 * If any subdevs are listed, then any that don't
244 * match ident are discarded. Remainder must all match and
245 * become the array.
246 * If no subdevs, then we scan all devices in the config file, but
247 * there must be something in the identity
248 */
249
250 if (!devlist &&
251 ident->uuid_set == 0 &&
252 (ident->super_minor < 0 || ident->super_minor == UnSet) &&
253 ident->name[0] == 0 &&
254 (ident->container == NULL || ident->member == NULL) &&
255 ident->devices == NULL) {
256 fprintf(stderr, Name ": No identity information available for %s - cannot assemble.\n",
257 mddev ? mddev : "further assembly");
258 return 1;
259 }
260
261 if (devlist == NULL)
262 devlist = conf_get_devs();
263 else if (mddev)
264 inargv = 1;
265
266 report_missmatch = ((inargv && verbose >= 0) || verbose > 0);
267 try_again:
268 /* We come back here when doing auto-assembly and attempting some
269 * set of devices failed. Those are now marked as ->used==2 and
270 * we ignore them and try again
271 */
272
273 tmpdev = devlist; num_devs = 0;
274 while (tmpdev) {
275 if (tmpdev->used)
276 tmpdev->used = 2;
277 else
278 num_devs++;
279 tmpdev = tmpdev->next;
280 }
281
282 if (!st && ident->st) st = ident->st;
283
284 if (verbose>0)
285 fprintf(stderr, Name ": looking for devices for %s\n",
286 mddev ? mddev : "further assembly");
287
288 /* first walk the list of devices to find a consistent set
289 * that match the criterea, if that is possible.
290 * We flag the ones we like with 'used'.
291 */
292 for (tmpdev = devlist;
293 tmpdev;
294 tmpdev = tmpdev ? tmpdev->next : NULL) {
295 char *devname = tmpdev->devname;
296 int dfd;
297 struct stat stb;
298 struct supertype *tst;
299 struct dev_policy *pol = NULL;
300 int found_container = 0;
301
302 if (tmpdev->used > 1) continue;
303
304 if (ident->devices &&
305 !match_oneof(ident->devices, devname)) {
306 if (report_missmatch)
307 fprintf(stderr, Name ": %s is not one of %s\n", devname, ident->devices);
308 continue;
309 }
310
311 tst = dup_super(st);
312
313 dfd = dev_open(devname, O_RDONLY);
314 if (dfd < 0) {
315 if (report_missmatch)
316 fprintf(stderr, Name ": cannot open device %s: %s\n",
317 devname, strerror(errno));
318 tmpdev->used = 2;
319 } else if (fstat(dfd, &stb)< 0) {
320 /* Impossible! */
321 fprintf(stderr, Name ": fstat failed for %s: %s\n",
322 devname, strerror(errno));
323 tmpdev->used = 2;
324 } else if ((stb.st_mode & S_IFMT) != S_IFBLK) {
325 fprintf(stderr, Name ": %s is not a block device.\n",
326 devname);
327 tmpdev->used = 2;
328 } else if (must_be_container(dfd)) {
329 if (st) {
330 /* already found some components, this cannot
331 * be another one.
332 */
333 if (report_missmatch)
334 fprintf(stderr, Name ": %s is a container, but we are looking for components\n",
335 devname);
336 tmpdev->used = 2;
337#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
338 } if (!tst && (tst = super_by_fd(dfd, NULL)) == NULL) {
339 if (report_missmatch)
340 fprintf(stderr, Name ": not a recognisable container: %s\n",
341 devname);
342 tmpdev->used = 2;
343#endif
344 } else if (!tst->ss->load_container
345 || tst->ss->load_container(tst, dfd, NULL)) {
346 if (report_missmatch)
347 fprintf(stderr, Name ": no correct container type: %s\n",
348 devname);
349 tmpdev->used = 2;
350 } else if (auto_assem &&
351 !conf_test_metadata(tst->ss->name, (pol = devnum_policy(stb.st_rdev)),
352 tst->ss->match_home(tst, homehost) == 1)) {
353 if (report_missmatch)
354 fprintf(stderr, Name ": %s has metadata type %s for which "
355 "auto-assembly is disabled\n",
356 devname, tst->ss->name);
357 tmpdev->used = 2;
358 } else
359 found_container = 1;
360 } else {
361 if (!tst && (tst = guess_super(dfd)) == NULL) {
362 if (report_missmatch)
363 fprintf(stderr, Name ": no recogniseable superblock on %s\n",
364 devname);
365 tmpdev->used = 2;
366 } else if (tst->ss->load_super(tst,dfd, NULL)) {
367 if (report_missmatch)
368 fprintf(stderr, Name ": no RAID superblock on %s\n",
369 devname);
370 tmpdev->used = 2;
371 } else if (tst->ss->compare_super == NULL) {
372 if (report_missmatch)
373 fprintf(stderr, Name ": Cannot assemble %s metadata on %s\n",
374 tst->ss->name, devname);
375 tmpdev->used = 2;
376 } else if (auto_assem && st == NULL &&
377 !conf_test_metadata(tst->ss->name, (pol = devnum_policy(stb.st_rdev)),
378 tst->ss->match_home(tst, homehost) == 1)) {
379 if (report_missmatch)
380 fprintf(stderr, Name ": %s has metadata type %s for which "
381 "auto-assembly is disabled\n",
382 devname, tst->ss->name);
383 tmpdev->used = 2;
384 }
385 }
386 if (dfd >= 0) close(dfd);
387 if (tmpdev->used == 2) {
388 if (auto_assem || !inargv)
389 /* Ignore unrecognised devices during auto-assembly */
390 goto loop;
391 if (ident->uuid_set || ident->name[0] ||
392 ident->super_minor != UnSet)
393 /* Ignore unrecognised device if looking for
394 * specific array */
395 goto loop;
396
397
398 fprintf(stderr, Name ": %s has no superblock - assembly aborted\n",
399 devname);
400 if (st)
401 st->ss->free_super(st);
402 dev_policy_free(pol);
403 domain_free(domains);
404 return 1;
405 }
406
407 if (found_container) {
408 /* tmpdev is a container. We need to be either
409 * looking for a member, or auto-assembling
410 */
411 /* should be safe to try an exclusive open now, we
412 * have rejected anything that some other mdadm might
413 * be looking at
414 */
415 dfd = dev_open(devname, O_RDONLY | O_EXCL);
416 if (dfd < 0) {
417 if (report_missmatch)
418 fprintf(stderr, Name ": %s is busy - skipping\n", devname);
419 goto loop;
420 }
421 close(dfd);
422
423 if (ident->container) {
424 if (ident->container[0] == '/' &&
425 !same_dev(ident->container, devname)) {
426 if (report_missmatch)
427 fprintf(stderr, Name ": %s is not the container required (%s)\n",
428 devname, ident->container);
429 goto loop;
430 }
431 if (ident->container[0] != '/') {
432 /* we have a uuid */
433 int uuid[4];
434
435 content = &info;
436 tst->ss->getinfo_super(tst, content, NULL);
437
438 if (!parse_uuid(ident->container, uuid) ||
439 !same_uuid(content->uuid, uuid, tst->ss->swapuuid)) {
440 if (report_missmatch)
441 fprintf(stderr, Name ": %s has wrong UUID to be required container\n",
442 devname);
443 goto loop;
444 }
445 }
446 }
447 /* It is worth looking inside this container.
448 */
449 if (verbose > 0)
450 fprintf(stderr, Name ": looking in container %s\n",
451 devname);
452
453 for (content = tst->ss->container_content(tst, NULL);
454 content;
455 content = content->next) {
456
457 if (!ident_matches(ident, content, tst,
458 homehost, update,
459 report_missmatch ? devname : NULL))
460 /* message already printed */;
461 else if (is_member_busy(content->text_version)) {
462 if (report_missmatch)
463 fprintf(stderr, Name ": member %s in %s is already assembled\n",
464 content->text_version,
465 devname);
466 } else if (content->array.state & (1<<MD_SB_BLOCK_VOLUME)) {
467 /* do not assemble arrays with unsupported configurations */
468 fprintf(stderr, Name ": Cannot activate member %s in %s.\n",
469 content->text_version,
470 devname);
471 } else
472 break;
473 }
474 if (!content) {
475 tmpdev->used = 2;
476 goto loop; /* empty container */
477 }
478
479 st = tst; tst = NULL;
480 if (!auto_assem && inargv && tmpdev->next != NULL) {
481 fprintf(stderr, Name ": %s is a container, but is not "
482 "only device given: confused and aborting\n",
483 devname);
484 st->ss->free_super(st);
485 dev_policy_free(pol);
486 domain_free(domains);
487 return 1;
488 }
489 if (verbose > 0)
490 fprintf(stderr, Name ": found match on member %s in %s\n",
491 content->text_version, devname);
492
493 /* make sure we finished the loop */
494 tmpdev = NULL;
495 goto loop;
496 } else {
497
498 content = &info;
499 tst->ss->getinfo_super(tst, content, NULL);
500
501 if (!ident_matches(ident, content, tst,
502 homehost, update,
503 report_missmatch ? devname : NULL))
504 goto loop;
505
506 /* should be safe to try an exclusive open now, we
507 * have rejected anything that some other mdadm might
508 * be looking at
509 */
510 dfd = dev_open(devname, O_RDONLY | O_EXCL);
511 if (dfd < 0) {
512 if (report_missmatch)
513 fprintf(stderr, Name ": %s is busy - skipping\n", devname);
514 goto loop;
515 }
516 close(dfd);
517
518 if (st == NULL)
519 st = dup_super(tst);
520 if (st->minor_version == -1)
521 st->minor_version = tst->minor_version;
522
523 if (memcmp(content->uuid, uuid_zero,
524 sizeof(int[4])) == 0) {
525 /* this is a floating spare. It cannot define
526 * an array unless there are no more arrays of
527 * this type to be found. It can be included
528 * in an array of this type though.
529 */
530 tmpdev->used = 3;
531 goto loop;
532 }
533
534 if (st->ss != tst->ss ||
535 st->minor_version != tst->minor_version ||
536 st->ss->compare_super(st, tst) != 0) {
537 /* Some mismatch. If exactly one array matches this host,
538 * we can resolve on that one.
539 * Or, if we are auto assembling, we just ignore the second
540 * for now.
541 */
542 if (auto_assem)
543 goto loop;
544 if (homehost) {
545 int first = st->ss->match_home(st, homehost);
546 int last = tst->ss->match_home(tst, homehost);
547 if (first != last &&
548 (first == 1 || last == 1)) {
549 /* We can do something */
550 if (first) {/* just ignore this one */
551 if (report_missmatch)
552 fprintf(stderr, Name ": %s misses out due to wrong homehost\n",
553 devname);
554 goto loop;
555 } else { /* reject all those sofar */
556 struct mddev_dev *td;
557 if (report_missmatch)
558 fprintf(stderr, Name ": %s overrides previous devices due to good homehost\n",
559 devname);
560 for (td=devlist; td != tmpdev; td=td->next)
561 if (td->used == 1)
562 td->used = 0;
563 tmpdev->used = 1;
564 goto loop;
565 }
566 }
567 }
568 fprintf(stderr, Name ": superblock on %s doesn't match others - assembly aborted\n",
569 devname);
570 tst->ss->free_super(tst);
571 st->ss->free_super(st);
572 dev_policy_free(pol);
573 domain_free(domains);
574 return 1;
575 }
576 tmpdev->used = 1;
577 }
578 loop:
579 /* Collect domain information from members only */
580 if (tmpdev && tmpdev->used == 1) {
581 if (!pol)
582 pol = devnum_policy(stb.st_rdev);
583 domain_merge(&domains, pol, tst?tst->ss->name:NULL);
584 }
585 dev_policy_free(pol);
586 pol = NULL;
587 if (tst)
588 tst->ss->free_super(tst);
589 }
590
591 /* Check if we found some imsm spares but no members */
592 if ((auto_assem ||
593 (ident->uuid_set &&
594 memcmp(uuid_zero, ident->uuid,sizeof(uuid_zero)) == 0)) &&
595 (!st || !st->sb))
596 for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
597 if (tmpdev->used != 3)
598 continue;
599 tmpdev->used = 1;
600 content = &info;
601
602 if (!st->sb) {
603 /* we need sb from one of the spares */
604 int dfd = dev_open(tmpdev->devname, O_RDONLY);
605 if (dfd < 0 ||
606 st->ss->load_super(st, dfd, NULL))
607 tmpdev->used = 2;
608 if (dfd > 0)
609 close(dfd);
610 }
611 }
612
613 /* Now reject spares that don't match domains of identified members */
614 for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
615 struct stat stb;
616 if (tmpdev->used != 3)
617 continue;
618 if (stat(tmpdev->devname, &stb)< 0) {
619 fprintf(stderr, Name ": fstat failed for %s: %s\n",
620 tmpdev->devname, strerror(errno));
621 tmpdev->used = 2;
622 } else {
623 struct dev_policy *pol = devnum_policy(stb.st_rdev);
624 int dt = domain_test(domains, pol, NULL);
625 if (inargv && dt != 0)
626 /* take this spare as domains match
627 * if there are any */
628 tmpdev->used = 1;
629 else if (!inargv && dt == 1)
630 /* device wasn't explicitly listed, so need
631 * explicit domain match - which we have */
632 tmpdev->used = 1;
633 else
634 /* if domains don't match mark as unused */
635 tmpdev->used = 0;
636 dev_policy_free(pol);
637 }
638 }
639 domain_free(domains);
640
641 if (!st || !st->sb || !content)
642 return 2;
643
644 /* Now need to open the array device. Use create_mddev */
645 if (content == &info)
646 st->ss->getinfo_super(st, content, NULL);
647
648 trustworthy = FOREIGN;
649 name = content->name;
650 switch (st->ss->match_home(st, homehost)
651 ?: st->ss->match_home(st, "any")) {
652 case 1:
653 trustworthy = LOCAL;
654 name = strchr(content->name, ':');
655 if (name)
656 name++;
657 else
658 name = content->name;
659 break;
660 }
661 if (!auto_assem)
662 /* If the array is listed in mdadm.conf or on
663 * command line, then we trust the name
664 * even if the array doesn't look local
665 */
666 trustworthy = LOCAL;
667
668 if (name[0] == 0 &&
669 content->array.level == LEVEL_CONTAINER) {
670 name = content->text_version;
671 trustworthy = METADATA;
672 }
673
674 if (name[0] && trustworthy != LOCAL &&
675 ! require_homehost &&
676 conf_name_is_free(name))
677 trustworthy = LOCAL;
678
679 if (trustworthy == LOCAL &&
680 strchr(name, ':'))
681 /* Ignore 'host:' prefix of name */
682 name = strchr(name, ':')+1;
683
684 mdfd = create_mddev(mddev, name, ident->autof, trustworthy,
685 chosen_name);
686 if (mdfd < 0) {
687 st->ss->free_super(st);
688 if (auto_assem)
689 goto try_again;
690 return 1;
691 }
692 mddev = chosen_name;
693 vers = md_get_version(mdfd);
694 if (vers < 9000) {
695 fprintf(stderr, Name ": Assemble requires driver version 0.90.0 or later.\n"
696 " Upgrade your kernel or try --build\n");
697 close(mdfd);
698 return 1;
699 }
700 if (mddev_busy(fd2devnum(mdfd))) {
701 fprintf(stderr, Name ": %s already active, cannot restart it!\n",
702 mddev);
703 for (tmpdev = devlist ;
704 tmpdev && tmpdev->used != 1;
705 tmpdev = tmpdev->next)
706 ;
707 if (tmpdev && auto_assem)
708 fprintf(stderr, Name ": %s needed for %s...\n",
709 mddev, tmpdev->devname);
710 close(mdfd);
711 mdfd = -3;
712 st->ss->free_super(st);
713 if (auto_assem)
714 goto try_again;
715 return 1;
716 }
717 ioctl(mdfd, STOP_ARRAY, NULL); /* just incase it was started but has no content */
718
719#ifndef MDASSEMBLE
720 if (content != &info) {
721 /* This is a member of a container. Try starting the array. */
722 int err;
723 err = assemble_container_content(st, mdfd, content, runstop,
724 chosen_name, verbose,
725 backup_file, freeze_reshape);
726 close(mdfd);
727 return err;
728 }
729 bitmap_done = 0;
730#endif
731 /* Ok, no bad inconsistancy, we can try updating etc */
732 devices = malloc(num_devs * sizeof(*devices));
733 devmap = calloc(num_devs * content->array.raid_disks, 1);
734 for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) {
735 char *devname = tmpdev->devname;
736 struct stat stb;
737 /* looks like a good enough match to update the super block if needed */
738#ifndef MDASSEMBLE
739 if (update) {
740 int dfd;
741 /* prepare useful information in info structures */
742 struct stat stb2;
743 struct supertype *tst;
744 int err;
745 fstat(mdfd, &stb2);
746
747 if (strcmp(update, "uuid")==0 &&
748 !ident->uuid_set) {
749 int rfd;
750 if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
751 read(rfd, ident->uuid, 16) != 16) {
752 *(__u32*)(ident->uuid) = random();
753 *(__u32*)(ident->uuid+1) = random();
754 *(__u32*)(ident->uuid+2) = random();
755 *(__u32*)(ident->uuid+3) = random();
756 }
757 if (rfd >= 0) close(rfd);
758 }
759 dfd = dev_open(devname, O_RDWR|O_EXCL);
760
761 tst = dup_super(st);
762 if (dfd < 0 || tst->ss->load_super(tst, dfd, NULL) != 0) {
763 fprintf(stderr, Name ": cannot re-read metadata from %s - aborting\n",
764 devname);
765 if (dfd >= 0)
766 close(dfd);
767 close(mdfd);
768 free(devices);
769 free(devmap);
770 return 1;
771 }
772 tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
773
774 memcpy(content->uuid, ident->uuid, 16);
775 strcpy(content->name, ident->name);
776 content->array.md_minor = minor(stb2.st_rdev);
777
778 if (strcmp(update, "byteorder") == 0)
779 err = 0;
780 else
781 err = tst->ss->update_super(tst, content, update,
782 devname, verbose,
783 ident->uuid_set,
784 homehost);
785 if (err < 0) {
786 fprintf(stderr,
787 Name ": --update=%s not understood"
788 " for %s metadata\n",
789 update, tst->ss->name);
790 tst->ss->free_super(tst);
791 free(tst);
792 close(mdfd);
793 close(dfd);
794 free(devices);
795 free(devmap);
796 return 1;
797 }
798 if (strcmp(update, "uuid")==0 &&
799 !ident->uuid_set) {
800 ident->uuid_set = 1;
801 memcpy(ident->uuid, content->uuid, 16);
802 }
803 if (tst->ss->store_super(tst, dfd))
804 fprintf(stderr, Name ": Could not re-write superblock on %s.\n",
805 devname);
806 close(dfd);
807
808 if (strcmp(update, "uuid")==0 &&
809 ident->bitmap_fd >= 0 && !bitmap_done) {
810 if (bitmap_update_uuid(ident->bitmap_fd,
811 content->uuid,
812 tst->ss->swapuuid) != 0)
813 fprintf(stderr, Name ": Could not update uuid on external bitmap.\n");
814 else
815 bitmap_done = 1;
816 }
817 tst->ss->free_super(tst);
818 } else
819#endif
820 {
821 struct supertype *tst = dup_super(st);
822 int dfd;
823 dfd = dev_open(devname, O_RDWR|O_EXCL);
824
825 if (dfd < 0 || tst->ss->load_super(tst, dfd, NULL) != 0) {
826 fprintf(stderr, Name ": cannot re-read metadata from %s - aborting\n",
827 devname);
828 if (dfd >= 0)
829 close(dfd);
830 close(mdfd);
831 free(devices);
832 free(devmap);
833 return 1;
834 }
835 tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
836 tst->ss->free_super(tst);
837 close(dfd);
838 }
839
840 stat(devname, &stb);
841
842 if (verbose > 0)
843 fprintf(stderr, Name ": %s is identified as a member of %s, slot %d.\n",
844 devname, mddev, content->disk.raid_disk);
845 devices[devcnt].devname = devname;
846 devices[devcnt].uptodate = 0;
847 devices[devcnt].i = *content;
848 devices[devcnt].i.disk.major = major(stb.st_rdev);
849 devices[devcnt].i.disk.minor = minor(stb.st_rdev);
850 if (most_recent < devcnt) {
851 if (devices[devcnt].i.events
852 > devices[most_recent].i.events)
853 most_recent = devcnt;
854 }
855 if (content->array.level == LEVEL_MULTIPATH)
856 /* with multipath, the raid_disk from the superblock is meaningless */
857 i = devcnt;
858 else
859 i = devices[devcnt].i.disk.raid_disk;
860 if (i+1 == 0) {
861 if (nextspare < content->array.raid_disks)
862 nextspare = content->array.raid_disks;
863 i = nextspare++;
864 } else {
865 if (i >= content->array.raid_disks &&
866 i >= nextspare)
867 nextspare = i+1;
868 }
869 if (i < 10000) {
870 if (i >= bestcnt) {
871 int newbestcnt = i+10;
872 int *newbest = malloc(sizeof(int)*newbestcnt);
873 int c;
874 for (c=0; c < newbestcnt; c++)
875 if (c < bestcnt)
876 newbest[c] = best[c];
877 else
878 newbest[c] = -1;
879 if (best)free(best);
880 best = newbest;
881 bestcnt = newbestcnt;
882 }
883 if (best[i] >=0 &&
884 devices[best[i]].i.events
885 == devices[devcnt].i.events
886 && (devices[best[i]].i.disk.minor
887 != devices[devcnt].i.disk.minor)
888 && st->ss == &super0
889 && content->array.level != LEVEL_MULTIPATH) {
890 /* two different devices with identical superblock.
891 * Could be a mis-detection caused by overlapping
892 * partitions. fail-safe.
893 */
894 fprintf(stderr, Name ": WARNING %s and %s appear"
895 " to have very similar superblocks.\n"
896 " If they are really different, "
897 "please --zero the superblock on one\n"
898 " If they are the same or overlap,"
899 " please remove one from %s.\n",
900 devices[best[i]].devname, devname,
901 inargv ? "the list" :
902 "the\n DEVICE list in mdadm.conf"
903 );
904 close(mdfd);
905 free(devices);
906 free(devmap);
907 return 1;
908 }
909 if (best[i] == -1
910 || (devices[best[i]].i.events
911 < devices[devcnt].i.events))
912 best[i] = devcnt;
913 }
914 devcnt++;
915 }
916
917 if (devcnt == 0) {
918 fprintf(stderr, Name ": no devices found for %s\n",
919 mddev);
920 if (st)
921 st->ss->free_super(st);
922 close(mdfd);
923 free(devices);
924 free(devmap);
925 return 1;
926 }
927
928 if (update && strcmp(update, "byteorder")==0)
929 st->minor_version = 90;
930
931 st->ss->getinfo_super(st, content, NULL);
932 clean = content->array.state & 1;
933
934 /* now we have some devices that might be suitable.
935 * I wonder how many
936 */
937 avail = malloc(content->array.raid_disks);
938 memset(avail, 0, content->array.raid_disks);
939 okcnt = 0;
940 sparecnt=0;
941 rebuilding_cnt=0;
942 for (i=0; i< bestcnt; i++) {
943 int j = best[i];
944 int event_margin = 1; /* always allow a difference of '1'
945 * like the kernel does
946 */
947 if (j < 0) continue;
948 /* note: we ignore error flags in multipath arrays
949 * as they don't make sense
950 */
951 if (content->array.level != LEVEL_MULTIPATH)
952 if (!(devices[j].i.disk.state & (1<<MD_DISK_ACTIVE))) {
953 if (!(devices[j].i.disk.state
954 & (1<<MD_DISK_FAULTY))) {
955 devices[j].uptodate = 1;
956 sparecnt++;
957 }
958 continue;
959 }
960 /* If this device thinks that 'most_recent' has failed, then
961 * we must reject this device.
962 */
963 if (j != most_recent &&
964 content->array.raid_disks > 0 &&
965 devices[most_recent].i.disk.raid_disk >= 0 &&
966 devmap[j * content->array.raid_disks + devices[most_recent].i.disk.raid_disk] == 0) {
967 if (verbose > -1)
968 fprintf(stderr, Name ": ignoring %s as it reports %s as failed\n",
969 devices[j].devname, devices[most_recent].devname);
970 best[i] = -1;
971 continue;
972 }
973 if (devices[j].i.events+event_margin >=
974 devices[most_recent].i.events) {
975 devices[j].uptodate = 1;
976 if (i < content->array.raid_disks) {
977 if (devices[j].i.recovery_start == MaxSector ||
978 (content->reshape_active &&
979 ((i >= content->array.raid_disks - content->delta_disks) ||
980 (i >= content->array.raid_disks - content->delta_disks - 1
981 && content->array.level == 4)))) {
982 okcnt++;
983 avail[i]=1;
984 } else
985 rebuilding_cnt++;
986 } else
987 sparecnt++;
988 }
989 }
990 free(devmap);
991 while (force &&
992 (!enough(content->array.level, content->array.raid_disks,
993 content->array.layout, 1,
994 avail)
995 ||
996 (content->reshape_active && content->delta_disks > 0 &&
997 !enough(content->array.level, (content->array.raid_disks
998 - content->delta_disks),
999 content->new_layout, 1,
1000 avail)
1001 ))) {
1002 /* Choose the newest best drive which is
1003 * not up-to-date, update the superblock
1004 * and add it.
1005 */
1006 int fd;
1007 struct supertype *tst;
1008 unsigned long long current_events;
1009 chosen_drive = -1;
1010 for (i = 0; i < content->array.raid_disks && i < bestcnt; i++) {
1011 int j = best[i];
1012 if (j>=0 &&
1013 !devices[j].uptodate &&
1014 devices[j].i.recovery_start == MaxSector &&
1015 (chosen_drive < 0 ||
1016 devices[j].i.events
1017 > devices[chosen_drive].i.events))
1018 chosen_drive = j;
1019 }
1020 if (chosen_drive < 0)
1021 break;
1022 current_events = devices[chosen_drive].i.events;
1023 add_another:
1024 if (verbose >= 0)
1025 fprintf(stderr, Name ": forcing event count in %s(%d) from %d upto %d\n",
1026 devices[chosen_drive].devname,
1027 devices[chosen_drive].i.disk.raid_disk,
1028 (int)(devices[chosen_drive].i.events),
1029 (int)(devices[most_recent].i.events));
1030 fd = dev_open(devices[chosen_drive].devname, O_RDWR|O_EXCL);
1031 if (fd < 0) {
1032 fprintf(stderr, Name ": Couldn't open %s for write - not updating\n",
1033 devices[chosen_drive].devname);
1034 devices[chosen_drive].i.events = 0;
1035 continue;
1036 }
1037 tst = dup_super(st);
1038 if (tst->ss->load_super(tst,fd, NULL)) {
1039 close(fd);
1040 fprintf(stderr, Name ": RAID superblock disappeared from %s - not updating.\n",
1041 devices[chosen_drive].devname);
1042 devices[chosen_drive].i.events = 0;
1043 continue;
1044 }
1045 content->events = devices[most_recent].i.events;
1046 tst->ss->update_super(tst, content, "force-one",
1047 devices[chosen_drive].devname, verbose,
1048 0, NULL);
1049
1050 if (tst->ss->store_super(tst, fd)) {
1051 close(fd);
1052 fprintf(stderr, Name ": Could not re-write superblock on %s\n",
1053 devices[chosen_drive].devname);
1054 devices[chosen_drive].i.events = 0;
1055 tst->ss->free_super(tst);
1056 continue;
1057 }
1058 close(fd);
1059 devices[chosen_drive].i.events = devices[most_recent].i.events;
1060 devices[chosen_drive].uptodate = 1;
1061 avail[chosen_drive] = 1;
1062 okcnt++;
1063 tst->ss->free_super(tst);
1064
1065 /* If there are any other drives of the same vintage,
1066 * add them in as well. We can't lose and we might gain
1067 */
1068 for (i = 0; i < content->array.raid_disks && i < bestcnt ; i++) {
1069 int j = best[i];
1070 if (j >= 0 &&
1071 !devices[j].uptodate &&
1072 devices[j].i.recovery_start == MaxSector &&
1073 devices[j].i.events == current_events) {
1074 chosen_drive = j;
1075 goto add_another;
1076 }
1077 }
1078 }
1079
1080 /* Now we want to look at the superblock which the kernel will base things on
1081 * and compare the devices that we think are working with the devices that the
1082 * superblock thinks are working.
1083 * If there are differences and --force is given, then update this chosen
1084 * superblock.
1085 */
1086 chosen_drive = -1;
1087 st->ss->free_super(st);
1088 for (i=0; chosen_drive < 0 && i<bestcnt; i++) {
1089 int j = best[i];
1090 int fd;
1091
1092 if (j<0)
1093 continue;
1094 if (!devices[j].uptodate)
1095 continue;
1096 if (devices[j].i.events < devices[most_recent].i.events)
1097 continue;
1098 chosen_drive = j;
1099 if ((fd=dev_open(devices[j].devname, O_RDONLY|O_EXCL))< 0) {
1100 fprintf(stderr, Name ": Cannot open %s: %s\n",
1101 devices[j].devname, strerror(errno));
1102 close(mdfd);
1103 free(devices);
1104 return 1;
1105 }
1106 if (st->ss->load_super(st,fd, NULL)) {
1107 close(fd);
1108 fprintf(stderr, Name ": RAID superblock has disappeared from %s\n",
1109 devices[j].devname);
1110 close(mdfd);
1111 free(devices);
1112 return 1;
1113 }
1114 close(fd);
1115 }
1116 if (st->sb == NULL) {
1117 fprintf(stderr, Name ": No suitable drives found for %s\n", mddev);
1118 close(mdfd);
1119 free(devices);
1120 return 1;
1121 }
1122 st->ss->getinfo_super(st, content, NULL);
1123#ifndef MDASSEMBLE
1124 sysfs_init(content, mdfd, 0);
1125#endif
1126 for (i=0; i<bestcnt; i++) {
1127 int j = best[i];
1128 unsigned int desired_state;
1129
1130 if (i < content->array.raid_disks)
1131 desired_state = (1<<MD_DISK_ACTIVE) | (1<<MD_DISK_SYNC);
1132 else
1133 desired_state = 0;
1134
1135 if (j<0)
1136 continue;
1137 if (!devices[j].uptodate)
1138 continue;
1139
1140 devices[j].i.disk.state = desired_state;
1141 if (!(devices[j].i.array.state & 1))
1142 clean = 0;
1143
1144 if (st->ss->update_super(st, &devices[j].i, "assemble", NULL,
1145 verbose, 0, NULL)) {
1146 if (force) {
1147 if (verbose >= 0)
1148 fprintf(stderr, Name ": "
1149 "clearing FAULTY flag for device %d in %s for %s\n",
1150 j, mddev, devices[j].devname);
1151 change = 1;
1152 } else {
1153 if (verbose >= -1)
1154 fprintf(stderr, Name ": "
1155 "device %d in %s has wrong state in superblock, but %s seems ok\n",
1156 i, mddev, devices[j].devname);
1157 }
1158 }
1159#if 0
1160 if (!(super.disks[i].i.disk.state & (1 << MD_DISK_FAULTY))) {
1161 fprintf(stderr, Name ": devices %d of %s is not marked FAULTY in superblock, but cannot be found\n",
1162 i, mddev);
1163 }
1164#endif
1165 }
1166 if (force && !clean &&
1167 !enough(content->array.level, content->array.raid_disks,
1168 content->array.layout, clean,
1169 avail)) {
1170 change += st->ss->update_super(st, content, "force-array",
1171 devices[chosen_drive].devname, verbose,
1172 0, NULL);
1173 clean = 1;
1174 }
1175
1176 if (change) {
1177 int fd;
1178 fd = dev_open(devices[chosen_drive].devname, O_RDWR|O_EXCL);
1179 if (fd < 0) {
1180 fprintf(stderr, Name ": Could not open %s for write - cannot Assemble array.\n",
1181 devices[chosen_drive].devname);
1182 close(mdfd);
1183 free(devices);
1184 return 1;
1185 }
1186 if (st->ss->store_super(st, fd)) {
1187 close(fd);
1188 fprintf(stderr, Name ": Could not re-write superblock on %s\n",
1189 devices[chosen_drive].devname);
1190 close(mdfd);
1191 free(devices);
1192 return 1;
1193 }
1194 if (verbose >= 0)
1195 fprintf(stderr, Name ": Marking array %s as 'clean'\n",
1196 mddev);
1197 close(fd);
1198 }
1199
1200 /* If we are in the middle of a reshape we may need to restore saved data
1201 * that was moved aside due to the reshape overwriting live data
1202 * The code of doing this lives in Grow.c
1203 */
1204#ifndef MDASSEMBLE
1205 if (content->reshape_active) {
1206 int err = 0;
1207 int *fdlist = malloc(sizeof(int)* bestcnt);
1208 if (verbose > 0)
1209 fprintf(stderr, Name ":%s has an active reshape - checking "
1210 "if critical section needs to be restored\n",
1211 chosen_name);
1212 for (i=0; i<bestcnt; i++) {
1213 int j = best[i];
1214 if (j >= 0) {
1215 fdlist[i] = dev_open(devices[j].devname, O_RDWR|O_EXCL);
1216 if (fdlist[i] < 0) {
1217 fprintf(stderr, Name ": Could not open %s for write - cannot Assemble array.\n",
1218 devices[j].devname);
1219 err = 1;
1220 break;
1221 }
1222 } else
1223 fdlist[i] = -1;
1224 }
1225 if (!err) {
1226 if (st->ss->external && st->ss->recover_backup)
1227 err = st->ss->recover_backup(st, content);
1228 else
1229 err = Grow_restart(st, content, fdlist, bestcnt,
1230 backup_file, verbose > 0);
1231 if (err && invalid_backup) {
1232 if (verbose > 0)
1233 fprintf(stderr, Name ": continuing"
1234 " without restoring backup\n");
1235 err = 0;
1236 }
1237 }
1238 while (i>0) {
1239 i--;
1240 if (fdlist[i]>=0) close(fdlist[i]);
1241 }
1242 if (err) {
1243 fprintf(stderr, Name ": Failed to restore critical section for reshape, sorry.\n");
1244 if (backup_file == NULL)
1245 fprintf(stderr," Possibly you needed to specify the --backup-file\n");
1246 close(mdfd);
1247 free(devices);
1248 return err;
1249 }
1250 }
1251#endif
1252 /* count number of in-sync devices according to the superblock.
1253 * We must have this number to start the array without -s or -R
1254 */
1255 req_cnt = content->array.working_disks;
1256
1257 /* Almost ready to actually *do* something */
1258 if (!old_linux) {
1259 int rv;
1260
1261 /* First, fill in the map, so that udev can find our name
1262 * as soon as we become active.
1263 */
1264 map_update(NULL, fd2devnum(mdfd), content->text_version,
1265 content->uuid, chosen_name);
1266
1267 rv = set_array_info(mdfd, st, content);
1268 if (rv) {
1269 fprintf(stderr, Name ": failed to set array info for %s: %s\n",
1270 mddev, strerror(errno));
1271 ioctl(mdfd, STOP_ARRAY, NULL);
1272 close(mdfd);
1273 free(devices);
1274 return 1;
1275 }
1276 if (ident->bitmap_fd >= 0) {
1277 if (ioctl(mdfd, SET_BITMAP_FILE, ident->bitmap_fd) != 0) {
1278 fprintf(stderr, Name ": SET_BITMAP_FILE failed.\n");
1279 ioctl(mdfd, STOP_ARRAY, NULL);
1280 close(mdfd);
1281 free(devices);
1282 return 1;
1283 }
1284 } else if (ident->bitmap_file) {
1285 /* From config file */
1286 int bmfd = open(ident->bitmap_file, O_RDWR);
1287 if (bmfd < 0) {
1288 fprintf(stderr, Name ": Could not open bitmap file %s\n",
1289 ident->bitmap_file);
1290 ioctl(mdfd, STOP_ARRAY, NULL);
1291 close(mdfd);
1292 free(devices);
1293 return 1;
1294 }
1295 if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) {
1296 fprintf(stderr, Name ": Failed to set bitmapfile for %s\n", mddev);
1297 close(bmfd);
1298 ioctl(mdfd, STOP_ARRAY, NULL);
1299 close(mdfd);
1300 free(devices);
1301 return 1;
1302 }
1303 close(bmfd);
1304 }
1305
1306 /* First, add the raid disks, but add the chosen one last */
1307 for (i=0; i<= bestcnt; i++) {
1308 int j;
1309 if (i < bestcnt) {
1310 j = best[i];
1311 if (j == chosen_drive)
1312 continue;
1313 } else
1314 j = chosen_drive;
1315
1316 if (j >= 0 /* && devices[j].uptodate */) {
1317 int dfd = dev_open(devices[j].devname,
1318 O_RDWR|O_EXCL);
1319 if (dfd >= 0) {
1320 remove_partitions(dfd);
1321 close(dfd);
1322 }
1323 rv = add_disk(mdfd, st, content, &devices[j].i);
1324
1325 if (rv) {
1326 fprintf(stderr, Name ": failed to add "
1327 "%s to %s: %s\n",
1328 devices[j].devname,
1329 mddev,
1330 strerror(errno));
1331 if (i < content->array.raid_disks
1332 || i == bestcnt)
1333 okcnt--;
1334 else
1335 sparecnt--;
1336 } else if (verbose > 0)
1337 fprintf(stderr, Name ": added %s "
1338 "to %s as %d%s\n",
1339 devices[j].devname, mddev,
1340 devices[j].i.disk.raid_disk,
1341 devices[j].uptodate?"":
1342 " (possibly out of date)");
1343 } else if (verbose > 0 && i < content->array.raid_disks)
1344 fprintf(stderr, Name ": no uptodate device for "
1345 "slot %d of %s\n",
1346 i, mddev);
1347 }
1348
1349 if (content->array.level == LEVEL_CONTAINER) {
1350 if (verbose >= 0) {
1351 fprintf(stderr, Name ": Container %s has been "
1352 "assembled with %d drive%s",
1353 mddev, okcnt+sparecnt, okcnt+sparecnt==1?"":"s");
1354 if (okcnt < (unsigned)content->array.raid_disks)
1355 fprintf(stderr, " (out of %d)",
1356 content->array.raid_disks);
1357 fprintf(stderr, "\n");
1358 }
1359 st->ss->free_super(st);
1360 sysfs_uevent(content, "change");
1361 wait_for(chosen_name, mdfd);
1362 close(mdfd);
1363 free(devices);
1364 return 0;
1365 }
1366
1367 if (runstop == 1 ||
1368 (runstop <= 0 &&
1369 ( enough(content->array.level, content->array.raid_disks,
1370 content->array.layout, clean, avail) &&
1371 (okcnt + rebuilding_cnt >= req_cnt || start_partial_ok)
1372 ))) {
1373 /* This array is good-to-go.
1374 * If a reshape is in progress then we might need to
1375 * continue monitoring it. In that case we start
1376 * it read-only and let the grow code make it writable.
1377 */
1378 int rv;
1379#ifndef MDASSEMBLE
1380 if (content->reshape_active &&
1381 content->delta_disks <= 0) {
1382 rv = sysfs_set_str(content, NULL,
1383 "array_state", "readonly");
1384 if (rv == 0)
1385 rv = Grow_continue(mdfd, st, content,
1386 backup_file,
1387 freeze_reshape);
1388 } else
1389#endif
1390 rv = ioctl(mdfd, RUN_ARRAY, NULL);
1391 if (rv == 0) {
1392 if (verbose >= 0) {
1393 fprintf(stderr, Name ": %s has been started with %d drive%s",
1394 mddev, okcnt, okcnt==1?"":"s");
1395 if (okcnt < (unsigned)content->array.raid_disks)
1396 fprintf(stderr, " (out of %d)", content->array.raid_disks);
1397 if (rebuilding_cnt)
1398 fprintf(stderr, "%s %d rebuilding", sparecnt?",":" and", rebuilding_cnt);
1399 if (sparecnt)
1400 fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
1401 fprintf(stderr, ".\n");
1402 }
1403 if (content->reshape_active &&
1404 content->array.level >= 4 &&
1405 content->array.level <= 6) {
1406 /* might need to increase the size
1407 * of the stripe cache - default is 256
1408 */
1409 if (256 < 4 * (content->array.chunk_size/4096)) {
1410 struct mdinfo *sra = sysfs_read(mdfd, 0, 0);
1411 if (sra)
1412 sysfs_set_num(sra, NULL,
1413 "stripe_cache_size",
1414 (4 * content->array.chunk_size / 4096) + 1);
1415 sysfs_free(sra);
1416 }
1417 }
1418 if (okcnt < (unsigned)content->array.raid_disks) {
1419 /* If any devices did not get added
1420 * because the kernel rejected them based
1421 * on event count, try adding them
1422 * again providing the action policy is
1423 * 're-add' or greater. The bitmap
1424 * might allow them to be included, or
1425 * they will become spares.
1426 */
1427 for (i = 0; i < bestcnt; i++) {
1428 int j = best[i];
1429 if (j >= 0 && !devices[j].uptodate) {
1430 if (!disk_action_allows(&devices[j].i, st->ss->name, act_re_add))
1431 continue;
1432 rv = add_disk(mdfd, st, content,
1433 &devices[j].i);
1434 if (rv == 0 && verbose >= 0)
1435 fprintf(stderr,
1436 Name ": %s has been re-added.\n",
1437 devices[j].devname);
1438 }
1439 }
1440 }
1441 wait_for(mddev, mdfd);
1442 close(mdfd);
1443 if (auto_assem) {
1444 int usecs = 1;
1445 /* There is a nasty race with 'mdadm --monitor'.
1446 * If it opens this device before we close it,
1447 * it gets an incomplete open on which IO
1448 * doesn't work and the capacity is
1449 * wrong.
1450 * If we reopen (to check for layered devices)
1451 * before --monitor closes, we loose.
1452 *
1453 * So: wait upto 1 second for there to be
1454 * a non-zero capacity.
1455 */
1456 while (usecs < 1000) {
1457 mdfd = open(mddev, O_RDONLY);
1458 if (mdfd >= 0) {
1459 unsigned long long size;
1460 if (get_dev_size(mdfd, NULL, &size) &&
1461 size > 0)
1462 break;
1463 close(mdfd);
1464 }
1465 usleep(usecs);
1466 usecs <<= 1;
1467 }
1468 }
1469 free(devices);
1470 return 0;
1471 }
1472 fprintf(stderr, Name ": failed to RUN_ARRAY %s: %s\n",
1473 mddev, strerror(errno));
1474
1475 if (!enough(content->array.level, content->array.raid_disks,
1476 content->array.layout, 1, avail))
1477 fprintf(stderr, Name ": Not enough devices to "
1478 "start the array.\n");
1479 else if (!enough(content->array.level,
1480 content->array.raid_disks,
1481 content->array.layout, clean,
1482 avail))
1483 fprintf(stderr, Name ": Not enough devices to "
1484 "start the array while not clean "
1485 "- consider --force.\n");
1486
1487 if (auto_assem)
1488 ioctl(mdfd, STOP_ARRAY, NULL);
1489 close(mdfd);
1490 free(devices);
1491 return 1;
1492 }
1493 if (runstop == -1) {
1494 fprintf(stderr, Name ": %s assembled from %d drive%s",
1495 mddev, okcnt, okcnt==1?"":"s");
1496 if (okcnt != (unsigned)content->array.raid_disks)
1497 fprintf(stderr, " (out of %d)", content->array.raid_disks);
1498 fprintf(stderr, ", but not started.\n");
1499 close(mdfd);
1500 free(devices);
1501 return 0;
1502 }
1503 if (verbose >= -1) {
1504 fprintf(stderr, Name ": %s assembled from %d drive%s", mddev, okcnt, okcnt==1?"":"s");
1505 if (rebuilding_cnt)
1506 fprintf(stderr, "%s %d rebuilding", sparecnt?", ":" and ", rebuilding_cnt);
1507 if (sparecnt)
1508 fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
1509 if (!enough(content->array.level, content->array.raid_disks,
1510 content->array.layout, 1, avail))
1511 fprintf(stderr, " - not enough to start the array.\n");
1512 else if (!enough(content->array.level,
1513 content->array.raid_disks,
1514 content->array.layout, clean,
1515 avail))
1516 fprintf(stderr, " - not enough to start the "
1517 "array while not clean - consider "
1518 "--force.\n");
1519 else {
1520 if (req_cnt == (unsigned)content->array.raid_disks)
1521 fprintf(stderr, " - need all %d to start it", req_cnt);
1522 else
1523 fprintf(stderr, " - need %d of %d to start", req_cnt, content->array.raid_disks);
1524 fprintf(stderr, " (use --run to insist).\n");
1525 }
1526 }
1527 if (auto_assem)
1528 ioctl(mdfd, STOP_ARRAY, NULL);
1529 close(mdfd);
1530 free(devices);
1531 return 1;
1532 } else {
1533 /* The "chosen_drive" is a good choice, and if necessary, the superblock has
1534 * been updated to point to the current locations of devices.
1535 * so we can just start the array
1536 */
1537 unsigned long dev;
1538 dev = makedev(devices[chosen_drive].i.disk.major,
1539 devices[chosen_drive].i.disk.minor);
1540 if (ioctl(mdfd, START_ARRAY, dev)) {
1541 fprintf(stderr, Name ": Cannot start array: %s\n",
1542 strerror(errno));
1543 }
1544
1545 }
1546 close(mdfd);
1547 free(devices);
1548 return 0;
1549}
1550
1551#ifndef MDASSEMBLE
1552int assemble_container_content(struct supertype *st, int mdfd,
1553 struct mdinfo *content, int runstop,
1554 char *chosen_name, int verbose,
1555 char *backup_file, int freeze_reshape)
1556{
1557 struct mdinfo *dev, *sra;
1558 int working = 0, preexist = 0;
1559 int expansion = 0;
1560 struct map_ent *map = NULL;
1561 int old_raid_disks;
1562 int start_reshape;
1563
1564 sysfs_init(content, mdfd, 0);
1565
1566 sra = sysfs_read(mdfd, 0, GET_VERSION);
1567 if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0)
1568 if (sysfs_set_array(content, md_get_version(mdfd)) != 0) {
1569 if (sra)
1570 sysfs_free(sra);
1571 return 1;
1572 }
1573
1574 /* There are two types of reshape: container wide or sub-array specific
1575 * Check if metadata requests blocking container wide reshapes
1576 */
1577 start_reshape = (content->reshape_active &&
1578 !((content->reshape_active == CONTAINER_RESHAPE) &&
1579 (content->array.state & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE))));
1580
1581 /* Block subarray here if it is under reshape now
1582 * Do not allow for any changes in this array
1583 */
1584 if (st->ss->external && content->recovery_blocked && start_reshape)
1585 block_subarray(content);
1586
1587 if (sra)
1588 sysfs_free(sra);
1589 old_raid_disks = content->array.raid_disks - content->delta_disks;
1590 for (dev = content->devs; dev; dev = dev->next)
1591 if (sysfs_add_disk(content, dev, 1) == 0) {
1592 if (dev->disk.raid_disk >= old_raid_disks &&
1593 content->reshape_active)
1594 expansion++;
1595 else
1596 working++;
1597 } else if (errno == EEXIST)
1598 preexist++;
1599 if (working + expansion == 0)
1600 return 1;/* Nothing new, don't try to start */
1601
1602 map_update(&map, fd2devnum(mdfd),
1603 content->text_version,
1604 content->uuid, chosen_name);
1605
1606 if (runstop > 0 ||
1607 (working + preexist + expansion) >=
1608 content->array.working_disks) {
1609 int err;
1610
1611 if (start_reshape) {
1612 int spare = content->array.raid_disks + expansion;
1613 if (restore_backup(st, content,
1614 working,
1615 spare, backup_file, verbose) == 1)
1616 return 1;
1617
1618 err = sysfs_set_str(content, NULL,
1619 "array_state", "readonly");
1620 if (err)
1621 return 1;
1622
1623 if (st->ss->external) {
1624 if (!mdmon_running(st->container_dev))
1625 start_mdmon(st->container_dev);
1626 ping_monitor_by_id(st->container_dev);
1627 if (mdmon_running(st->container_dev) &&
1628 st->update_tail == NULL)
1629 st->update_tail = &st->updates;
1630 }
1631
1632 err = Grow_continue(mdfd, st, content, backup_file,
1633 freeze_reshape);
1634 } else switch(content->array.level) {
1635 case LEVEL_LINEAR:
1636 case LEVEL_MULTIPATH:
1637 case 0:
1638 err = sysfs_set_str(content, NULL, "array_state",
1639 "active");
1640 break;
1641 default:
1642 err = sysfs_set_str(content, NULL, "array_state",
1643 "readonly");
1644 /* start mdmon if needed. */
1645 if (!err) {
1646 if (!mdmon_running(st->container_dev))
1647 start_mdmon(st->container_dev);
1648 ping_monitor_by_id(st->container_dev);
1649 }
1650 break;
1651 }
1652 if (!err)
1653 sysfs_set_safemode(content, content->safe_mode_delay);
1654
1655 /* Block subarray here if it is not reshaped now
1656 * It has be blocked a little later to allow mdmon to switch in
1657 * in to R/W state
1658 */
1659 if (st->ss->external && content->recovery_blocked &&
1660 !start_reshape)
1661 block_subarray(content);
1662
1663 if (verbose >= 0) {
1664 if (err)
1665 fprintf(stderr, Name
1666 ": array %s now has %d device%s",
1667 chosen_name, working + preexist,
1668 working + preexist == 1 ? "":"s");
1669 else
1670 fprintf(stderr, Name
1671 ": Started %s with %d device%s",
1672 chosen_name, working + preexist,
1673 working + preexist == 1 ? "":"s");
1674 if (preexist)
1675 fprintf(stderr, " (%d new)", working);
1676 if (expansion)
1677 fprintf(stderr, " ( + %d for expansion)",
1678 expansion);
1679 fprintf(stderr, "\n");
1680 }
1681 if (!err)
1682 wait_for(chosen_name, mdfd);
1683 return err;
1684 /* FIXME should have an O_EXCL and wait for read-auto */
1685 } else {
1686 if (verbose >= 0) {
1687 fprintf(stderr, Name
1688 ": %s assembled with %d device%s",
1689 chosen_name, preexist + working,
1690 preexist + working == 1 ? "":"s");
1691 if (preexist)
1692 fprintf(stderr, " (%d new)", working);
1693 fprintf(stderr, " but not started\n");
1694 }
1695 return 1;
1696 }
1697}
1698#endif
1699
01700
=== removed file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/Assemble.c'
--- .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/Assemble.c 2012-02-09 16:53:02 +0000
+++ .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/Assemble.c 1970-01-01 00:00:00 +0000
@@ -1,1650 +0,0 @@
1/*
2 * mdadm - manage Linux "md" devices aka RAID arrays.
3 *
4 * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Author: Neil Brown
22 * Email: <neilb@suse.de>
23 */
24
25#include "mdadm.h"
26#include <ctype.h>
27
28static int name_matches(char *found, char *required, char *homehost)
29{
30 /* See if the name found matches the required name, possibly
31 * prefixed with 'homehost'
32 */
33 char fnd[33];
34
35 strncpy(fnd, found, 32);
36 fnd[32] = 0;
37 if (strcmp(found, required)==0)
38 return 1;
39 if (homehost) {
40 int l = strlen(homehost);
41 if (l < 32 && fnd[l] == ':' &&
42 strcmp(fnd+l+1, required)==0)
43 return 1;
44 }
45 return 0;
46}
47
48static int is_member_busy(char *metadata_version)
49{
50 /* check if the given member array is active */
51 struct mdstat_ent *mdstat = mdstat_read(1, 0);
52 struct mdstat_ent *ent;
53 int busy = 0;
54
55 for (ent = mdstat; ent; ent = ent->next) {
56 if (ent->metadata_version == NULL)
57 continue;
58 if (strncmp(ent->metadata_version, "external:", 9) != 0)
59 continue;
60 if (!is_subarray(&ent->metadata_version[9]))
61 continue;
62 /* Skip first char - it can be '/' or '-' */
63 if (strcmp(&ent->metadata_version[10], metadata_version+1) == 0) {
64 busy = 1;
65 break;
66 }
67 }
68 free_mdstat(mdstat);
69
70 return busy;
71}
72
73static int ident_matches(struct mddev_ident *ident,
74 struct mdinfo *content,
75 struct supertype *tst,
76 char *homehost,
77 char *update, char *devname)
78{
79
80 if (ident->uuid_set && (!update || strcmp(update, "uuid")!= 0) &&
81 same_uuid(content->uuid, ident->uuid, tst->ss->swapuuid)==0 &&
82 memcmp(content->uuid, uuid_zero, sizeof(int[4])) != 0) {
83 if (devname)
84 fprintf(stderr, Name ": %s has wrong uuid.\n",
85 devname);
86 return 0;
87 }
88 if (ident->name[0] && (!update || strcmp(update, "name")!= 0) &&
89 name_matches(content->name, ident->name, homehost)==0) {
90 if (devname)
91 fprintf(stderr, Name ": %s has wrong name.\n",
92 devname);
93 return 0;
94 }
95 if (ident->super_minor != UnSet &&
96 ident->super_minor != content->array.md_minor) {
97 if (devname)
98 fprintf(stderr, Name ": %s has wrong super-minor.\n",
99 devname);
100 return 0;
101 }
102 if (ident->level != UnSet &&
103 ident->level != content->array.level) {
104 if (devname)
105 fprintf(stderr, Name ": %s has wrong raid level.\n",
106 devname);
107 return 0;
108 }
109 if (ident->raid_disks != UnSet &&
110 ident->raid_disks!= content->array.raid_disks) {
111 if (devname)
112 fprintf(stderr, Name ": %s requires wrong number of drives.\n",
113 devname);
114 return 0;
115 }
116 if (ident->member && ident->member[0]) {
117 /* content->text_version must match */
118 char *s = strchr(content->text_version+1, '/');
119 if (s == NULL) {
120 if (devname)
121 fprintf(stderr, Name ": %s is not a container and one is required.\n",
122 devname);
123 return 0;
124 } else if (strcmp(ident->member, s+1) != 0) {
125 if (devname)
126 fprintf(stderr, Name ": skipping wrong member %s is %s\n",
127 content->text_version, devname);
128 return 0;
129 }
130 }
131 return 1;
132}
133
134
135int Assemble(struct supertype *st, char *mddev,
136 struct mddev_ident *ident,
137 struct mddev_dev *devlist,
138 char *backup_file, int invalid_backup,
139 int readonly, int runstop,
140 char *update, char *homehost, int require_homehost,
141 int verbose, int force, int freeze_reshape)
142{
143 /*
144 * The task of Assemble is to find a collection of
145 * devices that should (according to their superblocks)
146 * form an array, and to give this collection to the MD driver.
147 * In Linux-2.4 and later, this involves submitting a
148 * SET_ARRAY_INFO ioctl with no arg - to prepare
149 * the array - and then submit a number of
150 * ADD_NEW_DISK ioctls to add disks into
151 * the array. Finally RUN_ARRAY might
152 * be submitted to start the array.
153 *
154 * Much of the work of Assemble is in finding and/or
155 * checking the disks to make sure they look right.
156 *
157 * If mddev is not set, then scan must be set and we
158 * read through the config file for dev+uuid mapping
159 * We recurse, setting mddev, for each device that
160 * - isn't running
161 * - has a valid uuid (or any uuid if !uuidset)
162 *
163 * If mddev is set, we try to determine state of md.
164 * check version - must be at least 0.90.0
165 * check kernel version. must be at least 2.4.
166 * If not, we can possibly fall back on START_ARRAY
167 * Try to GET_ARRAY_INFO.
168 * If possible, give up
169 * If not, try to STOP_ARRAY just to make sure
170 *
171 * If !uuidset and scan, look in conf-file for uuid
172 * If not found, give up
173 * If !devlist and scan and uuidset, get list of devs from conf-file
174 *
175 * For each device:
176 * Check superblock - discard if bad
177 * Check uuid (set if we don't have one) - discard if no match
178 * Check superblock similarity if we have a superblock - discard if different
179 * Record events, devicenum
180 * This should give us a list of devices for the array
181 * We should collect the most recent event number
182 *
183 * Count disks with recent enough event count
184 * While force && !enough disks
185 * Choose newest rejected disks, update event count
186 * mark clean and rewrite superblock
187 * If recent kernel:
188 * SET_ARRAY_INFO
189 * foreach device with recent events : ADD_NEW_DISK
190 * if runstop == 1 || "enough" disks and runstop==0 -> RUN_ARRAY
191 * If old kernel:
192 * Check the device numbers in superblock are right
193 * update superblock if any changes
194 * START_ARRAY
195 *
196 */
197 int mdfd;
198 int clean;
199 int auto_assem = (mddev == NULL && !ident->uuid_set &&
200 ident->super_minor == UnSet && ident->name[0] == 0
201 && (ident->container == NULL || ident->member == NULL));
202 int old_linux = 0;
203 int vers = vers; /* Keep gcc quite - it really is initialised */
204 struct {
205 char *devname;
206 int uptodate; /* set once we decide that this device is as
207 * recent as everything else in the array.
208 */
209 struct mdinfo i;
210 } *devices;
211 char *devmap;
212 int *best = NULL; /* indexed by raid_disk */
213 int bestcnt = 0;
214 int devcnt = 0;
215 unsigned int okcnt, sparecnt, rebuilding_cnt;
216 unsigned int req_cnt;
217 int i;
218 int most_recent = 0;
219 int chosen_drive;
220 int change = 0;
221 int inargv = 0;
222 int report_missmatch;
223#ifndef MDASSEMBLE
224 int bitmap_done;
225#endif
226 int start_partial_ok = (runstop >= 0) &&
227 (force || devlist==NULL || auto_assem);
228 unsigned int num_devs;
229 struct mddev_dev *tmpdev;
230 struct mdinfo info;
231 struct mdinfo *content = NULL;
232 char *avail;
233 int nextspare = 0;
234 char *name = NULL;
235 int trustworthy;
236 char chosen_name[1024];
237 struct domainlist *domains = NULL;
238
239 if (get_linux_version() < 2004000)
240 old_linux = 1;
241
242 /*
243 * If any subdevs are listed, then any that don't
244 * match ident are discarded. Remainder must all match and
245 * become the array.
246 * If no subdevs, then we scan all devices in the config file, but
247 * there must be something in the identity
248 */
249
250 if (!devlist &&
251 ident->uuid_set == 0 &&
252 (ident->super_minor < 0 || ident->super_minor == UnSet) &&
253 ident->name[0] == 0 &&
254 (ident->container == NULL || ident->member == NULL) &&
255 ident->devices == NULL) {
256 fprintf(stderr, Name ": No identity information available for %s - cannot assemble.\n",
257 mddev ? mddev : "further assembly");
258 return 1;
259 }
260
261 if (devlist == NULL)
262 devlist = conf_get_devs();
263 else if (mddev)
264 inargv = 1;
265
266 report_missmatch = ((inargv && verbose >= 0) || verbose > 0);
267 try_again:
268 /* We come back here when doing auto-assembly and attempting some
269 * set of devices failed. Those are now marked as ->used==2 and
270 * we ignore them and try again
271 */
272
273 tmpdev = devlist; num_devs = 0;
274 while (tmpdev) {
275 if (tmpdev->used)
276 tmpdev->used = 2;
277 else
278 num_devs++;
279 tmpdev = tmpdev->next;
280 }
281
282 if (!st && ident->st) st = ident->st;
283
284 if (verbose>0)
285 fprintf(stderr, Name ": looking for devices for %s\n",
286 mddev ? mddev : "further assembly");
287
288 /* first walk the list of devices to find a consistent set
289 * that match the criterea, if that is possible.
290 * We flag the ones we like with 'used'.
291 */
292 for (tmpdev = devlist;
293 tmpdev;
294 tmpdev = tmpdev ? tmpdev->next : NULL) {
295 char *devname = tmpdev->devname;
296 int dfd;
297 struct stat stb;
298 struct supertype *tst;
299 struct dev_policy *pol = NULL;
300 int found_container = 0;
301
302 if (tmpdev->used > 1) continue;
303
304 if (ident->devices &&
305 !match_oneof(ident->devices, devname)) {
306 if (report_missmatch)
307 fprintf(stderr, Name ": %s is not one of %s\n", devname, ident->devices);
308 continue;
309 }
310
311 tst = dup_super(st);
312
313 dfd = dev_open(devname, O_RDONLY|O_EXCL);
314 if (dfd < 0) {
315 if (report_missmatch)
316 fprintf(stderr, Name ": cannot open device %s: %s\n",
317 devname, strerror(errno));
318 tmpdev->used = 2;
319 } else if (fstat(dfd, &stb)< 0) {
320 /* Impossible! */
321 fprintf(stderr, Name ": fstat failed for %s: %s\n",
322 devname, strerror(errno));
323 tmpdev->used = 2;
324 } else if ((stb.st_mode & S_IFMT) != S_IFBLK) {
325 fprintf(stderr, Name ": %s is not a block device.\n",
326 devname);
327 tmpdev->used = 2;
328 } else if (must_be_container(dfd)) {
329 if (st) {
330 /* already found some components, this cannot
331 * be another one.
332 */
333 if (report_missmatch)
334 fprintf(stderr, Name ": %s is a container, but we are looking for components\n",
335 devname);
336 tmpdev->used = 2;
337#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
338 } if (!tst && (tst = super_by_fd(dfd, NULL)) == NULL) {
339 if (report_missmatch)
340 fprintf(stderr, Name ": not a recognisable container: %s\n",
341 devname);
342 tmpdev->used = 2;
343#endif
344 } else if (!tst->ss->load_container
345 || tst->ss->load_container(tst, dfd, NULL)) {
346 if (report_missmatch)
347 fprintf(stderr, Name ": no correct container type: %s\n",
348 devname);
349 tmpdev->used = 2;
350 } else if (auto_assem &&
351 !conf_test_metadata(tst->ss->name, (pol = devnum_policy(stb.st_rdev)),
352 tst->ss->match_home(tst, homehost) == 1)) {
353 if (report_missmatch)
354 fprintf(stderr, Name ": %s has metadata type %s for which "
355 "auto-assembly is disabled\n",
356 devname, tst->ss->name);
357 tmpdev->used = 2;
358 } else
359 found_container = 1;
360 } else {
361 if (!tst && (tst = guess_super(dfd)) == NULL) {
362 if (report_missmatch)
363 fprintf(stderr, Name ": no recogniseable superblock on %s\n",
364 devname);
365 tmpdev->used = 2;
366 } else if (tst->ss->load_super(tst,dfd, NULL)) {
367 if (report_missmatch)
368 fprintf(stderr, Name ": no RAID superblock on %s\n",
369 devname);
370 tmpdev->used = 2;
371 } else if (tst->ss->compare_super == NULL) {
372 if (report_missmatch)
373 fprintf(stderr, Name ": Cannot assemble %s metadata on %s\n",
374 tst->ss->name, devname);
375 tmpdev->used = 2;
376 } else if (auto_assem && st == NULL &&
377 !conf_test_metadata(tst->ss->name, (pol = devnum_policy(stb.st_rdev)),
378 tst->ss->match_home(tst, homehost) == 1)) {
379 if (report_missmatch)
380 fprintf(stderr, Name ": %s has metadata type %s for which "
381 "auto-assembly is disabled\n",
382 devname, tst->ss->name);
383 tmpdev->used = 2;
384 }
385 }
386 if (dfd >= 0) close(dfd);
387 if (tmpdev->used == 2) {
388 if (auto_assem || !inargv)
389 /* Ignore unrecognised devices during auto-assembly */
390 goto loop;
391 if (ident->uuid_set || ident->name[0] ||
392 ident->super_minor != UnSet)
393 /* Ignore unrecognised device if looking for
394 * specific array */
395 goto loop;
396
397
398 fprintf(stderr, Name ": %s has no superblock - assembly aborted\n",
399 devname);
400 if (st)
401 st->ss->free_super(st);
402 dev_policy_free(pol);
403 domain_free(domains);
404 return 1;
405 }
406
407 if (found_container) {
408 /* tmpdev is a container. We need to be either
409 * looking for a member, or auto-assembling
410 */
411
412 if (ident->container) {
413 if (ident->container[0] == '/' &&
414 !same_dev(ident->container, devname)) {
415 if (report_missmatch)
416 fprintf(stderr, Name ": %s is not the container required (%s)\n",
417 devname, ident->container);
418 goto loop;
419 }
420 if (ident->container[0] != '/') {
421 /* we have a uuid */
422 int uuid[4];
423
424 content = &info;
425 tst->ss->getinfo_super(tst, content, NULL);
426
427 if (!parse_uuid(ident->container, uuid) ||
428 !same_uuid(content->uuid, uuid, tst->ss->swapuuid)) {
429 if (report_missmatch)
430 fprintf(stderr, Name ": %s has wrong UUID to be required container\n",
431 devname);
432 goto loop;
433 }
434 }
435 }
436 /* It is worth looking inside this container.
437 */
438 if (verbose > 0)
439 fprintf(stderr, Name ": looking in container %s\n",
440 devname);
441
442 for (content = tst->ss->container_content(tst, NULL);
443 content;
444 content = content->next) {
445
446 if (!ident_matches(ident, content, tst,
447 homehost, update,
448 report_missmatch ? devname : NULL))
449 /* message already printed */;
450 else if (is_member_busy(content->text_version)) {
451 if (report_missmatch)
452 fprintf(stderr, Name ": member %s in %s is already assembled\n",
453 content->text_version,
454 devname);
455 } else if (content->array.state & (1<<MD_SB_BLOCK_VOLUME)) {
456 /* do not assemble arrays with unsupported configurations */
457 fprintf(stderr, Name ": Cannot activate member %s in %s.\n",
458 content->text_version,
459 devname);
460 } else
461 break;
462 }
463 if (!content) {
464 tmpdev->used = 2;
465 goto loop; /* empty container */
466 }
467
468 st = tst; tst = NULL;
469 if (!auto_assem && inargv && tmpdev->next != NULL) {
470 fprintf(stderr, Name ": %s is a container, but is not "
471 "only device given: confused and aborting\n",
472 devname);
473 st->ss->free_super(st);
474 dev_policy_free(pol);
475 domain_free(domains);
476 return 1;
477 }
478 if (verbose > 0)
479 fprintf(stderr, Name ": found match on member %s in %s\n",
480 content->text_version, devname);
481
482 /* make sure we finished the loop */
483 tmpdev = NULL;
484 goto loop;
485 } else {
486
487 content = &info;
488 tst->ss->getinfo_super(tst, content, NULL);
489
490 if (!ident_matches(ident, content, tst,
491 homehost, update,
492 report_missmatch ? devname : NULL))
493 goto loop;
494
495 if (st == NULL)
496 st = dup_super(tst);
497 if (st->minor_version == -1)
498 st->minor_version = tst->minor_version;
499
500 if (memcmp(content->uuid, uuid_zero,
501 sizeof(int[4])) == 0) {
502 /* this is a floating spare. It cannot define
503 * an array unless there are no more arrays of
504 * this type to be found. It can be included
505 * in an array of this type though.
506 */
507 tmpdev->used = 3;
508 goto loop;
509 }
510
511 if (st->ss != tst->ss ||
512 st->minor_version != tst->minor_version ||
513 st->ss->compare_super(st, tst) != 0) {
514 /* Some mismatch. If exactly one array matches this host,
515 * we can resolve on that one.
516 * Or, if we are auto assembling, we just ignore the second
517 * for now.
518 */
519 if (auto_assem)
520 goto loop;
521 if (homehost) {
522 int first = st->ss->match_home(st, homehost);
523 int last = tst->ss->match_home(tst, homehost);
524 if (first != last &&
525 (first == 1 || last == 1)) {
526 /* We can do something */
527 if (first) {/* just ignore this one */
528 if (report_missmatch)
529 fprintf(stderr, Name ": %s misses out due to wrong homehost\n",
530 devname);
531 goto loop;
532 } else { /* reject all those sofar */
533 struct mddev_dev *td;
534 if (report_missmatch)
535 fprintf(stderr, Name ": %s overrides previous devices due to good homehost\n",
536 devname);
537 for (td=devlist; td != tmpdev; td=td->next)
538 if (td->used == 1)
539 td->used = 0;
540 tmpdev->used = 1;
541 goto loop;
542 }
543 }
544 }
545 fprintf(stderr, Name ": superblock on %s doesn't match others - assembly aborted\n",
546 devname);
547 tst->ss->free_super(tst);
548 st->ss->free_super(st);
549 dev_policy_free(pol);
550 domain_free(domains);
551 return 1;
552 }
553 tmpdev->used = 1;
554 }
555 loop:
556 /* Collect domain information from members only */
557 if (tmpdev && tmpdev->used == 1) {
558 if (!pol)
559 pol = devnum_policy(stb.st_rdev);
560 domain_merge(&domains, pol, tst?tst->ss->name:NULL);
561 }
562 dev_policy_free(pol);
563 pol = NULL;
564 if (tst)
565 tst->ss->free_super(tst);
566 }
567
568 /* Check if we found some imsm spares but no members */
569 if ((auto_assem ||
570 (ident->uuid_set &&
571 memcmp(uuid_zero, ident->uuid,sizeof(uuid_zero)) == 0)) &&
572 (!st || !st->sb))
573 for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
574 if (tmpdev->used != 3)
575 continue;
576 tmpdev->used = 1;
577 content = &info;
578
579 if (!st->sb) {
580 /* we need sb from one of the spares */
581 int dfd = dev_open(tmpdev->devname, O_RDONLY);
582 if (dfd < 0 ||
583 st->ss->load_super(st, dfd, NULL))
584 tmpdev->used = 2;
585 if (dfd > 0)
586 close(dfd);
587 }
588 }
589
590 /* Now reject spares that don't match domains of identified members */
591 for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
592 struct stat stb;
593 if (tmpdev->used != 3)
594 continue;
595 if (stat(tmpdev->devname, &stb)< 0) {
596 fprintf(stderr, Name ": fstat failed for %s: %s\n",
597 tmpdev->devname, strerror(errno));
598 tmpdev->used = 2;
599 } else {
600 struct dev_policy *pol = devnum_policy(stb.st_rdev);
601 int dt = domain_test(domains, pol, NULL);
602 if (inargv && dt != 0)
603 /* take this spare as domains match
604 * if there are any */
605 tmpdev->used = 1;
606 else if (!inargv && dt == 1)
607 /* device wasn't explicitly listed, so need
608 * explicit domain match - which we have */
609 tmpdev->used = 1;
610 else
611 /* if domains don't match mark as unused */
612 tmpdev->used = 0;
613 dev_policy_free(pol);
614 }
615 }
616 domain_free(domains);
617
618 if (!st || !st->sb || !content)
619 return 2;
620
621 /* Now need to open the array device. Use create_mddev */
622 if (content == &info)
623 st->ss->getinfo_super(st, content, NULL);
624
625 trustworthy = FOREIGN;
626 name = content->name;
627 switch (st->ss->match_home(st, homehost)
628 ?: st->ss->match_home(st, "any")) {
629 case 1:
630 trustworthy = LOCAL;
631 name = strchr(content->name, ':');
632 if (name)
633 name++;
634 else
635 name = content->name;
636 break;
637 }
638 if (!auto_assem)
639 /* If the array is listed in mdadm.conf or on
640 * command line, then we trust the name
641 * even if the array doesn't look local
642 */
643 trustworthy = LOCAL;
644
645 if (name[0] == 0 &&
646 content->array.level == LEVEL_CONTAINER) {
647 name = content->text_version;
648 trustworthy = METADATA;
649 }
650
651 if (name[0] && trustworthy != LOCAL &&
652 ! require_homehost &&
653 conf_name_is_free(name))
654 trustworthy = LOCAL;
655
656 if (trustworthy == LOCAL &&
657 strchr(name, ':'))
658 /* Ignore 'host:' prefix of name */
659 name = strchr(name, ':')+1;
660
661 mdfd = create_mddev(mddev, name, ident->autof, trustworthy,
662 chosen_name);
663 if (mdfd < 0) {
664 st->ss->free_super(st);
665 if (auto_assem)
666 goto try_again;
667 return 1;
668 }
669 mddev = chosen_name;
670 vers = md_get_version(mdfd);
671 if (vers < 9000) {
672 fprintf(stderr, Name ": Assemble requires driver version 0.90.0 or later.\n"
673 " Upgrade your kernel or try --build\n");
674 close(mdfd);
675 return 1;
676 }
677 if (mddev_busy(fd2devnum(mdfd))) {
678 fprintf(stderr, Name ": %s already active, cannot restart it!\n",
679 mddev);
680 for (tmpdev = devlist ;
681 tmpdev && tmpdev->used != 1;
682 tmpdev = tmpdev->next)
683 ;
684 if (tmpdev && auto_assem)
685 fprintf(stderr, Name ": %s needed for %s...\n",
686 mddev, tmpdev->devname);
687 close(mdfd);
688 mdfd = -3;
689 st->ss->free_super(st);
690 if (auto_assem)
691 goto try_again;
692 return 1;
693 }
694 ioctl(mdfd, STOP_ARRAY, NULL); /* just incase it was started but has no content */
695
696#ifndef MDASSEMBLE
697 if (content != &info) {
698 /* This is a member of a container. Try starting the array. */
699 int err;
700 err = assemble_container_content(st, mdfd, content, runstop,
701 chosen_name, verbose,
702 backup_file, freeze_reshape);
703 close(mdfd);
704 return err;
705 }
706 bitmap_done = 0;
707#endif
708 /* Ok, no bad inconsistancy, we can try updating etc */
709 devices = malloc(num_devs * sizeof(*devices));
710 devmap = calloc(num_devs * content->array.raid_disks, 1);
711 for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) {
712 char *devname = tmpdev->devname;
713 struct stat stb;
714 /* looks like a good enough match to update the super block if needed */
715#ifndef MDASSEMBLE
716 if (update) {
717 int dfd;
718 /* prepare useful information in info structures */
719 struct stat stb2;
720 struct supertype *tst;
721 int err;
722 fstat(mdfd, &stb2);
723
724 if (strcmp(update, "uuid")==0 &&
725 !ident->uuid_set) {
726 int rfd;
727 if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
728 read(rfd, ident->uuid, 16) != 16) {
729 *(__u32*)(ident->uuid) = random();
730 *(__u32*)(ident->uuid+1) = random();
731 *(__u32*)(ident->uuid+2) = random();
732 *(__u32*)(ident->uuid+3) = random();
733 }
734 if (rfd >= 0) close(rfd);
735 }
736 dfd = dev_open(devname, O_RDWR|O_EXCL);
737
738 tst = dup_super(st);
739 if (dfd < 0 || tst->ss->load_super(tst, dfd, NULL) != 0) {
740 fprintf(stderr, Name ": cannot re-read metadata from %s - aborting\n",
741 devname);
742 if (dfd >= 0)
743 close(dfd);
744 close(mdfd);
745 free(devices);
746 free(devmap);
747 return 1;
748 }
749 tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
750
751 memcpy(content->uuid, ident->uuid, 16);
752 strcpy(content->name, ident->name);
753 content->array.md_minor = minor(stb2.st_rdev);
754
755 if (strcmp(update, "byteorder") == 0)
756 err = 0;
757 else
758 err = tst->ss->update_super(tst, content, update,
759 devname, verbose,
760 ident->uuid_set,
761 homehost);
762 if (err < 0) {
763 fprintf(stderr,
764 Name ": --update=%s not understood"
765 " for %s metadata\n",
766 update, tst->ss->name);
767 tst->ss->free_super(tst);
768 free(tst);
769 close(mdfd);
770 close(dfd);
771 free(devices);
772 free(devmap);
773 return 1;
774 }
775 if (strcmp(update, "uuid")==0 &&
776 !ident->uuid_set) {
777 ident->uuid_set = 1;
778 memcpy(ident->uuid, content->uuid, 16);
779 }
780 if (tst->ss->store_super(tst, dfd))
781 fprintf(stderr, Name ": Could not re-write superblock on %s.\n",
782 devname);
783 close(dfd);
784
785 if (strcmp(update, "uuid")==0 &&
786 ident->bitmap_fd >= 0 && !bitmap_done) {
787 if (bitmap_update_uuid(ident->bitmap_fd,
788 content->uuid,
789 tst->ss->swapuuid) != 0)
790 fprintf(stderr, Name ": Could not update uuid on external bitmap.\n");
791 else
792 bitmap_done = 1;
793 }
794 tst->ss->free_super(tst);
795 } else
796#endif
797 {
798 struct supertype *tst = dup_super(st);
799 int dfd;
800 dfd = dev_open(devname, O_RDWR|O_EXCL);
801
802 if (dfd < 0 || tst->ss->load_super(tst, dfd, NULL) != 0) {
803 fprintf(stderr, Name ": cannot re-read metadata from %s - aborting\n",
804 devname);
805 if (dfd >= 0)
806 close(dfd);
807 close(mdfd);
808 free(devices);
809 free(devmap);
810 return 1;
811 }
812 tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
813 tst->ss->free_super(tst);
814 close(dfd);
815 }
816
817 stat(devname, &stb);
818
819 if (verbose > 0)
820 fprintf(stderr, Name ": %s is identified as a member of %s, slot %d.\n",
821 devname, mddev, content->disk.raid_disk);
822 devices[devcnt].devname = devname;
823 devices[devcnt].uptodate = 0;
824 devices[devcnt].i = *content;
825 devices[devcnt].i.disk.major = major(stb.st_rdev);
826 devices[devcnt].i.disk.minor = minor(stb.st_rdev);
827 if (most_recent < devcnt) {
828 if (devices[devcnt].i.events
829 > devices[most_recent].i.events)
830 most_recent = devcnt;
831 }
832 if (content->array.level == LEVEL_MULTIPATH)
833 /* with multipath, the raid_disk from the superblock is meaningless */
834 i = devcnt;
835 else
836 i = devices[devcnt].i.disk.raid_disk;
837 if (i+1 == 0) {
838 if (nextspare < content->array.raid_disks)
839 nextspare = content->array.raid_disks;
840 i = nextspare++;
841 } else {
842 if (i >= content->array.raid_disks &&
843 i >= nextspare)
844 nextspare = i+1;
845 }
846 if (i < 10000) {
847 if (i >= bestcnt) {
848 int newbestcnt = i+10;
849 int *newbest = malloc(sizeof(int)*newbestcnt);
850 int c;
851 for (c=0; c < newbestcnt; c++)
852 if (c < bestcnt)
853 newbest[c] = best[c];
854 else
855 newbest[c] = -1;
856 if (best)free(best);
857 best = newbest;
858 bestcnt = newbestcnt;
859 }
860 if (best[i] >=0 &&
861 devices[best[i]].i.events
862 == devices[devcnt].i.events
863 && (devices[best[i]].i.disk.minor
864 != devices[devcnt].i.disk.minor)
865 && st->ss == &super0
866 && content->array.level != LEVEL_MULTIPATH) {
867 /* two different devices with identical superblock.
868 * Could be a mis-detection caused by overlapping
869 * partitions. fail-safe.
870 */
871 fprintf(stderr, Name ": WARNING %s and %s appear"
872 " to have very similar superblocks.\n"
873 " If they are really different, "
874 "please --zero the superblock on one\n"
875 " If they are the same or overlap,"
876 " please remove one from %s.\n",
877 devices[best[i]].devname, devname,
878 inargv ? "the list" :
879 "the\n DEVICE list in mdadm.conf"
880 );
881 close(mdfd);
882 free(devices);
883 free(devmap);
884 return 1;
885 }
886 if (best[i] == -1
887 || (devices[best[i]].i.events
888 < devices[devcnt].i.events))
889 best[i] = devcnt;
890 }
891 devcnt++;
892 }
893
894 if (devcnt == 0) {
895 fprintf(stderr, Name ": no devices found for %s\n",
896 mddev);
897 if (st)
898 st->ss->free_super(st);
899 close(mdfd);
900 free(devices);
901 free(devmap);
902 return 1;
903 }
904
905 if (update && strcmp(update, "byteorder")==0)
906 st->minor_version = 90;
907
908 st->ss->getinfo_super(st, content, NULL);
909 clean = content->array.state & 1;
910
911 /* now we have some devices that might be suitable.
912 * I wonder how many
913 */
914 avail = malloc(content->array.raid_disks);
915 memset(avail, 0, content->array.raid_disks);
916 okcnt = 0;
917 sparecnt=0;
918 rebuilding_cnt=0;
919 for (i=0; i< bestcnt; i++) {
920 int j = best[i];
921 int event_margin = 1; /* always allow a difference of '1'
922 * like the kernel does
923 */
924 if (j < 0) continue;
925 /* note: we ignore error flags in multipath arrays
926 * as they don't make sense
927 */
928 if (content->array.level != LEVEL_MULTIPATH)
929 if (!(devices[j].i.disk.state & (1<<MD_DISK_ACTIVE))) {
930 if (!(devices[j].i.disk.state
931 & (1<<MD_DISK_FAULTY))) {
932 devices[j].uptodate = 1;
933 sparecnt++;
934 }
935 continue;
936 }
937 /* If this devices thinks that 'most_recent' has failed, then
938 * we must reject this device.
939 */
940 if (j != most_recent &&
941 content->array.raid_disks > 0 &&
942 devices[most_recent].i.disk.raid_disk >= 0 &&
943 devmap[j * content->array.raid_disks + devices[most_recent].i.disk.raid_disk] == 0) {
944 if (verbose > -1)
945 fprintf(stderr, Name ": ignoring %s as it reports %s as failed\n",
946 devices[j].devname, devices[most_recent].devname);
947 best[i] = -1;
948 continue;
949 }
950 if (devices[j].i.events+event_margin >=
951 devices[most_recent].i.events) {
952 devices[j].uptodate = 1;
953 if (i < content->array.raid_disks) {
954 if (devices[j].i.recovery_start == MaxSector ||
955 (content->reshape_active &&
956 j >= content->array.raid_disks - content->delta_disks)) {
957 okcnt++;
958 avail[i]=1;
959 } else
960 rebuilding_cnt++;
961 } else
962 sparecnt++;
963 }
964 }
965 free(devmap);
966 while (force && !enough(content->array.level, content->array.raid_disks,
967 content->array.layout, 1,
968 avail, okcnt)) {
969 /* Choose the newest best drive which is
970 * not up-to-date, update the superblock
971 * and add it.
972 */
973 int fd;
974 struct supertype *tst;
975 unsigned long long current_events;
976 chosen_drive = -1;
977 for (i = 0; i < content->array.raid_disks && i < bestcnt; i++) {
978 int j = best[i];
979 if (j>=0 &&
980 !devices[j].uptodate &&
981 devices[j].i.recovery_start == MaxSector &&
982 (chosen_drive < 0 ||
983 devices[j].i.events
984 > devices[chosen_drive].i.events))
985 chosen_drive = j;
986 }
987 if (chosen_drive < 0)
988 break;
989 current_events = devices[chosen_drive].i.events;
990 add_another:
991 if (verbose >= 0)
992 fprintf(stderr, Name ": forcing event count in %s(%d) from %d upto %d\n",
993 devices[chosen_drive].devname,
994 devices[chosen_drive].i.disk.raid_disk,
995 (int)(devices[chosen_drive].i.events),
996 (int)(devices[most_recent].i.events));
997 fd = dev_open(devices[chosen_drive].devname, O_RDWR|O_EXCL);
998 if (fd < 0) {
999 fprintf(stderr, Name ": Couldn't open %s for write - not updating\n",
1000 devices[chosen_drive].devname);
1001 devices[chosen_drive].i.events = 0;
1002 continue;
1003 }
1004 tst = dup_super(st);
1005 if (tst->ss->load_super(tst,fd, NULL)) {
1006 close(fd);
1007 fprintf(stderr, Name ": RAID superblock disappeared from %s - not updating.\n",
1008 devices[chosen_drive].devname);
1009 devices[chosen_drive].i.events = 0;
1010 continue;
1011 }
1012 content->events = devices[most_recent].i.events;
1013 tst->ss->update_super(tst, content, "force-one",
1014 devices[chosen_drive].devname, verbose,
1015 0, NULL);
1016
1017 if (tst->ss->store_super(tst, fd)) {
1018 close(fd);
1019 fprintf(stderr, Name ": Could not re-write superblock on %s\n",
1020 devices[chosen_drive].devname);
1021 devices[chosen_drive].i.events = 0;
1022 tst->ss->free_super(tst);
1023 continue;
1024 }
1025 close(fd);
1026 devices[chosen_drive].i.events = devices[most_recent].i.events;
1027 devices[chosen_drive].uptodate = 1;
1028 avail[chosen_drive] = 1;
1029 okcnt++;
1030 tst->ss->free_super(tst);
1031
1032 /* If there are any other drives of the same vintage,
1033 * add them in as well. We can't lose and we might gain
1034 */
1035 for (i = 0; i < content->array.raid_disks && i < bestcnt ; i++) {
1036 int j = best[i];
1037 if (j >= 0 &&
1038 !devices[j].uptodate &&
1039 devices[j].i.events == current_events) {
1040 chosen_drive = j;
1041 goto add_another;
1042 }
1043 }
1044 }
1045
1046 /* Now we want to look at the superblock which the kernel will base things on
1047 * and compare the devices that we think are working with the devices that the
1048 * superblock thinks are working.
1049 * If there are differences and --force is given, then update this chosen
1050 * superblock.
1051 */
1052 chosen_drive = -1;
1053 st->ss->free_super(st);
1054 for (i=0; chosen_drive < 0 && i<bestcnt; i++) {
1055 int j = best[i];
1056 int fd;
1057
1058 if (j<0)
1059 continue;
1060 if (!devices[j].uptodate)
1061 continue;
1062 if (devices[j].i.events < devices[most_recent].i.events)
1063 continue;
1064 chosen_drive = j;
1065 if ((fd=dev_open(devices[j].devname, O_RDONLY|O_EXCL))< 0) {
1066 fprintf(stderr, Name ": Cannot open %s: %s\n",
1067 devices[j].devname, strerror(errno));
1068 close(mdfd);
1069 free(devices);
1070 return 1;
1071 }
1072 if (st->ss->load_super(st,fd, NULL)) {
1073 close(fd);
1074 fprintf(stderr, Name ": RAID superblock has disappeared from %s\n",
1075 devices[j].devname);
1076 close(mdfd);
1077 free(devices);
1078 return 1;
1079 }
1080 close(fd);
1081 }
1082 if (st->sb == NULL) {
1083 fprintf(stderr, Name ": No suitable drives found for %s\n", mddev);
1084 close(mdfd);
1085 free(devices);
1086 return 1;
1087 }
1088 st->ss->getinfo_super(st, content, NULL);
1089#ifndef MDASSEMBLE
1090 sysfs_init(content, mdfd, 0);
1091#endif
1092 for (i=0; i<bestcnt; i++) {
1093 int j = best[i];
1094 unsigned int desired_state;
1095
1096 if (i < content->array.raid_disks)
1097 desired_state = (1<<MD_DISK_ACTIVE) | (1<<MD_DISK_SYNC);
1098 else
1099 desired_state = 0;
1100
1101 if (j<0)
1102 continue;
1103 if (!devices[j].uptodate)
1104 continue;
1105
1106 devices[j].i.disk.state = desired_state;
1107 if (!(devices[j].i.array.state & 1))
1108 clean = 0;
1109
1110 if (st->ss->update_super(st, &devices[j].i, "assemble", NULL,
1111 verbose, 0, NULL)) {
1112 if (force) {
1113 if (verbose >= 0)
1114 fprintf(stderr, Name ": "
1115 "clearing FAULTY flag for device %d in %s for %s\n",
1116 j, mddev, devices[j].devname);
1117 change = 1;
1118 } else {
1119 if (verbose >= -1)
1120 fprintf(stderr, Name ": "
1121 "device %d in %s has wrong state in superblock, but %s seems ok\n",
1122 i, mddev, devices[j].devname);
1123 }
1124 }
1125#if 0
1126 if (!(super.disks[i].i.disk.state & (1 << MD_DISK_FAULTY))) {
1127 fprintf(stderr, Name ": devices %d of %s is not marked FAULTY in superblock, but cannot be found\n",
1128 i, mddev);
1129 }
1130#endif
1131 }
1132 if (force && !clean &&
1133 !enough(content->array.level, content->array.raid_disks,
1134 content->array.layout, clean,
1135 avail, okcnt)) {
1136 change += st->ss->update_super(st, content, "force-array",
1137 devices[chosen_drive].devname, verbose,
1138 0, NULL);
1139 clean = 1;
1140 }
1141
1142 if (change) {
1143 int fd;
1144 fd = dev_open(devices[chosen_drive].devname, O_RDWR|O_EXCL);
1145 if (fd < 0) {
1146 fprintf(stderr, Name ": Could not open %s for write - cannot Assemble array.\n",
1147 devices[chosen_drive].devname);
1148 close(mdfd);
1149 free(devices);
1150 return 1;
1151 }
1152 if (st->ss->store_super(st, fd)) {
1153 close(fd);
1154 fprintf(stderr, Name ": Could not re-write superblock on %s\n",
1155 devices[chosen_drive].devname);
1156 close(mdfd);
1157 free(devices);
1158 return 1;
1159 }
1160 if (verbose >= 0)
1161 fprintf(stderr, Name ": Marking array %s as 'clean'\n",
1162 mddev);
1163 close(fd);
1164 }
1165
1166 /* If we are in the middle of a reshape we may need to restore saved data
1167 * that was moved aside due to the reshape overwriting live data
1168 * The code of doing this lives in Grow.c
1169 */
1170#ifndef MDASSEMBLE
1171 if (content->reshape_active) {
1172 int err = 0;
1173 int *fdlist = malloc(sizeof(int)* bestcnt);
1174 if (verbose > 0)
1175 fprintf(stderr, Name ":%s has an active reshape - checking "
1176 "if critical section needs to be restored\n",
1177 chosen_name);
1178 for (i=0; i<bestcnt; i++) {
1179 int j = best[i];
1180 if (j >= 0) {
1181 fdlist[i] = dev_open(devices[j].devname, O_RDWR|O_EXCL);
1182 if (fdlist[i] < 0) {
1183 fprintf(stderr, Name ": Could not open %s for write - cannot Assemble array.\n",
1184 devices[j].devname);
1185 err = 1;
1186 break;
1187 }
1188 } else
1189 fdlist[i] = -1;
1190 }
1191 if (!err) {
1192 if (st->ss->external && st->ss->recover_backup)
1193 err = st->ss->recover_backup(st, content);
1194 else
1195 err = Grow_restart(st, content, fdlist, bestcnt,
1196 backup_file, verbose > 0);
1197 if (err && invalid_backup) {
1198 if (verbose > 0)
1199 fprintf(stderr, Name ": continuing"
1200 " without restoring backup\n");
1201 err = 0;
1202 }
1203 }
1204 while (i>0) {
1205 i--;
1206 if (fdlist[i]>=0) close(fdlist[i]);
1207 }
1208 if (err) {
1209 fprintf(stderr, Name ": Failed to restore critical section for reshape, sorry.\n");
1210 if (backup_file == NULL)
1211 fprintf(stderr," Possibly you needed to specify the --backup-file\n");
1212 close(mdfd);
1213 free(devices);
1214 return err;
1215 }
1216 }
1217#endif
1218 /* count number of in-sync devices according to the superblock.
1219 * We must have this number to start the array without -s or -R
1220 */
1221 req_cnt = content->array.working_disks;
1222
1223 /* Almost ready to actually *do* something */
1224 if (!old_linux) {
1225 int rv;
1226
1227 /* First, fill in the map, so that udev can find our name
1228 * as soon as we become active.
1229 */
1230 map_update(NULL, fd2devnum(mdfd), content->text_version,
1231 content->uuid, chosen_name);
1232
1233 rv = set_array_info(mdfd, st, content);
1234 if (rv) {
1235 fprintf(stderr, Name ": failed to set array info for %s: %s\n",
1236 mddev, strerror(errno));
1237 ioctl(mdfd, STOP_ARRAY, NULL);
1238 close(mdfd);
1239 free(devices);
1240 return 1;
1241 }
1242 if (ident->bitmap_fd >= 0) {
1243 if (ioctl(mdfd, SET_BITMAP_FILE, ident->bitmap_fd) != 0) {
1244 fprintf(stderr, Name ": SET_BITMAP_FILE failed.\n");
1245 ioctl(mdfd, STOP_ARRAY, NULL);
1246 close(mdfd);
1247 free(devices);
1248 return 1;
1249 }
1250 } else if (ident->bitmap_file) {
1251 /* From config file */
1252 int bmfd = open(ident->bitmap_file, O_RDWR);
1253 if (bmfd < 0) {
1254 fprintf(stderr, Name ": Could not open bitmap file %s\n",
1255 ident->bitmap_file);
1256 ioctl(mdfd, STOP_ARRAY, NULL);
1257 close(mdfd);
1258 free(devices);
1259 return 1;
1260 }
1261 if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) {
1262 fprintf(stderr, Name ": Failed to set bitmapfile for %s\n", mddev);
1263 close(bmfd);
1264 ioctl(mdfd, STOP_ARRAY, NULL);
1265 close(mdfd);
1266 free(devices);
1267 return 1;
1268 }
1269 close(bmfd);
1270 }
1271
1272 /* First, add the raid disks, but add the chosen one last */
1273 for (i=0; i<= bestcnt; i++) {
1274 int j;
1275 if (i < bestcnt) {
1276 j = best[i];
1277 if (j == chosen_drive)
1278 continue;
1279 } else
1280 j = chosen_drive;
1281
1282 if (j >= 0 /* && devices[j].uptodate */) {
1283 int dfd = dev_open(devices[j].devname,
1284 O_RDWR|O_EXCL);
1285 if (dfd >= 0) {
1286 remove_partitions(dfd);
1287 close(dfd);
1288 }
1289 rv = add_disk(mdfd, st, content, &devices[j].i);
1290
1291 if (rv) {
1292 fprintf(stderr, Name ": failed to add "
1293 "%s to %s: %s\n",
1294 devices[j].devname,
1295 mddev,
1296 strerror(errno));
1297 if (i < content->array.raid_disks
1298 || i == bestcnt)
1299 okcnt--;
1300 else
1301 sparecnt--;
1302 } else if (verbose > 0)
1303 fprintf(stderr, Name ": added %s "
1304 "to %s as %d\n",
1305 devices[j].devname, mddev,
1306 devices[j].i.disk.raid_disk);
1307 } else if (verbose > 0 && i < content->array.raid_disks)
1308 fprintf(stderr, Name ": no uptodate device for "
1309 "slot %d of %s\n",
1310 i, mddev);
1311 }
1312
1313 if (content->array.level == LEVEL_CONTAINER) {
1314 if (verbose >= 0) {
1315 fprintf(stderr, Name ": Container %s has been "
1316 "assembled with %d drive%s",
1317 mddev, okcnt+sparecnt, okcnt+sparecnt==1?"":"s");
1318 if (okcnt < (unsigned)content->array.raid_disks)
1319 fprintf(stderr, " (out of %d)",
1320 content->array.raid_disks);
1321 fprintf(stderr, "\n");
1322 }
1323 st->ss->free_super(st);
1324 sysfs_uevent(content, "change");
1325 wait_for(chosen_name, mdfd);
1326 close(mdfd);
1327 free(devices);
1328 return 0;
1329 }
1330
1331 if (runstop == 1 ||
1332 (runstop <= 0 &&
1333 ( enough(content->array.level, content->array.raid_disks,
1334 content->array.layout, clean, avail, okcnt) &&
1335 (okcnt + rebuilding_cnt >= req_cnt || start_partial_ok)
1336 ))) {
1337 /* This array is good-to-go.
1338 * If a reshape is in progress then we might need to
1339 * continue monitoring it. In that case we start
1340 * it read-only and let the grow code make it writable.
1341 */
1342 int rv;
1343#ifndef MDASSEMBLE
1344 if (content->reshape_active &&
1345 content->delta_disks <= 0) {
1346 rv = sysfs_set_str(content, NULL,
1347 "array_state", "readonly");
1348 if (rv == 0)
1349 rv = Grow_continue(mdfd, st, content,
1350 backup_file,
1351 freeze_reshape);
1352 } else
1353#endif
1354 rv = ioctl(mdfd, RUN_ARRAY, NULL);
1355 if (rv == 0) {
1356 if (verbose >= 0) {
1357 fprintf(stderr, Name ": %s has been started with %d drive%s",
1358 mddev, okcnt, okcnt==1?"":"s");
1359 if (okcnt < (unsigned)content->array.raid_disks)
1360 fprintf(stderr, " (out of %d)", content->array.raid_disks);
1361 if (rebuilding_cnt)
1362 fprintf(stderr, "%s %d rebuilding", sparecnt?",":" and", rebuilding_cnt);
1363 if (sparecnt)
1364 fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
1365 fprintf(stderr, ".\n");
1366 }
1367 if (content->reshape_active &&
1368 content->array.level >= 4 &&
1369 content->array.level <= 6) {
1370 /* might need to increase the size
1371 * of the stripe cache - default is 256
1372 */
1373 if (256 < 4 * (content->array.chunk_size/4096)) {
1374 struct mdinfo *sra = sysfs_read(mdfd, 0, 0);
1375 if (sra)
1376 sysfs_set_num(sra, NULL,
1377 "stripe_cache_size",
1378 (4 * content->array.chunk_size / 4096) + 1);
1379 sysfs_free(sra);
1380 }
1381 }
1382 if (okcnt < (unsigned)content->array.raid_disks) {
1383 /* If any devices did not get added
1384 * because the kernel rejected them based
1385 * on event count, try adding them
1386 * again providing the action policy is
1387 * 're-add' or greater. The bitmap
1388 * might allow them to be included, or
1389 * they will become spares.
1390 */
1391 for (i = 0; i < bestcnt; i++) {
1392 int j = best[i];
1393 if (j >= 0 && !devices[j].uptodate) {
1394 if (!disk_action_allows(&devices[j].i, st->ss->name, act_re_add))
1395 continue;
1396 rv = add_disk(mdfd, st, content,
1397 &devices[j].i);
1398 if (rv == 0 && verbose >= 0)
1399 fprintf(stderr,
1400 Name ": %s has been re-added.\n",
1401 devices[j].devname);
1402 }
1403 }
1404 }
1405 wait_for(mddev, mdfd);
1406 close(mdfd);
1407 if (auto_assem) {
1408 int usecs = 1;
1409 /* There is a nasty race with 'mdadm --monitor'.
1410 * If it opens this device before we close it,
1411 * it gets an incomplete open on which IO
1412 * doesn't work and the capacity is
1413 * wrong.
1414 * If we reopen (to check for layered devices)
1415 * before --monitor closes, we loose.
1416 *
1417 * So: wait upto 1 second for there to be
1418 * a non-zero capacity.
1419 */
1420 while (usecs < 1000) {
1421 mdfd = open(mddev, O_RDONLY);
1422 if (mdfd >= 0) {
1423 unsigned long long size;
1424 if (get_dev_size(mdfd, NULL, &size) &&
1425 size > 0)
1426 break;
1427 close(mdfd);
1428 }
1429 usleep(usecs);
1430 usecs <<= 1;
1431 }
1432 }
1433 free(devices);
1434 return 0;
1435 }
1436 fprintf(stderr, Name ": failed to RUN_ARRAY %s: %s\n",
1437 mddev, strerror(errno));
1438
1439 if (!enough(content->array.level, content->array.raid_disks,
1440 content->array.layout, 1, avail, okcnt))
1441 fprintf(stderr, Name ": Not enough devices to "
1442 "start the array.\n");
1443 else if (!enough(content->array.level,
1444 content->array.raid_disks,
1445 content->array.layout, clean,
1446 avail, okcnt))
1447 fprintf(stderr, Name ": Not enough devices to "
1448 "start the array while not clean "
1449 "- consider --force.\n");
1450
1451 if (auto_assem)
1452 ioctl(mdfd, STOP_ARRAY, NULL);
1453 close(mdfd);
1454 free(devices);
1455 return 1;
1456 }
1457 if (runstop == -1) {
1458 fprintf(stderr, Name ": %s assembled from %d drive%s",
1459 mddev, okcnt, okcnt==1?"":"s");
1460 if (okcnt != (unsigned)content->array.raid_disks)
1461 fprintf(stderr, " (out of %d)", content->array.raid_disks);
1462 fprintf(stderr, ", but not started.\n");
1463 close(mdfd);
1464 free(devices);
1465 return 0;
1466 }
1467 if (verbose >= -1) {
1468 fprintf(stderr, Name ": %s assembled from %d drive%s", mddev, okcnt, okcnt==1?"":"s");
1469 if (rebuilding_cnt)
1470 fprintf(stderr, "%s %d rebuilding", sparecnt?", ":" and ", rebuilding_cnt);
1471 if (sparecnt)
1472 fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
1473 if (!enough(content->array.level, content->array.raid_disks,
1474 content->array.layout, 1, avail, okcnt))
1475 fprintf(stderr, " - not enough to start the array.\n");
1476 else if (!enough(content->array.level,
1477 content->array.raid_disks,
1478 content->array.layout, clean,
1479 avail, okcnt))
1480 fprintf(stderr, " - not enough to start the "
1481 "array while not clean - consider "
1482 "--force.\n");
1483 else {
1484 if (req_cnt == (unsigned)content->array.raid_disks)
1485 fprintf(stderr, " - need all %d to start it", req_cnt);
1486 else
1487 fprintf(stderr, " - need %d of %d to start", req_cnt, content->array.raid_disks);
1488 fprintf(stderr, " (use --run to insist).\n");
1489 }
1490 }
1491 if (auto_assem)
1492 ioctl(mdfd, STOP_ARRAY, NULL);
1493 close(mdfd);
1494 free(devices);
1495 return 1;
1496 } else {
1497 /* The "chosen_drive" is a good choice, and if necessary, the superblock has
1498 * been updated to point to the current locations of devices.
1499 * so we can just start the array
1500 */
1501 unsigned long dev;
1502 dev = makedev(devices[chosen_drive].i.disk.major,
1503 devices[chosen_drive].i.disk.minor);
1504 if (ioctl(mdfd, START_ARRAY, dev)) {
1505 fprintf(stderr, Name ": Cannot start array: %s\n",
1506 strerror(errno));
1507 }
1508
1509 }
1510 close(mdfd);
1511 free(devices);
1512 return 0;
1513}
1514
1515#ifndef MDASSEMBLE
1516int assemble_container_content(struct supertype *st, int mdfd,
1517 struct mdinfo *content, int runstop,
1518 char *chosen_name, int verbose,
1519 char *backup_file, int freeze_reshape)
1520{
1521 struct mdinfo *dev, *sra;
1522 int working = 0, preexist = 0;
1523 int expansion = 0;
1524 struct map_ent *map = NULL;
1525 int old_raid_disks;
1526
1527 sysfs_init(content, mdfd, 0);
1528
1529 sra = sysfs_read(mdfd, 0, GET_VERSION);
1530 if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0)
1531 if (sysfs_set_array(content, md_get_version(mdfd)) != 0) {
1532 if (sra)
1533 sysfs_free(sra);
1534 return 1;
1535 }
1536
1537 if (st->ss->external && content->recovery_blocked)
1538 block_subarray(content);
1539
1540 if (sra)
1541 sysfs_free(sra);
1542 old_raid_disks = content->array.raid_disks - content->delta_disks;
1543 for (dev = content->devs; dev; dev = dev->next)
1544 if (sysfs_add_disk(content, dev, 1) == 0) {
1545 if (dev->disk.raid_disk >= old_raid_disks &&
1546 content->reshape_active)
1547 expansion++;
1548 else
1549 working++;
1550 } else if (errno == EEXIST)
1551 preexist++;
1552 if (working == 0)
1553 return 1;/* Nothing new, don't try to start */
1554
1555 map_update(&map, fd2devnum(mdfd),
1556 content->text_version,
1557 content->uuid, chosen_name);
1558
1559 if (runstop > 0 ||
1560 (working + preexist + expansion) >=
1561 content->array.working_disks) {
1562 int err;
1563 int start_reshape;
1564
1565 /* There are two types of reshape: container wide or sub-array specific
1566 * Check if metadata requests blocking container wide reshapes
1567 */
1568 start_reshape = (content->reshape_active &&
1569 !((content->reshape_active == CONTAINER_RESHAPE) &&
1570 (content->array.state & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE))));
1571 if (start_reshape) {
1572 int spare = content->array.raid_disks + expansion;
1573 if (restore_backup(st, content,
1574 working,
1575 spare, backup_file, verbose) == 1)
1576 return 1;
1577
1578 err = sysfs_set_str(content, NULL,
1579 "array_state", "readonly");
1580 if (err)
1581 return 1;
1582
1583 if (st->ss->external) {
1584 if (!mdmon_running(st->container_dev))
1585 start_mdmon(st->container_dev);
1586 ping_monitor_by_id(st->container_dev);
1587 if (mdmon_running(st->container_dev) &&
1588 st->update_tail == NULL)
1589 st->update_tail = &st->updates;
1590 }
1591
1592 err = Grow_continue(mdfd, st, content, backup_file,
1593 freeze_reshape);
1594 } else switch(content->array.level) {
1595 case LEVEL_LINEAR:
1596 case LEVEL_MULTIPATH:
1597 case 0:
1598 err = sysfs_set_str(content, NULL, "array_state",
1599 "active");
1600 break;
1601 default:
1602 err = sysfs_set_str(content, NULL, "array_state",
1603 "readonly");
1604 /* start mdmon if needed. */
1605 if (!err) {
1606 if (!mdmon_running(st->container_dev))
1607 start_mdmon(st->container_dev);
1608 ping_monitor_by_id(st->container_dev);
1609 }
1610 break;
1611 }
1612 if (!err)
1613 sysfs_set_safemode(content, content->safe_mode_delay);
1614 if (verbose >= 0) {
1615 if (err)
1616 fprintf(stderr, Name
1617 ": array %s now has %d device%s",
1618 chosen_name, working + preexist,
1619 working + preexist == 1 ? "":"s");
1620 else
1621 fprintf(stderr, Name
1622 ": Started %s with %d device%s",
1623 chosen_name, working + preexist,
1624 working + preexist == 1 ? "":"s");
1625 if (preexist)
1626 fprintf(stderr, " (%d new)", working);
1627 if (expansion)
1628 fprintf(stderr, " ( + %d for expansion)",
1629 expansion);
1630 fprintf(stderr, "\n");
1631 }
1632 if (!err)
1633 wait_for(chosen_name, mdfd);
1634 return err;
1635 /* FIXME should have an O_EXCL and wait for read-auto */
1636 } else {
1637 if (verbose >= 0) {
1638 fprintf(stderr, Name
1639 ": %s assembled with %d device%s",
1640 chosen_name, preexist + working,
1641 preexist + working == 1 ? "":"s");
1642 if (preexist)
1643 fprintf(stderr, " (%d new)", working);
1644 fprintf(stderr, " but not started\n");
1645 }
1646 return 1;
1647 }
1648}
1649#endif
1650
16510
=== added file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/ReadMe.c'
--- .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/ReadMe.c 1970-01-01 00:00:00 +0000
+++ .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/ReadMe.c 2012-06-18 08:55:05 +0000
@@ -0,0 +1,608 @@
1/*
2 * mdadm - manage Linux "md" devices aka RAID arrays.
3 *
4 * Copyright (C) 2001-2010 Neil Brown <neilb@suse.de>
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Author: Neil Brown
22 * Email: <neilb@suse.de>
23 */
24
25#include "mdadm.h"
26
27char Version[] = Name " - v3.2.5 - 18th May 2012\n";
28
29/*
30 * File: ReadMe.c
31 *
32 * This file contains general comments about the implementation
33 * and the various usage messages that can be displayed by mdadm
34 *
35 * mdadm is a single program that can be used to control Linux md devices.
36 * It is intended to provide all the functionality of the mdtools and
37 * raidtools but with a very different interface.
38 * mdadm can perform all functions without a configuration file.
39 * There is the option of using a configuration file, but not in the same
40 * way that raidtools uses one
41 * raidtools uses a configuration file to describe how to create a RAID
42 * array, and also uses this file partially to start a previously
43 * created RAID array. Further, raidtools requires the configuration
44 * file for such things as stopping a raid array which needs to know
45 * nothing about the array.
46 *
47 * The configuration file that can be used by mdadm lists two
48 * different things:
49 * 1/ a mapping from uuid to md device to identify which arrays are
50 * expect and what names (numbers) they should be given
51 * 2/ a list of devices that should be scanned for md sub-devices
52 *
53 *
54 */
55
56/*
57 * mdadm has 7 major modes of operation:
58 * 1/ Create
59 * This mode is used to create a new array with a superblock
60 * It can progress in several step create-add-add-run
61 * or it can all happen with one command
62 * 2/ Assemble
63 * This mode is used to assemble the parts of a previously created
64 * array into an active array. Components can be explicitly given
65 * or can be searched for. mdadm (optionally) check that the components
66 * do form a bona-fide array, and can, on request, fiddle superblock
67 * version numbers so as to assemble a faulty array.
68 * 3/ Build
69 * This is for building legacy arrays without superblocks
70 * 4/ Manage
71 * This is for doing something to one or more devices
72 * in an array, such as add,remove,fail.
73 * run/stop/readonly/readwrite are also available
74 * 5/ Misc
75 * This is for doing things to individual devices.
76 * They might be parts of an array so
77 * zero-superblock, examine might be appropriate
78 * They might be md arrays so
79 * run,stop,rw,ro,detail might be appropriate
80 * Also query will treat it as either
81 * 6/ Monitor
82 * This mode never exits but just monitors arrays and reports changes.
83 * 7/ Grow
84 * This mode allows for changing of key attributes of a raid array, such
85 * as size, number of devices, and possibly even layout.
86 * At the time if writing, there is only minimal support.
87 */
88
89char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
90char short_bitmap_options[]=
91 "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
92char short_bitmap_auto_options[]=
93 "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:";
94
95struct option long_options[] = {
96 {"manage", 0, 0, ManageOpt},
97 {"misc", 0, 0, MiscOpt},
98 {"assemble", 0, 0, 'A'},
99 {"build", 0, 0, 'B'},
100 {"create", 0, 0, 'C'},
101 {"detail", 0, 0, 'D'},
102 {"examine", 0, 0, 'E'},
103 {"follow", 0, 0, 'F'},
104 {"grow", 0, 0, 'G'},
105 {"incremental",0,0, 'I'},
106 {"zero-superblock", 0, 0, 'K'}, /* deliberately no a short_option */
107 {"query", 0, 0, 'Q'},
108 {"examine-bitmap", 0, 0, 'X'},
109 {"auto-detect", 0, 0, AutoDetect},
110 {"detail-platform", 0, 0, DetailPlatform},
111 {"kill-subarray", 1, 0, KillSubarray},
112 {"update-subarray", 1, 0, UpdateSubarray},
113 {"udev-rules", 2, 0, UdevRules},
114 {"offroot", 0, 0, OffRootOpt},
115
116 /* synonyms */
117 {"monitor", 0, 0, 'F'},
118
119 /* after those will normally come the name of the md device */
120 {"help", 0, 0, 'h'},
121 {"help-options",0,0, HelpOptions},
122 {"version", 0, 0, 'V'},
123 {"verbose", 0, 0, 'v'},
124 {"quiet", 0, 0, 'q'},
125
126 /* For create or build: */
127 {"chunk", 1, 0, ChunkSize},
128 {"rounding", 1, 0, ChunkSize}, /* for linear, chunk is really a
129 * rounding number */
130 {"level", 1, 0, 'l'}, /* 0,1,4,5,6,linear */
131 {"parity", 1, 0, Layout}, /* {left,right}-{a,}symmetric */
132 {"layout", 1, 0, Layout},
133 {"raid-disks",1, 0, 'n'},
134 {"raid-devices",1, 0, 'n'},
135 {"spare-disks",1,0, 'x'},
136 {"spare-devices",1,0, 'x'},
137 {"size", 1, 0, 'z'},
138 {"auto", 1, 0, Auto}, /* also for --assemble */
139 {"assume-clean",0,0, AssumeClean },
140 {"metadata", 1, 0, 'e'}, /* superblock format */
141 {"bitmap", 1, 0, Bitmap},
142 {"bitmap-chunk", 1, 0, BitmapChunk},
143 {"write-behind", 2, 0, WriteBehind},
144 {"write-mostly",0, 0, WriteMostly},
145 {"re-add", 0, 0, ReAdd},
146 {"homehost", 1, 0, HomeHost},
147 {"symlinks", 1, 0, Symlinks},
148
149 /* For assemble */
150 {"uuid", 1, 0, 'u'},
151 {"super-minor",1,0, SuperMinor},
152 {"name", 1, 0, 'N'},
153 {"config", 1, 0, ConfigFile},
154 {"scan", 0, 0, 's'},
155 {"force", 0, 0, Force},
156 {"update", 1, 0, 'U'},
157 {"freeze-reshape", 0, 0, FreezeReshape},
158
159 /* Management */
160 {"add", 0, 0, Add},
161 {"remove", 0, 0, Remove},
162 {"fail", 0, 0, Fail},
163 {"set-faulty",0, 0, Fail},
164 {"run", 0, 0, 'R'},
165 {"stop", 0, 0, 'S'},
166 {"readonly", 0, 0, 'o'},
167 {"readwrite", 0, 0, 'w'},
168 {"no-degraded",0,0, NoDegraded },
169 {"wait", 0, 0, WaitOpt},
170 {"wait-clean", 0, 0, Waitclean },
171
172 /* For Detail/Examine */
173 {"brief", 0, 0, Brief},
174 {"export", 0, 0, 'Y'},
175 {"sparc2.2", 0, 0, Sparc22},
176 {"test", 0, 0, 't'},
177 {"prefer", 1, 0, Prefer},
178
179 /* For Follow/monitor */
180 {"mail", 1, 0, EMail},
181 {"program", 1, 0, ProgramOpt},
182 {"alert", 1, 0, ProgramOpt},
183 {"increment", 1, 0, Increment},
184 {"delay", 1, 0, 'd'},
185 {"daemonise", 0, 0, Fork},
186 {"daemonize", 0, 0, Fork},
187 {"oneshot", 0, 0, '1'},
188 {"pid-file", 1, 0, 'i'},
189 {"syslog", 0, 0, 'y'},
190 {"no-sharing", 0, 0, NoSharing},
191
192 /* For Grow */
193 {"backup-file", 1,0, BackupFile},
194 {"invalid-backup",0,0,InvalidBackup},
195 {"array-size", 1, 0, 'Z'},
196 {"continue", 0, 0, Continue},
197
198 /* For Incremental */
199 {"rebuild-map", 0, 0, RebuildMapOpt},
200 {"path", 1, 0, IncrementalPath},
201
202 {0, 0, 0, 0}
203};
204
205char Usage[] =
206"Usage: mdadm --help\n"
207" for help\n"
208;
209
210char Help[] =
211"mdadm is used for building, managing, and monitoring\n"
212"Linux md devices (aka RAID arrays)\n"
213"Usage: mdadm --create device options...\n"
214" Create a new array from unused devices.\n"
215" mdadm --assemble device options...\n"
216" Assemble a previously created array.\n"
217" mdadm --build device options...\n"
218" Create or assemble an array without metadata.\n"
219" mdadm --manage device options...\n"
220" make changes to an existing array.\n"
221" mdadm --misc options... devices\n"
222" report on or modify various md related devices.\n"
223" mdadm --grow options device\n"
224" resize/reshape an active array\n"
225" mdadm --incremental device\n"
226" add/remove a device to/from an array as appropriate\n"
227" mdadm --monitor options...\n"
228" Monitor one or more array for significant changes.\n"
229" mdadm device options...\n"
230" Shorthand for --manage.\n"
231"Any parameter that does not start with '-' is treated as a device name\n"
232"or, for --examine-bitmap, a file name.\n"
233"The first such name is often the name of an md device. Subsequent\n"
234"names are often names of component devices.\n"
235"\n"
236" For detailed help on the above major modes use --help after the mode\n"
237" e.g.\n"
238" mdadm --assemble --help\n"
239" For general help on options use\n"
240" mdadm --help-options\n"
241;
242
243char OptionHelp[] =
244"Any parameter that does not start with '-' is treated as a device name\n"
245"or, for --examine-bitmap, a file name.\n"
246"The first such name is often the name of an md device. Subsequent\n"
247"names are often names of component devices.\n"
248"\n"
249"Some common options are:\n"
250" --help -h : General help message or, after above option,\n"
251" mode specific help message\n"
252" --help-options : This help message\n"
253" --version -V : Print version information for mdadm\n"
254" --verbose -v : Be more verbose about what is happening\n"
255" --quiet -q : Don't print un-necessary messages\n"
256" --brief -b : Be less verbose, more brief\n"
257" --export -Y : With --detail, use key=value format for easy\n"
258" import into environment\n"
259" --force -f : Override normal checks and be more forceful\n"
260"\n"
261" --assemble -A : Assemble an array\n"
262" --build -B : Build an array without metadata\n"
263" --create -C : Create a new array\n"
264" --detail -D : Display details of an array\n"
265" --examine -E : Examine superblock on an array component\n"
266" --examine-bitmap -X: Display the detail of a bitmap file\n"
267" --monitor -F : monitor (follow) some arrays\n"
268" --grow -G : resize/ reshape and array\n"
269" --incremental -I : add/remove a single device to/from an array as appropriate\n"
270" --query -Q : Display general information about how a\n"
271" device relates to the md driver\n"
272" --auto-detect : Start arrays auto-detected by the kernel\n"
273" --offroot : Set first character of argv[0] to @ to indicate the\n"
274" application was launched from initrd/initramfs and\n"
275" should not be shutdown by systemd as part of the\n"
276" regular shutdown process.\n"
277;
278/*
279"\n"
280" For create or build:\n"
281" --bitmap= -b : File to store bitmap in - may pre-exist for --build\n"
282" --chunk= -c : chunk size of kibibytes\n"
283" --rounding= : rounding factor for linear array (==chunk size)\n"
284" --level= -l : raid level: 0,1,4,5,6,linear,mp. 0 or linear for build\n"
285" --parity= -p : raid5/6 parity algorithm: {left,right}-{,a}symmetric\n"
286" --layout= : same as --parity\n"
287" --raid-devices= -n : number of active devices in array\n"
288" --spare-devices= -x: number of spares (eXtras) devices in initial array\n"
289" --size= -z : Size (in K) of each drive in RAID1/4/5/6/10 - optional\n"
290" --force -f : Honour devices as listed on command line. Don't\n"
291" : insert a missing drive for RAID5.\n"
292" --assume-clean : Assume the array is already in-sync. This is dangerous.\n"
293" --bitmap-chunk= : chunksize of bitmap in bitmap file (Kilobytes)\n"
294" --delay= -d : seconds between bitmap updates\n"
295" --write-behind= : number of simultaneous write-behind requests to allow (requires bitmap)\n"
296" --name= -N : Textual name for array - max 32 characters\n"
297"\n"
298" For assemble:\n"
299" --bitmap= -b : File to find bitmap information in\n"
300" --uuid= -u : uuid of array to assemble. Devices which don't\n"
301" have this uuid are excluded\n"
302" --super-minor= -m : minor number to look for in super-block when\n"
303" choosing devices to use.\n"
304" --name= -N : Array name to look for in super-block.\n"
305" --config= -c : config file\n"
306" --scan -s : scan config file for missing information\n"
307" --force -f : Assemble the array even if some superblocks appear out-of-date\n"
308" --update= -U : Update superblock: try '-A --update=?' for list of options.\n"
309" --no-degraded : Do not start any degraded arrays - default unless --scan.\n"
310"\n"
311" For detail or examine:\n"
312" --brief -b : Just print device name and UUID\n"
313"\n"
314" For follow/monitor:\n"
315" --mail= -m : Address to mail alerts of failure to\n"
316" --program= -p : Program to run when an event is detected\n"
317" --alert= : same as --program\n"
318" --delay= -d : seconds of delay between polling state. default=60\n"
319"\n"
320" General management:\n"
321" --add -a : add, or hotadd subsequent devices\n"
322" --remove -r : remove subsequent devices\n"
323" --fail -f : mark subsequent devices a faulty\n"
324" --set-faulty : same as --fail\n"
325" --run -R : start a partially built array\n"
326" --stop -S : deactivate array, releasing all resources\n"
327" --readonly -o : mark array as readonly\n"
328" --readwrite -w : mark array as readwrite\n"
329" --zero-superblock : erase the MD superblock from a device.\n"
330" --wait -W : wait for recovery/resync/reshape to finish.\n"
331;
332*/
333
334char Help_create[] =
335"Usage: mdadm --create device -chunk=X --level=Y --raid-devices=Z devices\n"
336"\n"
337" This usage will initialise a new md array, associate some\n"
338" devices with it, and activate the array. In order to create an\n"
339" array with some devices missing, use the special word 'missing' in\n"
340" place of the relevant device name.\n"
341"\n"
342" Before devices are added, they are checked to see if they already contain\n"
343" raid superblocks or filesystems. They are also checked to see if\n"
344" the variance in device size exceeds 1%.\n"
345" If any discrepancy is found, the user will be prompted for confirmation\n"
346" before the array is created. The presence of a '--run' can override this\n"
347" caution.\n"
348"\n"
349" If the --size option is given then only that many kilobytes of each\n"
350" device is used, no matter how big each device is.\n"
351" If no --size is given, the apparent size of the smallest drive given\n"
352" is used for raid level 1 and greater, and the full device is used for\n"
353" other levels.\n"
354"\n"
355" Options that are valid with --create (-C) are:\n"
356" --bitmap= : Create a bitmap for the array with the given filename\n"
357" --chunk= -c : chunk size of kibibytes\n"
358" --rounding= : rounding factor for linear array (==chunk size)\n"
359" --level= -l : raid level: 0,1,4,5,6,linear,multipath and synonyms\n"
360" --parity= -p : raid5/6 parity algorithm: {left,right}-{,a}symmetric\n"
361" --layout= : same as --parity\n"
362" --raid-devices= -n : number of active devices in array\n"
363" --spare-devices= -x: number of spares (eXtras) devices in initial array\n"
364" --size= -z : Size (in K) of each drive in RAID1/4/5/6/10 - optional\n"
365" --force -f : Honour devices as listed on command line. Don't\n"
366" : insert a missing drive for RAID5.\n"
367" --run -R : insist of running the array even if not all\n"
368" : devices are present or some look odd.\n"
369" --readonly -o : start the array readonly - not supported yet.\n"
370" --name= -N : Textual name for array - max 32 characters\n"
371" --bitmap-chunk= : bitmap chunksize in Kilobytes.\n"
372" --delay= -d : bitmap update delay in seconds.\n"
373"\n"
374;
375
376char Help_build[] =
377"Usage: mdadm --build device -chunk=X --level=Y --raid-devices=Z devices\n"
378"\n"
379" This usage is similar to --create. The difference is that it creates\n"
380" a legacy array without a superblock. With these arrays there is no\n"
381" different between initially creating the array and subsequently\n"
382" assembling the array, except that hopefully there is useful data\n"
383" there in the second case.\n"
384"\n"
385" The level may only be 0, raid0, or linear.\n"
386" All devices must be listed and the array will be started once complete.\n"
387" Options that are valid with --build (-B) are:\n"
388" --bitmap= : file to store/find bitmap information in.\n"
389" --chunk= -c : chunk size of kibibytes\n"
390" --rounding= : rounding factor for linear array (==chunk size)\n"
391" --level= -l : 0, raid0, or linear\n"
392" --raid-devices= -n : number of active devices in array\n"
393" --bitmap-chunk= : bitmap chunksize in Kilobytes.\n"
394" --delay= -d : bitmap update delay in seconds.\n"
395;
396
397char Help_assemble[] =
398"Usage: mdadm --assemble device options...\n"
399" mdadm --assemble --scan options...\n"
400"\n"
401"This usage assembles one or more raid arrays from pre-existing\n"
402"components.\n"
403"For each array, mdadm needs to know the md device, the identity of\n"
404"the array, and a number of sub devices. These can be found in a number\n"
405"of ways.\n"
406"\n"
407"The md device is either given on the command line or is found listed\n"
408"in the config file. The array identity is determined either from the\n"
409"--uuid or --super-minor commandline arguments, from the config file,\n"
410"or from the first component device on the command line.\n"
411"\n"
412"The different combinations of these are as follows:\n"
413" If the --scan option is not given, then only devices and identities\n"
414" listed on the command line are considered.\n"
415" The first device will be the array device, and the remainder will be\n"
416" examined when looking for components.\n"
417" If an explicit identity is given with --uuid or --super-minor, then\n"
418" only devices with a superblock which matches that identity is considered,\n"
419" otherwise every device listed is considered.\n"
420"\n"
421" If the --scan option is given, and no devices are listed, then\n"
422" every array listed in the config file is considered for assembly.\n"
423" The identity of candidate devices are determined from the config file.\n"
424"\n"
425" If the --scan option is given as well as one or more devices, then\n"
426" Those devices are md devices that are to be assembled. Their identity\n"
427" and components are determined from the config file.\n"
428"\n"
429" If mdadm can not find all of the components for an array, it will assemble\n"
430" it but not activate it unless --run or --scan is given. To preserve this\n"
431" behaviour even with --scan, add --no-degraded. Note that \"all of the\n"
432" components\" means as many as were present the last time the array was running\n"
433" as recorded in the superblock. If the array was already degraded, and\n"
434" the missing device is not a new problem, it will still be assembled. It\n"
435" is only newly missing devices that cause the array not to be started.\n"
436"\n"
437"Options that are valid with --assemble (-A) are:\n"
438" --bitmap= : bitmap file to use wit the array\n"
439" --uuid= -u : uuid of array to assemble. Devices which don't\n"
440" have this uuid are excluded\n"
441" --super-minor= -m : minor number to look for in super-block when\n"
442" choosing devices to use.\n"
443" --name= -N : Array name to look for in super-block.\n"
444" --config= -c : config file\n"
445" --scan -s : scan config file for missing information\n"
446" --run -R : Try to start the array even if not enough devices\n"
447" for a full array are present\n"
448" --force -f : Assemble the array even if some superblocks appear\n"
449" : out-of-date. This involves modifying the superblocks.\n"
450" --update= -U : Update superblock: try '-A --update=?' for option list.\n"
451" --no-degraded : Assemble but do not start degraded arrays.\n"
452;
453
454char Help_manage[] =
455"Usage: mdadm arraydevice options component devices...\n"
456"\n"
457"This usage is for managing the component devices within an array.\n"
458"The --manage option is not needed and is assumed if the first argument\n"
459"is a device name or a management option.\n"
460"The first device listed will be taken to be an md array device, and\n"
461"subsequent devices are (potential) components of that array.\n"
462"\n"
463"Options that are valid with management mode are:\n"
464" --add -a : hotadd subsequent devices to the array\n"
465" --remove -r : remove subsequent devices, which must not be active\n"
466" --fail -f : mark subsequent devices a faulty\n"
467" --set-faulty : same as --fail\n"
468" --run -R : start a partially built array\n"
469" --stop -S : deactivate array, releasing all resources\n"
470" --readonly -o : mark array as readonly\n"
471" --readwrite -w : mark array as readwrite\n"
472;
473
474char Help_misc[] =
475"Usage: mdadm misc_option devices...\n"
476"\n"
477"This usage is for performing some task on one or more devices, which\n"
478"may be arrays or components, depending on the task.\n"
479"The --misc option is not needed (though it is allowed) and is assumed\n"
480"if the first argument in a misc option.\n"
481"\n"
482"Options that are valid with the miscellaneous mode are:\n"
483" --query -Q : Display general information about how a\n"
484" device relates to the md driver\n"
485" --detail -D : Display details of an array\n"
486" --detail-platform : Display hardware/firmware details\n"
487" --examine -E : Examine superblock on an array component\n"
488" --examine-bitmap -X: Display contents of a bitmap file\n"
489" --zero-superblock : erase the MD superblock from a device.\n"
490" --run -R : start a partially built array\n"
491" --stop -S : deactivate array, releasing all resources\n"
492" --readonly -o : mark array as readonly\n"
493" --readwrite -w : mark array as readwrite\n"
494" --test -t : exit status 0 if ok, 1 if degrade, 2 if dead, 4 if missing\n"
495" --wait -W : wait for resync/rebuild/recovery to finish\n"
496;
497
498char Help_monitor[] =
499"Usage: mdadm --monitor options devices\n"
500"\n"
501"This usage causes mdadm to monitor a number of md arrays by periodically\n"
502"polling their status and acting on any changes.\n"
503"If any devices are listed then those devices are monitored, otherwise\n"
504"all devices listed in the config file are monitored.\n"
505"The address for mailing advisories to, and the program to handle\n"
506"each change can be specified in the config file or on the command line.\n"
507"If no mail address or program are specified, then mdadm reports all\n"
508"state changes to stdout.\n"
509"\n"
510"Options that are valid with the monitor (-F --follow) mode are:\n"
511" --mail= -m : Address to mail alerts of failure to\n"
512" --program= -p : Program to run when an event is detected\n"
513" --alert= : same as --program\n"
514" --syslog -y : Report alerts via syslog\n"
515" --increment= -r : Report RebuildNN events in the given increment. default=20\n"
516" --delay= -d : seconds of delay between polling state. default=60\n"
517" --config= -c : specify a different config file\n"
518" --scan -s : find mail-address/program in config file\n"
519" --daemonise -f : Fork and continue in child, parent exits\n"
520" --pid-file= -i : In daemon mode write pid to specified file instead of stdout\n"
521" --oneshot -1 : Check for degraded arrays, then exit\n"
522" --test -t : Generate a TestMessage event against each array at startup\n"
523;
524
525char Help_grow[] =
526"Usage: mdadm --grow device options\n"
527"\n"
528"This usage causes mdadm to attempt to reconfigure a running array.\n"
529"This is only possibly if the kernel being used supports a particular\n"
530"reconfiguration. This version supports changing the number of\n"
531"devices in a RAID1/5/6, changing the active size of all devices in\n"
532"a RAID1/4/5/6, adding or removing a write-intent bitmap, and changing\n"
533"the error mode for a 'FAULTY' array.\n"
534"\n"
535"Options that are valid with the grow (-G --grow) mode are:\n"
536" --level= -l : Tell mdadm what level the array is so that it can\n"
537" : interpret '--layout' properly.\n"
538" --layout= -p : For a FAULTY array, set/change the error mode.\n"
539" --size= -z : Change the active size of devices in an array.\n"
540" : This is useful if all devices have been replaced\n"
541" : with larger devices. Value is in Kilobytes, or\n"
542" : the special word 'max' meaning 'as large as possible'.\n"
543" --raid-devices= -n : Change the number of active devices in an array.\n"
544" --bitmap= -b : Add or remove a write-intent bitmap.\n"
545" --backup-file= file : A file on a differt device to store data for a\n"
546" : short time while increasing raid-devices on a\n"
547" : RAID4/5/6 array. Not needed when a spare is present.\n"
548" --array-size= -Z : Change visible size of array. This does not change\n"
549" : any data on the device, and is not stable across restarts.\n"
550;
551
552char Help_incr[] =
553"Usage: mdadm --incremental [-Rqrsf] device\n"
554"\n"
555"This usage allows for incremental assembly of md arrays. Devices can be\n"
556"added one at a time as they are discovered. Once an array has all expected\n"
557"devices, it will be started.\n"
558"\n"
559"Optionally, the process can be reversed by using the fail option.\n"
560"When fail mode is invoked, mdadm will see if the device belongs to an array\n"
561"and then both fail (if needed) and remove the device from that array.\n"
562"\n"
563"Options that are valid with incremental assembly (-I --incremental) are:\n"
564" --run -R : Run arrays as soon as a minimal number of devices are\n"
565" : present rather than waiting for all expected.\n"
566" --quiet -q : Don't print any information messages, just errors.\n"
567" --rebuild-map -r : Rebuild the 'map' file that mdadm uses for tracking\n"
568" : partial arrays.\n"
569" --scan -s : Use with -R to start any arrays that have the minimal\n"
570" : required number of devices, but are not yet started.\n"
571" --fail -f : First fail (if needed) and then remove device from\n"
572" : any array that it is a member of.\n"
573;
574
575char Help_config[] =
576"The /etc/mdadm/mdadm.conf config file:\n\n"
577" The config file contains, apart from blank lines and comment lines that\n"
578" start with a hash(#), four sorts of configuration lines: array lines, \n"
579" device lines, mailaddr lines and program lines.\n"
580" Each configuration line is constructed of a number of space separated\n"
581" words, and can be continued on subsequent physical lines by indenting\n"
582" those lines.\n"
583"\n"
584" A device line starts with the word 'device' and then has a number of words\n"
585" which identify devices. These words should be names of devices in the\n"
586" filesystem, and can contain wildcards. There can be multiple words or each\n"
587" device line, and multiple device lines. All devices so listed are checked\n"
588" for relevant super blocks when assembling arrays.\n"
589"\n"
590" An array line start with the word 'array'. This is followed by the name of\n"
591" the array device in the filesystem, e.g. '/dev/md2'. Subsequent words\n"
592" describe the identity of the array, used to recognise devices to include in the\n"
593" array. The identity can be given as a UUID with a word starting 'uuid=', or\n"
594" as a minor-number stored in the superblock using 'super-minor=', or as a list\n"
595" of devices. This is given as a comma separated list of names, possibly\n"
596" containing wildcards, preceded by 'devices='. If multiple critea are given,\n"
597" than a device must match all of them to be considered.\n"
598"\n"
599" A mailaddr line starts with the word 'mailaddr' and should contain exactly\n"
600" one Email address. 'mdadm --monitor --scan' will send alerts of failed drives\n"
601" to this Email address."
602"\n"
603" A program line starts with the word 'program' and should contain exactly\n"
604" one program name. 'mdadm --monitor --scan' will run this program when any\n"
605" event is detected.\n"
606"\n"
607;
608
0609
=== removed file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/ReadMe.c'
--- .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/ReadMe.c 2012-02-09 16:53:02 +0000
+++ .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/ReadMe.c 1970-01-01 00:00:00 +0000
@@ -1,602 +0,0 @@
1/*
2 * mdadm - manage Linux "md" devices aka RAID arrays.
3 *
4 * Copyright (C) 2001-2010 Neil Brown <neilb@suse.de>
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Author: Neil Brown
22 * Email: <neilb@suse.de>
23 */
24
25#include "mdadm.h"
26
27char Version[] = Name " - v3.2.3 - 23rd December 2011\n";
28
29/*
30 * File: ReadMe.c
31 *
32 * This file contains general comments about the implementation
33 * and the various usage messages that can be displayed by mdadm
34 *
35 * mdadm is a single program that can be used to control Linux md devices.
36 * It is intended to provide all the functionality of the mdtools and
37 * raidtools but with a very different interface.
38 * mdadm can perform all functions without a configuration file.
39 * There is the option of using a configuration file, but not in the same
40 * way that raidtools uses one
41 * raidtools uses a configuration file to describe how to create a RAID
42 * array, and also uses this file partially to start a previously
43 * created RAID array. Further, raidtools requires the configuration
44 * file for such things as stopping a raid array which needs to know
45 * nothing about the array.
46 *
47 * The configuration file that can be used by mdadm lists two
48 * different things:
49 * 1/ a mapping from uuid to md device to identify which arrays are
50 * expect and what names (numbers) they should be given
51 * 2/ a list of devices that should be scanned for md sub-devices
52 *
53 *
54 */
55
56/*
57 * mdadm has 7 major modes of operation:
58 * 1/ Create
59 * This mode is used to create a new array with a superblock
60 * It can progress in several step create-add-add-run
61 * or it can all happen with one command
62 * 2/ Assemble
63 * This mode is used to assemble the parts of a previously created
64 * array into an active array. Components can be explicitly given
65 * or can be searched for. mdadm (optionally) check that the components
66 * do form a bona-fide array, and can, on request, fiddle superblock
67 * version numbers so as to assemble a faulty array.
68 * 3/ Build
69 * This is for building legacy arrays without superblocks
70 * 4/ Manage
71 * This is for doing something to one or more devices
72 * in an array, such as add,remove,fail.
73 * run/stop/readonly/readwrite are also available
74 * 5/ Misc
75 * This is for doing things to individual devices.
76 * They might be parts of an array so
77 * zero-superblock, examine might be appropriate
78 * They might be md arrays so
79 * run,stop,rw,ro,detail might be appropriate
80 * Also query will treat it as either
81 * 6/ Monitor
82 * This mode never exits but just monitors arrays and reports changes.
83 * 7/ Grow
84 * This mode allows for changing of key attributes of a raid array, such
85 * as size, number of devices, and possibly even layout.
86 * At the time if writing, there is only minimal support.
87 */
88
89char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
90char short_bitmap_options[]=
91 "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
92char short_bitmap_auto_options[]=
93 "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:";
94
95struct option long_options[] = {
96 {"manage", 0, 0, ManageOpt},
97 {"misc", 0, 0, MiscOpt},
98 {"assemble", 0, 0, 'A'},
99 {"build", 0, 0, 'B'},
100 {"create", 0, 0, 'C'},
101 {"detail", 0, 0, 'D'},
102 {"examine", 0, 0, 'E'},
103 {"follow", 0, 0, 'F'},
104 {"grow", 0, 0, 'G'},
105 {"incremental",0,0, 'I'},
106 {"zero-superblock", 0, 0, 'K'}, /* deliberately no a short_option */
107 {"query", 0, 0, 'Q'},
108 {"examine-bitmap", 0, 0, 'X'},
109 {"auto-detect", 0, 0, AutoDetect},
110 {"detail-platform", 0, 0, DetailPlatform},
111 {"kill-subarray", 1, 0, KillSubarray},
112 {"update-subarray", 1, 0, UpdateSubarray},
113 {"udev-rules", 2, 0, UdevRules},
114
115 /* synonyms */
116 {"monitor", 0, 0, 'F'},
117
118 /* after those will normally come the name of the md device */
119 {"help", 0, 0, 'h'},
120 {"help-options",0,0, HelpOptions},
121 {"version", 0, 0, 'V'},
122 {"verbose", 0, 0, 'v'},
123 {"quiet", 0, 0, 'q'},
124
125 /* For create or build: */
126 {"chunk", 1, 0, ChunkSize},
127 {"rounding", 1, 0, ChunkSize}, /* for linear, chunk is really a
128 * rounding number */
129 {"level", 1, 0, 'l'}, /* 0,1,4,5,6,linear */
130 {"parity", 1, 0, Layout}, /* {left,right}-{a,}symmetric */
131 {"layout", 1, 0, Layout},
132 {"raid-disks",1, 0, 'n'},
133 {"raid-devices",1, 0, 'n'},
134 {"spare-disks",1,0, 'x'},
135 {"spare-devices",1,0, 'x'},
136 {"size", 1, 0, 'z'},
137 {"auto", 1, 0, Auto}, /* also for --assemble */
138 {"assume-clean",0,0, AssumeClean },
139 {"metadata", 1, 0, 'e'}, /* superblock format */
140 {"bitmap", 1, 0, Bitmap},
141 {"bitmap-chunk", 1, 0, BitmapChunk},
142 {"write-behind", 2, 0, WriteBehind},
143 {"write-mostly",0, 0, WriteMostly},
144 {"re-add", 0, 0, ReAdd},
145 {"homehost", 1, 0, HomeHost},
146 {"symlinks", 1, 0, Symlinks},
147
148 /* For assemble */
149 {"uuid", 1, 0, 'u'},
150 {"super-minor",1,0, SuperMinor},
151 {"name", 1, 0, 'N'},
152 {"config", 1, 0, ConfigFile},
153 {"scan", 0, 0, 's'},
154 {"force", 0, 0, Force},
155 {"update", 1, 0, 'U'},
156 {"freeze-reshape", 0, 0, FreezeReshape},
157
158 /* Management */
159 {"add", 0, 0, Add},
160 {"remove", 0, 0, Remove},
161 {"fail", 0, 0, Fail},
162 {"set-faulty",0, 0, Fail},
163 {"run", 0, 0, 'R'},
164 {"stop", 0, 0, 'S'},
165 {"readonly", 0, 0, 'o'},
166 {"readwrite", 0, 0, 'w'},
167 {"no-degraded",0,0, NoDegraded },
168 {"wait", 0, 0, WaitOpt},
169 {"wait-clean", 0, 0, Waitclean },
170
171 /* For Detail/Examine */
172 {"brief", 0, 0, Brief},
173 {"export", 0, 0, 'Y'},
174 {"sparc2.2", 0, 0, Sparc22},
175 {"test", 0, 0, 't'},
176
177 /* For Follow/monitor */
178 {"mail", 1, 0, EMail},
179 {"program", 1, 0, ProgramOpt},
180 {"alert", 1, 0, ProgramOpt},
181 {"increment", 1, 0, Increment},
182 {"delay", 1, 0, 'd'},
183 {"daemonise", 0, 0, Fork},
184 {"daemonize", 0, 0, Fork},
185 {"oneshot", 0, 0, '1'},
186 {"pid-file", 1, 0, 'i'},
187 {"syslog", 0, 0, 'y'},
188 {"no-sharing", 0, 0, NoSharing},
189
190 /* For Grow */
191 {"backup-file", 1,0, BackupFile},
192 {"invalid-backup",0,0,InvalidBackup},
193 {"array-size", 1, 0, 'Z'},
194 {"continue", 0, 0, Continue},
195
196 /* For Incremental */
197 {"rebuild-map", 0, 0, RebuildMapOpt},
198 {"path", 1, 0, IncrementalPath},
199
200 {0, 0, 0, 0}
201};
202
203char Usage[] =
204"Usage: mdadm --help\n"
205" for help\n"
206;
207
208char Help[] =
209"mdadm is used for building, managing, and monitoring\n"
210"Linux md devices (aka RAID arrays)\n"
211"Usage: mdadm --create device options...\n"
212" Create a new array from unused devices.\n"
213" mdadm --assemble device options...\n"
214" Assemble a previously created array.\n"
215" mdadm --build device options...\n"
216" Create or assemble an array without metadata.\n"
217" mdadm --manage device options...\n"
218" make changes to an existing array.\n"
219" mdadm --misc options... devices\n"
220" report on or modify various md related devices.\n"
221" mdadm --grow options device\n"
222" resize/reshape an active array\n"
223" mdadm --incremental device\n"
224" add/remove a device to/from an array as appropriate\n"
225" mdadm --monitor options...\n"
226" Monitor one or more array for significant changes.\n"
227" mdadm device options...\n"
228" Shorthand for --manage.\n"
229"Any parameter that does not start with '-' is treated as a device name\n"
230"or, for --examine-bitmap, a file name.\n"
231"The first such name is often the name of an md device. Subsequent\n"
232"names are often names of component devices.\n"
233"\n"
234" For detailed help on the above major modes use --help after the mode\n"
235" e.g.\n"
236" mdadm --assemble --help\n"
237" For general help on options use\n"
238" mdadm --help-options\n"
239;
240
241char OptionHelp[] =
242"Any parameter that does not start with '-' is treated as a device name\n"
243"or, for --examine-bitmap, a file name.\n"
244"The first such name is often the name of an md device. Subsequent\n"
245"names are often names of component devices.\n"
246"\n"
247"Some common options are:\n"
248" --help -h : General help message or, after above option,\n"
249" mode specific help message\n"
250" --help-options : This help message\n"
251" --version -V : Print version information for mdadm\n"
252" --verbose -v : Be more verbose about what is happening\n"
253" --quiet -q : Don't print un-necessary messages\n"
254" --brief -b : Be less verbose, more brief\n"
255" --export -Y : With --detail, use key=value format for easy\n"
256" import into environment\n"
257" --force -f : Override normal checks and be more forceful\n"
258"\n"
259" --assemble -A : Assemble an array\n"
260" --build -B : Build an array without metadata\n"
261" --create -C : Create a new array\n"
262" --detail -D : Display details of an array\n"
263" --examine -E : Examine superblock on an array component\n"
264" --examine-bitmap -X: Display the detail of a bitmap file\n"
265" --monitor -F : monitor (follow) some arrays\n"
266" --grow -G : resize/ reshape and array\n"
267" --incremental -I : add/remove a single device to/from an array as appropriate\n"
268" --query -Q : Display general information about how a\n"
269" device relates to the md driver\n"
270" --auto-detect : Start arrays auto-detected by the kernel\n"
271;
272/*
273"\n"
274" For create or build:\n"
275" --bitmap= -b : File to store bitmap in - may pre-exist for --build\n"
276" --chunk= -c : chunk size of kibibytes\n"
277" --rounding= : rounding factor for linear array (==chunk size)\n"
278" --level= -l : raid level: 0,1,4,5,6,linear,mp. 0 or linear for build\n"
279" --parity= -p : raid5/6 parity algorithm: {left,right}-{,a}symmetric\n"
280" --layout= : same as --parity\n"
281" --raid-devices= -n : number of active devices in array\n"
282" --spare-devices= -x: number of spares (eXtras) devices in initial array\n"
283" --size= -z : Size (in K) of each drive in RAID1/4/5/6/10 - optional\n"
284" --force -f : Honour devices as listed on command line. Don't\n"
285" : insert a missing drive for RAID5.\n"
286" --assume-clean : Assume the array is already in-sync. This is dangerous.\n"
287" --bitmap-chunk= : chunksize of bitmap in bitmap file (Kilobytes)\n"
288" --delay= -d : seconds between bitmap updates\n"
289" --write-behind= : number of simultaneous write-behind requests to allow (requires bitmap)\n"
290" --name= -N : Textual name for array - max 32 characters\n"
291"\n"
292" For assemble:\n"
293" --bitmap= -b : File to find bitmap information in\n"
294" --uuid= -u : uuid of array to assemble. Devices which don't\n"
295" have this uuid are excluded\n"
296" --super-minor= -m : minor number to look for in super-block when\n"
297" choosing devices to use.\n"
298" --name= -N : Array name to look for in super-block.\n"
299" --config= -c : config file\n"
300" --scan -s : scan config file for missing information\n"
301" --force -f : Assemble the array even if some superblocks appear out-of-date\n"
302" --update= -U : Update superblock: try '-A --update=?' for list of options.\n"
303" --no-degraded : Do not start any degraded arrays - default unless --scan.\n"
304"\n"
305" For detail or examine:\n"
306" --brief -b : Just print device name and UUID\n"
307"\n"
308" For follow/monitor:\n"
309" --mail= -m : Address to mail alerts of failure to\n"
310" --program= -p : Program to run when an event is detected\n"
311" --alert= : same as --program\n"
312" --delay= -d : seconds of delay between polling state. default=60\n"
313"\n"
314" General management:\n"
315" --add -a : add, or hotadd subsequent devices\n"
316" --remove -r : remove subsequent devices\n"
317" --fail -f : mark subsequent devices a faulty\n"
318" --set-faulty : same as --fail\n"
319" --run -R : start a partially built array\n"
320" --stop -S : deactivate array, releasing all resources\n"
321" --readonly -o : mark array as readonly\n"
322" --readwrite -w : mark array as readwrite\n"
323" --zero-superblock : erase the MD superblock from a device.\n"
324" --wait -W : wait for recovery/resync/reshape to finish.\n"
325;
326*/
327
328char Help_create[] =
329"Usage: mdadm --create device -chunk=X --level=Y --raid-devices=Z devices\n"
330"\n"
331" This usage will initialise a new md array, associate some\n"
332" devices with it, and activate the array. In order to create an\n"
333" array with some devices missing, use the special word 'missing' in\n"
334" place of the relevant device name.\n"
335"\n"
336" Before devices are added, they are checked to see if they already contain\n"
337" raid superblocks or filesystems. They are also checked to see if\n"
338" the variance in device size exceeds 1%.\n"
339" If any discrepancy is found, the user will be prompted for confirmation\n"
340" before the array is created. The presence of a '--run' can override this\n"
341" caution.\n"
342"\n"
343" If the --size option is given then only that many kilobytes of each\n"
344" device is used, no matter how big each device is.\n"
345" If no --size is given, the apparent size of the smallest drive given\n"
346" is used for raid level 1 and greater, and the full device is used for\n"
347" other levels.\n"
348"\n"
349" Options that are valid with --create (-C) are:\n"
350" --bitmap= : Create a bitmap for the array with the given filename\n"
351" --chunk= -c : chunk size of kibibytes\n"
352" --rounding= : rounding factor for linear array (==chunk size)\n"
353" --level= -l : raid level: 0,1,4,5,6,linear,multipath and synonyms\n"
354" --parity= -p : raid5/6 parity algorithm: {left,right}-{,a}symmetric\n"
355" --layout= : same as --parity\n"
356" --raid-devices= -n : number of active devices in array\n"
357" --spare-devices= -x: number of spares (eXtras) devices in initial array\n"
358" --size= -z : Size (in K) of each drive in RAID1/4/5/6/10 - optional\n"
359" --force -f : Honour devices as listed on command line. Don't\n"
360" : insert a missing drive for RAID5.\n"
361" --run -R : insist of running the array even if not all\n"
362" : devices are present or some look odd.\n"
363" --readonly -o : start the array readonly - not supported yet.\n"
364" --name= -N : Textual name for array - max 32 characters\n"
365" --bitmap-chunk= : bitmap chunksize in Kilobytes.\n"
366" --delay= -d : bitmap update delay in seconds.\n"
367"\n"
368;
369
370char Help_build[] =
371"Usage: mdadm --build device -chunk=X --level=Y --raid-devices=Z devices\n"
372"\n"
373" This usage is similar to --create. The difference is that it creates\n"
374" a legacy array without a superblock. With these arrays there is no\n"
375" different between initially creating the array and subsequently\n"
376" assembling the array, except that hopefully there is useful data\n"
377" there in the second case.\n"
378"\n"
379" The level may only be 0, raid0, or linear.\n"
380" All devices must be listed and the array will be started once complete.\n"
381" Options that are valid with --build (-B) are:\n"
382" --bitmap= : file to store/find bitmap information in.\n"
383" --chunk= -c : chunk size of kibibytes\n"
384" --rounding= : rounding factor for linear array (==chunk size)\n"
385" --level= -l : 0, raid0, or linear\n"
386" --raid-devices= -n : number of active devices in array\n"
387" --bitmap-chunk= : bitmap chunksize in Kilobytes.\n"
388" --delay= -d : bitmap update delay in seconds.\n"
389;
390
391char Help_assemble[] =
392"Usage: mdadm --assemble device options...\n"
393" mdadm --assemble --scan options...\n"
394"\n"
395"This usage assembles one or more raid arrays from pre-existing\n"
396"components.\n"
397"For each array, mdadm needs to know the md device, the identity of\n"
398"the array, and a number of sub devices. These can be found in a number\n"
399"of ways.\n"
400"\n"
401"The md device is either given on the command line or is found listed\n"
402"in the config file. The array identity is determined either from the\n"
403"--uuid or --super-minor commandline arguments, from the config file,\n"
404"or from the first component device on the command line.\n"
405"\n"
406"The different combinations of these are as follows:\n"
407" If the --scan option is not given, then only devices and identities\n"
408" listed on the command line are considered.\n"
409" The first device will be the array device, and the remainder will be\n"
410" examined when looking for components.\n"
411" If an explicit identity is given with --uuid or --super-minor, then\n"
412" only devices with a superblock which matches that identity is considered,\n"
413" otherwise every device listed is considered.\n"
414"\n"
415" If the --scan option is given, and no devices are listed, then\n"
416" every array listed in the config file is considered for assembly.\n"
417" The identity of candidate devices are determined from the config file.\n"
418"\n"
419" If the --scan option is given as well as one or more devices, then\n"
420" Those devices are md devices that are to be assembled. Their identity\n"
421" and components are determined from the config file.\n"
422"\n"
423" If mdadm can not find all of the components for an array, it will assemble\n"
424" it but not activate it unless --run or --scan is given. To preserve this\n"
425" behaviour even with --scan, add --no-degraded. Note that \"all of the\n"
426" components\" means as many as were present the last time the array was running\n"
427" as recorded in the superblock. If the array was already degraded, and\n"
428" the missing device is not a new problem, it will still be assembled. It\n"
429" is only newly missing devices that cause the array not to be started.\n"
430"\n"
431"Options that are valid with --assemble (-A) are:\n"
432" --bitmap= : bitmap file to use wit the array\n"
433" --uuid= -u : uuid of array to assemble. Devices which don't\n"
434" have this uuid are excluded\n"
435" --super-minor= -m : minor number to look for in super-block when\n"
436" choosing devices to use.\n"
437" --name= -N : Array name to look for in super-block.\n"
438" --config= -c : config file\n"
439" --scan -s : scan config file for missing information\n"
440" --run -R : Try to start the array even if not enough devices\n"
441" for a full array are present\n"
442" --force -f : Assemble the array even if some superblocks appear\n"
443" : out-of-date. This involves modifying the superblocks.\n"
444" --update= -U : Update superblock: try '-A --update=?' for option list.\n"
445" --no-degraded : Assemble but do not start degraded arrays.\n"
446;
447
448char Help_manage[] =
449"Usage: mdadm arraydevice options component devices...\n"
450"\n"
451"This usage is for managing the component devices within an array.\n"
452"The --manage option is not needed and is assumed if the first argument\n"
453"is a device name or a management option.\n"
454"The first device listed will be taken to be an md array device, and\n"
455"subsequent devices are (potential) components of that array.\n"
456"\n"
457"Options that are valid with management mode are:\n"
458" --add -a : hotadd subsequent devices to the array\n"
459" --remove -r : remove subsequent devices, which must not be active\n"
460" --fail -f : mark subsequent devices a faulty\n"
461" --set-faulty : same as --fail\n"
462" --run -R : start a partially built array\n"
463" --stop -S : deactivate array, releasing all resources\n"
464" --readonly -o : mark array as readonly\n"
465" --readwrite -w : mark array as readwrite\n"
466;
467
468char Help_misc[] =
469"Usage: mdadm misc_option devices...\n"
470"\n"
471"This usage is for performing some task on one or more devices, which\n"
472"may be arrays or components, depending on the task.\n"
473"The --misc option is not needed (though it is allowed) and is assumed\n"
474"if the first argument in a misc option.\n"
475"\n"
476"Options that are valid with the miscellaneous mode are:\n"
477" --query -Q : Display general information about how a\n"
478" device relates to the md driver\n"
479" --detail -D : Display details of an array\n"
480" --detail-platform : Display hardware/firmware details\n"
481" --examine -E : Examine superblock on an array component\n"
482" --examine-bitmap -X: Display contents of a bitmap file\n"
483" --zero-superblock : erase the MD superblock from a device.\n"
484" --run -R : start a partially built array\n"
485" --stop -S : deactivate array, releasing all resources\n"
486" --readonly -o : mark array as readonly\n"
487" --readwrite -w : mark array as readwrite\n"
488" --test -t : exit status 0 if ok, 1 if degrade, 2 if dead, 4 if missing\n"
489" --wait -W : wait for resync/rebuild/recovery to finish\n"
490;
491
492char Help_monitor[] =
493"Usage: mdadm --monitor options devices\n"
494"\n"
495"This usage causes mdadm to monitor a number of md arrays by periodically\n"
496"polling their status and acting on any changes.\n"
497"If any devices are listed then those devices are monitored, otherwise\n"
498"all devices listed in the config file are monitored.\n"
499"The address for mailing advisories to, and the program to handle\n"
500"each change can be specified in the config file or on the command line.\n"
501"If no mail address or program are specified, then mdadm reports all\n"
502"state changes to stdout.\n"
503"\n"
504"Options that are valid with the monitor (-F --follow) mode are:\n"
505" --mail= -m : Address to mail alerts of failure to\n"
506" --program= -p : Program to run when an event is detected\n"
507" --alert= : same as --program\n"
508" --syslog -y : Report alerts via syslog\n"
509" --increment= -r : Report RebuildNN events in the given increment. default=20\n"
510" --delay= -d : seconds of delay between polling state. default=60\n"
511" --config= -c : specify a different config file\n"
512" --scan -s : find mail-address/program in config file\n"
513" --daemonise -f : Fork and continue in child, parent exits\n"
514" --pid-file= -i : In daemon mode write pid to specified file instead of stdout\n"
515" --oneshot -1 : Check for degraded arrays, then exit\n"
516" --test -t : Generate a TestMessage event against each array at startup\n"
517;
518
519char Help_grow[] =
520"Usage: mdadm --grow device options\n"
521"\n"
522"This usage causes mdadm to attempt to reconfigure a running array.\n"
523"This is only possibly if the kernel being used supports a particular\n"
524"reconfiguration. This version supports changing the number of\n"
525"devices in a RAID1/5/6, changing the active size of all devices in\n"
526"a RAID1/4/5/6, adding or removing a write-intent bitmap, and changing\n"
527"the error mode for a 'FAULTY' array.\n"
528"\n"
529"Options that are valid with the grow (-G --grow) mode are:\n"
530" --level= -l : Tell mdadm what level the array is so that it can\n"
531" : interpret '--layout' properly.\n"
532" --layout= -p : For a FAULTY array, set/change the error mode.\n"
533" --size= -z : Change the active size of devices in an array.\n"
534" : This is useful if all devices have been replaced\n"
535" : with larger devices. Value is in Kilobytes, or\n"
536" : the special word 'max' meaning 'as large as possible'.\n"
537" --raid-devices= -n : Change the number of active devices in an array.\n"
538" --bitmap= -b : Add or remove a write-intent bitmap.\n"
539" --backup-file= file : A file on a differt device to store data for a\n"
540" : short time while increasing raid-devices on a\n"
541" : RAID4/5/6 array. Not needed when a spare is present.\n"
542" --array-size= -Z : Change visible size of array. This does not change\n"
543" : any data on the device, and is not stable across restarts.\n"
544;
545
546char Help_incr[] =
547"Usage: mdadm --incremental [-Rqrsf] device\n"
548"\n"
549"This usage allows for incremental assembly of md arrays. Devices can be\n"
550"added one at a time as they are discovered. Once an array has all expected\n"
551"devices, it will be started.\n"
552"\n"
553"Optionally, the process can be reversed by using the fail option.\n"
554"When fail mode is invoked, mdadm will see if the device belongs to an array\n"
555"and then both fail (if needed) and remove the device from that array.\n"
556"\n"
557"Options that are valid with incremental assembly (-I --incremental) are:\n"
558" --run -R : Run arrays as soon as a minimal number of devices are\n"
559" : present rather than waiting for all expected.\n"
560" --quiet -q : Don't print any information messages, just errors.\n"
561" --rebuild-map -r : Rebuild the 'map' file that mdadm uses for tracking\n"
562" : partial arrays.\n"
563" --scan -s : Use with -R to start any arrays that have the minimal\n"
564" : required number of devices, but are not yet started.\n"
565" --fail -f : First fail (if needed) and then remove device from\n"
566" : any array that it is a member of.\n"
567;
568
569char Help_config[] =
570"The /etc/mdadm/mdadm.conf config file:\n\n"
571" The config file contains, apart from blank lines and comment lines that\n"
572" start with a hash(#), four sorts of configuration lines: array lines, \n"
573" device lines, mailaddr lines and program lines.\n"
574" Each configuration line is constructed of a number of space separated\n"
575" words, and can be continued on subsequent physical lines by indenting\n"
576" those lines.\n"
577"\n"
578" A device line starts with the word 'device' and then has a number of words\n"
579" which identify devices. These words should be names of devices in the\n"
580" filesystem, and can contain wildcards. There can be multiple words or each\n"
581" device line, and multiple device lines. All devices so listed are checked\n"
582" for relevant super blocks when assembling arrays.\n"
583"\n"
584" An array line start with the word 'array'. This is followed by the name of\n"
585" the array device in the filesystem, e.g. '/dev/md2'. Subsequent words\n"
586" describe the identity of the array, used to recognise devices to include in the\n"
587" array. The identity can be given as a UUID with a word starting 'uuid=', or\n"
588" as a minor-number stored in the superblock using 'super-minor=', or as a list\n"
589" of devices. This is given as a comma separated list of names, possibly\n"
590" containing wildcards, preceded by 'devices='. If multiple critea are given,\n"
591" than a device must match all of them to be considered.\n"
592"\n"
593" A mailaddr line starts with the word 'mailaddr' and should contain exactly\n"
594" one Email address. 'mdadm --monitor --scan' will send alerts of failed drives\n"
595" to this Email address."
596"\n"
597" A program line starts with the word 'program' and should contain exactly\n"
598" one program name. 'mdadm --monitor --scan' will run this program when any\n"
599" event is detected.\n"
600"\n"
601;
602
6030
=== added directory '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/check.d'
=== removed directory '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/check.d'
=== added file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/check.d/_numbers'
=== removed file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/check.d/_numbers'
=== added file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/check.d/root_on_raid'
=== removed file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/check.d/root_on_raid'
=== added file '.pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/config.c'
--- .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/config.c 1970-01-01 00:00:00 +0000
+++ .pc/debian-changes-3.1.4-1+8efb9d1ubuntu4/config.c 2012-06-18 08:55:05 +0000
@@ -0,0 +1,1131 @@
1/*
2 * mdadm - manage Linux "md" devices aka RAID arrays.
3 *
4 * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Author: Neil Brown
22 * Email: <neilb@suse.de>
23 */
24
25#include "mdadm.h"
26#include "dlink.h"
27#include <dirent.h>
28#include <glob.h>
29#include <fnmatch.h>
30#include <ctype.h>
31#include <pwd.h>
32#include <grp.h>
33
34/*
35 * Read the config file
36 *
37 * conf_get_uuids gets a list of devicename+uuid pairs
38 * conf_get_devs gets device names after expanding wildcards
39 *
40 * Each keeps the returned list and frees it when asked to make
41 * a new list.
42 *
43 * The format of the config file needs to be fairly extensible.
44 * Now, arrays only have names and uuids and devices merely are.
45 * But later arrays might want names, and devices might want superblock
46 * versions, and who knows what else.
47 * I like free format, abhore backslash line continuation, adore
48 * indentation for structure and am ok about # comments.
49 *
50 * So, each line that isn't blank or a #comment must either start
51 * with a key word, and not be indented, or must start with a
52 * non-key-word and must be indented.
53 *
54 * Keywords are DEVICE and ARRAY ... and several others.
55 * DEV{ICE} introduces some devices that might contain raid components.
56 * e.g.
57 * DEV style=0 /dev/sda* /dev/hd*
58 * DEV style=1 /dev/sd[b-f]*
59 * ARR{AY} describes an array giving md device and attributes like uuid=whatever
60 * e.g.
61 * ARRAY /dev/md0 uuid=whatever name=something
62 * Spaces separate words on each line. Quoting, with "" or '' protects them,
63 * but may not wrap over lines
64 *
65 */
66
67#ifndef CONFFILE
68#define CONFFILE "/etc/mdadm.conf"
69#endif
70#ifndef CONFFILE2
71/* for Debian compatibility .... */
72#define CONFFILE2 "/etc/mdadm/mdadm.conf"
73#endif
74char DefaultConfFile[] = CONFFILE;
75char DefaultAltConfFile[] = CONFFILE2;
76
77enum linetype { Devices, Array, Mailaddr, Mailfrom, Program, CreateDev,
78 Homehost, AutoMode, Policy, PartPolicy, LTEnd };
79char *keywords[] = {
80 [Devices] = "devices",
81 [Array] = "array",
82 [Mailaddr] = "mailaddr",
83 [Mailfrom] = "mailfrom",
84 [Program] = "program",
85 [CreateDev]= "create",
86 [Homehost] = "homehost",
87 [AutoMode] = "auto",
88 [Policy] = "policy",
89 [PartPolicy]="part-policy",
90 [LTEnd] = NULL
91};
92
93/*
94 * match_keyword returns an index into the keywords array, or -1 for no match
95 * case is ignored, and at least three characters must be given
96 */
97
98int match_keyword(char *word)
99{
100 int len = strlen(word);
101 int n;
102
103 if (len < 3) return -1;
104 for (n=0; keywords[n]; n++) {
105 if (strncasecmp(word, keywords[n], len)==0)
106 return n;
107 }
108 return -1;
109}
110
111/*
112 * conf_line reads one logical line from the conffile.
113 * It skips comments and continues until it finds a line that starts
114 * with a non blank/comment. This character is pushed back for the next call
115 * A doubly linked list of words is returned.
116 * the first word will be a keyword. Other words will have had quotes removed.
117 */
118
119char *conf_line(FILE *file)
120{
121 char *w;
122 char *list;
123
124 w = conf_word(file, 1);
125 if (w == NULL) return NULL;
126
127 list = dl_strdup(w);
128 free(w);
129 dl_init(list);
130
131 while ((w = conf_word(file,0))){
132 char *w2 = dl_strdup(w);
133 free(w);
134 dl_add(list, w2);
135 }
136/* printf("got a line\n");*/
137 return list;
138}
139
140void free_line(char *line)
141{
142 char *w;
143 for (w=dl_next(line); w != line; w=dl_next(line)) {
144 dl_del(w);
145 dl_free(w);
146 }
147 dl_free(line);
148}
149
150
151struct conf_dev {
152 struct conf_dev *next;
153 char *name;
154} *cdevlist = NULL;
155
156struct mddev_dev *load_partitions(void)
157{
158 FILE *f = fopen("/proc/partitions", "r");
159 char buf[1024];
160 struct mddev_dev *rv = NULL;
161 if (f == NULL) {
162 fprintf(stderr, Name ": cannot open /proc/partitions\n");
163 return NULL;
164 }
165 while (fgets(buf, 1024, f)) {
166 int major, minor;
167 char *name, *mp;
168 struct mddev_dev *d;
169
170 buf[1023] = '\0';
171 if (buf[0] != ' ')
172 continue;
173 major = strtoul(buf, &mp, 10);
174 if (mp == buf || *mp != ' ')
175 continue;
176 minor = strtoul(mp, NULL, 10);
177
178 name = map_dev(major, minor, 1);
179 if (!name)
180 continue;
181 d = malloc(sizeof(*d));
182 d->devname = strdup(name);
183 d->next = rv;
184 d->used = 0;
185 rv = d;
186 }
187 fclose(f);
188 return rv;
189}
190
191struct mddev_dev *load_containers(void)
192{
193 struct mdstat_ent *mdstat = mdstat_read(1, 0);
194 struct mdstat_ent *ent;
195 struct mddev_dev *d;
196 struct mddev_dev *rv = NULL;
197
198 if (!mdstat)
199 return NULL;
200
201 for (ent = mdstat; ent; ent = ent->next)
202 if (ent->metadata_version &&
203 strncmp(ent->metadata_version, "external:", 9) == 0 &&
204 !is_subarray(&ent->metadata_version[9])) {
205 d = malloc(sizeof(*d));
206 if (!d)
207 continue;
208 if (asprintf(&d->devname, "/dev/%s", ent->dev) < 0) {
209 free(d);
210 continue;
211 }
212 d->next = rv;
213 d->used = 0;
214 rv = d;
215 }
216 free_mdstat(mdstat);
217
218 return rv;
219}
220
221struct createinfo createinfo = {
222 .autof = 2, /* by default, create devices with standard names */
223 .symlinks = 1,
224#ifdef DEBIAN
225 .gid = 6, /* disk */
226 .mode = 0660,
227#else
228 .mode = 0600,
229#endif
230};
231
232int parse_auto(char *str, char *msg, int config)
233{
234 int autof;
235 if (str == NULL || *str == 0)
236 autof = 2;
237 else if (strcasecmp(str,"no")==0)
238 autof = 1;
239 else if (strcasecmp(str,"yes")==0)
240 autof = 2;
241 else if (strcasecmp(str,"md")==0)
242 autof = config?5:3;
243 else {
244 /* There might be digits, and maybe a hypen, at the end */
245 char *e = str + strlen(str);
246 int num = 4;
247 int len;
248 while (e > str && isdigit(e[-1]))
249 e--;
250 if (*e) {
251 num = atoi(e);
252 if (num <= 0) num = 1;
253 }
254 if (e > str && e[-1] == '-')
255 e--;
256 len = e - str;
257 if ((len == 2 && strncasecmp(str,"md",2)==0)) {
258 autof = config ? 5 : 3;
259 } else if ((len == 3 && strncasecmp(str,"yes",3)==0)) {
260 autof = 2;
261 } else if ((len == 3 && strncasecmp(str,"mdp",3)==0)) {
262 autof = config ? 6 : 4;
263 } else if ((len == 1 && strncasecmp(str,"p",1)==0) ||
264 (len >= 4 && strncasecmp(str,"part",4)==0)) {
265 autof = 6;
266 } else {
267 fprintf(stderr, Name ": %s arg of \"%s\" unrecognised: use no,yes,md,mdp,part\n"
268 " optionally followed by a number.\n",
269 msg, str);
270 exit(2);
271 }
272 autof |= num << 3;
273 }
274 return autof;
275}
276
277static void createline(char *line)
278{
279 char *w;
280 char *ep;
281
282 for (w=dl_next(line); w!=line; w=dl_next(w)) {
283 if (strncasecmp(w, "auto=", 5) == 0)
284 createinfo.autof = parse_auto(w+5, "auto=", 1);
285 else if (strncasecmp(w, "owner=", 6) == 0) {
286 if (w[6] == 0) {
287 fprintf(stderr, Name ": missing owner name\n");
288 continue;
289 }
290 createinfo.uid = strtoul(w+6, &ep, 10);
291 if (*ep != 0) {
292 struct passwd *pw;
293 /* must be a name */
294 pw = getpwnam(w+6);
295 if (pw)
296 createinfo.uid = pw->pw_uid;
297 else
298 fprintf(stderr, Name ": CREATE user %s not found\n", w+6);
299 }
300 } else if (strncasecmp(w, "group=", 6) == 0) {
301 if (w[6] == 0) {
302 fprintf(stderr, Name ": missing group name\n");
303 continue;
304 }
305 createinfo.gid = strtoul(w+6, &ep, 10);
306 if (*ep != 0) {
307 struct group *gr;
308 /* must be a name */
309 gr = getgrnam(w+6);
310 if (gr)
311 createinfo.gid = gr->gr_gid;
312 else
313 fprintf(stderr, Name ": CREATE group %s not found\n", w+6);
314 }
315 } else if (strncasecmp(w, "mode=", 5) == 0) {
316 if (w[5] == 0) {
317 fprintf(stderr, Name ": missing CREATE mode\n");
318 continue;
319 }
320 createinfo.mode = strtoul(w+5, &ep, 8);
321 if (*ep != 0) {
322 createinfo.mode = 0600;
323 fprintf(stderr, Name ": unrecognised CREATE mode %s\n",
324 w+5);
325 }
326 } else if (strncasecmp(w, "metadata=", 9) == 0) {
327 /* style of metadata to use by default */
328 int i;
329 for (i=0; superlist[i] && !createinfo.supertype; i++)
330 createinfo.supertype =
331 superlist[i]->match_metadata_desc(w+9);
332 if (!createinfo.supertype)
333 fprintf(stderr, Name ": metadata format %s unknown, ignoring\n",
334 w+9);
335 } else if (strncasecmp(w, "symlinks=yes", 12) == 0)
336 createinfo.symlinks = 1;
337 else if (strncasecmp(w, "symlinks=no", 11) == 0)
338 createinfo.symlinks = 0;
339 else {
340 fprintf(stderr, Name ": unrecognised word on CREATE line: %s\n",
341 w);
342 }
343 }
344}
345
346void devline(char *line)
347{
348 char *w;
349 struct conf_dev *cd;
350
351 for (w=dl_next(line); w != line; w=dl_next(w)) {
352 if (w[0] == '/' || strcasecmp(w, "partitions") == 0 ||
353 strcasecmp(w, "containers") == 0) {
354 cd = malloc(sizeof(*cd));
355 cd->name = strdup(w);
356 cd->next = cdevlist;
357 cdevlist = cd;
358 } else {
359 fprintf(stderr, Name ": unreconised word on DEVICE line: %s\n",
360 w);
361 }
362 }
363}
364
365struct mddev_ident *mddevlist = NULL;
366struct mddev_ident **mddevlp = &mddevlist;
367
368static int is_number(char *w)
369{
370 /* check if there are 1 or more digits and nothing else */
371 int digits = 0;
372 while (*w && isdigit(*w)) {
373 digits++;
374 w++;
375 }
376 return (digits && ! *w);
377}
378
379void arrayline(char *line)
380{
381 char *w;
382
383 struct mddev_ident mis;
384 struct mddev_ident *mi;
385
386 mis.uuid_set = 0;
387 mis.super_minor = UnSet;
388 mis.level = UnSet;
389 mis.raid_disks = UnSet;
390 mis.spare_disks = 0;
391 mis.devices = NULL;
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: