mdadm-1.3.0
Neil Brown
20 years ago
0 | Subject: ANNOUNCE: mdadm 1.3.0 - A tools for managing Soft RAID under Linux | |
1 | ||
2 | ||
3 | I am pleased to announce the availability of | |
4 | mdadm version 1.3.0 | |
5 | It is available at | |
6 | http://www.cse.unsw.edu.au/~neilb/source/mdadm/ | |
7 | and | |
8 | http://www.{countrycode}.kernel.org/pub/utils/raid/mdadm/ | |
9 | ||
10 | as a source tar-ball and (at the first site) as an SRPM, and as an RPM for i386. | |
11 | ||
12 | mdadm is a tool for creating, managing and monitoring | |
13 | device arrays using the "md" driver in Linux, also | |
14 | known as Software RAID arrays. | |
15 | ||
16 | Release 1.3.0 is a bug-fix and minor feature update release over 1.2.0. | |
17 | ||
18 | Development of mdadm is sponsored by CSE@UNSW: | |
19 | The School of Computer Science and Engineering | |
20 | at | |
21 | The University of New South Wales | |
22 | ||
23 | NeilBrown 29 Jul 2003 |
108 | 108 | int *best = NULL; /* indexed by raid_disk */ |
109 | 109 | int bestcnt = 0; |
110 | 110 | int devcnt = 0, okcnt, sparecnt; |
111 | int req_cnt; | |
111 | 112 | int i; |
112 | 113 | int most_recent = 0; |
113 | 114 | int chosen_drive; |
364 | 365 | * as they don't make sense |
365 | 366 | */ |
366 | 367 | if (first_super.level != -4) |
367 | if (!(devices[j].state & (1<<MD_DISK_SYNC))) | |
368 | if (!(devices[j].state & (1<<MD_DISK_SYNC))) { | |
369 | if (!(devices[j].state & (1<<MD_DISK_FAULTY))) | |
370 | sparecnt++; | |
368 | 371 | continue; |
372 | } | |
369 | 373 | if (devices[j].events+event_margin >= |
370 | 374 | devices[most_recent].events) { |
371 | 375 | devices[j].uptodate = 1; |
533 | 537 | close(fd); |
534 | 538 | change = 0; |
535 | 539 | } |
540 | ||
541 | /* count number of in-sync devices according to the superblock. | |
542 | * We must have this number to start the array without -s or -R | |
543 | */ | |
544 | req_cnt = 0; | |
545 | for (i=0; i<MD_SB_DISKS; i++) | |
546 | if ((first_super.disks[i].state & (1<<MD_DISK_SYNC)) && | |
547 | (first_super.disks[i].state & (1<<MD_DISK_ACTIVE)) && | |
548 | !(first_super.disks[i].state & (1<<MD_DISK_FAULTY))) | |
549 | req_cnt ++; | |
550 | ||
536 | 551 | |
537 | 552 | /* Almost ready to actually *do* something */ |
538 | 553 | if (!old_linux) { |
575 | 590 | |
576 | 591 | if (runstop == 1 || |
577 | 592 | (runstop == 0 && |
578 | ( first_super.raid_disks == okcnt | |
579 | || (start_partial_ok && enough(first_super.level, first_super.raid_disks, okcnt))) | |
580 | )) { | |
593 | ( enough(first_super.level, first_super.raid_disks, okcnt) && | |
594 | (okcnt >= req_cnt || start_partial_ok) | |
595 | ))) { | |
581 | 596 | if (ioctl(mdfd, RUN_ARRAY, NULL)==0) { |
582 | 597 | fprintf(stderr, Name ": %s has been started with %d drive%s", |
583 | 598 | mddev, okcnt, okcnt==1?"":"s"); |
599 | if (okcnt < first_super.raid_disks) | |
600 | fprintf(stderr, " (out of %d)", first_super.raid_disks); | |
584 | 601 | if (sparecnt) |
585 | 602 | fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s"); |
586 | 603 | fprintf(stderr, ".\n"); |
595 | 612 | mddev, okcnt, okcnt==1?"":"s"); |
596 | 613 | return 0; |
597 | 614 | } |
598 | fprintf(stderr, Name ": %s assembled from %d drive%s - not enough to start it (use --run to insist).\n", | |
599 | mddev, okcnt, okcnt==1?"":"s"); | |
615 | fprintf(stderr, Name ": %s assembled from %d drive%s", mddev, okcnt, okcnt==1?"":"s"); | |
616 | if (sparecnt) | |
617 | fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s"); | |
618 | if (!enough(first_super.level, first_super.raid_disks, okcnt)) | |
619 | fprintf(stderr, " - not enough to start the array.\n"); | |
620 | else { | |
621 | if (req_cnt == first_super.raid_disks) | |
622 | fprintf(stderr, " - need all %d to start it", req_cnt); | |
623 | else | |
624 | fprintf(stderr, " - need %d of %d to start", req_cnt, first_super.raid_disks); | |
625 | fprintf(stderr, " (use --run to insist).\n"); | |
626 | } | |
600 | 627 | return 1; |
601 | 628 | } else { |
602 | 629 | /* The "chosen_drive" is a good choice, and if necessary, the superblock has |
0 | Changes Prior to 1.3.0 release | |
1 | - Make 'size' and unsigned long in Create to allow creation of | |
2 | larger arrays. | |
3 | - Explicitly flag spare devices as 'spare' in --detail and --examine | |
4 | output. Previously they simply had no flags lists. | |
5 | - Make MailCmd (for monitor) configurable in Makefile, and default | |
6 | to "/usr/sbin/sendmail -t". Also split out the warning related | |
7 | flags into CWFLAGS for easier build configurability. | |
8 | - Minor bugfix in Manage code. | |
9 | - --monitor now notices and reports degraded arrays at startup using | |
10 | "DegradedArray" event, and also has a --oneshot option to only | |
11 | report DegradedArrays, and then exit. | |
12 | - Small man-page clarification w.r.t. raid levels and raid4 in | |
13 | particular. | |
14 | - Disallow creation of arrays with only one device as this is | |
15 | probably a mistake. --force will override this check. | |
16 | - Correct some misleading documentation in the "mdadm --create --help" | |
17 | message. | |
18 | - Ignore chunksize if raid1 or multipath. | |
19 | - Explicit statement in man page that raid-disks cannot be changed | |
20 | after array is created. | |
21 | - Improve message when attempting to start an array with | |
22 | insufficient devices. Instead of required the array to be full, | |
23 | we only require it has as many active devices as last time. | |
24 | ||
0 | 25 | Changes Prior to 1.2.0 release |
1 | 26 | - Fix bug where --daemonise required an argument. |
2 | 27 | - In --assemble --verbose, print appropriate message if device is |
31 | 31 | #include "md_p.h" |
32 | 32 | |
33 | 33 | int Create(char *mddev, int mdfd, |
34 | int chunk, int level, int layout, int size, int raiddisks, int sparedisks, | |
34 | int chunk, int level, int layout, unsigned long size, int raiddisks, int sparedisks, | |
35 | 35 | int subdevs, mddev_dev_t devlist, |
36 | 36 | int runstop, int verbose, int force) |
37 | 37 | { |
51 | 51 | * if runstop==run, or raiddisks diskswere used, |
52 | 52 | * RUN_ARRAY |
53 | 53 | */ |
54 | int minsize=0, maxsize=0; | |
54 | unsigned long minsize=0, maxsize=0; | |
55 | 55 | char *mindisc = NULL; |
56 | 56 | char *maxdisc = NULL; |
57 | 57 | int dnum; |
114 | 114 | break; |
115 | 115 | } |
116 | 116 | |
117 | if (chunk == 0) { | |
118 | chunk = 64; | |
119 | if (verbose) | |
120 | fprintf(stderr, Name ": chunk size defaults to 64K\n"); | |
117 | switch(level) { | |
118 | case 4: | |
119 | case 5: | |
120 | case 0: | |
121 | case -1: /* linear */ | |
122 | if (chunk == 0) { | |
123 | chunk = 64; | |
124 | if (verbose) | |
125 | fprintf(stderr, Name ": chunk size defaults to 64K\n"); | |
126 | } | |
127 | break; | |
128 | default: /* raid1, multipath */ | |
129 | if (chunk) { | |
130 | chunk = 0; | |
131 | if (verbose) | |
132 | fprintf(stderr, Name ": chunk size ignored for this level\n"); | |
133 | } | |
134 | break; | |
121 | 135 | } |
122 | 136 | |
123 | 137 | /* now look at the subdevs */ |
126 | 140 | dnum = 0; |
127 | 141 | for (dv=devlist; dv; dv=dv->next, dnum++) { |
128 | 142 | char *dname = dv->devname; |
129 | int dsize, freesize; | |
143 | unsigned long dsize, freesize; | |
130 | 144 | int fd; |
131 | 145 | if (strcasecmp(dname, "missing")==0) { |
132 | 146 | if (first_missing > dnum) |
152 | 166 | continue; |
153 | 167 | } |
154 | 168 | if (dsize < MD_RESERVED_SECTORS*2) { |
155 | fprintf(stderr, Name ": %s is too small: %dK\n", | |
169 | fprintf(stderr, Name ": %s is too small: %luK\n", | |
156 | 170 | dname, dsize/2); |
157 | 171 | fail = 1; |
158 | 172 | close(fd); |
163 | 177 | |
164 | 178 | if (size && freesize < size) { |
165 | 179 | fprintf(stderr, Name ": %s is smaller that given size." |
166 | " %dK < %dK + superblock\n", dname, freesize, size); | |
180 | " %luK < %luK + superblock\n", dname, freesize, size); | |
167 | 181 | fail = 1; |
168 | 182 | close(fd); |
169 | 183 | continue; |
192 | 206 | } |
193 | 207 | size = minsize; |
194 | 208 | if (verbose && level>0) |
195 | fprintf(stderr, Name ": size set to %dK\n", size); | |
209 | fprintf(stderr, Name ": size set to %luK\n", size); | |
196 | 210 | } |
197 | 211 | if (level >= 1 && ((maxsize-size)*100 > maxsize)) { |
198 | fprintf(stderr, Name ": largest drive (%s) exceed size (%dK) by more than 1%%\n", | |
212 | fprintf(stderr, Name ": largest drive (%s) exceed size (%luK) by more than 1%%\n", | |
199 | 213 | maxdisc, size); |
200 | 214 | warn = 1; |
201 | 215 | } |
161 | 161 | if (disk.state & (1<<MD_DISK_ACTIVE)) printf(" active"); |
162 | 162 | if (disk.state & (1<<MD_DISK_SYNC)) printf(" sync"); |
163 | 163 | if (disk.state & (1<<MD_DISK_REMOVED)) printf(" removed"); |
164 | if (disk.state == 0) printf(" spare"); | |
164 | 165 | } |
165 | 166 | if ((dv=map_dev(disk.major, disk.minor))) { |
166 | 167 | if (brief) { |
204 | 204 | if (dp->state & (1<<MD_DISK_ACTIVE)) printf(" active"); |
205 | 205 | if (dp->state & (1<<MD_DISK_SYNC)) printf(" sync"); |
206 | 206 | if (dp->state & (1<<MD_DISK_REMOVED)) printf(" removed"); |
207 | if (dp->state == 0) printf(" spare"); | |
207 | 208 | if ((dv=map_dev(dp->major, dp->minor))) |
208 | 209 | printf(" %s", dv); |
209 | 210 | printf("\n"); |
33 | 33 | |
34 | 34 | CC = gcc |
35 | 35 | CXFLAGS = -ggdb |
36 | CWFLAGS = -Wall -Werror -Wstrict-prototypes | |
36 | 37 | SYSCONFDIR = /etc |
37 | 38 | CONFFILE = $(SYSCONFDIR)/mdadm.conf |
38 | CFLAGS = -Wall -Werror -Wstrict-prototypes -DCONFFILE=\"$(CONFFILE)\" $(CXFLAGS) | |
39 | MAILCMD =/usr/sbin/sendmail -t | |
40 | CFLAGS = $(CWFLAGS) -DCONFFILE=\"$(CONFFILE)\" $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\" | |
39 | 41 | |
40 | 42 | # If you want a static binary, you might uncomment these |
41 | 43 | # LDFLAGS = -static |
93 | 95 | $(INSTALL) -D -m 644 mdadm.conf.5 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5 |
94 | 96 | |
95 | 97 | clean : |
96 | rm -f mdadm $(OBJS) core *.man mdadm.tcc mdadm.uclibc mdadm.static | |
98 | rm -f mdadm $(OBJS) core *.man mdadm.tcc mdadm.uclibc mdadm.static *.orig *.porig *.rej | |
97 | 99 | |
98 | 100 | dist : clean |
99 | 101 | ./makedist |
176 | 176 | * in case |
177 | 177 | */ |
178 | 178 | for (j=0; j<array.nr_disks; j++) { |
179 | disc.number = j; | |
179 | 180 | if (ioctl(fd, GET_DISK_INFO, &disc)) |
180 | 181 | break; |
181 | 182 | if (disc.major==0 && disc.minor==0) |
44 | 44 | |
45 | 45 | int Monitor(mddev_dev_t devlist, |
46 | 46 | char *mailaddr, char *alert_cmd, |
47 | int period, int daemonise, int scan, | |
47 | int period, int daemonise, int scan, int oneshot, | |
48 | 48 | char *config) |
49 | 49 | { |
50 | 50 | /* |
175 | 175 | |
176 | 176 | |
177 | 177 | while (! finished) { |
178 | int new_found = 0; | |
178 | 179 | struct state *st; |
179 | 180 | |
180 | 181 | if (mdstat) |
240 | 241 | st->err = 0; |
241 | 242 | continue; |
242 | 243 | } |
244 | if (st->utime == 0 && /* new array */ | |
245 | mse && /* is in /proc/mdstat */ | |
246 | mse->pattern && strchr(mse->pattern, '_') /* degraded */ | |
247 | ) | |
248 | alert("DegradedArray", dev, NULL, mailaddr, alert_cmd); | |
249 | ||
243 | 250 | if (mse && |
244 | 251 | st->percent == -1 && |
245 | 252 | mse->percent >= 0) |
322 | 329 | st->spare_group = NULL; |
323 | 330 | statelist = st; |
324 | 331 | alert("NewArray", st->devname, NULL, mailaddr, alert_cmd); |
332 | new_found = 1; | |
325 | 333 | } |
326 | 334 | } |
327 | 335 | /* If an array has active < raid && spare == 0 && spare_group != NULL |
373 | 381 | close(fd2); |
374 | 382 | } |
375 | 383 | } |
376 | ||
377 | sleep(period); | |
384 | if (!new_found) { | |
385 | if (oneshot) | |
386 | break; | |
387 | else | |
388 | sleep(period); | |
389 | } | |
378 | 390 | } |
379 | 391 | return 0; |
380 | 392 | } |
400 | 412 | exit(2); |
401 | 413 | } |
402 | 414 | } |
403 | if (mailaddr && strncmp(event, "Fail", 4)==0) { | |
415 | if (mailaddr && | |
416 | (strncmp(event, "Fail", 4)==0 || | |
417 | strncmp(event, "Degrade", 7)==0)) { | |
404 | 418 | FILE *mp = popen(Sendmail, "w"); |
405 | 419 | if (mp) { |
406 | 420 | char hname[256]; |
28 | 28 | |
29 | 29 | #include "mdadm.h" |
30 | 30 | |
31 | char Version[] = Name " - v1.2.0 - 13 Mar 2003\n"; | |
31 | char Version[] = Name " - v1.3.0 - 29 Jul 2003\n"; | |
32 | 32 | /* |
33 | 33 | * File: ReadMe.c |
34 | 34 | * |
85 | 85 | * This mode never exits but just monitors arrays and reports changes. |
86 | 86 | */ |
87 | 87 | |
88 | char short_options[]="-ABCDEFGQhVvbc:l:p:m:n:x:u:c:d:z:U:sarfRSow"; | |
88 | char short_options[]="-ABCDEFGQhVvbc:l:p:m:n:x:u:c:d:z:U:sarfRSow1"; | |
89 | 89 | struct option long_options[] = { |
90 | 90 | {"manage", 0, 0, '@'}, |
91 | 91 | {"misc", 0, 0, '#'}, |
148 | 148 | {"delay", 1, 0, 'd'}, |
149 | 149 | {"daemonise", 0, 0, 'f'}, |
150 | 150 | {"daemonize", 0, 0, 'f'}, |
151 | ||
151 | {"oneshot", 0, 0, '1'}, | |
152 | 152 | |
153 | 153 | {0, 0, 0, 0} |
154 | 154 | }; |
247 | 247 | char Help_create[] = |
248 | 248 | "Usage: mdadm --create device -chunk=X --level=Y --raid-devices=Z devices\n" |
249 | 249 | "\n" |
250 | " This usage will initialise a new md array and associate some\n" | |
251 | " devices with it. If enough devices are given to complete the array,\n" | |
252 | " the array will be activated. Otherwise it will be left inactive\n" | |
253 | " to be completed and activated by subsequent management commands.\n" | |
254 | "\n" | |
255 | " As devices are added, they are checked to see if they already contain\n" | |
250 | " This usage will initialise a new md array, associate some\n" | |
251 | " devices with it, and activate the array. In order to create an\n" | |
252 | " array with some devices missing, use the special word 'missing' in\n" | |
253 | " place of the relevant device name.\n" | |
254 | "\n" | |
255 | " Before devices are added, they are checked to see if they already contain\n" | |
256 | 256 | " raid superblocks or filesystems. They are also checked to see if\n" |
257 | 257 | " the variance in device size exceeds 1%.\n" |
258 | " If any discrepancy is found, the array will not automatically\n" | |
259 | " be run, though the presence of a '--run' can override this\n" | |
258 | " If any discrepancy is found, the user will be prompted for confirmation\n" | |
259 | " before the array is created. The presence of a '--run' can override this\n" | |
260 | 260 | " caution.\n" |
261 | 261 | "\n" |
262 | 262 | " If the --size option is given then only that many kilobytes of each\n" |
269 | 269 | " --chunk= -c : chunk size of kibibytes\n" |
270 | 270 | " --rounding= : rounding factor for linear array (==chunk size)\n" |
271 | 271 | " --level= -l : raid level: 0,1,4,5,linear,multipath and synonyms\n" |
272 | " --parity= -p : raid5 parity algorithm: {left,right}-{,a}symmetric\n" | |
272 | " --parity= -p : raid5 parity algorithm: {left,right}-{,a}symmetric\n" | |
273 | 273 | " --layout= : same as --parity\n" |
274 | 274 | " --raid-devices= -n : number of active devices in array\n" |
275 | 275 | " --spare-devices= -x: number of spares (eXtras) devices in initial array\n" |
276 | 276 | " --size= -z : Size (in K) of each drive in RAID1/4/5 - optional\n" |
277 | 277 | " --force -f : Honour devices as listed on command line. Don't\n" |
278 | 278 | " : insert a missing drive for RAID5.\n" |
279 | " --run : insist of running the array even if not all\n" | |
279 | " --run -R : insist of running the array even if not all\n" | |
280 | 280 | " : devices are present or some look odd.\n" |
281 | " --readonly : start the array readonly - not supported yet.\n" | |
281 | " --readonly -o : start the array readonly - not supported yet.\n" | |
282 | 282 | "\n" |
283 | 283 | ; |
284 | 284 | |
406 | 406 | " --config= -c : specify a different config file\n" |
407 | 407 | " --scan -s : find mail-address/program in config file\n" |
408 | 408 | " --daemonise -f : Fork and continue in child, parent exits\n" |
409 | " --oneshot -1 : Check for degraded arrays, then exit\n" | |
409 | 410 | ; |
410 | 411 | |
411 | 412 |
0 | * mdadm --monitor to monitor failed multipath paths and re-instate them. | |
1 | ||
0 | 2 | * Maybe make "--help" fit in 80x24 and have a --long-help with more info. DONE |
1 | 3 | |
2 | 4 |
34 | 34 | exit 1 |
35 | 35 | fi |
36 | 36 | trap "rm $target/$base; exit" 1 2 3 |
37 | ( cd .. ; ln -s mdadm mdadm-$version ; tar chvf - --exclude="TAGS" --exclude='*,v' --exclude='*.o' --exclude mdadm --exclude=mdadm'.[^ch0-9]' --exclude=RCS mdadm-$version ; rm mdadm-$version ) | gzip --best > $target/$base | |
37 | ( cd .. ; ln -s mdadm mdadm-$version ; tar chvf - --exclude="TAGS" --exclude='*~' --exclude=.patches --exclude='*,v' --exclude='*.o' --exclude mdadm --exclude=mdadm'.[^ch0-9]' --exclude=RCS mdadm-$version ; rm mdadm-$version ) | gzip --best > $target/$base | |
38 | 38 | chmod a+r $target/$base |
39 | 39 | ls -l $target/$base |
40 | 40 |
112 | 112 | .SS RAID4 |
113 | 113 | |
114 | 114 | A RAID4 array is like a RAID0 array with an extra device for storing |
115 | parity. Unlike RAID0, RAID4 also requires that all stripes span all | |
115 | parity. This device is the last of the active devices in the | |
116 | array. Unlike RAID0, RAID4 also requires that all stripes span all | |
116 | 117 | drives, so extra space on devices that are larger than the smallest is |
117 | 118 | wasted. |
118 | 119 |
0 | 0 | .\" -*- nroff -*- |
1 | .TH MDADM 8 "" v1.2.0 | |
1 | .TH MDADM 8 "" v1.3.0 | |
2 | 2 | .SH NAME |
3 | 3 | mdadm \- manage MD devices |
4 | 4 | .I aka |
231 | 231 | |
232 | 232 | .TP |
233 | 233 | .BR -l ", " --level= |
234 | Set raid level. Options are: linear, raid0, 0, stripe, raid1, 1, mirror, raid5, 4, | |
234 | Set raid level. When used with | |
235 | .IR --create , | |
236 | options are: linear, raid0, 0, stripe, raid1, 1, mirror, raid5, 4, | |
235 | 237 | raid5, 5, multipath, mp. Obviously some of these are synonymous. |
236 | Only the first 4 are valid when Building. | |
238 | ||
239 | When used with | |
240 | .IR --build , | |
241 | only linear, raid0, 0, stripe are valid. | |
237 | 242 | |
238 | 243 | .TP |
239 | 244 | .BR -p ", " --parity= |
254 | 259 | number of spare devices (see below) must equal the number of |
255 | 260 | .I component-devices |
256 | 261 | (including "\fBmissing\fP" devices) |
257 | that are listed on the command line. | |
262 | that are listed on the command line. Setting a value of 1 is probably | |
263 | a mistake and so requires that | |
264 | .B --force | |
265 | be specified first. A value of 1 will then be allowed for linear, | |
266 | multipath, raid0 and raid1. It is never allowed for raid4 or raid5. | |
267 | .br | |
268 | Note that this number cannot be changed once the array has been created. | |
258 | 269 | |
259 | 270 | .TP |
260 | 271 | .BR -x ", " --spare-devices= |
427 | 438 | .B --scan |
428 | 439 | which will only continue monitoring if a mail address or alert program |
429 | 440 | is found in the config file. |
441 | ||
442 | .TP | |
443 | .BR -1 ", " --oneshot | |
444 | Check arrays only once. This will generate | |
445 | .B NewArray | |
446 | events and more significantly | |
447 | .B DegradedArray | |
448 | events. Running | |
449 | .in +5 | |
450 | .B " mdadm --monitor --scan -1" | |
451 | .in -5 | |
452 | from a cron script will ensure regular notification of any degraded arrays. | |
430 | 453 | |
431 | 454 | .SH ASSEMBLE MODE |
432 | 455 | |
773 | 796 | A new md array has been detected in the |
774 | 797 | .B /proc/mdstat |
775 | 798 | file. |
799 | ||
800 | .TP | |
801 | .B DegradedArray | |
802 | A newly noticed array appears to be degraded. This message is not | |
803 | generated when | |
804 | .I mdadm | |
805 | notices a drive failure which causes degradation, but only when | |
806 | .I mdadm | |
807 | notices that an array is degraded when it first sees the array. | |
776 | 808 | |
777 | 809 | .TP |
778 | 810 | .B MoveSpare |
82 | 82 | char *program = NULL; |
83 | 83 | int delay = 0; |
84 | 84 | int daemonise = 0; |
85 | int oneshot = 0; | |
85 | 86 | |
86 | 87 | int mdfd = -1; |
87 | 88 | |
319 | 320 | optarg); |
320 | 321 | exit(2); |
321 | 322 | } |
323 | if (raiddisks == 1 && !force) { | |
324 | fprintf(stderr, Name ": '1' is an unusual number of drives for an array, so it is probably\n" | |
325 | " a mistake. If you really mean it you will need to specify --force before\n" | |
326 | " setting the number of drives.\n"); | |
327 | exit(2); | |
328 | } | |
322 | 329 | ident.raid_disks = raiddisks; |
323 | 330 | continue; |
324 | 331 | |
340 | 347 | exit(2); |
341 | 348 | } |
342 | 349 | continue; |
350 | case O(BUILD,'f'): /* force honouring '-n 1' */ | |
343 | 351 | case O(CREATE,'f'): /* force honouring of device list */ |
344 | 352 | case O(ASSEMBLE,'f'): /* force assembly */ |
345 | 353 | case O(MISC,'f'): /* force zero */ |
440 | 448 | case O(MONITOR,'f'): /* daemonise */ |
441 | 449 | daemonise = 1; |
442 | 450 | continue; |
443 | ||
451 | case O(MONITOR,'1'): /* oneshot */ | |
452 | oneshot = 1; | |
453 | continue; | |
444 | 454 | |
445 | 455 | /* now the general management options. Some are applicable |
446 | 456 | * to other modes. None have arguments. |
716 | 726 | break; |
717 | 727 | } |
718 | 728 | rv= Monitor(devlist, mailaddr, program, |
719 | delay?delay:60, daemonise, scan, configfile); | |
729 | delay?delay:60, daemonise, scan, oneshot, configfile); | |
720 | 730 | break; |
721 | 731 | } |
722 | 732 | exit(rv); |
158 | 158 | |
159 | 159 | |
160 | 160 | extern int Create(char *mddev, int mdfd, |
161 | int chunk, int level, int layout, int size, int raiddisks, int sparedisks, | |
161 | int chunk, int level, int layout, unsigned long size, int raiddisks, int sparedisks, | |
162 | 162 | int subdevs, mddev_dev_t devlist, |
163 | 163 | int runstop, int verbose, int force); |
164 | 164 | |
167 | 167 | extern int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust); |
168 | 168 | extern int Monitor(mddev_dev_t devlist, |
169 | 169 | char *mailaddr, char *alert_cmd, |
170 | int period, int daemonise, int scan, | |
170 | int period, int daemonise, int scan, int oneshot, | |
171 | 171 | char *config); |
172 | 172 | |
173 | 173 | extern int Kill(char *dev, int force); |