2 * mdadm - manage Linux "md" devices aka RAID arrays.
4 * Copyright (C) 2001-2002 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
33 #if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN)
34 #error no endian defined
38 int Examine(mddev_dev_t devlist
, int brief
, int scan
, int SparcAdjust
)
41 /* Read the raid superblock from a device and
42 * display important content.
44 * If cannot be found, print reason: too small, bad magic
47 * version, ctime, level, size, raid+spare+
53 * If (brief) gather devices for same array and just print a mdadm.conf line including devices=
54 * if devlist==NULL, use conf_get_devs(
71 for (; devlist
; devlist
=devlist
->next
) {
72 fd
= open(devlist
->devname
, O_RDONLY
);
75 fprintf(stderr
,Name
": cannot open %s: %s\n",
76 devlist
->devname
, strerror(errno
));
80 err
= load_super(fd
, &super
);
83 if (err
&& (brief
||scan
))
88 fprintf(stderr
, Name
": cannot find device size for %s: %s\n",
89 devlist
->devname
, strerror(errno
));
92 /* fprintf(stderr, Name ": %s is too small for md: size is %ld sectors\n",
93 devlist->devname, size);
95 fprintf(stderr
, Name
": %s is too small for md\n",
99 fprintf(stderr
, Name
": Cannot seek to superblock on %s: %s\n",
100 devlist
->devname
, strerror(errno
));
103 fprintf(stderr
, Name
": Cannot read superblock on %s\n",
107 fprintf(stderr
, Name
": No super block found on %s (Expected magic %08x, got %08x)\n",
108 devlist
->devname
, MD_SB_MAGIC
, super
.md_magic
);
111 fprintf(stderr
, Name
": Cannot interpret superblock on %s - version is %d\n",
112 devlist
->devname
, super
.major_version
);
116 /* Ok, its good enough to try, though the checksum could be wrong */
120 for (ap
=arrays
; ap
; ap
=ap
->next
) {
121 if (compare_super(&ap
->super
, &super
)==0)
125 ap
= malloc(sizeof(*ap
));
127 ap
->devs
= dl_head();
131 d
= dl_strdup(devlist
->devname
);
134 printf("%s:\n",devlist
->devname
);
135 printf(" Magic : %08x\n", super
.md_magic
);
136 printf(" Version : %02d.%02d.%02d\n", super
.major_version
, super
.minor_version
,
137 super
.patch_version
);
138 if (super
.minor_version
>= 90)
139 printf(" UUID : %08x:%08x:%08x:%08x\n", super
.set_uuid0
, super
.set_uuid1
,
140 super
.set_uuid2
, super
.set_uuid3
);
142 printf(" UUID : %08x\n", super
.set_uuid0
);
145 printf(" Creation Time : %.24s\n", ctime(&atime
));
146 c
=map_num(pers
, super
.level
);
147 printf(" Raid Level : %s\n", c
?c
:"-unknown-");
148 if (super
.level
<= 0)
149 printf(" Device Size : %u%s\n", super
.size
, human_size((long long)super
.size
<<10));
150 printf(" Raid Devices : %d\n", super
.raid_disks
);
151 printf(" Total Devices : %d\n", super
.nr_disks
);
152 printf("Preferred Minor : %d\n", super
.md_minor
);
155 printf(" Update Time : %.24s\n", ctime(&atime
));
156 printf(" State : %s\n",
157 (super
.state
&(1<<MD_SB_CLEAN
))?"clean":"active");
158 printf(" Active Devices : %d\n", super
.active_disks
);
159 printf("Working Devices : %d\n", super
.working_disks
);
160 printf(" Failed Devices : %d\n", super
.failed_disks
);
161 printf(" Spare Devices : %d\n", super
.spare_disks
);
162 if (calc_sb_csum(&super
) == super
.sb_csum
)
163 printf(" Checksum : %x - correct\n", super
.sb_csum
);
165 printf(" Checksum : %x - expected %lx\n", super
.sb_csum
, calc_sb_csum(&super
));
167 /* 2.2 sparc put the events in the wrong place
168 * So we copy the tail of the superblock
169 * up 4 bytes before continuing
171 __u32
*sb32
= (__u32
*)&super
;
172 memcpy(sb32
+MD_SB_GENERIC_CONSTANT_WORDS
+7,
173 sb32
+MD_SB_GENERIC_CONSTANT_WORDS
+7+1,
174 (MD_SB_WORDS
- (MD_SB_GENERIC_CONSTANT_WORDS
+7+1))*4);
175 printf (" --- adjusting superblock for 2.2/sparc compatability ---\n");
177 printf(" Events : %d.%d\n", super
.events_hi
, super
.events_lo
);
178 if (super
.events_hi
== super
.cp_events_hi
&&
179 super
.events_lo
== super
.cp_events_lo
&&
180 super
.recovery_cp
> 0 &&
181 (super
.state
& (1<<MD_SB_CLEAN
)) == 0 )
182 printf("Sync checkpoint : %d KB (%d%%)\n", super
.recovery_cp
/2, super
.recovery_cp
/(super
.size
/100*2));
184 if (super
.level
== 5) {
185 c
= map_num(r5layout
, super
.layout
);
186 printf(" Layout : %s\n", c
?c
:"-unknown-");
188 if (super
.level
== 10)
189 printf(" Layout : near=%d, far=%d\n",
190 super
.layout
&255, (super
.layout
>>8) & 255);
192 switch(super
.level
) {
196 printf(" Chunk Size : %dK\n", super
.chunk_size
/1024);
199 printf(" Rounding : %dK\n", super
.chunk_size
/1024);
204 printf(" Number Major Minor RaidDevice State\n");
205 for (d
= -1; d
<(signed int)(super
.raid_disks
+super
.spare_disks
); d
++) {
209 if (d
>=0) dp
= &super
.disks
[d
];
210 else dp
= &super
.this_disk
;
211 sprintf(nb
, "%4d", d
);
212 printf("%4s %5d %5d %5d %5d ", d
< 0 ? "this" : nb
,
213 dp
->number
, dp
->major
, dp
->minor
, dp
->raid_disk
);
214 if (dp
->state
& (1<<MD_DISK_FAULTY
)) printf(" faulty");
215 if (dp
->state
& (1<<MD_DISK_ACTIVE
)) printf(" active");
216 if (dp
->state
& (1<<MD_DISK_SYNC
)) printf(" sync");
217 if (dp
->state
& (1<<MD_DISK_REMOVED
)) printf(" removed");
218 if (dp
->state
== 0) { printf(" spare"); spares
++; }
219 if ((dv
=map_dev(dp
->major
, dp
->minor
)))
222 if (d
== -1) printf("\n");
225 if (SparcAdjust
== 2) {
226 printf(" ----- updating superblock on device ----\n");
227 fd
= open(devlist
->devname
, O_RDWR
);
229 fprintf(stderr
, Name
": cannot open %s to update superblock: %s\n",
230 devlist
->devname
, strerror(errno
));
233 super
.sb_csum
= calc_sb_csum(&super
);
234 if (store_super(fd
, &super
)) {
235 fprintf(stderr
, Name
": Count not re-write superblock on %s\n",
245 for (ap
=arrays
; ap
; ap
=ap
->next
) {
247 char *c
=map_num(pers
, ap
->super
.level
);
249 printf("ARRAY %s level=%s num-devices=%d UUID=",
250 get_md_name(ap
->super
.md_minor
),
251 c
?c
:"-unknown-", ap
->super
.raid_disks
);
252 if (spares
) printf(" spares=%d", spares
);
253 if (ap
->super
.minor_version
>= 90)
254 printf("%08x:%08x:%08x:%08x", ap
->super
.set_uuid0
, ap
->super
.set_uuid1
,
255 ap
->super
.set_uuid2
, ap
->super
.set_uuid3
);
257 printf("%08x", ap
->super
.set_uuid0
);
258 printf("\n devices");
259 for (d
=dl_next(ap
->devs
); d
!= ap
->devs
; d
=dl_next(d
)) {
260 printf("%c%s", sep
, d
);