]>
git.ipfire.org Git - thirdparty/mdadm.git/blob - Create.c
2 * mdctl - manage Linux "md" devices aka RAID arrays.
4 * Copyright (C) 2001 Neil Brown <neilb@cse.unsw.edu.au>
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.
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.
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
22 * Email: <neilb@cse.unsw.edu.au>
24 * School of Computer Science and Engineering
25 * The University of New South Wales
34 int Create(char *mddev
, int mdfd
,
35 int chunk
, int level
, int layout
, int size
, int raiddisks
, int sparedisks
,
36 int subdevs
, char *subdev
[],
37 int runstop
, int verbose
)
40 * Create a new raid array.
42 * First check that necessary details are available
43 * (i.e. level, raid-disks)
45 * Then check each disk to see what might be on it
46 * and report anything interesting.
48 * If anything looks odd, and runstop not set,
51 * SET_ARRAY_INFO and ADD_NEW_DISK, and
52 * if runstop==run, or raiddisks diskswere used,
56 int maxdisc
= -1, mindisc
= -1;
60 mdu_array_info_t array
;
64 if (md_get_version(mdfd
) < 9000) {
65 fprintf(stderr
, Name
": Create requires md driver verison 0.90.0 or later\n");
70 Name
": a RAID level is needed to create an array.\n");
75 Name
": a number of --raid-disks must be given to create an array\n");
78 if (raiddisks
+sparedisks
> MD_SB_DISKS
) {
80 Name
": too many discs requested: %d+%d > %d\n",
81 raiddisks
, sparedisks
, MD_SB_DISKS
);
84 if (subdevs
> raiddisks
+sparedisks
) {
85 fprintf(stderr
, Name
": You have listed more disks (%d) than are in the array(%d)!\n", subdevs
, raiddisks
+sparedisks
);
88 /* now set some defaults */
91 default: /* no layout */
95 layout
= map_name(r5layout
, "default");
98 Name
": layout defaults to %s\n", map_num(r5layout
, layout
));
105 fprintf(stderr
, Name
": chunk size defaults to 64K\n");
108 /* now look at the subdevs */
109 for (i
=0; i
<subdevs
; i
++) {
110 char *dname
= subdev
[i
];
112 int fd
= open(dname
, O_RDONLY
, 0);
114 fprintf(stderr
, Name
": Cannot open %s: %s\n",
115 dname
, strerror(errno
));
119 if (ioctl(fd
, BLKGETSIZE
, &dsize
)) {
120 fprintf(stderr
, Name
": Cannot get size of %s: %s\n",
121 dname
, strerror(errno
));
126 if (dsize
< MD_RESERVED_SECTORS
*2) {
127 fprintf(stderr
, Name
": %s is too small: %dK\n",
133 freesize
= MD_NEW_SIZE_SECTORS(dsize
);
136 if (size
&& freesize
< size
) {
137 fprintf(stderr
, Name
": %s is smaller that given size."
138 " %dK < %dK + superblock\n", dname
, freesize
, size
);
143 if (maxdisc
< 0 || (maxdisc
>=0 && freesize
> maxsize
)) {
147 if (mindisc
< 0 || (mindisc
>=0 && freesize
< minsize
)) {
151 warn
|= check_ext2(fd
, dname
);
152 warn
|= check_reiser(fd
, dname
);
153 warn
|= check_raid(fd
, dname
);
157 fprintf(stderr
, Name
": create aborted\n");
162 fprintf(stderr
, Name
": no size and no drives given - aborting create.\n");
167 fprintf(stderr
, Name
": size set to %dK\n", size
);
169 if ((maxsize
-size
)*100 > maxsize
) {
170 fprintf(stderr
, Name
": largest drive (%s) exceed size (%dK) by more than 1%\n",
171 subdev
[maxdisc
], size
);
177 if (!ask("Continue creating array? ")) {
178 fprintf(stderr
, Name
": create aborted.\n");
183 fprintf(stderr
, Name
": creation continuing despite oddities due to --run\n");
187 /* Ok, lets try some ioctls */
191 array
.nr_disks
= raiddisks
+sparedisks
;
192 array
.raid_disks
= raiddisks
;
194 array
.not_persistent
= 0;
195 array
.state
= 0; /* not clean, but no errors */
196 array
.active_disks
=0;
197 array
.working_disks
=0;
199 array
.failed_disks
=0;
200 array
.layout
= layout
;
201 array
.chunk_size
= chunk
*1024;
203 if (ioctl(mdfd
, SET_ARRAY_INFO
, &array
)) {
204 fprintf(stderr
, Name
": SET_ARRAY_INFO failed for %s: %s\n",
205 mddev
, strerror(errno
));
209 for (i
=0; i
<subdevs
; i
++) {
210 int fd
= open(subdev
[i
], O_RDONLY
, 0);
212 mdu_disk_info_t disk
;
214 fprintf(stderr
, Name
": failed to open %s after earlier success - aborting\n",
221 disk
.state
= 6; /* active and in sync */
222 disk
.major
= MAJOR(stb
.st_rdev
);
223 disk
.minor
= MINOR(stb
.st_rdev
);
225 if (ioctl(mdfd
, ADD_NEW_DISK
, &disk
)) {
226 fprintf(stderr
, Name
": ADD_NEW_DISK for %s failed: %s\b",
227 subdev
[i
], strerror(errno
));
232 /* param is not actually used */
233 if (runstop
== 1 || subdevs
>= raiddisks
) {
234 if (ioctl(mdfd
, RUN_ARRAY
, ¶m
)) {
235 fprintf(stderr
, Name
": RUN_ARRAY failed: %s\n",
239 fprintf(stderr
, Name
": array %s started.\n", mddev
);
241 fprintf(stderr
, Name
": not starting array - not enough discs.\n");