mdadm-1.2.0
Neil Brown
21 years ago
0 | Subject: ANNOUNCE: mdadm 1.2.0 - A tool for managing Soft RAID under Linux | |
1 | ||
2 | ||
3 | I am pleased to announce the availability of | |
4 | mdadm version 1.2.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.2.0 is a bug-fix release over 1.1.0. | |
17 | ||
18 | - Fix bug where --daemonise required an argument. | |
19 | - In --assemble --verbose, print appropriate message if device is | |
20 | not in devices= list | |
21 | - Updated mdadm.conf.5 to reflect fact that device= takes wildcards | |
22 | - Typos: componenet -> component | |
23 | - Reduce size of "--help" message put excess into "--help-options" | |
24 | - Fix bug introduced when MD_SB_DISKS dependancy removed, and which | |
25 | caused spares not be assembled properly. | |
26 | - Print appropriate message if --monitor --scan decides not to | |
27 | monitor anything. | |
28 | ||
29 | ||
30 | Development of mdadm is sponsored by CSE@UNSW: | |
31 | The School of Computer Science and Engineering | |
32 | at | |
33 | The University of New South Wales | |
34 | ||
35 | NeilBrown 13/03/03 |
105 | 105 | int state; |
106 | 106 | int raid_disk; |
107 | 107 | } *devices; |
108 | int *best; /* indexed by raid_disk */ | |
108 | int *best = NULL; /* indexed by raid_disk */ | |
109 | int bestcnt = 0; | |
109 | 110 | int devcnt = 0, okcnt, sparecnt; |
110 | 111 | int i; |
111 | 112 | int most_recent = 0; |
183 | 184 | devlist = devlist->next; |
184 | 185 | |
185 | 186 | if (ident->devices && |
186 | !match_oneof(ident->devices, devname)) | |
187 | continue; | |
187 | !match_oneof(ident->devices, devname)) { | |
188 | if (inargv || verbose) | |
189 | fprintf(stderr, Name ": %s is not one of %s\n", devname, ident->devices); | |
190 | continue; | |
191 | } | |
188 | 192 | |
189 | 193 | dfd = open(devname, O_RDONLY, 0); |
190 | 194 | if (dfd < 0) { |
321 | 325 | i = devcnt; |
322 | 326 | else |
323 | 327 | i = devices[devcnt].raid_disk; |
324 | if (i>=0 && i < num_devs) | |
328 | if (i>=0 && i < 10000) { | |
329 | if (i >= bestcnt) { | |
330 | int newbestcnt = i+10; | |
331 | int *newbest = malloc(sizeof(int)*newbestcnt); | |
332 | int c; | |
333 | for (c=0; c < newbestcnt; c++) | |
334 | if (c < bestcnt) | |
335 | newbest[c] = best[c]; | |
336 | else | |
337 | newbest[c] = -1; | |
338 | if (best)free(best); | |
339 | best = newbest; | |
340 | bestcnt = newbestcnt; | |
341 | } | |
325 | 342 | if (best[i] == -1 |
326 | 343 | || devices[best[i]].events < devices[devcnt].events) |
327 | 344 | best[i] = devcnt; |
328 | ||
345 | } | |
329 | 346 | devcnt++; |
330 | 347 | } |
331 | 348 | |
339 | 356 | */ |
340 | 357 | okcnt = 0; |
341 | 358 | sparecnt=0; |
342 | for (i=0; i< num_devs ;i++) { | |
359 | for (i=0; i< bestcnt ;i++) { | |
343 | 360 | int j = best[i]; |
344 | 361 | int event_margin = !force; |
345 | 362 | if (j < 0) continue; |
365 | 382 | */ |
366 | 383 | int fd; |
367 | 384 | chosen_drive = -1; |
368 | for (i=0; i<first_super.raid_disks; i++) { | |
385 | for (i=0; i<first_super.raid_disks && i < bestcnt; i++) { | |
369 | 386 | int j = best[i]; |
370 | 387 | if (j>=0 && |
371 | 388 | !devices[j].uptodate && |
421 | 438 | * superblock. |
422 | 439 | */ |
423 | 440 | chosen_drive = -1; |
424 | for (i=0; chosen_drive < 0 && i<num_devs; i++) { | |
441 | for (i=0; chosen_drive < 0 && i<bestcnt; i++) { | |
425 | 442 | int j = best[i]; |
426 | 443 | int fd; |
427 | 444 | if (j<0) |
443 | 460 | close(fd); |
444 | 461 | } |
445 | 462 | |
446 | for (i=0; i<num_devs; i++) { | |
463 | for (i=0; i<bestcnt; i++) { | |
447 | 464 | int j = best[i]; |
448 | 465 | int desired_state; |
449 | 466 | |
525 | 542 | return 1; |
526 | 543 | } |
527 | 544 | /* First, add the raid disks, but add the chosen one last */ |
528 | for (i=0; i<= num_devs; i++) { | |
545 | for (i=0; i<= bestcnt; i++) { | |
529 | 546 | int j; |
530 | if (i < num_devs) { | |
547 | if (i < bestcnt) { | |
531 | 548 | j = best[i]; |
532 | 549 | if (j == chosen_drive) |
533 | 550 | continue; |
534 | 551 | } else |
535 | 552 | j = chosen_drive; |
536 | 553 | |
537 | if (j >= 0 && devices[j].uptodate) { | |
554 | if (j >= 0 /* && devices[j].uptodate */) { | |
538 | 555 | mdu_disk_info_t disk; |
539 | 556 | memset(&disk, 0, sizeof(disk)); |
540 | 557 | disk.major = devices[j].major; |
0 | Changes Prior to 1.2.0 release | |
1 | - Fix bug where --daemonise required an argument. | |
2 | - In --assemble --verbose, print appropriate message if device is | |
3 | not in devices= list | |
4 | - Updated mdadm.conf.5 to reflect fact that device= takes wildcards | |
5 | - Typos: componenet -> component | |
6 | - Reduce size of "--help" message put excess into "--help-options" | |
7 | - Fix bug introduced when MD_SB_DISKS dependancy removed, and which | |
8 | caused spares not be assembled properly. | |
9 | - Print appropriate message if --monitor --scan decides not to | |
10 | monitor anything. | |
0 | 11 | Changes Prior to 1.1.0 release |
1 | 12 | - add --deamonise flag for --monitor - forks and prints pid to stdout |
2 | 13 | - Fix bug so we REALLY clear dirty flag with -Af |
107 | 107 | if (!mailaddr) { |
108 | 108 | mailaddr = conf_get_mailaddr(config); |
109 | 109 | if (mailaddr && ! scan) |
110 | printf("mdadm: Monitor using email address \"%s\" from config file\n", | |
110 | fprintf(stderr, Name ": Monitor using email address \"%s\" from config file\n", | |
111 | 111 | mailaddr); |
112 | 112 | } |
113 | 113 | if (!alert_cmd) { |
114 | 114 | alert_cmd = conf_get_program(config); |
115 | 115 | if (alert_cmd && ! scan) |
116 | printf("mdadm: Monitor using program \"%s\" from config file\n", | |
116 | fprintf(stderr, Name ": Monitor using program \"%s\" from config file\n", | |
117 | 117 | alert_cmd); |
118 | 118 | } |
119 | if (scan && !mailaddr && !alert_cmd) | |
119 | if (scan && !mailaddr && !alert_cmd) { | |
120 | fprintf(stderr, Name ": No mail address or alert command - not monitoring.\n"); | |
120 | 121 | return 1; |
122 | } | |
121 | 123 | |
122 | 124 | if (daemonise) { |
123 | 125 | int pid = fork(); |
414 | 416 | fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev); |
415 | 417 | |
416 | 418 | if (disc) |
417 | fprintf(mp, "It could be related to componenet device %s.\n\n", disc); | |
419 | fprintf(mp, "It could be related to component device %s.\n\n", disc); | |
418 | 420 | |
419 | 421 | fprintf(mp, "Faithfully yours, etc.\n"); |
420 | 422 | fclose(mp); |
100 | 100 | dev, strerror(superrno)); |
101 | 101 | break; |
102 | 102 | case 2: |
103 | printf("%s: is too small to be an md componenet.\n", | |
103 | printf("%s: is too small to be an md component.\n", | |
104 | 104 | dev); |
105 | 105 | break; |
106 | 106 | case 3: |
28 | 28 | |
29 | 29 | #include "mdadm.h" |
30 | 30 | |
31 | char Version[] = Name " - v1.1.0 - 3 Mar 2003\n"; | |
31 | char Version[] = Name " - v1.2.0 - 13 Mar 2003\n"; | |
32 | 32 | /* |
33 | 33 | * File: ReadMe.c |
34 | 34 | * |
104 | 104 | |
105 | 105 | /* after those will normally come the name of the md device */ |
106 | 106 | {"help", 0, 0, 'h'}, |
107 | {"help-options",0,0,'h'}, | |
107 | 108 | {"version", 0, 0, 'V'}, |
108 | 109 | {"verbose", 0, 0, 'v'}, |
109 | 110 | |
145 | 146 | {"program", 1, 0, 'p'}, |
146 | 147 | {"alert", 1, 0, 'p'}, |
147 | 148 | {"delay", 1, 0, 'd'}, |
148 | {"daemonise", 1, 0, 'f'}, | |
149 | {"daemonize", 1, 0, 'f'}, | |
149 | {"daemonise", 0, 0, 'f'}, | |
150 | {"daemonize", 0, 0, 'f'}, | |
150 | 151 | |
151 | 152 | |
152 | 153 | {0, 0, 0, 0} |
166 | 167 | " mdadm --monitor options...\n" |
167 | 168 | " mdadm device options...\n" |
168 | 169 | " mdadm is used for building, managing, and monitoring\n" |
169 | " Linux md devices (aka RAID arrays)\n" | |
170 | " For detail help on the above major modes use --help after the mode\n" | |
170 | " Linux md devices (aka RAID arrays)\n" | |
171 | " For detailed help on the above major modes use --help after the mode\n" | |
171 | 172 | " e.g.\n" |
172 | 173 | " mdadm --assemble --help\n" |
173 | "\n" | |
174 | " For general help on options use\n" | |
175 | " mdadm --help-options\n" | |
176 | ; | |
177 | ||
178 | char OptionHelp[] = | |
174 | 179 | "Any parameter that does not start with '-' is treated as a device name\n" |
175 | 180 | "The first such name is often the name of an md device. Subsequent\n" |
176 | 181 | "names are often names of component devices." |
177 | 182 | "\n" |
178 | 183 | "Some common options are:\n" |
179 | " --help -h : This help message or, after above option,\n" | |
184 | " --help -h : General help message or, after above option,\n" | |
180 | 185 | " mode specific help message\n" |
186 | " --help-options : This help message\n" | |
181 | 187 | " --version -V : Print version information for mdadm\n" |
182 | 188 | " --verbose -v : Be more verbose about what is happening\n" |
183 | 189 | " --brief -b : Be less verbose, more brief\n" |
0 | * Maybe make "--help" fit in 80x24 and have a --long-help with more info. DONE | |
1 | ||
2 | ||
0 | 3 | * maybe "missing" instead of <bold>missing</> in doco DONE |
1 | 4 | * possibly wait for resync to start, or even finish while assembling.- NO |
2 | 5 | |
89 | 92 | |
90 | 93 | - mdadm -S /dev/md0 /dev/md1 gives internal error FIXED |
91 | 94 | |
92 | - mdadm --detail --scan print summary of what it can find? | |
95 | - mdadm --detail --scan print summary of what it can find? DONE | |
93 | 96 | |
94 | 97 | |
95 | 98 | --------- |
0 | 0 | #!/bin/sh |
1 | ||
2 | target=${1-~/public_html/source/mdadm} | |
1 | arg=$1 | |
2 | target=~/public_html/source/mdadm | |
3 | 3 | if [ -d $target ] |
4 | 4 | then : |
5 | 5 | else echo $target is not a directory |
7 | 7 | fi |
8 | 8 | set `grep '^char Version' ReadMe.c ` |
9 | 9 | version=`echo $7 | sed 's/v//'` |
10 | grep "^.TH MDADM 8 .. v$version" mdadm.8 > /dev/null 2>&1 || | |
11 | { | |
12 | echo mdadm.8 does not mention verion $version. | |
13 | exit 1 | |
14 | } | |
10 | 15 | grep "^Version: *$version$" mdadm.spec > /dev/null 2>&1 || |
11 | 16 | { |
12 | 17 | echo mdadm.spec does not mention version $version. |
13 | 18 | exit 1 |
14 | 19 | } |
20 | if [ -f ANNOUNCE-$version ] | |
21 | then : | |
22 | else | |
23 | echo ANNONCE-$version does not exist | |
24 | exit 1 | |
25 | fi | |
26 | ||
15 | 27 | echo version = $version |
16 | 28 | base=mdadm-$version.tgz |
17 | if [ -f $target/$base ] | |
18 | then | |
19 | echo $target/$base exists. | |
20 | exit 1 | |
29 | if [ " $arg" != " diff" ] | |
30 | then | |
31 | if [ -f $target/$base ] | |
32 | then | |
33 | echo $target/$base exists. | |
34 | exit 1 | |
35 | fi | |
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 | |
38 | chmod a+r $target/$base | |
39 | ls -l $target/$base | |
40 | ||
41 | rpm -ta $target/$base | |
42 | find /home/neilb/src/RPM -name "*mdadm-$version-*" \ | |
43 | -exec cp {} $target/RPM \; | |
44 | cp ANNOUNCE-$version $target/ANNOUNCE | |
45 | cp ChangeLog $target/ChangeLog | |
46 | scp $target/$base master.kernel.org:/pub/linux/utils/raid/mdadm/mdadm-$version.tar.gz | |
47 | scp $target/ANNOUNCE $target/ChangeLog master.kernel.org:/pub/linux/utils/raid/mdadm/ | |
48 | else | |
49 | if [ ! -f $target/$base ] | |
50 | then | |
51 | echo $target/$base does not exist. | |
52 | exit 1 | |
53 | fi | |
54 | ( cd .. ; ln -s mdadm mdadm-$version ; tar chf - --exclude="TAGS" --exclude='*,v' --exclude='*.o' --exclude mdadm --exclude=mdadm'.[^ch0-9]' --exclude=RCS mdadm-$version ; rm mdadm-$version ) | gzip --best > /var/tmp/mdadm-new.tgz | |
55 | mkdir /var/tmp/mdadm-old ; zcat $target/$base | ( cd /var/tmp/mdadm-old ; tar xf - ) | |
56 | mkdir /var/tmp/mdadm-new ; zcat /var/tmp/mdadm-new.tgz | ( cd /var/tmp/mdadm-new ; tar xf - ) | |
57 | diff -ru /var/tmp/mdadm-old /var/tmp/mdadm-new | |
58 | rm -rf /var/tmp/mdadm-old /var/tmp/mdadm-new /var/tmp/mdadm-new.tgz | |
21 | 59 | fi |
22 | trap "rm $target/$base; exit" 1 2 3 | |
23 | ( 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 | |
24 | chmod a+r $target/$base | |
25 | ls -l $target/$base | |
26 | ||
27 | rpm -ta $target/$base | |
28 | find /home/neilb/src/RPM -name "*mdadm-$version-*" \ | |
29 | -exec cp {} $target/RPM \; |
0 | 0 | .\" -*- nroff -*- |
1 | .TH MDADM 8 "" v1.1.0 | |
1 | .TH MDADM 8 "" v1.2.0 | |
2 | 2 | .SH NAME |
3 | 3 | mdadm \- manage MD devices |
4 | 4 | .I aka |
152 | 152 | |
153 | 153 | .TP |
154 | 154 | .BR -h ", " --help |
155 | Display help message or, after above option, mode specific help message. | |
155 | Display help message or, after above option, mode specific help | |
156 | message. | |
157 | ||
158 | .TP | |
159 | .B --help-options | |
160 | Display more detailed help about command line parsing and some commonly | |
161 | used options. | |
156 | 162 | |
157 | 163 | .TP |
158 | 164 | .BR -V ", " --version |
100 | 100 | switch(opt) { |
101 | 101 | case 'h': |
102 | 102 | help_text = Help; |
103 | switch (mode) { | |
104 | case ASSEMBLE : help_text = Help_assemble; break; | |
105 | case BUILD : help_text = Help_build; break; | |
106 | case CREATE : help_text = Help_create; break; | |
107 | case MANAGE : help_text = Help_manage; break; | |
108 | case MISC : help_text = Help_misc; break; | |
109 | case MONITOR : help_text = Help_monitor; break; | |
110 | } | |
103 | if (option_index > 0 && | |
104 | strcmp(long_options[option_index].name, "help-options")==0) | |
105 | help_text = OptionHelp; | |
106 | else | |
107 | switch (mode) { | |
108 | case ASSEMBLE : help_text = Help_assemble; break; | |
109 | case BUILD : help_text = Help_build; break; | |
110 | case CREATE : help_text = Help_create; break; | |
111 | case MANAGE : help_text = Help_manage; break; | |
112 | case MISC : help_text = Help_misc; break; | |
113 | case MONITOR : help_text = Help_monitor; break; | |
114 | } | |
111 | 115 | fputs(help_text,stderr); |
112 | 116 | exit(0); |
113 | 117 |
95 | 95 | created as /dev/mdX, then the minor number X is stored. |
96 | 96 | .TP |
97 | 97 | .B devices= |
98 | The value is a comma separated list of device names. Precisely these | |
99 | devices will be used to assemble the array. Note that the devices | |
98 | The value is a comma separated list of device names or device name | |
99 | patterns. | |
100 | Only devices with names which match one entry in the list will be used | |
101 | to assemble the array. Note that the devices | |
100 | 102 | listed there must also be listed on a DEVICE line. |
101 | 103 | .TP |
102 | 104 | .B level= |
68 | 68 | |
69 | 69 | extern char short_options[]; |
70 | 70 | extern struct option long_options[]; |
71 | extern char Version[], Usage[], Help[], | |
71 | extern char Version[], Usage[], Help[], OptionHelp[], | |
72 | 72 | Help_create[], Help_build[], Help_assemble[], |
73 | 73 | Help_manage[], Help_misc[], Help_monitor[], Help_config[]; |
74 | 74 |