Codebase list mdadm / 682c705
mdctl-v0.3 Neil Brown 22 years ago
13 changed file(s) with 814 addition(s) and 126 deletion(s). Raw diff Collapse all Expand all
106106 int most_recent = 0;
107107
108108 if (!mddev && !scan) {
109 fputs("mdctl: internal error - Assemble called with no devie or scan\n", stderr);
109 fputs(Name ": internal error - Assemble called with no devie or scan\n", stderr);
110110 return 1;
111111 }
112112 if (!mddev) {
114114 int found = 0;
115115 device_list = conf_get_uuids(conffile);
116116 if (!device_list) {
117 fprintf(stderr, "mdctl: No devices found in config file\n");
117 fprintf(stderr, Name ": No devices found in config file\n");
118118 return 1;
119119 }
120120 while (device_list) {
122122 mdfd = open(device_list->devname, O_RDONLY, 0);
123123 if (mdfd < 0) {
124124 fprintf(stderr,
125 "mdctl: error opening %s: %s\n",
125 Name ": error opening %s: %s\n",
126126 device_list->devname,
127127 strerror(errno));
128128 continue;
139139 }
140140 if (found)
141141 return 0;
142 fprintf(stderr,"mdctl: Did not successful Assemble any devices\n");
142 fprintf(stderr,Name ": Did not successful Assemble any devices\n");
143143 return 1;
144144 }
145145
148148 */
149149 vers = md_get_version(mdfd);
150150 if (vers <= 0) {
151 fprintf(stderr, "mdctl: %s appears not to be an md device.\n");
152 return 1;
153 }
154 if (vers < (90<<8)) {
155 fprintf(stderr, "mdctl: Assemble requires driver version 0.90.0 or later.\n"
151 fprintf(stderr, Name ": %s appears not to be an md device.\n");
152 return 1;
153 }
154 if (vers < 9000) {
155 fprintf(stderr, Name ": Assemble requires driver version 0.90.0 or later.\n"
156156 " Upgrade your kernel or try --Build\n");
157157 return 1;
158158 }
159 if (get_linux_version() < 0x020400)
159 if (get_linux_version() < 2004000)
160160 old_linux = 1;
161161
162162 if (ioctl(mdfd, GET_ARRAY_INFO, &array)>=0) {
163 fprintf(stderr, "mdctl: device %s already active - cannot assemble it\n",
163 fprintf(stderr, Name ": device %s already active - cannot assemble it\n",
164164 mddev);
165165 return 1;
166166 }
178178 device_list = device_list->next;
179179
180180 if (!device_list) {
181 fprintf(stderr, "mdctl: --scan set and no uuid found for %s in config file.\n",
181 fprintf(stderr, Name ": --scan set and no uuid found for %s in config file.\n",
182182 mddev);
183183 return 1;
184184 }
197197 devlist = conf_get_devs(conffile);
198198
199199 if (subdevs == 0 && devlist == NULL) {
200 fprintf(stderr, "mdctl: no devices given for %s\n", mddev);
200 fprintf(stderr, Name ": no devices given for %s\n", mddev);
201201 return 1;
202202 }
203203 /* now for each device */
224224 dfd = open(devname, O_RDONLY, 0);
225225 if (dfd < 0) {
226226 if (inargv || verbose)
227 fprintf(stderr, "mdctl: cannot open device %s: %s\n",
227 fprintf(stderr, Name ": cannot open device %s: %s\n",
228228 devname, strerror(errno));
229229 continue;
230230 }
231231 if (fstat(dfd, &stb)< 0) {
232232 /* Impossible! */
233 fprintf(stderr, "mdctl: fstat failed for %s: %s\n",
233 fprintf(stderr, Name ": fstat failed for %s: %s\n",
234234 devname, strerror(errno));
235235 close(dfd);
236236 continue;
237237 }
238238 if ((stb.st_mode & S_IFMT) != S_IFBLK) {
239 fprintf(stderr, "mdctl: %d is not a block device.\n",
239 fprintf(stderr, Name ": %d is not a block device.\n",
240240 devname);
241241 close(dfd);
242242 continue;
243243 }
244244 if (load_super(dfd, &super)) {
245245 if (inargv || verbose)
246 fprintf( stderr, "mdctl: no RAID superblock on %s\n",
246 fprintf( stderr, Name ": no RAID superblock on %s\n",
247247 devname);
248248 close(dfd);
249249 continue;
251251 close(dfd);
252252 if (compare_super(&first_super, &super)) {
253253 if (inargv || verbose)
254 fprintf(stderr, "mdctl: superblock on %s doesn't match\n",
254 fprintf(stderr, Name ": superblock on %s doesn't match\n",
255255 devname);
256256 continue;
257257 }
259259 uuid_from_super(this_uuid, &first_super);
260260 if (!same_uuid(this_uuid, uuid)) {
261261 if (inargv || verbose)
262 fprintf(stderr, "mdctl: %s has wrong uuid.\n",
262 fprintf(stderr, Name ": %s has wrong uuid.\n",
263263 devname);
264264 continue;
265265 }
270270
271271 /* Ok, this one is at least worth considering */
272272 if (devcnt >= MD_SB_DISKS) {
273 fprintf(stderr, "mdctl: ouch - too many devices appear to be in this array. Ignoring %s\n",
273 fprintf(stderr, Name ": ouch - too many devices appear to be in this array. Ignoring %s\n",
274274 devname);
275275 continue;
276276 }
294294 }
295295
296296 if (devcnt == 0) {
297 fprintf(stderr, "mdctl: no devices found for %s\n",
297 fprintf(stderr, Name ": no devices found for %s\n",
298298 mddev);
299299 return 1;
300300 }
316316 * not up-to-date, update the superblock
317317 * and add it.
318318 */
319 fprintf(stderr,"NoImplementedYet\n");
319 fprintf(stderr,"NotImplementedYet\n");
320320 /* FIXME */
321321 exit(2);
322322 }
323323 /* Almost ready to actually *do* something */
324324 if (!old_linux) {
325325 if (ioctl(mdfd, SET_ARRAY_INFO, NULL) != 0) {
326 fprintf(stderr, "mdctl: SET_ARRAY_INFO failed for %s: %s\n",
326 fprintf(stderr, Name ": SET_ARRAY_INFO failed for %s: %s\n",
327327 mddev, strerror(errno));
328328 return 1;
329329 }
336336 disk.major = devices[j].major;
337337 disk.minor = devices[j].minor;
338338 if (ioctl(mdfd, ADD_NEW_DISK, &disk)!=0) {
339 fprintf(stderr, "mdctl: failed to add %s to %s: %s\n",
339 fprintf(stderr, Name ": failed to add %s to %s: %s\n",
340340 devices[j].devname,
341341 mddev,
342342 strerror(errno));
343343 } else
344344 okcnt--;
345345 } else if (verbose)
346 fprintf(stderr, "mdctl: no uptodate device for slot %d of %s\n",
346 fprintf(stderr, Name ": no uptodate device for slot %d of %s\n",
347347 i, mddev);
348348 }
349349 if (runstop == 1 ||
351351 enough(first_super.level, first_super.raid_disks, okcnt))) {
352352 if (ioctl(mdfd, RUN_ARRAY, NULL)==0)
353353 return 0;
354 fprintf(stderr, "mdctl: failed to RUN_ARRAY %s: %s\n",
354 fprintf(stderr, Name ": failed to RUN_ARRAY %s: %s\n",
355355 mddev, strerror(errno));
356356 return 1;
357357 }
2727 */
2828
2929 #include "mdctl.h"
30 #include "md_u.h"
31 #include "md_p.h"
3032
3133 int Create(char *mddev, int mdfd,
32 int chunk, int level, int layout, int raiddisks, int sparedisks,
34 int chunk, int level, int layout, int size, int raiddisks, int sparedisks,
3335 int subdevs, char *subdev[],
34 int runstop)
36 int runstop, int verbose)
3537 {
38 /*
39 * Create a new raid array.
40 *
41 * First check that necessary details are available
42 * (i.e. level, raid-disks)
43 *
44 * Then check each disk to see what might be on it
45 * and report anything interesting.
46 *
47 * If anything looks odd, and runstop not set,
48 * abort.
49 *
50 * SET_ARRAY_INFO and ADD_NEW_DISK, and
51 * if runstop==run, or raiddisks diskswere used,
52 * RUN_ARRAY
53 */
54 int minsize, maxsize;
55 int maxdisc= -1, mindisc = -1;
56 int i;
57 int fail=0, warn=0;
58
59 mdu_array_info_t array;
60 mdu_param_t param;
61
62
63 if (md_get_version(mdfd) < 9000) {
64 fprintf(stderr, Name ": Create requires md driver verison 0.90.0 or later\n");
65 return 1;
66 }
67 if (level == -10) {
68 fprintf(stderr,
69 Name ": a RAID level is needed to create an array.\n");
70 return 1;
71 }
72 if (raiddisks < 1) {
73 fprintf(stderr,
74 Name ": a number of --raid-disks must be given to create an array\n");
75 return 1;
76 }
77 if (raiddisks+sparedisks > MD_SB_DISKS) {
78 fprintf(stderr,
79 Name ": too many discs requested: %d+%d > %d\n",
80 raiddisks, sparedisks, MD_SB_DISKS);
81 return 1;
82 }
83 if (subdevs > raiddisks+sparedisks) {
84 fprintf(stderr, Name ": You have listed more disks (%d) than are in the array(%d)!\n", subdevs, raiddisks+sparedisks);
85 return 1;
86 }
87 /* now set some defaults */
88 if (layout == -1)
89 switch(level) {
90 default: /* no layout */
91 layout = 0;
92 break;
93 case 5:
94 layout = map_name(r5layout, "default");
95 if (verbose)
96 fprintf(stderr,
97 Name ": layout defaults to %s\n", map_num(r5layout, layout));
98 break;
99 }
100
101 if (chunk == 0) {
102 chunk = 64;
103 if (verbose)
104 fprintf(stderr, Name ": chunk size defaults to 64K\n");
105 }
106
107 /* now look at the subdevs */
108 for (i=0; i<subdevs; i++) {
109 char *dname = subdev[i];
110 int dsize, freesize;
111 int fd = open(dname, O_RDONLY, 0);
112 if (fd <0 ) {
113 fprintf(stderr, Name ": Cannot open %s: %s\n",
114 dname, strerror(errno));
115 fail=1;
116 continue;
117 }
118 if (ioctl(fd, BLKGETSIZE, &dsize)) {
119 fprintf(stderr, Name ": Cannot get size of %s: %s\n",
120 dname, strerror(errno));
121 fail = 1;
122 close(fd);
123 continue;
124 }
125 if (dsize < MD_RESERVED_SECTORS*2) {
126 fprintf(stderr, Name ": %s is too small: %dK\n",
127 dname, dsize/2);
128 fail = 1;
129 close(fd);
130 continue;
131 }
132 freesize = MD_NEW_SIZE_SECTORS(dsize);
133 freesize /= 2;
134
135 if (size && freesize < size) {
136 fprintf(stderr, Name ": %s is smaller that given size."
137 " %dK < %dK + superblock\n", dname, freesize, size);
138 fail = 1;
139 close(fd);
140 continue;
141 }
142 if (maxdisc< 0 || (maxdisc>=0 && freesize > maxsize)) {
143 maxdisc = i;
144 maxsize = freesize;
145 }
146 if (mindisc < 0 || (mindisc >=0 && freesize < minsize)) {
147 mindisc = i;
148 minsize = freesize;
149 }
150 warn |= check_ext2(fd, dname);
151 warn |= check_reiser(fd, dname);
152 warn |= check_raid(fd, dname);
153 close(fd);
154 }
155 if (fail) {
156 fprintf(stderr, Name ": create aborted\n");
157 return 1;
158 }
159 if (size == 0) {
160 if (mindisc == -1) {
161 fprintf(stderr, Name ": no size and no drives given - aborting create.\n");
162 return 1;
163 }
164 size = minsize;
165 if (verbose)
166 fprintf(stderr, Name ": size set to %dK\n", size);
167 }
168 if ((maxsize-size)*100 > maxsize) {
169 fprintf(stderr, Name ": largest drive (%s) exceed size (%dK) by more than 1%\n",
170 subdev[maxdisc], size);
171 warn = 1;
172 }
173
174 if (warn) {
175 if (runstop!= 1) {
176 if (!ask("Continue creating array? ")) {
177 fprintf(stderr, Name ": create aborted.\n");
178 return 1;
179 }
180 } else {
181 if (verbose)
182 fprintf(stderr, Name ": creation continuing despite oddities due to --run\n");
183 }
184 }
185
186 /* Ok, lets try some ioctls */
187
188 array.level = level;
189 array.size = size;
190 array.nr_disks = raiddisks+sparedisks;
191 array.raid_disks = raiddisks;
192 array.md_minor = 0;
193 array.not_persistent = 0;
194 array.state = 0; /* not clean, but no errors */
195 array.active_disks=0;
196 array.working_disks=0;
197 array.spare_disks=0;
198 array.failed_disks=0;
199 array.layout = layout;
200 array.chunk_size = chunk*1024;
201
202 if (ioctl(mdfd, SET_ARRAY_INFO, &array)) {
203 fprintf(stderr, Name ": SET_ARRAY_INFO failed for %s: %s\n",
204 mddev, strerror(errno));
205 return 1;
206 }
207
208 for (i=0; i<subdevs; i++) {
209 int fd = open(subdev[i], O_RDONLY, 0);
210 struct stat stb;
211 mdu_disk_info_t disk;
212 if (fd < 0) {
213 fprintf(stderr, Name ": failed to open %s after earlier success - aborting\n",
214 subdev[i]);
215 return 1;
216 }
217 fstat(fd, &stb);
218 disk.number = i;
219 disk.raid_disk = i;
220 disk.state = 6; /* active and in sync */
221 disk.major = MAJOR(stb.st_rdev);
222 disk.minor = MINOR(stb.st_rdev);
223 close(fd);
224 if (ioctl(mdfd, ADD_NEW_DISK, &disk)) {
225 fprintf(stderr, Name ": ADD_NEW_DISK for %s failed: %s\b",
226 subdev[i], strerror(errno));
227 return 1;
228 }
229 }
230
231 /* param is not actually used */
232 if (runstop == 1 || subdevs >= raiddisks) {
233 if (ioctl(mdfd, RUN_ARRAY, &param)) {
234 fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",
235 strerror(errno));
236 return 1;
237 }
238 fprintf(stderr, Name ": array %s started.\n", mddev);
239 } else {
240 fprintf(stderr, Name ": not starting array - not enough discs.\n");
241 }
242 return 0;
36243 }
4242 mdu_array_info_t array;
4343 int d;
4444 time_t atime;
45 char *c;
4546
4647 if (fd < 0) {
47 fprintf(stderr, "mdctl: cannot open %s: %s\n",
48 fprintf(stderr, Name ": cannot open %s: %s\n",
4849 dev, strerror(errno));
4950 return 1;
5051 }
5152 vers = md_get_version(fd);
5253 if (vers < 0) {
53 fprintf(stderr, "mdctl: %s does not appear to be an md device\n",
54 fprintf(stderr, Name ": %s does not appear to be an md device\n",
5455 dev);
5556 close(fd);
5657 return 1;
5758 }
58 if (vers < (90<<8)) {
59 fprintf(stderr, "mdctl: cannot get detail for md device %s: driver version too old.\n",
59 if (vers < 9000) {
60 fprintf(stderr, Name ": cannot get detail for md device %s: driver version too old.\n",
6061 dev);
6162 close(fd);
6263 return 1;
6364 }
6465 if (ioctl(fd, GET_ARRAY_INFO, &array)<0) {
6566 if (errno == ENODEV)
66 fprintf(stderr, "mdctl: md device %s does not appear to be active.\n",
67 fprintf(stderr, Name ": md device %s does not appear to be active.\n",
6768 dev);
6869 else
69 fprintf(stderr, "mdctl: cannot get array detail for %s: %s\n",
70 fprintf(stderr, Name ": cannot get array detail for %s: %s\n",
7071 dev, strerror(errno));
7172 close(fd);
7273 return 1;
7778 array.major_version, array.minor_version, array.patch_version);
7879 atime = array.ctime;
7980 printf(" Creation Time : %.24s\n", ctime(&atime));
80 printf(" Raid Level : %d\n", array.level);
81 c = map_num(pers, array.level);
82 printf(" Raid Level : %s\n", c?c:"-unknown-");
8183 printf(" Size : %d\n", array.size);
8284 printf(" Raid Disks : %d\n", array.raid_disks);
8385 printf(" Total Disks : %d\n", array.nr_disks);
9597 printf(" Failed Drives : %d\n", array.failed_disks);
9698 printf(" Spare Drives : %d\n", array.spare_disks);
9799 printf("\n");
98 printf(" Layout : %d\n", array.layout);
100 if (array.level == 5) {
101 c = map_num(r5layout, array.layout);
102 printf(" Layout : %s\n", c?c:"-unknown-");
103 }
99104 printf(" Chunk Size : %dK\n", array.chunk_size/1024);
100105 printf("\n");
101106 printf(" Number Major Minor RaidDisk State\n");
103108 mdu_disk_info_t disk;
104109 disk.number = d;
105110 if (ioctl(fd, GET_DISK_INFO, &disk) < 0) {
106 fprintf(stderr, "mdctl: cannot get disk detail for disk %d: %s\n",
111 fprintf(stderr, Name ": cannot get disk detail for disk %d: %s\n",
107112 d, strerror(errno));
108113 continue;
109114 }
5050 time_t atime;
5151 mdp_super_t super;
5252 int d;
53 char *c;
5354 int rv;
5455
5556 if (fd < 0) {
56 fprintf(stderr,"mdctl: cannot open %s: %s\n",
57 fprintf(stderr,Name ": cannot open %s: %s\n",
5758 dev, strerror(errno));
5859 return 1;
5960 }
6263 close(fd);
6364 switch(rv) {
6465 case 1:
65 fprintf(stderr, "mdctl: cannot find device size for %s: %s\n",
66 fprintf(stderr, Name ": cannot find device size for %s: %s\n",
6667 dev, strerror(errno));
6768 return 1;
6869 case 2:
69 /* fprintf(stderr, "mdctl: %s is too small for md: size is %ld sectors\n",
70 /* fprintf(stderr, Name ": %s is too small for md: size is %ld sectors\n",
7071 dev, size);
7172 */
72 fprintf(stderr, "mdctl: %s is too small for md\n",
73 fprintf(stderr, Name ": %s is too small for md\n",
7374 dev);
7475 return 1;
7576 case 3:
76 fprintf(stderr, "mdctl: Cannot seek to superblock on %s: %s\n",
77 fprintf(stderr, Name ": Cannot seek to superblock on %s: %s\n",
7778 dev, strerror(errno));
7879 return 1;
7980 case 4:
80 fprintf(stderr, "mdctl: Cannot read superblock on %s\n",
81 fprintf(stderr, Name ": Cannot read superblock on %s\n",
8182 dev);
8283 return 1;
8384 case 5:
84 fprintf(stderr, "mdctl: No super block found on %s (Expected magic %08x, got %08x)\n",
85 fprintf(stderr, Name ": No super block found on %s (Expected magic %08x, got %08x)\n",
8586 dev, MD_SB_MAGIC, super.md_magic);
8687 return 1;
8788 case 6:
88 fprintf(stderr, "mdctl: Cannot interpret superblock on %s - version is %d\n",
89 fprintf(stderr, Name ": Cannot interpret superblock on %s - version is %d\n",
8990 dev, super.major_version);
9091 return 1;
9192 }
103104
104105 atime = super.ctime;
105106 printf(" Creation Time : %.24s\n", ctime(&atime));
106 printf(" Raid Level : %d\n", super.level);
107 c=map_num(pers, super.level);
108 printf(" Raid Level : %s\n", c?c:"-unknown-");
107109 printf(" Size : %d\n", super.size);
108110 printf(" Raid Disks : %d\n", super.raid_disks);
109111 printf(" Total Disks : %d\n", super.nr_disks);
121123 printf(" - checksum not checked yet - \n");
122124 printf(" Events : %d.%d\n", super.events_hi, super.events_lo);
123125 printf("\n");
124 printf(" Layout : %d\n", super.layout);
126 if (super.level == 5) {
127 c = map_num(r5layout, super.layout);
128 printf(" Layout : %s\n", c?c:"-unknown-");
129 }
125130 printf(" Chunk Size : %dK\n", super.chunk_size/1024);
126131 printf("\n");
127132 printf(" Number Major Minor RaidDisk State\n");
4141
4242 dist : clean
4343 ./makedist
44
45 TAGS :
46 etags *.h *.c
2727 */
2828
2929 #include "mdctl.h"
30 #include "md_u.h"
31 #include "md_p.h"
3032
3133 int Manage_ro(char *devname, int fd, int readonly)
3234 {
35 /* switch to readonly or rw
36 *
37 * requires >= 0.90.0
38 * first check that array is runing
39 * use RESTART_ARRAY_RW or STOP_ARRAY_RO
40 *
41 */
42 mdu_array_info_t array;
43
44 if (md_get_version(fd) < 9000) {
45 fprintf(stderr, Name ": need md driver version 0.90.0 or later\n");
46 return 1;
47 }
48 if (ioctl(fd, GET_ARRAY_INFO, &array)) {
49 fprintf(stderr, Name ": %s does not appear to be active.\n",
50 devname);
51 return 1;
52 }
53
54 if (readonly>0) {
55 if (ioctl(fd, STOP_ARRAY_RO, NULL)) {
56 fprintf(stderr, Name ": failed to set readonly for %s: %s\n",
57 devname, strerror(errno));
58 return 1;
59 }
60 } else if (readonly < 0) {
61 if (ioctl(fd, RESTART_ARRAY_RW, NULL)) {
62 fprintf(stderr, Name ": fail to re writable for %s: %s\n",
63 devname, strerror(errno));
64 return 1;
65 }
66 }
67 return 0;
3368 }
3469
3570 int Manage_runstop(char *devname, int fd, int runstop)
3671 {
72 /* Run or stop the array. array must already be configured
73 * required >= 0.90.0
74 */
75 mdu_array_info_t array;
76 mdu_param_t param; /* unused */
77
78 if (md_get_version(fd) < 9000) {
79 fprintf(stderr, Name ": need md driver version 0.90.0 or later\n");
80 return 1;
81 }
82 if (ioctl(fd, GET_ARRAY_INFO, &array)) {
83 fprintf(stderr, Name ": %s does not appear to be active.\n",
84 devname);
85 return 1;
86 }
87
88 if (runstop>0) {
89 if (ioctl(fd, RUN_ARRAY, &param)) {
90 fprintf(stderr, Name ": failed to run array %s: %s\n",
91 devname, strerror(errno));
92 return 1;
93 }
94 } else if (runstop < 0){
95 if (ioctl(fd, STOP_ARRAY, NULL)) {
96 fprintf(stderr, Name ": fail to re writable for %s: %s\n",
97 devname, strerror(errno));
98 return 1;
99 }
100 }
101 return 0;
37102 }
38103
39104 int Manage_subdevs(char *devname, int fd,
40105 int devcnt, char *devnames[], int devmodes[])
41 {
106 {
107 /* do something to each dev.
108 * devmode can be
109 * 'a' - add the device
110 * try HOT_ADD_DISK
111 * If that fails EINVAL, try ADD_NEW_DISK
112 * 'r' - remove the device HOT_REMOVE_DISK
113 * 'f' - set the device faulty SET_DISK_FAULTY
114 */
115 mdu_array_info_t array;
116 mdu_disk_info_t disc;
117 struct stat stb;
118 int i,j;
119
120 if (ioctl(fd, GET_ARRAY_INFO, &array)) {
121 fprintf(stderr, Name ": cannot get array info for %s\n",
122 devname);
123 return 1;
124 }
125 for (i=0 ; i<devcnt; i++) {
126 if (stat(devnames[i], &stb)) {
127 fprintf(stderr, Name ": cannot find %s: %s\n",
128 devnames[i], strerror(errno));
129 return 1;
130 }
131 if ((stb.st_mode & S_IFMT) != S_IFBLK) {
132 fprintf(stderr, Name ": %s is not a block device.\n",
133 devnames[i]);
134 return 1;
135 }
136 switch(devmodes[i]){
137 default:
138 fprintf(stderr, Name ": internal error - devmode[%d]=%d\n",
139 i, devmodes[i]);
140 return 1;
141 case 'a':
142 /* add the device - hot or cold */
143 if (ioctl(fd, HOT_ADD_DISK, stb.st_rdev)==0) {
144 fprintf(stderr, Name ": hot added %s\n",
145 devnames[i]);
146 continue;
147 }
148 /* try ADD_NEW_DISK.
149 * we might be creating, we might be assembling,
150 * it is hard to tell.
151 * set up number/raid_disk/state just
152 * in case
153 */
154 for (j=0; j<array.nr_disks; j++) {
155 if (ioctl(fd, GET_DISK_INFO, &disc))
156 break;
157 if (disc.major==0 && disc.minor==0)
158 break;
159 if (disc.state & 8) /* removed */
160 break;
161 }
162 disc.number =j;
163 disc.raid_disk = j;
164 disc.state = 0;
165 disc.major = MAJOR(stb.st_rdev);
166 disc.minor = MINOR(stb.st_rdev);
167 if (ioctl(fd,ADD_NEW_DISK, &disc)) {
168 fprintf(stderr, Name ": add new disk failed for %s: %s\n",
169 devnames[i], strerror(errno));
170 return 1;
171 }
172 fprintf(stderr, Name ": added %s\n", devnames[i]);
173 break;
174
175 case 'r':
176 /* hot remove */
177 /* FIXME check that is is a current member */
178 if (ioctl(fd, HOT_REMOVE_DISK, stb.st_rdev)) {
179 fprintf(stderr, Name ": hot remove failed for %s: %s\n",
180 devnames[i], strerror(errno));
181 return 1;
182 }
183 fprintf(stderr, Name ": hot removed %s\n", devnames[i]);
184 break;
185
186 case 'f': /* set faulty */
187 /* FIXME check current member */
188 if (ioctl(fd, SET_DISK_FAULTY, stb.st_rdev)) {
189 fprintf(stderr, Name ": set disk faulty failed for %s: %s\n",
190 devnames[i], strerror(errno));
191 return 1;
192 }
193 fprintf(stderr, Name ": set %s faulty in %s\n",
194 devnames[i], devname);
195 break;
196 }
197 }
198 return 0;
199
42200 }
2828
2929 #include "mdctl.h"
3030
31 char Version[] = "mdctl - v0.2 - 06 June 2001\n";
31 char Version[] = Name " - v0.3 - 14 June 2001\n";
3232 /*
3333 * File: ReadMe.c
3434 *
7777 * command, subsequent Manage commands can finish the job.
7878 */
7979
80 char short_options[]="-ABCDEhVvc:l:p:n:x:u:c:sarfRSow";
80 char short_options[]="-ABCDEhVvc:l:p:n:x:u:c:z:sarfRSow";
8181 struct option long_options[] = {
8282 {"manage", 0, 0, '@'},
8383 {"assemble", 0, 0, 'A'},
9898 {"layout", 1, 0, 'p'},
9999 {"raid-disks",1, 0, 'n'},
100100 {"spare-disks",1,0, 'x'},
101 {"size" ,1, 0, 'z'},
101102
102103 /* For assemble */
103104 {"uuid", 1, 0, 'u'},
156157 " --layout= : same as --parity\n"
157158 " --raid-disks= -n : number of active devices in array\n"
158159 " --spare-disks= -x : number of spares (eXtras) to allow space for\n"
160 " --size= -z : Size (in K) of each drive in RAID1/4/5 - optional\n"
159161 "\n"
160162 " For assemble:\n"
161163 " --uuid= -u : uuid of array to assemble. Devices which don't\n"
191193 " be run, though the presence of a '--run' can override this\n"
192194 " caution.\n"
193195 "\n"
196 " If the --size option is given, it is not necessary to list any subdevices\n"
197 " in this command. They can be added later, before a --run.\n"
198 " If no --size is given, the apparent size of the smallest drive given\n"
199 " is used.\n"
200 "\n"
194201 " The General management options that are valid with --create are:\n"
195202 " --run : insist of running the array even if not all devices\n"
196203 " are present or some look odd.\n"
243250 " not yet documented\n"
244251 "\n"
245252 ;
253
254
255 /* name/number mappings */
256
257 mapping_t r5layout[] = {
258 { "left_asymmetric", 0},
259 { "right_asymmetric", 1},
260 { "left_symmetric", 2},
261 { "right_symmetric", 3},
262
263 { "default", 2},
264 { "la", 0},
265 { "ra", 1},
266 { "ls", 2},
267 { "rs", 3},
268 { NULL, 0}
269 };
270
271 mapping_t pers[] = {
272 { "linear", -1},
273 { "raid0", 0},
274 { "0", 0},
275 { "stripe", 0},
276 { "raid1", 1},
277 { "1", 1},
278 { "mirror", 1},
279 { "raid4", 4},
280 { "4", 4},
281 { "raid5", 5},
282 { "5", 5},
283 { NULL, 0}
284 };
+140
-0
TAGS less more
0
1 md_p.h,1316
2 #define _MD_P_H16,582
3 #define MD_RESERVED_BYTES 44,1414
4 #define MD_RESERVED_SECTORS 45,1453
5 #define MD_RESERVED_BLOCKS 46,1508
6 #define MD_NEW_SIZE_SECTORS(MD_NEW_SIZE_SECTORS48,1570
7 #define MD_NEW_SIZE_BLOCKS(MD_NEW_SIZE_BLOCKS49,1659
8 #define MD_SB_BYTES 51,1746
9 #define MD_SB_WORDS 52,1773
10 #define MD_SB_BLOCKS 53,1813
11 #define MD_SB_SECTORS 54,1863
12 #define MD_SB_GENERIC_OFFSET 59,1960
13 #define MD_SB_PERSONALITY_OFFSET 60,1992
14 #define MD_SB_DISKS_OFFSET 61,2028
15 #define MD_SB_DESCRIPTOR_OFFSET 62,2060
16 #define MD_SB_GENERIC_CONSTANT_WORDS 64,2098
17 #define MD_SB_GENERIC_STATE_WORDS 65,2138
18 #define MD_SB_GENERIC_WORDS 66,2175
19 #define MD_SB_PERSONALITY_WORDS 67,2263
20 #define MD_SB_DESCRIPTOR_WORDS 68,2299
21 #define MD_SB_DISKS 69,2334
22 #define MD_SB_DISKS_WORDS 70,2359
23 #define MD_SB_RESERVED_WORDS 71,2423
24 #define MD_SB_EQUAL_WORDS 72,2553
25 #define MD_DISK_FAULTY 77,2691
26 #define MD_DISK_ACTIVE 78,2752
27 #define MD_DISK_SYNC 79,2814
28 #define MD_DISK_REMOVED 80,2878
29 typedef struct mdp_device_descriptor_s mdp_device_descriptor_s82,2946
30 } mdp_disk_t;mdp_disk_t89,3310
31 #define MD_SB_MAGIC 91,3325
32 #define MD_SB_CLEAN 96,3390
33 #define MD_SB_ERRORS 97,3413
34 typedef struct mdp_superblock_s mdp_superblock_s99,3438
35 } mdp_super_t;mdp_super_t164,5820
36 static inline __u64 md_event(166,5836
37
38 md_u.h,1118
39 #define _MD_U_H16,590
40 #define RAID_VERSION 21,634
41 #define GET_ARRAY_INFO 22,693
42 #define GET_DISK_INFO 23,757
43 #define PRINT_RAID_DEBUG 24,819
44 #define RAID_AUTORUN 25,865
45 #define CLEAR_ARRAY 28,929
46 #define ADD_NEW_DISK 29,971
47 #define HOT_REMOVE_DISK 30,1032
48 #define SET_ARRAY_INFO 31,1078
49 #define SET_DISK_INFO 32,1142
50 #define WRITE_RAID_INFO 33,1186
51 #define UNPROTECT_ARRAY 34,1232
52 #define PROTECT_ARRAY 35,1278
53 #define HOT_ADD_DISK 36,1322
54 #define SET_DISK_FAULTY 37,1365
55 #define RUN_ARRAY 40,1424
56 #define START_ARRAY 41,1478
57 #define STOP_ARRAY 42,1520
58 #define STOP_ARRAY_RO 43,1561
59 #define RESTART_ARRAY_RW 44,1605
60 typedef struct mdu_version_s mdu_version_s46,1652
61 } mdu_version_t;mdu_version_t50,1724
62 typedef struct mdu_array_info_s mdu_array_info_s52,1742
63 } mdu_array_info_t;mdu_array_info_t83,2516
64 typedef struct mdu_disk_info_s mdu_disk_info_s85,2537
65 } mdu_disk_info_t;mdu_disk_info_t95,2693
66 typedef struct mdu_start_info_s mdu_start_info_s97,2713
67 } mdu_start_info_t;mdu_start_info_t106,2857
68 typedef struct mdu_param_smdu_param_s108,2878
69 } mdu_param_t;mdu_param_t113,3014
70
71 mdctl.h,823
72 #define __USE_LARGEFILE6430,1115
73 #define MD_MAJOR 47,1491
74 extern char short_options[52,1531
75 extern struct option long_options[53,1560
76 extern char Version[54,1597
77 extern char Version[], Usage[54,1597
78 extern char Version[], Usage[], Help[54,1597
79 extern char Version[], Usage[], Help[], Help_create[54,1597
80 extern char Version[], Usage[], Help[], Help_create[], Help_build[54,1597
81 extern char Version[], Usage[], Help[], Help_create[], Help_build[], Help_assemble[54,1597
82 typedef struct mddev_uuid_s mddev_uuid_s58,1762
83 } *mddev_uuid_t;mddev_uuid_t62,1852
84 typedef struct mddev_dev_s mddev_dev_s65,1918
85 } *mddev_dev_t;mddev_dev_t68,1990
86 #define ALGORITHM_LEFT_ASYMMETRIC 73,2044
87 #define ALGORITHM_RIGHT_ASYMMETRIC 74,2080
88 #define ALGORITHM_LEFT_SYMMETRIC 75,2117
89 #define ALGORITHM_RIGHT_SYMMETRIC 76,2152
90
91 Assemble.c,22
92 int Assemble(34,1171
93
94 Build.c,19
95 int Build(32,1135
96
97 Create.c,20
98 int Create(32,1135
99
100 Detail.c,20
101 int Detail(34,1171
102
103 Examine.c,21
104 int Examine(34,1171
105
106 Manage.c,79
107 int Manage_ro(32,1135
108 int Manage_runstop(36,1191
109 int Manage_subdevs(40,1251
110
111 ReadMe.c,231
112 #define Name 32,1135
113 char Version[33,1156
114 char short_options[82,3241
115 struct option long_options[83,3297
116 char Usage[122,4441
117 char Help[127,4498
118 char Help_create[181,6989
119 char Help_build[203,7973
120 char Help_assemble[216,8513
121
122 config.c,102
123 char DefaultConfFile[43,1371
124 mddev_uuid_t conf_get_uuids(45,1416
125 mddev_dev_t conf_get_devs(50,1482
126
127 mdctl.c,40
128 int main(33,1153
129 #define O(O131,3313
130
131 util.c,212
132 int parse_uuid(40,1354
133 int md_get_version(80,2091
134 int get_linux_version(99,2448
135 int enough(111,2639
136 int same_uuid(127,2889
137 void uuid_from_super(137,3018
138 int compare_super(151,3295
139 int load_super(185,4258
00
11 - check superblock checksum in examine
22 - report "chunk" or "rounding" depending on raid level
3 - report "linear" instead of "-1" for raid level
4 - decode ayout depending on raid level
3 - report "linear" instead of "-1" for raid level DONE
4 - decode ayout depending on raid level DONE
55 - get Assemble to upgrade devices if force flag.
6 - --verbose and --force flags.
6 - --verbose and --force flags.
7
8 - set md_minor, *_disks for Create
9 - for create raid5, how to choose between
10 all working, but not insync
11 one missing, one spare, insync
66 exit 2
77 fi
88 set `grep '^char Version' ReadMe.c `
9 echo version = $6
10 base=mdctl-$6.tgz
9 echo version = $7
10 base=mdctl-$7.tgz
1111 if [ -f $target/$base ]
1212 then
1313 echo $target/$base exists.
1616 trap "rm $target/$base; exit" 1 2 3
1717 ( cd .. ; tar czvf - mdctl ) > $target/$base
1818 chmod a+r $target/$base
19 ls -l $target/$base
19 ls -l $target/$base
3939 int i;
4040
4141 int chunk = 0;
42 int size = 0;
4243 int level = -10;
4344 int layout = -1;
4445 int raiddisks = 0;
7273 case 'E':
7374 /* setting mode - only once */
7475 if (mode) {
75 fprintf(stderr, "mdctl: --%s/-%c not allowed, mode already set to %s\n",
76 fprintf(stderr, Name ": --%s/-%c not allowed, mode already set to %s\n",
7677 long_options[opt-'A'+1].name,
7778 long_options[opt-'A'+1].val,
7879 long_options[mode-'A'+1].name);
106107 mddev = optarg;
107108 else {
108109 if (subdevs +1 >= MD_SB_DISKS) {
109 fprintf(stderr, "mdctl: too many devices at %s - current limit -s %d\n",
110 fprintf(stderr, Name ": too many devices at %s - current limit -s %d\n",
110111 optarg, MD_SB_DISKS);
111112 exit(2);
112113 }
132133 case O('C','c'):
133134 case O('B','c'): /* chunk or rounding */
134135 if (chunk) {
135 fprintf(stderr, "mdctl: chunk/rounding may only be specified once. "
136 fprintf(stderr, Name ": chunk/rounding may only be specified once. "
136137 "Second value is %s.\n", optarg);
137138 exit(2);
138139 }
139140 chunk = strtol(optarg, &c, 10);
140 if (!optarg[0] || *c) {
141 fprintf(stderr, "mdctl: invalid chunk/rounding value: %s\n",
142 optarg);
143 exit(2);
144 }
145 continue;
141 if (!optarg[0] || *c || chunk<4 || ((chunk-1)&chunk)) {
142 fprintf(stderr, Name ": invalid chunk/rounding value: %s\n",
143 optarg);
144 exit(2);
145 }
146 continue;
147
148 case O('c','z'): /* size */
149 if (size) {
150 fprintf(stderr, Name ": size may only be specified once. "
151 "Second value is %s.\n", optarg);
152 exit(2);
153 }
154 size = strtol(optarg, &c, 10);
155 if (!optarg[0] || *c || size < 4) {
156 fprintf(stderr, Name ": invalid size: %s\n",
157 optarg);
158 exit(2);
159 }
160 continue;
146161
147162 case O('C','l'):
148163 case O('B','l'): /* set raid level*/
149164 if (level != -10) {
150 fprintf(stderr, "mdctl: raid level may only be set once. "
165 fprintf(stderr, Name ": raid level may only be set once. "
151166 "Second value is %s.\n", optarg);
152167 exit(2);
153168 }
154 if (strcmp(optarg,"linear")==0)
155 level = -1;
156 else if (strlen(optarg)==1 && strchr("01245", optarg[0]))
157 level = optarg[0]-'0';
158 else {
159 fprintf(stderr, "mdctl: invalid raid level: %s\n",
169 level = map_name(pers, optarg);
170 if (level == -10) {
171 fprintf(stderr, Name ": invalid raid level: %s\n",
160172 optarg);
161173 exit(2);
162174 }
163175 if (level > 0 && mode == 'B') {
164 fprintf(stderr, "mdctl: Raid level %s not permitted with --build.\n",
165 optarg);
166 exit(2);
167 }
168 if (layout >=0 && level < 4) {
169 fprintf(stderr, "mdctl: raid level %s is incompatible with layout setting\n",
176 fprintf(stderr, Name ": Raid level %s not permitted with --build.\n",
170177 optarg);
171178 exit(2);
172179 }
173180 if (sparedisks > 0 && level < 1) {
174 fprintf(stderr, "mdctl: raid level %s is incompatible with spare-disks setting.\n",
181 fprintf(stderr, Name ": raid level %s is incompatible with spare-disks setting.\n",
175182 optarg);
176183 exit(2);
177184 }
179186
180187 case O('C','p'): /* raid5 layout */
181188 if (layout >= 0) {
182 fprintf(stderr,"mdctl: layout may only be sent once. "
189 fprintf(stderr,Name ": layout may only be sent once. "
183190 "Second value was %s\n", optarg);
184191 exit(2);
185192 }
186 if (level > -10 && level < 4) {
187 fprintf(stderr,"mdctl: layout is incompatible with raid levels below 4.\n");
188 exit(2);
189 }
190 if (strcmp(optarg, "left-symmetric")==0 || strcmp(optarg,"ls")==0)
191 layout = ALGORITHM_LEFT_SYMMETRIC;
192 else if (strcmp(optarg, "left-asymmetric")==0 || strcmp(optarg,"la")==0)
193 layout = ALGORITHM_LEFT_ASYMMETRIC;
194 else if (strcmp(optarg, "right-symmetric")==0 || strcmp(optarg,"rs")==0)
195 layout = ALGORITHM_RIGHT_SYMMETRIC;
196 else if (strcmp(optarg, "right-asymmetric")==0 || strcmp(optarg,"ra")==0)
197 layout = ALGORITHM_RIGHT_ASYMMETRIC;
198 else {
199 fprintf(stderr,"mdctl: %s is not a valid layout value\n",
200 optarg);
201 exit(2);
193 switch(level) {
194 default:
195 fprintf(stderr, Name ": layout now meaningful for %s arrays.\n",
196 map_num(pers, level));
197 exit(2);
198 case -10:
199 fprintf(stderr, Name ": raid level must be given before layout.\n");
200 exit(2);
201
202 case 5:
203 layout = map_name(r5layout, optarg);
204 if (layout==-10) {
205 fprintf(stderr, Name ": layout %s not understood for raid5.\n",
206 optarg);
207 exit(2);
208 }
209 break;
202210 }
203211 continue;
204212
205213 case O('C','n'):
206214 case O('B','n'): /* number of raid disks */
207215 if (raiddisks) {
208 fprintf(stderr, "mdctl: raid-disks set twice: %d and %s\n",
216 fprintf(stderr, Name ": raid-disks set twice: %d and %s\n",
209217 raiddisks, optarg);
210218 exit(2);
211219 }
212220 raiddisks = strtol(optarg, &c, 10);
213221 if (!optarg[0] || *c || raiddisks<=0 || raiddisks > MD_SB_DISKS) {
214 fprintf(stderr, "mdctl: invalid number of raid disks: %s\n",
222 fprintf(stderr, Name ": invalid number of raid disks: %s\n",
215223 optarg);
216224 exit(2);
217225 }
219227
220228 case O('C','x'): /* number of spare (eXtra) discs */
221229 if (sparedisks) {
222 fprintf(stderr,"mdctl: spare-disks set twice: %d and %s\n",
230 fprintf(stderr,Name ": spare-disks set twice: %d and %s\n",
223231 sparedisks, optarg);
224232 exit(2);
225233 }
226234 if (level > -10 && level < 1) {
227 fprintf(stderr, "mdctl: spare-disks setting is incompatible with raid level %d\n",
235 fprintf(stderr, Name ": spare-disks setting is incompatible with raid level %d\n",
228236 level);
229237 exit(2);
230238 }
231239 sparedisks = strtol(optarg, &c, 10);
232240 if (!optarg[0] || *c || sparedisks < 0 || sparedisks > MD_SB_DISKS - raiddisks) {
233 fprintf(stderr, "mdctl: invalid number of spare disks: %s\n",
241 fprintf(stderr, Name ": invalid number of spare disks: %s\n",
234242 optarg);
235243 exit(2);
236244 }
242250 continue;
243251 case O('A','u'): /* uuid of array */
244252 if (uuidset) {
245 fprintf(stderr, "mdctl: uuid cannot bet set twice. "
253 fprintf(stderr, Name ": uuid cannot bet set twice. "
246254 "Second value %s.\n", optarg);
247255 exit(2);
248256 }
249257 if (parse_uuid(optarg, uuid))
250258 uuidset = 1;
251259 else {
252 fprintf(stderr,"mdctl: Bad uuid: %s\n", optarg);
260 fprintf(stderr,Name ": Bad uuid: %s\n", optarg);
253261 exit(2);
254262 }
255263 continue;
256264
257265 case O('A','c'): /* config file */
258266 if (configfile) {
259 fprintf(stderr, "mdctl: configfile cannot be set twice. "
267 fprintf(stderr, Name ": configfile cannot be set twice. "
260268 "Second value is %s.\n", optarg);
261269 exit(2);
262270 }
288296 case O('B','R'):
289297 case O('C','R'): /* Run the array */
290298 if (runstop < 0) {
291 fprintf(stderr, "mdctl: Cannot both Stop and Run an array\n");
299 fprintf(stderr, Name ": Cannot both Stop and Run an array\n");
292300 exit(2);
293301 }
294302 runstop = 1;
295303 continue;
296304 case O('@','S'):
297305 if (runstop > 0) {
298 fprintf(stderr, "mdctl: Cannot both Run and Stop an array\n");
306 fprintf(stderr, Name ": Cannot both Run and Stop an array\n");
299307 exit(2);
300308 }
301309 runstop = -1;
303311
304312 case O('@','o'):
305313 if (readonly < 0) {
306 fprintf(stderr, "mdctl: Cannot have both readonly and readwrite\n");
314 fprintf(stderr, Name ": Cannot have both readonly and readwrite\n");
307315 exit(2);
308316 }
309317 readonly = 1;
319327 /* We have now processed all the valid options. Anything else is
320328 * an error
321329 */
322 fprintf(stderr, "mdctl: option %c not valid in mode %c\n",
330 fprintf(stderr, Name ": option %c not valid in mode %c\n",
323331 opt, mode);
324332 exit(2);
325333
340348 */
341349 if (mode !='D' && mode !='E' && ! (mode =='A' && scan)) {
342350 if (!mddev) {
343 fprintf(stderr, "mdctl: an md device must be given in this mode\n");
351 fprintf(stderr, Name ": an md device must be given in this mode\n");
344352 exit(2);
345353 }
346354 mdfd = open(mddev, O_RDWR, 0);
347355 if (mdfd < 0) {
348 fprintf(stderr,"mdctl: error opening %s: %s\n",
356 fprintf(stderr,Name ": error opening %s: %s\n",
349357 mddev, strerror(errno));
350358 exit(1);
351359 }
352360 if (md_get_version(mdfd) <= 0) {
353 fprintf(stderr, "mdctl: %s does not appear to be an md device\n",
361 fprintf(stderr, Name ": %s does not appear to be an md device\n",
354362 mddev);
355363 close(mdfd);
356364 exit(1);
377385 rv = Build(mddev, mdfd, chunk, level, raiddisks, subdevs,subdev);
378386 break;
379387 case 'C': /* Create */
380 rv = Create(mddev, mdfd, chunk, level, layout, raiddisks, sparedisks,
381 subdevs,subdev,runstop);
388 rv = Create(mddev, mdfd, chunk, level, layout, size, raiddisks, sparedisks,
389 subdevs,subdev,runstop, verbose);
382390 break;
383391 case 'D': /* Detail */
384392 for (i=0; i<subdevs; i++)
4848
4949 #include "md_u.h"
5050
51 #define Name "mdctl"
52
5153 extern char short_options[];
5254 extern struct option long_options[];
5355 extern char Version[], Usage[], Help[], Help_create[], Help_build[], Help_assemble[];
6668 struct mddev_dev_s *next;
6769 } *mddev_dev_t;
6870
69 /*
70 * RAID5 supported algorithms
71 */
72 #define ALGORITHM_LEFT_ASYMMETRIC 0
73 #define ALGORITHM_RIGHT_ASYMMETRIC 1
74 #define ALGORITHM_LEFT_SYMMETRIC 2
75 #define ALGORITHM_RIGHT_SYMMETRIC 3
71 typedef struct mapping {
72 char *name;
73 int num;
74 } mapping_t;
75
76 extern char *map_num(mapping_t *map, int num);
77 extern int map_name(mapping_t *map, char *name);
78 extern mapping_t r5layout[], pers[];
79
7680
7781
7882 extern int Manage_ro(char *devname, int fd, int readonly);
9498
9599
96100 extern int Create(char *mddev, int mdfd,
97 int chunk, int level, int layout, int raiddisks, int sparedisks,
101 int chunk, int level, int layout, int size, int raiddisks, int sparedisks,
98102 int subdevs, char *subdev[],
99 int runstop);
103 int runstop, int verbose);
100104
101105 extern int Detail(char *dev);
102106 extern int Examine(char *dev);
104108 extern int md_get_version(int fd);
105109 extern int get_linux_version();
106110 extern int parse_uuid(char *str, int uuid[4]);
111 extern int check_ext2(int fd, char *name);
112 extern int check_reiser(int fd, char *name);
113 extern int check_raid(int fd, char *name);
107114
108115 extern mddev_uuid_t conf_get_uuids(char *);
109116 extern mddev_dev_t conf_get_devs(char *);
8787 return -1;
8888
8989 if (ioctl(fd, RAID_VERSION, &vers) == 0)
90 return (vers.major<<16) | (vers.minor<<8) | vers.patchlevel;
90 return (vers.major*10000) + (vers.minor*100) + vers.patchlevel;
9191
9292 if (MAJOR(stb.st_rdev) == MD_MAJOR)
93 return (36<<8);
93 return (3600);
9494 return -1;
9595 }
9696
104104
105105 if (sscanf(name.release, "%d.%d.%d", &a,&b,&c)!= 3)
106106 return -1;
107 return (a<<16)+(b<<8)+c;
107 return (a*1000000)+(b*1000)+c;
108108 }
109109
110110 int enough(int level, int raid_disks, int avail_disks)
210210 if (lseek64(fd, offset, 0)< 0LL)
211211 return 3;
212212
213 if (read(fd, &super, sizeof(super)) != sizeof(super))
213 if (read(fd, super, sizeof(*super)) != sizeof(*super))
214214 return 4;
215215
216216 if (super->md_magic != MD_SB_MAGIC)
221221 return 0;
222222 }
223223
224
225 int check_ext2(int fd, char *name)
226 {
227 /*
228 * Check for an ext2fs file system.
229 * Superblock is always 1K at 1K offset
230 *
231 * s_magic is le16 at 56 == 0xEF53
232 * report mtime - le32 at 44
233 * blocks - le32 at 4
234 * logblksize - le32 at 24
235 */
236 unsigned char sb[1024];
237 time_t mtime;
238 int size, bsize;
239 if (lseek(fd, 1024,0)!= 1024)
240 return 0;
241 if (read(fd, sb, 1024)!= 1024)
242 return 0;
243 if (sb[56] != 0x53 || sb[57] != 0xef)
244 return 0;
245
246 mtime = sb[44]|(sb[45]|(sb[46]|sb[47]<<8)<<8)<<8;
247 bsize = sb[24]|(sb[25]|(sb[26]|sb[27]<<8)<<8)<<8;
248 size = sb[4]|(sb[5]|(sb[6]|sb[7]<<8)<<8)<<8;
249 fprintf(stderr, Name ": %s appears to contain an ext2fs file system\n",
250 name);
251 fprintf(stderr," size=%dK mtime=%s",
252 size*(1<<bsize), ctime(&mtime));
253 return 1;
254 }
255
256 int check_reiser(int fd, char *name)
257 {
258 /*
259 * superblock is at 64K
260 * size is 1024;
261 * Magic string "ReIsErFs" or "ReIsEr2Fs" at 52
262 *
263 */
264 unsigned char sb[1024];
265 int size;
266 if (lseek(fd, 64*1024, 0) != 64*1024)
267 return 0;
268 if (read(fd, sb, 1024) != 1024)
269 return 0;
270 if (strncmp(sb+52, "ReIsErFs",8)!=0 &&
271 strncmp(sb+52, "ReIsEr2Fs",9)!=0)
272 return 0;
273 fprintf(stderr, Name ": %s appears to contain a reiserfs file system\n",name);
274 size = sb[0]|(sb[1]|(sb[2]|sb[3]<<8)<<8)<<8;
275 fprintf(stderr, " size = %dK\n", size*4);
276
277 return 1;
278 }
279
280 int check_raid(int fd, char *name)
281 {
282 mdp_super_t super;
283 time_t crtime;
284 if (load_super(fd, &super))
285 return 0;
286 /* Looks like a raid array .. */
287 fprintf(stderr, Name ": %s appear to be part of a raid array:\n",
288 name);
289 crtime = super.ctime;
290 fprintf(stderr, " level=%d disks=%d ctime=%s",
291 super.level, super.raid_disks, ctime(&crtime));
292 return 1;
293 }
294
295
296 int ask(char *mesg)
297 {
298 char *add = "";
299 int i;
300 for (i=0; i<5; i++) {
301 char buf[100];
302 fprintf(stderr, "%s%s", mesg, add);
303 fflush(stderr);
304 if (fgets(buf, 100, stdin)==NULL)
305 return 0;
306 if (buf[0]=='y' || buf[0]=='Y')
307 return 1;
308 if (buf[0]=='n' || buf[0]=='N')
309 return 0;
310 add = "(y/n) ";
311 }
312 fprintf(stderr, Name ": assuming 'no'\n");
313 return 0;
314 }
315
316 char *map_num(mapping_t *map, int num)
317 {
318 while (map->name) {
319 if (map->num == num)
320 return map->name;
321 map++;
322 }
323 return NULL;
324 }
325
326 int map_name(mapping_t *map, char *name)
327 {
328 while (map->name) {
329 if (strcmp(map->name, name)==0)
330 return map->num;
331 map++;
332 }
333 return -10;
334 }