~xnox/ubuntu/quantal/mdadm/quantal

« back to all changes in this revision

Viewing changes to Examine.c

  • Committer: Dmitrijs Ledkovs
  • Author(s): Fabio M. Di Nitto
  • Date: 2004-10-01 06:23:38 UTC
  • Revision ID: dmitrijs.ledkovs@canonical.com-20041001062338-25s1tgnu6egigv1v
Tags: upstream-1.5.0
ImportĀ upstreamĀ versionĀ 1.5.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * mdadm - manage Linux "md" devices aka RAID arrays.
 
3
 *
 
4
 * Copyright (C) 2001-2002 Neil Brown <neilb@cse.unsw.edu.au>
 
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@cse.unsw.edu.au>
 
23
 *    Paper: Neil Brown
 
24
 *           School of Computer Science and Engineering
 
25
 *           The University of New South Wales
 
26
 *           Sydney, 2052
 
27
 *           Australia
 
28
 */
 
29
 
 
30
#include        "mdadm.h"
 
31
#include        "dlink.h"
 
32
 
 
33
#if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN)
 
34
#error no endian defined
 
35
#endif
 
36
#include        "md_u.h"
 
37
#include        "md_p.h"
 
38
int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
 
39
{
 
40
 
 
41
        /* Read the raid superblock from a device and
 
42
         * display important content.
 
43
         *
 
44
         * If cannot be found, print reason: too small, bad magic
 
45
         *
 
46
         * Print:
 
47
         *   version, ctime, level, size, raid+spare+
 
48
         *   prefered minor
 
49
         *   uuid
 
50
         *
 
51
         *   utime, state etc
 
52
         *
 
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(
 
55
         */
 
56
        int fd; 
 
57
        time_t atime;
 
58
        mdp_super_t super;
 
59
        int d;
 
60
        char *c;
 
61
        int rv = 0;
 
62
        int err;
 
63
        int spares = 0;
 
64
 
 
65
        struct array {
 
66
                mdp_super_t super;
 
67
                void *devs;
 
68
                struct array *next;
 
69
        } *arrays = NULL;
 
70
 
 
71
        for (; devlist ; devlist=devlist->next) {
 
72
                fd = open(devlist->devname, O_RDONLY);
 
73
                if (fd < 0) {
 
74
                        if (!scan)
 
75
                                fprintf(stderr,Name ": cannot open %s: %s\n",
 
76
                                        devlist->devname, strerror(errno));
 
77
                        err = 1;
 
78
                }
 
79
                else {
 
80
                        err = load_super(fd, &super);
 
81
                        close(fd);
 
82
                }
 
83
                if (err && (brief||scan))
 
84
                        continue;
 
85
                if (err) rv =1;
 
86
                switch(err) {
 
87
                case 1:
 
88
                        fprintf(stderr, Name ": cannot find device size for %s: %s\n",
 
89
                                devlist->devname, strerror(errno));
 
90
                        continue;
 
91
                case 2:
 
92
/*              fprintf(stderr, Name ": %s is too small for md: size is %ld sectors\n",
 
93
                devlist->devname, size);
 
94
*/
 
95
                        fprintf(stderr, Name ": %s is too small for md\n",
 
96
                                devlist->devname);
 
97
                        continue;
 
98
                case 3:
 
99
                        fprintf(stderr, Name ": Cannot seek to superblock on %s: %s\n",
 
100
                                devlist->devname, strerror(errno));
 
101
                        continue;
 
102
                case 4:
 
103
                        fprintf(stderr, Name ": Cannot read superblock on %s\n",
 
104
                                devlist->devname);
 
105
                        continue;
 
106
                case 5:
 
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);
 
109
                        continue;
 
110
                case 6:
 
111
                        fprintf(stderr, Name ": Cannot interpret superblock on %s - version is %d\n",
 
112
                                devlist->devname, super.major_version);
 
113
                        continue;
 
114
                }
 
115
    
 
116
                /* Ok, its good enough to try, though the checksum could be wrong */
 
117
                if (brief) {
 
118
                        struct array *ap;
 
119
                        char *d;
 
120
                        for (ap=arrays; ap; ap=ap->next) {
 
121
                                if (compare_super(&ap->super, &super)==0)
 
122
                                        break;
 
123
                        }
 
124
                        if (!ap) {
 
125
                                ap = malloc(sizeof(*ap));
 
126
                                ap->super = super;
 
127
                                ap->devs = dl_head();
 
128
                                ap->next = arrays;
 
129
                                arrays = ap;
 
130
                        }
 
131
                        d = dl_strdup(devlist->devname);
 
132
                        dl_add(ap->devs, d);
 
133
                } else {
 
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);
 
141
                        else
 
142
                                printf("           UUID : %08x\n", super.set_uuid0);
 
143
 
 
144
                        atime = super.ctime;
 
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
                        printf("    Device Size : %d%s\n", super.size, human_size((long long)super.size<<10));
 
149
                        printf("   Raid Devices : %d\n", super.raid_disks);
 
150
                        printf("  Total Devices : %d\n", super.nr_disks);
 
151
                        printf("Preferred Minor : %d\n", super.md_minor);
 
152
                        printf("\n");
 
153
                        atime = super.utime;
 
154
                        printf("    Update Time : %.24s\n", ctime(&atime));
 
155
                        printf("          State : %s, %serrors\n",
 
156
                               (super.state&(1<<MD_SB_CLEAN))?"clean":"dirty",
 
157
                               (super.state&(1<<MD_SB_ERRORS))?"":"no-");
 
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);
 
