Detail.c (mdadm-4.1) | : | Detail.c (mdadm-4.2) | ||
---|---|---|---|---|
skipping to change at line 59 | skipping to change at line 59 | |||
return n_devices + 1; | return n_devices + 1; | |||
} | } | |||
int Detail(char *dev, struct context *c) | int Detail(char *dev, struct context *c) | |||
{ | { | |||
/* | /* | |||
* Print out details for an md array | * Print out details for an md array | |||
*/ | */ | |||
int fd = open(dev, O_RDONLY); | int fd = open(dev, O_RDONLY); | |||
mdu_array_info_t array; | mdu_array_info_t array; | |||
mdu_disk_info_t *disks; | mdu_disk_info_t *disks = NULL; | |||
int next; | int next; | |||
int d; | int d; | |||
time_t atime; | time_t atime; | |||
char *str; | char *str; | |||
char **devices = NULL; | char **devices = NULL; | |||
int max_devices = 0, n_devices = 0; | int max_devices = 0, n_devices = 0; | |||
int spares = 0; | int spares = 0; | |||
struct stat stb; | struct stat stb; | |||
int failed = 0; | int failed = 0; | |||
struct supertype *st; | struct supertype *st = NULL; | |||
char *subarray = NULL; | char *subarray = NULL; | |||
int max_disks = MD_SB_DISKS; /* just a default */ | int max_disks = MD_SB_DISKS; /* just a default */ | |||
struct mdinfo *info = NULL; | struct mdinfo *info = NULL; | |||
struct mdinfo *sra; | struct mdinfo *sra = NULL; | |||
struct mdinfo *subdev; | struct mdinfo *subdev; | |||
char *member = NULL; | char *member = NULL; | |||
char *container = NULL; | char *container = NULL; | |||
int rv = c->test ? 4 : 1; | int rv = c->test ? 4 : 1; | |||
int avail_disks = 0; | int avail_disks = 0; | |||
char *avail = NULL; | char *avail = NULL; | |||
int external; | int external; | |||
int inactive; | int inactive; | |||
int is_container = 0; | int is_container = 0; | |||
char *arrayst; | ||||
if (fd < 0) { | if (fd < 0) { | |||
pr_err("cannot open %s: %s\n", | pr_err("cannot open %s: %s\n", | |||
dev, strerror(errno)); | dev, strerror(errno)); | |||
return rv; | return rv; | |||
} | } | |||
sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS | | sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS | | |||
GET_ARRAY_STATE | GET_STATE); | GET_ARRAY_STATE | GET_STATE); | |||
if (!sra) { | if (!sra) { | |||
if (md_get_array_info(fd, &array)) { | if (md_get_array_info(fd, &array)) { | |||
pr_err("%s does not appear to be an md device\n", dev); | pr_err("%s does not appear to be an md device\n", dev); | |||
close(fd); | goto out; | |||
return rv; | ||||
} | } | |||
} | } | |||
external = (sra != NULL && sra->array.major_version == -1 && | external = (sra != NULL && sra->array.major_version == -1 && | |||
sra->array.minor_version == -2); | sra->array.minor_version == -2); | |||
inactive = (sra != NULL && !md_array_is_active(sra)); | inactive = (sra != NULL && !md_array_is_active(sra)); | |||
st = super_by_fd(fd, &subarray); | st = super_by_fd(fd, &subarray); | |||
if (md_get_array_info(fd, &array)) { | if (md_get_array_info(fd, &array)) { | |||
if (errno == ENODEV) { | if (errno == ENODEV) { | |||
if (sra->array.major_version == -1 && | if (sra->array.major_version == -1 && | |||
sra->array.minor_version == -1 && | sra->array.minor_version == -1 && | |||
sra->devs == NULL) { | sra->devs == NULL) { | |||
pr_err("Array associated with md device %s does n ot exist.\n", | pr_err("Array associated with md device %s does n ot exist.\n", | |||
dev); | dev); | |||
close(fd); | goto out; | |||
sysfs_free(sra); | ||||
return rv; | ||||
} | } | |||
array = sra->array; | array = sra->array; | |||
} else { | } else { | |||
pr_err("cannot get array detail for %s: %s\n", | pr_err("cannot get array detail for %s: %s\n", | |||
dev, strerror(errno)); | dev, strerror(errno)); | |||
close(fd); | goto out; | |||
return rv; | ||||
} | } | |||
} | } | |||
if (array.raid_disks == 0 && external) | if (array.raid_disks == 0 && external) | |||
is_container = 1; | is_container = 1; | |||
if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode)) | if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode)) | |||
stb.st_rdev = 0; | stb.st_rdev = 0; | |||
rv = 0; | rv = 0; | |||
if (st) | if (st) | |||
skipping to change at line 226 | skipping to change at line 223 | |||
if (memcmp(uuid_zero, | if (memcmp(uuid_zero, | |||
info->uuid, | info->uuid, | |||
sizeof(uuid_zero)) == 0) { | sizeof(uuid_zero)) == 0) { | |||
st->ss->free_super(st); | st->ss->free_super(st); | |||
continue; | continue; | |||
} | } | |||
break; | break; | |||
} | } | |||
/* Ok, we have some info to print... */ | /* Ok, we have some info to print... */ | |||
str = map_num(pers, array.level); | if (inactive && info) | |||
str = map_num(pers, info->array.level); | ||||
else | ||||
str = map_num(pers, array.level); | ||||
if (c->export) { | if (c->export) { | |||
if (array.raid_disks) { | if (array.raid_disks) { | |||
if (str) | if (str) | |||
printf("MD_LEVEL=%s\n", str); | printf("MD_LEVEL=%s\n", str); | |||
printf("MD_DEVICES=%d\n", array.raid_disks); | printf("MD_DEVICES=%d\n", array.raid_disks); | |||
} else { | } else { | |||
if (is_container) | if (is_container) | |||
printf("MD_LEVEL=container\n"); | printf("MD_LEVEL=container\n"); | |||
printf("MD_DEVICES=%d\n", array.nr_disks); | printf("MD_DEVICES=%d\n", array.nr_disks); | |||
skipping to change at line 283 | skipping to change at line 283 | |||
printf("MD_UUID=%s\n", nbuf+5); | printf("MD_UUID=%s\n", nbuf+5); | |||
} | } | |||
if (mp && mp->path && | if (mp && mp->path && | |||
strncmp(mp->path, "/dev/md/", 8) == 0) { | strncmp(mp->path, "/dev/md/", 8) == 0) { | |||
printf("MD_DEVNAME="); | printf("MD_DEVNAME="); | |||
print_escape(mp->path+8); | print_escape(mp->path+8); | |||
putchar('\n'); | putchar('\n'); | |||
} | } | |||
map_free(map); | map_free(map); | |||
} | } | |||
if (sra) { | if (!c->no_devices && sra) { | |||
struct mdinfo *mdi; | struct mdinfo *mdi; | |||
for (mdi = sra->devs; mdi; mdi = mdi->next) { | for (mdi = sra->devs; mdi; mdi = mdi->next) { | |||
char *path; | char *path; | |||
char *sysdev = xstrdup(mdi->sys_name + 1); | char *sysdev = xstrdup(mdi->sys_name); | |||
char *cp; | char *cp; | |||
path = map_dev(mdi->disk.major, | path = map_dev(mdi->disk.major, | |||
mdi->disk.minor, 0); | mdi->disk.minor, 0); | |||
for (cp = sysdev; *cp; cp++) | for (cp = sysdev; *cp; cp++) | |||
if (!isalnum(*cp)) | if (!isalnum(*cp)) | |||
*cp = '_'; | *cp = '_'; | |||
if (mdi->disk.raid_disk >= 0) | if (mdi->disk.raid_disk >= 0) | |||
printf("MD_DEVICE_%s_ROLE=%d\n", | printf("MD_DEVICE_%s_ROLE=%d\n", | |||
skipping to change at line 354 | skipping to change at line 354 | |||
(1 << MD_DISK_REMOVED) && | (1 << MD_DISK_REMOVED) && | |||
!(disk.state & (1 << MD_DISK_JOURNAL))) | !(disk.state & (1 << MD_DISK_JOURNAL))) | |||
disks[disk.raid_disk * 2 + 1] = disk; | disks[disk.raid_disk * 2 + 1] = disk; | |||
else if (next < max_disks * 2) | else if (next < max_disks * 2) | |||
disks[next++] = disk; | disks[next++] = disk; | |||
} | } | |||
avail = xcalloc(array.raid_disks, 1); | avail = xcalloc(array.raid_disks, 1); | |||
for (d = 0; d < array.raid_disks; d++) { | for (d = 0; d < array.raid_disks; d++) { | |||
char dv[PATH_MAX], dv_rep[PATH_MAX]; | ||||
snprintf(dv, PATH_MAX, "/sys/dev/block/%d:%d", | ||||
disks[d*2].major, disks[d*2].minor); | ||||
snprintf(dv_rep, PATH_MAX, "/sys/dev/block/%d:%d", | ||||
disks[d*2+1].major, disks[d*2+1].minor); | ||||
if ((disks[d*2].state & (1<<MD_DISK_SYNC)) || | if ((is_dev_alive(dv) && (disks[d*2].state & (1<<MD_DISK_SYNC))) | |||
(disks[d*2+1].state & (1<<MD_DISK_SYNC))) { | || | |||
(is_dev_alive(dv_rep) && (disks[d*2+1].state & (1<<MD_DISK_SY | ||||
NC)))) { | ||||
avail_disks ++; | avail_disks ++; | |||
avail[d] = 1; | avail[d] = 1; | |||
} else | } else | |||
rv |= !! c->test; | rv |= !! c->test; | |||
} | } | |||
if (c->brief) { | if (c->brief) { | |||
mdu_bitmap_file_t bmf; | mdu_bitmap_file_t bmf; | |||
if (inactive && !is_container) | if (inactive && !is_container) | |||
printf("INACTIVE-ARRAY %s", dev); | printf("INACTIVE-ARRAY %s", dev); | |||
skipping to change at line 470 | skipping to change at line 475 | |||
(sra && sra->array.major_version == 0))) | (sra && sra->array.major_version == 0))) | |||
printf(" Preferred Minor : %d\n", array.md_minor); | printf(" Preferred Minor : %d\n", array.md_minor); | |||
if (sra == NULL || sra->array.major_version >= 0) | if (sra == NULL || sra->array.major_version >= 0) | |||
printf(" Persistence : Superblock is %spersistent\n ", | printf(" Persistence : Superblock is %spersistent\n ", | |||
array.not_persistent ? "not " : ""); | array.not_persistent ? "not " : ""); | |||
printf("\n"); | printf("\n"); | |||
/* Only try GET_BITMAP_FILE for 0.90.01 and later */ | /* Only try GET_BITMAP_FILE for 0.90.01 and later */ | |||
if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) { | if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) { | |||
printf(" Intent Bitmap : %s\n", bmf.pathname); | printf(" Intent Bitmap : %s\n", bmf.pathname); | |||
printf("\n"); | printf("\n"); | |||
} else if (array.state & (1<<MD_SB_BITMAP_PRESENT)) | } else if (array.state & (1<<MD_SB_CLUSTERED)) | |||
printf(" Intent Bitmap : Internal(Clustered)\n\n"); | ||||
else if (array.state & (1<<MD_SB_BITMAP_PRESENT)) | ||||
printf(" Intent Bitmap : Internal\n\n"); | printf(" Intent Bitmap : Internal\n\n"); | |||
atime = array.utime; | atime = array.utime; | |||
if (atime) | if (atime) | |||
printf(" Update Time : %.24s\n", ctime(&atime)); | printf(" Update Time : %.24s\n", ctime(&atime)); | |||
if (array.raid_disks) { | if (array.raid_disks) { | |||
static char *sync_action[] = { | static char *sync_action[] = { | |||
", recovering", ", resyncing", | ", recovering", ", resyncing", | |||
", reshaping", ", checking" }; | ", reshaping", ", checking" }; | |||
char *st; | char *st; | |||
if (avail_disks == array.raid_disks) | if (avail_disks == array.raid_disks) | |||
st = ""; | st = ""; | |||
else if (!enough(array.level, array.raid_disks, | else if (!enough(array.level, array.raid_disks, | |||
array.layout, 1, avail)) | array.layout, 1, avail)) | |||
st = ", FAILED"; | st = ", FAILED"; | |||
else | else | |||
st = ", degraded"; | st = ", degraded"; | |||
printf(" State : %s%s%s%s%s%s \n", | if (array.state & (1 << MD_SB_CLEAN)) { | |||
(array.state & (1 << MD_SB_CLEAN)) ? | if ((array.level == 0) || | |||
"clean" : "active", st, | (array.level == LEVEL_LINEAR)) | |||
arrayst = map_num(sysfs_array_states, | ||||
sra->array_state); | ||||
else | ||||
arrayst = "clean"; | ||||
} else { | ||||
arrayst = "active"; | ||||
if (array.state & (1<<MD_SB_CLUSTERED)) { | ||||
for (d = 0; d < max_disks * 2; d++) { | ||||
char *dv; | ||||
mdu_disk_info_t disk = disks[d]; | ||||
/* only check first valid disk in | ||||
cluster env */ | ||||
if ((disk.state & (MD_DISK_SYNC | | ||||
MD_DISK_ACTIVE)) | ||||
&& (disk.major | disk.min | ||||
or)) { | ||||
dv = map_dev_preferred(di | ||||
sk.major, disk.minor, 0, | ||||
c->prefer | ||||
); | ||||
if (!dv) | ||||
continue; | ||||
arrayst = IsBitmapDirty(d | ||||
v) ? "active" : "clean"; | ||||
break; | ||||
} | ||||
} | ||||
} | ||||
} | ||||
printf(" State : %s%s%s%s%s%s%s \n", | ||||
arrayst, st, | ||||
(!e || (e->percent < 0 && | (!e || (e->percent < 0 && | |||
e->percent != RESYNC_PENDING && | e->percent != RESYNC_PENDING && | |||
e->percent != RESYNC_DELAYED)) ? | e->percent != RESYNC_DELAYED && | |||
e->percent != RESYNC_REMOTE)) ? | ||||
"" : sync_action[e->resync], | "" : sync_action[e->resync], | |||
larray_size ? "": ", Not Started", | larray_size ? "": ", Not Started", | |||
(e && e->percent == RESYNC_DELAYED) ? | (e && e->percent == RESYNC_DELAYED) ? | |||
" (DELAYED)": "", | " (DELAYED)": "", | |||
(e && e->percent == RESYNC_PENDING) ? | (e && e->percent == RESYNC_PENDING) ? | |||
" (PENDING)": ""); | " (PENDING)": "", | |||
(e && e->percent == RESYNC_REMOTE) ? | ||||
" (REMOTE)": ""); | ||||
} else if (inactive && !is_container) { | } else if (inactive && !is_container) { | |||
printf(" State : inactive\n"); | printf(" State : inactive\n"); | |||
} | } | |||
if (array.raid_disks) | if (array.raid_disks) | |||
printf(" Active Devices : %d\n", array.active_disks); | printf(" Active Devices : %d\n", array.active_disks); | |||
if (array.working_disks > 0) | if (array.working_disks > 0) | |||
printf(" Working Devices : %d\n", | printf(" Working Devices : %d\n", | |||
array.working_disks); | array.working_disks); | |||
if (array.raid_disks) { | if (array.raid_disks) { | |||
printf(" Failed Devices : %d\n", array.failed_disks); | printf(" Failed Devices : %d\n", array.failed_disks); | |||
printf(" Spare Devices : %d\n", array.spare_disks); | if (!external) | |||
printf(" Spare Devices : %d\n", array.spare_d | ||||
isks); | ||||
} | } | |||
printf("\n"); | printf("\n"); | |||
if (array.level == 5) { | if (array.level == 5) { | |||
str = map_num(r5layout, array.layout); | str = map_num(r5layout, array.layout); | |||
printf(" Layout : %s\n", | printf(" Layout : %s\n", | |||
str ? str : "-unknown-"); | str ? str : "-unknown-"); | |||
} | } | |||
if (array.level == 0 && array.layout) { | ||||
str = map_num(r0layout, array.layout); | ||||
printf(" Layout : %s\n", | ||||
str ? str : "-unknown-"); | ||||
} | ||||
if (array.level == 6) { | if (array.level == 6) { | |||
str = map_num(r6layout, array.layout); | str = map_num(r6layout, array.layout); | |||
printf(" Layout : %s\n", | printf(" Layout : %s\n", | |||
str ? str : "-unknown-"); | str ? str : "-unknown-"); | |||
} | } | |||
if (array.level == 10) { | if (array.level == 10) { | |||
printf(" Layout :"); | printf(" Layout :"); | |||
print_r10_layout(array.layout); | print_r10_layout(array.layout); | |||
printf("\n"); | printf("\n"); | |||
} | } | |||
skipping to change at line 616 | skipping to change at line 659 | |||
} | } | |||
if (info->new_chunk != array.chunk_size) | if (info->new_chunk != array.chunk_size) | |||
printf(" New Chunksize : %dK\n", | printf(" New Chunksize : %dK\n", | |||
info->new_chunk/1024); | info->new_chunk/1024); | |||
printf("\n"); | printf("\n"); | |||
} else if (e && e->percent >= 0) | } else if (e && e->percent >= 0) | |||
printf("\n"); | printf("\n"); | |||
free_mdstat(ms); | free_mdstat(ms); | |||
if (st && st->sb) | if (st && st->sb) | |||
st->ss->detail_super(st, c->homehost); | st->ss->detail_super(st, c->homehost, subarray); | |||
if (array.raid_disks == 0 && sra && | if (array.raid_disks == 0 && sra && | |||
sra->array.major_version == -1 && | sra->array.major_version == -1 && | |||
sra->array.minor_version == -2 && | sra->array.minor_version == -2 && | |||
sra->text_version[0] != '/') { | sra->text_version[0] != '/') { | |||
/* This looks like a container. Find any active arrays | /* This looks like a container. Find any active arrays | |||
* That claim to be a member. | * That claim to be a member. | |||
*/ | */ | |||
DIR *dir = opendir("/sys/block"); | DIR *dir = opendir("/sys/block"); | |||
struct dirent *de; | struct dirent *de; | |||
skipping to change at line 658 | skipping to change at line 701 | |||
printf(" %s", | printf(" %s", | |||
map_dev_preferred(major(devid), | map_dev_preferred(major(devid), | |||
minor(devid), 1, | minor(devid), 1, | |||
c->prefer)); | c->prefer)); | |||
} | } | |||
if (dir) | if (dir) | |||
closedir(dir); | closedir(dir); | |||
printf("\n\n"); | printf("\n\n"); | |||
} | } | |||
if (array.raid_disks) | if (!c->no_devices) { | |||
printf(" Number Major Minor RaidDevice State\n") | if (array.raid_disks) | |||
; | printf(" Number Major Minor RaidDevice S | |||
else | tate\n"); | |||
printf(" Number Major Minor RaidDevice\n"); | else | |||
printf(" Number Major Minor RaidDevice\n | ||||
"); | ||||
} | ||||
} | } | |||
free(info); | ||||
/* if --no_devices specified, not print component devices info */ | ||||
if (c->no_devices) | ||||
goto skip_devices_state; | ||||
for (d = 0; d < max_disks * 2; d++) { | for (d = 0; d < max_disks * 2; d++) { | |||
char *dv; | char *dv; | |||
mdu_disk_info_t disk = disks[d]; | mdu_disk_info_t disk = disks[d]; | |||
if (d >= array.raid_disks * 2 && | if (d >= array.raid_disks * 2 && | |||
disk.major == 0 && disk.minor == 0) | disk.major == 0 && disk.minor == 0) | |||
continue; | continue; | |||
if ((d & 1) && disk.major == 0 && disk.minor == 0) | if ((d & 1) && disk.major == 0 && disk.minor == 0) | |||
continue; | continue; | |||
skipping to change at line 746 | skipping to change at line 794 | |||
} | } | |||
if (disk.state == 0) | if (disk.state == 0) | |||
spares++; | spares++; | |||
dv = map_dev_preferred(disk.major, disk.minor, 0, c->prefer); | dv = map_dev_preferred(disk.major, disk.minor, 0, c->prefer); | |||
if (dv != NULL) { | if (dv != NULL) { | |||
if (c->brief) | if (c->brief) | |||
n_devices = add_device(dv, &devices, | n_devices = add_device(dv, &devices, | |||
&max_devices, n_devices); | &max_devices, n_devices); | |||
else | else | |||
printf(" %s", dv); | printf(" %s", dv); | |||
} | } else if (disk.major | disk.minor) | |||
printf(" missing"); | ||||
if (!c->brief) | if (!c->brief) | |||
printf("\n"); | printf("\n"); | |||
} | } | |||
skip_devices_state: | ||||
if (spares && c->brief && array.raid_disks) | if (spares && c->brief && array.raid_disks) | |||
printf(" spares=%d", spares); | printf(" spares=%d", spares); | |||
if (c->brief && st && st->sb) | if (c->brief && st && st->sb) | |||
st->ss->brief_detail_super(st); | st->ss->brief_detail_super(st, subarray); | |||
if (st) | if (st) | |||
st->ss->free_super(st); | st->ss->free_super(st); | |||
if (c->brief && c->verbose > 0 && devices) { | if (c->brief && c->verbose > 0 && devices) { | |||
qsort(devices, n_devices, sizeof(*devices), cmpstringp); | qsort(devices, n_devices, sizeof(*devices), cmpstringp); | |||
printf("\n devices=%s", devices[0]); | printf("\n devices=%s", devices[0]); | |||
for (d = 1; d < n_devices; d++) | for (d = 1; d < n_devices; d++) | |||
printf(",%s", devices[d]); | printf(",%s", devices[d]); | |||
} | } | |||
if (c->brief) | if (c->brief) | |||
printf("\n"); | printf("\n"); | |||
if (c->test && | if (c->test && | |||
!enough(array.level, array.raid_disks, array.layout, 1, avail)) | !enough(array.level, array.raid_disks, array.layout, 1, avail)) | |||
rv = 2; | rv = 2; | |||
free(disks); | ||||
out: | out: | |||
free(info); | ||||
free(disks); | ||||
close(fd); | close(fd); | |||
free(subarray); | free(subarray); | |||
free(avail); | free(avail); | |||
for (d = 0; d < n_devices; d++) | if (devices) | |||
free(devices[d]); | for (d = 0; d < n_devices; d++) | |||
free(devices[d]); | ||||
free(devices); | free(devices); | |||
sysfs_free(sra); | sysfs_free(sra); | |||
free(st); | ||||
return rv; | return rv; | |||
} | } | |||
int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, c har *controller_path) | int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, c har *controller_path) | |||
{ | { | |||
/* display platform capabilities for the given metadata format | /* display platform capabilities for the given metadata format | |||
* 'scan' in this context means iterate over all metadata types | * 'scan' in this context means iterate over all metadata types | |||
*/ | */ | |||
int i; | int i; | |||
int err = 1; | int err = 1; | |||
End of changes. 28 change blocks. | ||||
34 lines changed or deleted | 98 lines changed or added |