X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=Detail.c;h=ca34f1d48f125618bf33b554c7c96385296772d9;hb=beae1dfe2e5a3f11e6e52a93fbf617d644708415;hp=46b483c4bd023cd9cf3d7073fa10b6231fb8b9c3;hpb=22892d5632b454a18be7fb36a82b4c1af691ef66;p=thirdparty%2Fmdadm.git diff --git a/Detail.c b/Detail.c index 46b483c4..ca34f1d4 100644 --- a/Detail.c +++ b/Detail.c @@ -1,7 +1,7 @@ /* * mdadm - manage Linux "md" devices aka RAID arrays. * - * Copyright (C) 2001-2002 Neil Brown + * Copyright (C) 2001-2006 Neil Brown * * * This program is free software; you can redistribute it and/or modify @@ -31,7 +31,7 @@ #include "md_p.h" #include "md_u.h" -int Detail(char *dev, int brief, int test) +int Detail(char *dev, int brief, int test, char *homehost) { /* * Print out details for an md array by using @@ -41,6 +41,8 @@ int Detail(char *dev, int brief, int test) int fd = open(dev, O_RDONLY, 0); int vers; mdu_array_info_t array; + mdu_disk_info_t *disks; + int next; int d; time_t atime; char *c; @@ -51,7 +53,8 @@ int Detail(char *dev, int brief, int test) int is_rebuilding = 0; int failed = 0; struct supertype *st = NULL; - int max_disks = MD_SB_DISKS; + int max_disks = MD_SB_DISKS; /* just a default */ + struct mdinfo info; void *super = NULL; int rv = test ? 4 : 1; @@ -103,15 +106,14 @@ int Detail(char *dev, int brief, int test) disk.major == 0 && disk.minor == 0) continue; - if ((dv=map_dev(disk.major, disk.minor))) { + if ((dv=map_dev(disk.major, disk.minor, 1))) { if (!super && (disk.state & (1<=0 && st && st->ss->load_super(st, fd2, &super, NULL) == 0) { - struct mdinfo info; st->ss->getinfo_super(&info, super); if (info.array.ctime != array.ctime || info.array.level != array.level) { @@ -129,9 +131,9 @@ int Detail(char *dev, int brief, int test) if (brief) printf("ARRAY %s level=%s num-devices=%d", dev, c?c:"-unknown-",array.raid_disks ); else { - unsigned long array_size; + mdu_bitmap_file_t bmf; unsigned long long larray_size; - struct mdstat_ent *ms = mdstat_read(0); + struct mdstat_ent *ms = mdstat_read(0, 0); struct mdstat_ent *e; int devnum = array.md_minor; if (major(stb.st_rdev) != MD_MAJOR) @@ -140,17 +142,8 @@ int Detail(char *dev, int brief, int test) for (e=ms; e; e=e->next) if (e->devnum == devnum) break; -#ifdef BLKGETSIZE64 - if (ioctl(fd, BLKGETSIZE64, &larray_size)==0) - ; - else -#endif - if (ioctl(fd, BLKGETSIZE, &array_size)==0) { - larray_size = array_size; - larray_size <<= 9; - } - - else larray_size = 0; + if (!get_dev_size(fd, NULL, &larray_size)) + larray_size = 0; printf("%s:\n", dev); printf(" Version : %02d.%02d.%02d\n", @@ -160,21 +153,42 @@ int Detail(char *dev, int brief, int test) printf(" Raid Level : %s\n", c?c:"-unknown-"); if (larray_size) printf(" Array Size : %llu%s\n", (larray_size>>10), human_size(larray_size)); - if (array.level >= 1) - printf(" Device Size : %d%s\n", array.size, human_size((long long)array.size<<10)); + if (array.level >= 1) { + if (array.major_version != 0 && + (larray_size >= 0xFFFFFFFFULL|| array.size == 0)) { + unsigned long long dsize = get_component_size(fd); + if (dsize > 0) + printf(" Used Dev Size : %llu%s\n", + dsize, + human_size((long long)array.size<<10)); + else + printf(" Used Dev Size : unknown\n"); + } else + printf(" Used Dev Size : %d%s\n", array.size, + human_size((long long)array.size<<10)); + } printf(" Raid Devices : %d\n", array.raid_disks); printf(" Total Devices : %d\n", array.nr_disks); printf("Preferred Minor : %d\n", array.md_minor); printf(" Persistence : Superblock is %spersistent\n", array.not_persistent?"not ":""); printf("\n"); + /* Only try GET_BITMAP_FILE for 0.90.01 and later */ + if (vers >= 9001 && + ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && + bmf.pathname[0]) { + printf(" Intent Bitmap : %s\n", bmf.pathname); + printf("\n"); + } else if (array.state & (1<percent < 0) ? "" : - (e->resync) ? ", resyncing": ", recovering"); + (e->resync) ? ", resyncing": ", recovering", + larray_size ? "": ", Not Started"); printf(" Active Devices : %d\n", array.active_disks); printf("Working Devices : %d\n", array.working_disks); printf(" Failed Devices : %d\n", array.failed_disks); @@ -185,8 +199,9 @@ int Detail(char *dev, int brief, int test) printf(" Layout : %s\n", c?c:"-unknown-"); } if (array.level == 10) { - printf(" Layout : near=%d, far=%d\n", - array.layout&255, (array.layout>>8)&255); + printf(" Layout : near=%d, %s=%d\n", + array.layout&255, (array.layout&0x10000)?"offset":"far", + (array.layout>>8)&255); } switch (array.level) { case 0: @@ -203,19 +218,63 @@ int Detail(char *dev, int brief, int test) } if (e && e->percent >= 0) { - printf(" Rebuild Status : %d%% complete\n\n", e->percent); + printf(" Re%s Status : %d%% complete\n", + (super && info.reshape_active)? "shape":"build", + e->percent); is_rebuilding = 1; } free_mdstat(ms); + if (super && info.reshape_active) { +#if 0 +This is pretty boring + printf(" Reshape pos'n : %llu%s\n", (unsigned long long) info.reshape_progress<<9, + human_size(info.reshape_progress<<9)); +#endif + if (info.delta_disks > 0) + printf(" Delta Devices : %d, (%d->%d)\n", + info.delta_disks, array.raid_disks - info.delta_disks, array.raid_disks); + if (info.delta_disks < 0) + printf(" Delta Devices : %d, (%d->%d)\n", + info.delta_disks, array.raid_disks, array.raid_disks + info.delta_disks); + if (info.new_level != array.level) { + char *c = map_num(pers, info.new_level); + printf(" New Level : %s\n", c?c:"-unknown-"); + } + if (info.new_level != array.level || + info.new_layout != array.layout) { + if (info.new_level == 5) { + char *c = map_num(r5layout, info.new_layout); + printf(" New Layout : %s\n", + c?c:"-unknown-"); + } + if (info.new_level == 10) { + printf(" New Layout : near=%d, %s=%d\n", + info.new_layout&255, + (info.new_layout&0x10000)?"offset":"far", + (info.new_layout>>8)&255); + } + } + if (info.new_chunk != array.chunk_size) + printf(" New Chunksize : %dK\n", info.new_chunk/1024); + printf("\n"); + } else if (e && e->percent >= 0) + printf("\n"); if (super && st) - st->ss->detail_super(super); + st->ss->detail_super(super, homehost); printf(" Number Major Minor RaidDevice State\n"); } - for (d= 0; d < max_disks; d++) { + disks = malloc(max_disks * sizeof(mdu_disk_info_t)); + for (d=0; d= 0 && disk.raid_disk < array.raid_disks) + disks[disk.raid_disk] = disk; + else if (next < max_disks) + disks[next++] = disk; + } + + for (d= 0; d < max_disks; d++) { + char *dv; + mdu_disk_info_t disk = disks[d]; + if (d >= array.raid_disks && disk.major == 0 && disk.minor == 0) continue; if (!brief) { - if (disk.number == array.raid_disks) printf("\n"); + if (d == array.raid_disks) printf("\n"); if (disk.raid_disk < 0) printf(" %5d %5d %5d - ", disk.number, disk.major, disk.minor); @@ -244,8 +315,11 @@ int Detail(char *dev, int brief, int test) if (disk.state & (1<= 0) printf(" rebuilding"); @@ -267,7 +341,7 @@ int Detail(char *dev, int brief, int test) rv |= 2; rv |= 1; } - if ((dv=map_dev(disk.major, disk.minor))) { + if ((dv=map_dev(disk.major, disk.minor, 0))) { if (brief) { if (devices) { devices = realloc(devices,