164
                        else
 
165
                                printf("       Checksum : %x - expected %lx\n", super.sb_csum, calc_sb_csum(&super));
 
166
                        if (SparcAdjust) {
 
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
 
170
                                 */
 
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");
 
176
                        }
 
177
                        printf("         Events : %d.%d\n", super.events_hi, super.events_lo);
 
178
                        printf("\n");
 
179
                        if (super.level == 5) {
 
180
                                c = map_num(r5layout, super.layout);
 
181
                                printf("         Layout : %s\n", c?c:"-unknown-");
 
182
                        }
 
183
                        switch(super.level) {
 
184
                        case 0:
 
185
                        case 4:
 
186
                        case 5:
 
187
                                printf("     Chunk Size : %dK\n", super.chunk_size/1024);
 
188
                                break;
 
189
                        case -1:
 
190
                                printf("       Rounding : %dK\n", super.chunk_size/1024);
 
191
                                break;
 
192
                        default: break;         
 
193
                        }
 
194
                        printf("\n");
 
195
                        printf("      Number   Major   Minor   RaidDevice State\n");
 
196
                        for (d= -1; d<(signed int)(super.raid_disks+super.spare_disks); d++) {
 
197
                                mdp_disk_t *dp;
 
198
                                char *dv;
 
199
                                char nb[5];
 
200
                                if (d>=0) dp = &super.disks[d];
 
201
                                else dp = &super.this_disk;
 
202
                                sprintf(nb, "%4d", d);
 
203
                                printf("%4s %5d   %5d    %5d    %5d     ", d < 0 ? "this" :  nb,
 
204
                                       dp->number, dp->major, dp->minor, dp->raid_disk);
 
205
                                if (dp->state & (1<<MD_DISK_FAULTY)) printf(" faulty");
 
206
                                if (dp->state & (1<<MD_DISK_ACTIVE)) printf(" active");
 
207
                                if (dp->state & (1<<MD_DISK_SYNC)) printf(" sync");
 
208
                                if (dp->state & (1<<MD_DISK_REMOVED)) printf(" removed");
 
209
                                if (dp->state == 0) { printf(" spare"); spares++; }
 
210
                                if ((dv=map_dev(dp->major, dp->minor)))
 
211
                                        printf("   %s", dv);
 
212
                                printf("\n");
 
213
                        }
 
214
                }
 
215
                if (SparcAdjust == 2) {
 
216
                        printf(" ----- updating superblock on device ----\n");
 
217
                        fd = open(devlist->devname, O_RDWR);
 
218
                        if (fd < 0) {
 
219
                                fprintf(stderr, Name ": cannot open %s to update superblock: %s\n",
 
220
                                        devlist->devname, strerror(errno));
 
221
                                err = 1;
 
222
                        } else {
 
223
                                super.sb_csum = calc_sb_csum(&super);
 
224
                                if (store_super(fd, &super)) {
 
225
                                        fprintf(stderr, Name ": Count not re-write superblock on %s\n",
 
226
                                                devlist->devname);
 
227
                                        err = 1;
 
228
                                }
 
229
                                close(fd);
 
230
                        }
 
231
                }
 
232
        }
 
233
        if (brief) {
 
234
                struct array *ap;
 
235
                for (ap=arrays; ap; ap=ap->next) {
 
236
                        char sep='=';
 
237
                        char *c=map_num(pers, ap->super.level);
 
238
                        char *d;
 
239
                        printf("ARRAY /dev/md%d level=%s num-devices=%d UUID=",
 
240
                               ap->super.md_minor, c?c:"-unknown-", ap->super.raid_disks);
 
241
                        if (spares) printf(" spares=%d", spares);
 
242
                        if (ap->super.minor_version >= 90)
 
243
                                printf("%08x:%08x:%08x:%08x", ap->super.set_uuid0, ap->super.set_uuid1,
 
244
                                       ap->super.set_uuid2, ap->super.set_uuid3);
 
245
                        else
 
246
                                printf("%08x", ap->super.set_uuid0);
 
247
                        printf("\n   devices");
 
248
                        for (d=dl_next(ap->devs); d!= ap->devs; d=dl_next(d)) {
 
249
                                printf("%c%s", sep, d);
 
250
                                sep=',';
 
251
                        }
 
252
                        printf("\n");
 
253
                }
 
254
        }
 
255
        return rv;
 
256
}