static int show_config(int ac, char **av) { CONFIG_PAGE_IOC_2 *ioc2; CONFIG_PAGE_IOC_2_RAID_VOL *vol; CONFIG_PAGE_IOC_5 *ioc5; IOC_5_HOT_SPARE *spare; CONFIG_PAGE_RAID_VOL_0 *vinfo; RAID_VOL0_PHYS_DISK *disk; CONFIG_PAGE_RAID_VOL_1 *vnames; CONFIG_PAGE_RAID_PHYS_DISK_0 *pinfo; struct mpt_standalone_disk *sdisks; int error, fd, i, j, nsdisks; if (ac != 1) { warnx("show config: extra arguments"); return (EINVAL); } fd = mpt_open(mpt_unit); if (fd < 0) { error = errno; warn("mpt_open"); return (error); } /* Get the config from the controller. */ ioc2 = mpt_read_ioc_page(fd, 2, NULL); ioc5 = mpt_read_ioc_page(fd, 5, NULL); if (ioc2 == NULL || ioc5 == NULL) { error = errno; warn("Failed to get config"); return (error); } if (mpt_fetch_disks(fd, &nsdisks, &sdisks) < 0) { error = errno; warn("Failed to get standalone drive list"); return (error); } /* Dump out the configuration. */ printf("mpt%d Configuration: %d volumes, %d drives\n", mpt_unit, ioc2->NumActiveVolumes, ioc2->NumActivePhysDisks + nsdisks); vol = ioc2->RaidVolume; for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { printf(" volume %s ", mpt_volume_name(vol->VolumeBus, vol->VolumeID)); vinfo = mpt_vol_info(fd, vol->VolumeBus, vol->VolumeID, NULL); if (vinfo == NULL) { printf("%s UNKNOWN", mpt_raid_level(vol->VolumeType)); } else print_vol(vinfo, -1); vnames = mpt_vol_names(fd, vol->VolumeBus, vol->VolumeID, NULL); if (vnames != NULL) { if (vnames->Name[0] != '\0') printf(" <%s>", vnames->Name); free(vnames); } if (vinfo == NULL) { printf("\n"); continue; } printf(" spans:\n"); disk = vinfo->PhysDisk; for (j = 0; j < vinfo->NumPhysDisks; disk++, j++) { printf(" drive %u ", disk->PhysDiskNum); pinfo = mpt_pd_info(fd, disk->PhysDiskNum, NULL); if (pinfo != NULL) { print_pd(pinfo, -1, 0); free(pinfo); } printf("\n"); } if (vinfo->VolumeSettings.HotSparePool != 0) { printf(" spare pools: "); print_spare_pools(vinfo->VolumeSettings.HotSparePool); printf("\n"); } free(vinfo); } spare = ioc5->HotSpare; for (i = 0; i < ioc5->NumHotSpares; spare++, i++) { printf(" spare %u ", spare->PhysDiskNum); pinfo = mpt_pd_info(fd, spare->PhysDiskNum, NULL); if (pinfo != NULL) { print_pd(pinfo, -1, 0); free(pinfo); } printf(" backs pool %d\n", ffs(spare->HotSparePool) - 1); } for (i = 0; i < nsdisks; i++) { printf(" drive %s ", sdisks[i].devname); print_standalone(&sdisks[i], -1, 0); printf("\n"); } free(ioc2); free(ioc5); free(sdisks); close(fd); return (0); }
static int show_volumes(int ac, char **av) { CONFIG_PAGE_IOC_2 *ioc2; CONFIG_PAGE_IOC_2_RAID_VOL *vol; CONFIG_PAGE_RAID_VOL_0 **volumes; CONFIG_PAGE_RAID_VOL_1 *vnames; int error, fd, i, len, state_len; if (ac != 1) { warnx("show volumes: extra arguments"); return (EINVAL); } fd = mpt_open(mpt_unit); if (fd < 0) { error = errno; warn("mpt_open"); return (error); } /* Get the volume list from the controller. */ ioc2 = mpt_read_ioc_page(fd, 2, NULL); if (ioc2 == NULL) { error = errno; warn("Failed to get volume list"); return (error); } /* * Go ahead and read the info for all the volumes and figure * out the maximum width of the state field. */ volumes = malloc(sizeof(*volumes) * ioc2->NumActiveVolumes); state_len = strlen("State"); vol = ioc2->RaidVolume; for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { volumes[i] = mpt_vol_info(fd, vol->VolumeBus, vol->VolumeID, NULL); if (volumes[i] == NULL) len = strlen("UNKNOWN"); else len = strlen(mpt_volstate( volumes[i]->VolumeStatus.State)); if (len > state_len) state_len = len; } printf("mpt%d Volumes:\n", mpt_unit); printf(" Id Size Level Stripe "); len = state_len - strlen("State"); for (i = 0; i < (len + 1) / 2; i++) printf(" "); printf("State"); for (i = 0; i < len / 2; i++) printf(" "); printf(" Write-Cache Name\n"); vol = ioc2->RaidVolume; for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { printf("%6s ", mpt_volume_name(vol->VolumeBus, vol->VolumeID)); if (volumes[i] != NULL) print_vol(volumes[i], state_len); else printf(" %-8s %-*s", mpt_raid_level(vol->VolumeType), state_len, "UNKNOWN"); if (volumes[i] != NULL) { if (volumes[i]->VolumeSettings.Settings & MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE) printf(" Enabled "); else printf(" Disabled "); } else printf(" "); free(volumes[i]); vnames = mpt_vol_names(fd, vol->VolumeBus, vol->VolumeID, NULL); if (vnames != NULL) { if (vnames->Name[0] != '\0') printf(" <%s>", vnames->Name); free(vnames); } printf("\n"); } free(ioc2); close(fd); return (0); }