]> git.neil.brown.name Git - mdadm.git/blob - Examine.c
Release mdadm-4.0
[mdadm.git] / Examine.c
1 /*
2  * mdadm - manage Linux "md" devices aka RAID arrays.
3  *
4  * Copyright (C) 2001-2013 Neil Brown <neilb@suse.de>
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@suse.de>
23  */
24
25 #include        "mdadm.h"
26 #include        "dlink.h"
27
28 #if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN)
29 #error no endian defined
30 #endif
31 #include        "md_u.h"
32 #include        "md_p.h"
33 int Examine(struct mddev_dev *devlist,
34             struct context *c,
35             struct supertype *forcest)
36 {
37
38         /* Read the raid superblock from a device and
39          * display important content.
40          *
41          * If cannot be found, print reason: too small, bad magic
42          *
43          * Print:
44          *   version, ctime, level, size, raid+spare+
45          *   prefered minor
46          *   uuid
47          *
48          *   utime, state etc
49          *
50          * If (brief) gather devices for same array and just print a mdadm.conf
51          * line including devices=
52          * if devlist==NULL, use conf_get_devs()
53          */
54         int fd;
55         int rv = 0;
56         int err = 0;
57
58         struct array {
59                 struct supertype *st;
60                 struct mdinfo info;
61                 void *devs;
62                 struct array *next;
63                 int spares;
64         } *arrays = NULL;
65
66         for (; devlist ; devlist = devlist->next) {
67                 struct supertype *st;
68                 int have_container = 0;
69
70                 fd = dev_open(devlist->devname, O_RDONLY);
71                 if (fd < 0) {
72                         if (!c->scan) {
73                                 pr_err("cannot open %s: %s\n",
74                                        devlist->devname, strerror(errno));
75                                 rv = 1;
76                         }
77                         err = 1;
78                 }
79                 else {
80                         int container = 0;
81                         if (forcest)
82                                 st = dup_super(forcest);
83                         else if (must_be_container(fd)) {
84                                 /* might be a container */
85                                 st = super_by_fd(fd, NULL);
86                                 container = 1;
87                         } else
88                                 st = guess_super(fd);
89                         if (st) {
90                                 err = 1;
91                                 st->ignore_hw_compat = 1;
92                                 if (!container)
93                                         err = st->ss->load_super(st, fd,
94                                                                  (c->brief||c->scan) ? NULL
95                                                                  :devlist->devname);
96                                 if (err && st->ss->load_container) {
97                                         err = st->ss->load_container(st, fd,
98                                                                  (c->brief||c->scan) ? NULL
99                                                                  :devlist->devname);
100                                         if (!err)
101                                                 have_container = 1;
102                                 }
103                                 st->ignore_hw_compat = 0;
104                         } else {
105                                 if (!c->brief) {
106                                         pr_err("No md superblock detected on %s.\n", devlist->devname);
107                                         rv = 1;
108                                 }
109                                 err = 1;
110                         }
111                         close(fd);
112                 }
113                 if (err)
114                         continue;
115
116                 if (c->SparcAdjust)
117                         st->ss->update_super(st, NULL, "sparc2.2",
118                                              devlist->devname, 0, 0, NULL);
119                 /* Ok, its good enough to try, though the checksum could be wrong */
120
121                 if (c->brief && st->ss->brief_examine_super == NULL) {
122                         if (!c->scan)
123                                 pr_err("No brief listing for %s on %s\n",
124                                         st->ss->name, devlist->devname);
125                 } else if (c->brief) {
126                         struct array *ap;
127                         char *d;
128                         for (ap = arrays; ap; ap = ap->next) {
129                                 if (st->ss == ap->st->ss &&
130                                     st->ss->compare_super(ap->st, st) == 0)
131                                         break;
132                         }
133                         if (!ap) {
134                                 ap = xmalloc(sizeof(*ap));
135                                 ap->devs = dl_head();
136                                 ap->next = arrays;
137                                 ap->spares = 0;
138                                 ap->st = st;
139                                 arrays = ap;
140                                 st->ss->getinfo_super(st, &ap->info, NULL);
141                         } else
142                                 st->ss->getinfo_super(st, &ap->info, NULL);
143                         if (!have_container &&
144                             !(ap->info.disk.state & (1<<MD_DISK_SYNC)))
145                                 ap->spares++;
146                         d = dl_strdup(devlist->devname);
147                         dl_add(ap->devs, d);
148                 } else if (c->export) {
149                         if (st->ss->export_examine_super)
150                                 st->ss->export_examine_super(st);
151                         st->ss->free_super(st);
152                 } else {
153                         printf("%s:\n",devlist->devname);
154                         st->ss->examine_super(st, c->homehost);
155                         st->ss->free_super(st);
156                 }
157         }
158         if (c->brief) {
159                 struct array *ap;
160                 for (ap = arrays; ap; ap = ap->next) {
161                         char sep='=';
162                         char *d;
163                         int newline = 0;
164
165                         ap->st->ss->brief_examine_super(ap->st, c->verbose > 0);
166                         if (ap->spares)
167                                 newline += printf("   spares=%d", ap->spares);
168                         if (c->verbose > 0) {
169                                 newline += printf("   devices");
170                                 for (d = dl_next(ap->devs);
171                                      d != ap->devs;
172                                      d=dl_next(d)) {
173                                         printf("%c%s", sep, d);
174                                         sep=',';
175                                 }
176                         }
177                         if (ap->st->ss->brief_examine_subarrays) {
178                                 if (newline)
179                                         printf("\n");
180                                 ap->st->ss->brief_examine_subarrays(ap->st, c->verbose);
181                         }
182                         ap->st->ss->free_super(ap->st);
183                         /* FIXME free ap */
184                         if (ap->spares || c->verbose > 0)
185                                 printf("\n");
186                 }
187         }
188         return rv;
189 }
190
191 int ExamineBadblocks(char *devname, int brief, struct supertype *forcest)
192 {
193         int fd = dev_open(devname, O_RDONLY);
194         struct supertype *st = forcest;
195         int err = 1;
196
197         if (fd < 0) {
198                 pr_err("cannot open %s: %s\n", devname, strerror(errno));
199                 return 1;
200         }
201         if (!st)
202                 st = guess_super(fd);
203         if (!st) {
204                 if (!brief)
205                         pr_err("No md superblock detected on %s\n", devname);
206                 goto out;
207         }
208         if (!st->ss->examine_badblocks) {
209                 pr_err("%s metadata does not support badblocks\n", st->ss->name);
210                 goto out;
211         }
212         err = st->ss->load_super(st, fd, brief ? NULL : devname);
213         if (err)
214                 goto out;
215         err = st->ss->examine_badblocks(st, fd, devname);
216
217 out:
218         if (fd >= 0)
219                 close(fd);
220         if (st) {
221                 st->ss->free_super(st);
222                 free(st);
223         }
224         return err;
225 }