]>
git.ipfire.org Git - thirdparty/mdadm.git/blob - Grow.c
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.
48 mdu_array_info_t array
;
56 if (ioctl(fd
, GET_ARRAY_INFO
, &array
) < 0) {
57 fprintf(stderr
, Name
": cannot get array info for %s\n", devname
);
61 if (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
< 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 (load_super(fd2
, &super
)) {
100 fprintf(stderr
, Name
": cannot find super block on %s\n", dv
);
106 /* Ok, looks good. Lets update the superblock and write it out to
110 memset(&super
.disks
[d
], 0, sizeof(super
.disks
[d
]));
111 super
.disks
[d
].number
= d
;
112 super
.disks
[d
].major
= MAJOR(stb
.st_rdev
);
113 super
.disks
[d
].minor
= MINOR(stb
.st_rdev
);
114 super
.disks
[d
].raid_disk
= d
;
115 super
.disks
[d
].state
= (1 << MD_DISK_SYNC
) | (1 << MD_DISK_ACTIVE
);
117 super
.this_disk
= super
.disks
[d
];
118 super
.sb_csum
= calc_sb_csum(&super
);
119 if (store_super(nfd
, &super
)) {
120 fprintf(stderr
, Name
": Cannot store new superblock on %s\n", newdev
);
125 disk
.major
= MAJOR(stb
.st_rdev
);
126 disk
.minor
= MINOR(stb
.st_rdev
);
128 disk
.state
= (1 << MD_DISK_SYNC
) | (1 << MD_DISK_ACTIVE
);
130 if (ioctl(fd
, ADD_NEW_DISK
, &disk
) != 0) {
131 fprintf(stderr
, Name
": Cannot add new disk to this array\n");
134 /* Well, that seems to have worked.
135 * Now go through and update all superblocks
138 if (ioctl(fd
, GET_ARRAY_INFO
, &array
) < 0) {
139 fprintf(stderr
, Name
": cannot get array info for %s\n", devname
);
144 for (d
=0 ; d
< array
.raid_disks
; d
++) {
145 mdu_disk_info_t disk
;
149 if (ioctl(fd
, GET_DISK_INFO
, &disk
) < 0) {
150 fprintf(stderr
, Name
": cannot get device detail for device %d\n",
154 dv
= map_dev(disk
.major
, disk
.minor
);
156 fprintf(stderr
, Name
": cannot find device file for device %d\n",
160 fd2
= open(dv
, O_RDWR
);
162 fprintf(stderr
, Name
": cannot open device file %s\n", dv
);
165 if (load_super(fd2
, &super
)) {
166 fprintf(stderr
, Name
": cannot find super block on %s\n", dv
);
170 super
.raid_disks
= nd
+1;
171 super
.nr_disks
= nd
+1;
172 super
.active_disks
= nd
+1;
173 super
.working_disks
= nd
+1;
174 memset(&super
.disks
[nd
], 0, sizeof(super
.disks
[nd
]));
175 super
.disks
[nd
].number
= nd
;
176 super
.disks
[nd
].major
= MAJOR(stb
.st_rdev
);
177 super
.disks
[nd
].minor
= MINOR(stb
.st_rdev
);
178 super
.disks
[nd
].raid_disk
= nd
;
179 super
.disks
[nd
].state
= (1 << MD_DISK_SYNC
) | (1 << MD_DISK_ACTIVE
);
181 super
.this_disk
= super
.disks
[d
];
182 super
.sb_csum
= calc_sb_csum(&super
);
183 if (store_super(fd2
, &super
)) {
184 fprintf(stderr
, Name
": Cannot store new superblock on %s\n", dv
);