]>
git.ipfire.org Git - thirdparty/mdadm.git/blob - Grow.c
8de28d407ba5bac7e5328d4b0756be0cd606d782
2 * mdadm - manage Linux "md" devices aka RAID arrays.
4 * Copyright (C) 2001-2004 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
32 #if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN)
33 #error no endian defined
38 int Grow_Add_device(char *devname
, int fd
, char *newdev
)
40 /* Add a device to an active array.
41 * Currently, just extend a linear array.
42 * This requires writing a new superblock on the
43 * new device, calling the kernel to add the device,
44 * and if that succeeds, update the superblock on
46 * This means that we need to *find* all other devices.
56 if (ioctl(fd
, GET_ARRAY_INFO
, &info
.array
) < 0) {
57 fprintf(stderr
, Name
": cannot get array info for %s\n", devname
);
61 if (info
.array
.level
!= -1) {
62 fprintf(stderr
, Name
": can only add devices to linear arrays\n");
66 nfd
= open(newdev
, O_RDWR
|O_EXCL
);
68 fprintf(stderr
, Name
": cannot open %s\n", newdev
);
72 if ((stb
.st_mode
& S_IFMT
) != S_IFBLK
) {
73 fprintf(stderr
, Name
": %s is not a block device!\n", newdev
);
77 /* now check out all the devices and make sure we can read the superblock */
78 for (d
=0 ; d
< info
.array
.raid_disks
; d
++) {
83 if (ioctl(fd
, GET_DISK_INFO
, &disk
) < 0) {
84 fprintf(stderr
, Name
": cannot get device detail for device %d\n",
88 dv
= map_dev(disk
.major
, disk
.minor
);
90 fprintf(stderr
, Name
": cannot find device file for device %d\n",
94 fd2
= open(dv
, O_RDWR
);
96 fprintf(stderr
, Name
": cannot open device file %s\n", dv
);
99 if (super
) free(super
);
101 if (load_super0(fd2
, &super
, NULL
)) {
102 fprintf(stderr
, Name
": cannot find super block on %s\n", dv
);
108 /* Ok, looks good. Lets update the superblock and write it out to
112 info
.disk
.number
= d
;
113 info
.disk
.major
= major(stb
.st_rdev
);
114 info
.disk
.minor
= minor(stb
.st_rdev
);
115 info
.disk
.raid_disk
= d
;
116 info
.disk
.state
= (1 << MD_DISK_SYNC
) | (1 << MD_DISK_ACTIVE
);
117 update_super0(&info
, super
, "grow", newdev
, 0);
119 if (store_super0(nfd
, super
)) {
120 fprintf(stderr
, Name
": Cannot store new superblock on %s\n", newdev
);
126 if (ioctl(fd
, ADD_NEW_DISK
, &info
.disk
) != 0) {
127 fprintf(stderr
, Name
": Cannot add new disk to this array\n");
130 /* Well, that seems to have worked.
131 * Now go through and update all superblocks
134 if (ioctl(fd
, GET_ARRAY_INFO
, &info
.array
) < 0) {
135 fprintf(stderr
, Name
": cannot get array info for %s\n", devname
);
140 for (d
=0 ; d
< info
.array
.raid_disks
; d
++) {
141 mdu_disk_info_t disk
;
145 if (ioctl(fd
, GET_DISK_INFO
, &disk
) < 0) {
146 fprintf(stderr
, Name
": cannot get device detail for device %d\n",
150 dv
= map_dev(disk
.major
, disk
.minor
);
152 fprintf(stderr
, Name
": cannot find device file for device %d\n",
156 fd2
= open(dv
, O_RDWR
);
158 fprintf(stderr
, Name
": cannot open device file %s\n", dv
);
161 if (load_super0(fd2
, &super
, NULL
)) {
162 fprintf(stderr
, Name
": cannot find super block on %s\n", dv
);
166 info
.array
.raid_disks
= nd
+1;
167 info
.array
.nr_disks
= nd
+1;
168 info
.array
.active_disks
= nd
+1;
169 info
.array
.working_disks
= nd
+1;
170 info
.disk
.number
= nd
;
171 info
.disk
.major
= major(stb
.st_rdev
);
172 info
.disk
.minor
= minor(stb
.st_rdev
);
173 info
.disk
.raid_disk
= nd
;
174 info
.disk
.state
= (1 << MD_DISK_SYNC
) | (1 << MD_DISK_ACTIVE
);
175 update_super0(&info
, super
, "grow", dv
, 0);
177 if (store_super0(fd2
, super
)) {
178 fprintf(stderr
, Name
": Cannot store new superblock on %s\n", dv
);