Use O_EXCL when opening component devices to be assembled into an array
[thirdparty/mdadm.git] / Create.c
1 /*
2  * mdadm - manage Linux "md" devices aka RAID arrays.
3  *
4  * Copyright (C) 2001-2002 Neil Brown <neilb@cse.unsw.edu.au>
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@cse.unsw.edu.au>
23  *    Paper: Neil Brown
24  *           School of Computer Science and Engineering
25  *           The University of New South Wales
26  *           Sydney, 2052
27  *           Australia
28  */
29
30 #include "mdadm.h"
31 #include        "md_u.h"
32 #include        "md_p.h"
33
34 int Create(char *mddev, int mdfd,
35            int chunk, int level, int layout, unsigned long size, int raiddisks, int sparedisks,
36            int subdevs, mddev_dev_t devlist,
37            int runstop, int verbose, int force)
38 {
39         /*
40          * Create a new raid array.
41          *
42          * First check that necessary details are available
43          * (i.e. level, raid-disks)
44          *
45          * Then check each disk to see what might be on it
46          * and report anything interesting.
47          *
48          * If anything looks odd, and runstop not set,
49          * abort.
50          *
51          * SET_ARRAY_INFO and ADD_NEW_DISK, and
52          * if runstop==run, or raiddisks diskswere used,
53          * RUN_ARRAY
54          */
55         unsigned long long minsize=0, maxsize=0;
56         char *mindisc = NULL;
57         char *maxdisc = NULL;
58         int dnum;
59         mddev_dev_t dv;
60         int fail=0, warn=0;
61         struct stat stb;
62         int first_missing = MD_SB_DISKS*2;
63         int missing_disks = 0;
64         int insert_point = MD_SB_DISKS*2; /* where to insert a missing drive */
65         mddev_dev_t moved_disk = NULL; /* the disk that was moved out of the insert point */
66
67         mdu_array_info_t array;
68         
69
70         if (md_get_version(mdfd) < 9000) {
71                 fprintf(stderr, Name ": Create requires md driver version 0.90.0 or later\n");
72                 return 1;
73         }
74         if (level == UnSet) {
75                 fprintf(stderr,
76                         Name ": a RAID level is needed to create an array.\n");
77                 return 1;
78         }
79         if (raiddisks < 1) {
80                 fprintf(stderr,
81                         Name ": a number of --raid-devices must be given to create an array\n");
82                 return 1;
83         }
84         if (raiddisks < 4 && level == 6) {
85                 fprintf(stderr,
86                         Name ": at least 4 raid-devices needed for level 6\n");
87                 return 1;
88         }
89         if (raiddisks > 256 && level == 6) {
90                 fprintf(stderr,
91                         Name ": no more than 256 raid-devices supported for level 6\n");
92                 return 1;
93         }
94         if (raiddisks < 2 && level >= 4) {
95                 fprintf(stderr,
96                         Name ": at least 2 raid-devices needed for level 4 or 5\n");
97                 return 1;
98         }
99         if (raiddisks+sparedisks > MD_SB_DISKS) {
100                 fprintf(stderr,
101                         Name ": too many devices requested: %d+%d > %d\n",
102                         raiddisks, sparedisks, MD_SB_DISKS);
103                 return 1;
104         }
105         if (subdevs > raiddisks+sparedisks) {
106                 fprintf(stderr, Name ": You have listed more devices (%d) than are in the array(%d)!\n", subdevs, raiddisks+sparedisks);
107                 return 1;
108         }
109         if (subdevs < raiddisks+sparedisks) {
110                 fprintf(stderr, Name ": You haven't given enough devices (real or missing) to create this array\n");
111                 return 1;
112         }
113
114         /* now set some defaults */
115         if (layout == UnSet)
116                 switch(level) {
117                 default: /* no layout */
118                         layout = 0;
119                         break;
120                 case 10:
121                         layout = 0x102; /* near=2, far=1 */
122                         if (verbose)
123                                 fprintf(stderr,
124                                         Name ": layout defaults to n1\n");
125                         break;
126                 case 5:
127                 case 6:
128                         layout = map_name(r5layout, "default");
129                         if (verbose)
130                                 fprintf(stderr,
131                                         Name ": layout defaults to %s\n", map_num(r5layout, layout));
132                         break;
133                 case LEVEL_FAULTY:
134                         layout = map_name(faultylayout, "default");
135
136                         if (verbose)
137                                 fprintf(stderr,
138                                         Name ": layout defaults to %s\n", map_num(faultylayout, layout));
139                         break;
140                 }
141
142         if (level == 10)
143                 /* check layout fits in array*/
144                 if ((layout&255) * ((layout>>8)&255) > raiddisks) {
145                         fprintf(stderr, Name ": that layout requires at least %d devices\n",
146                                 (layout&255) * ((layout>>8)&255));
147                         return 1;
148                 }
149
150         switch(level) {
151         case 4:
152         case 5:
153         case 10:
154         case 6:
155         case 0:
156         case -1: /* linear */
157                 if (chunk == 0) {
158                         chunk = 64;
159                         if (verbose)
160                                 fprintf(stderr, Name ": chunk size defaults to 64K\n");
161                 }
162                 break;
163         default: /* raid1, multipath */
164                 if (chunk) {
165                         chunk = 0;
166                         if (verbose)
167                                 fprintf(stderr, Name ": chunk size ignored for this level\n");
168                 }
169                 break;
170         }
171
172         /* now look at the subdevs */
173         array.active_disks = 0;
174         array.working_disks = 0;
175         dnum = 0;
176         for (dv=devlist; dv; dv=dv->next, dnum++) {
177                 char *dname = dv->devname;
178                 unsigned long dsize;
179                 unsigned long long ldsize, freesize;
180                 int fd;
181                 if (strcasecmp(dname, "missing")==0) {
182                         if (first_missing > dnum)
183                                 first_missing = dnum;
184                         missing_disks ++;
185                         continue;
186                 }
187                 array.working_disks++;
188                 if (dnum < raiddisks)
189                         array.active_disks++;
190                 fd = open(dname, O_RDONLY|O_EXCL, 0);
191                 if (fd <0 ) {
192                         fprintf(stderr, Name ": Cannot open %s: %s\n",
193                                 dname, strerror(errno));
194                         fail=1;
195                         continue;
196                 }
197 #ifdef BLKGETSIZE64
198                 if (ioctl(fd, BLKGETSIZE64, &ldsize)==0)
199                         ;
200                 else
201 #endif
202                 if (ioctl(fd, BLKGETSIZE, &dsize)) {
203                         fprintf(stderr, Name ": Cannot get size of %s: %s\n",
204                                 dname, strerror(errno));
205                         fail = 1;
206                         close(fd);
207                         continue;
208                 }
209                 else {
210                         ldsize = dsize;
211                         dsize <<= 9;
212                 }
213                 if (ldsize < MD_RESERVED_SECTORS*2LL*512LL) {
214                         fprintf(stderr, Name ": %s is too small: %luK\n",
215                                 dname, (unsigned long)(ldsize>>10));
216                         fail = 1;
217                         close(fd);
218                         continue;
219                 }
220                 freesize = MD_NEW_SIZE_SECTORS((ldsize>>9));
221                 freesize /= 2;
222
223                 if (size && freesize < size) {
224                         fprintf(stderr, Name ": %s is smaller that given size."
225                                 " %lluK < %luK + superblock\n", dname, freesize, size);
226                         fail = 1;
227                         close(fd);
228                         continue;
229                 }
230                 if (maxdisc == NULL || (maxdisc && freesize > maxsize)) {
231                         maxdisc = dname;
232                         maxsize = freesize;
233                 }
234                 if (mindisc ==NULL || (mindisc && freesize < minsize)) {
235                         mindisc = dname;
236                         minsize = freesize;
237                 }
238                 warn |= check_ext2(fd, dname);
239                 warn |= check_reiser(fd, dname);
240                 warn |= check_raid(fd, dname);
241                 close(fd);
242         }
243         if (fail) {
244                 fprintf(stderr, Name ": create aborted\n");
245                 return 1;
246         }
247         if (size == 0) {
248                 if (mindisc == NULL) {
249                         fprintf(stderr, Name ": no size and no drives given - aborting create.\n");
250                         return 1;
251                 }
252                 if (level > 0) {
253                         /* size is meaningful */
254                         if (minsize > 0x100000000ULL) {
255                                 fprintf(stderr, Name ": devices too large for RAID level %d\n", level); 
256                                 return 1;
257                         }
258                         size = minsize;
259                         if (verbose)
260                                 fprintf(stderr, Name ": size set to %luK\n", size);
261                 }
262         }
263         if (level > 0 && ((maxsize-size)*100 > maxsize)) {
264                 fprintf(stderr, Name ": largest drive (%s) exceed size (%luK) by more than 1%%\n",
265                         maxdisc, size);
266                 warn = 1;
267         }
268
269         if (warn) {
270                 if (runstop!= 1) {
271                         if (!ask("Continue creating array? ")) {
272                                 fprintf(stderr, Name ": create aborted.\n");
273                                 return 1;
274                         }
275                 } else {
276                         if (verbose)
277                                 fprintf(stderr, Name ": creation continuing despite oddities due to --run\n");
278                 }
279         }
280
281         /* If this is  raid5, we want to configure the last active slot
282          * as missing, so that a reconstruct happens (faster than re-parity)
283          * FIX: Can we do this for raid6 as well?
284          */
285         if (force == 0 && first_missing >= raiddisks) {
286                 switch ( level ) {
287                 case 5:
288                         insert_point = raiddisks-1;
289                         sparedisks++;
290                         array.active_disks--;
291                         missing_disks++;
292                         break;
293                 default:
294                         break;
295                 }
296         }
297         
298         /* Ok, lets try some ioctls */
299
300         array.level = level;
301         array.size = size;
302         array.raid_disks = raiddisks;
303         /* The kernel should *know* what md_minor we are dealing
304          * with, but it chooses to trust me instead. Sigh
305          */
306         array.md_minor = 0;
307         if (fstat(mdfd, &stb)==0)
308                 array.md_minor = minor(stb.st_rdev);
309         array.not_persistent = 0;
310         /*** FIX: Need to do something about RAID-6 here ***/
311         if ( ( (level == 5) &&
312                (insert_point < raiddisks || first_missing < raiddisks) )
313              ||
314              ( level == 6 && missing_disks == 2)
315                 )
316                 array.state = 1; /* clean, but one+ drive will be missing */
317         else
318                 array.state = 0; /* not clean, but no errors */
319
320         /* There is lots of redundancy in these disk counts,
321          * raid_disks is the most meaningful value
322          *          it describes the geometry of the array
323          *          it is constant
324          * nr_disks is total number of used slots.
325          *          it should be raid_disks+spare_disks
326          * spare_disks is the number of extra disks present
327          *          see above
328          * active_disks is the number of working disks in
329          *          active slots. (With raid_disks)
330          * working_disks is the total number of working disks,
331          *          including spares
332          * failed_disks is the number of disks marked failed
333          *
334          * Ideally, the kernel would keep these (except raid_disks)
335          * up-to-date as we ADD_NEW_DISK, but it doesn't (yet).
336          * So for now, we assume that all raid and spare
337          * devices will be given.
338          */
339         array.spare_disks=sparedisks;
340         array.failed_disks=missing_disks;
341         array.nr_disks = array.working_disks + array.failed_disks;
342         array.layout = layout;
343         array.chunk_size = chunk*1024;
344
345         if (ioctl(mdfd, SET_ARRAY_INFO, &array)) {
346                 fprintf(stderr, Name ": SET_ARRAY_INFO failed for %s: %s\n",
347                         mddev, strerror(errno));
348                 return 1;
349         }
350         
351         for (dnum=0, dv = devlist ; dv ; dv=(dv->next)?(dv->next):moved_disk, dnum++) {
352                 int fd;
353                 struct stat stb;
354                 mdu_disk_info_t disk;
355
356                 disk.number = dnum;
357                 if (dnum == insert_point) {
358                         moved_disk = dv;
359                 }
360                 disk.raid_disk = disk.number;
361                 if (disk.raid_disk < raiddisks)
362                         disk.state = 6; /* active and in sync */
363                 else
364                         disk.state = 0;
365                 if (dnum == insert_point ||
366                     strcasecmp(dv->devname, "missing")==0) {
367                         disk.major = 0;
368                         disk.minor = 0;
369                         disk.state = 1; /* faulty */
370                 } else {
371                         fd = open(dv->devname, O_RDONLY|O_EXCL, 0);
372                         if (fd < 0) {
373                                 fprintf(stderr, Name ": failed to open %s after earlier success - aborting\n",
374                                         dv->devname);
375                                 return 1;
376                         }
377                         fstat(fd, &stb);
378                         disk.major = major(stb.st_rdev);
379                         disk.minor = minor(stb.st_rdev);
380                         close(fd);
381                 }
382                 if (ioctl(mdfd, ADD_NEW_DISK, &disk)) {
383                         fprintf(stderr, Name ": ADD_NEW_DISK for %s failed: %s\n",
384                                 dv->devname, strerror(errno));
385                         return 1;
386                 }
387                 if (dv == moved_disk && dnum != insert_point) break;
388         }
389
390         /* param is not actually used */
391         if (runstop == 1 || subdevs >= raiddisks) {
392                 mdu_param_t param;
393                 if (ioctl(mdfd, RUN_ARRAY, &param)) {
394                         fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",
395                                 strerror(errno));
396                         Manage_runstop(mddev, mdfd, -1);
397                         return 1;
398                 }
399                 fprintf(stderr, Name ": array %s started.\n", mddev);
400         } else {
401                 fprintf(stderr, Name ": not starting array - not enough devices.\n");
402         }
403         return 0;
404 }