diff options
-rw-r--r-- | sbin/atacontrol/atacontrol.c | 50 | ||||
-rw-r--r-- | sys/dev/ata/ata-raid.c | 36 | ||||
-rw-r--r-- | sys/sys/ata.h | 18 |
3 files changed, 70 insertions, 34 deletions
diff --git a/sbin/atacontrol/atacontrol.c b/sbin/atacontrol/atacontrol.c index 27aeb00..451ae75 100644 --- a/sbin/atacontrol/atacontrol.c +++ b/sbin/atacontrol/atacontrol.c @@ -528,30 +528,30 @@ main(int argc, char **argv) exit(EX_OK); } if (!strcmp(argv[1], "status") && argc == 3) { - struct ata_ioc_raid_config config; - int i; + struct ata_ioc_raid_status status; + int i, lun, state; - if (!(sscanf(argv[2], "ar%d", &config.lun) == 1)) { + if (!(sscanf(argv[2], "ar%d", &status.lun) == 1)) { fprintf(stderr, "atacontrol: Invalid array %s\n", argv[2]); usage(); } - if (ioctl(fd, IOCATARAIDSTATUS, &config) < 0) + if (ioctl(fd, IOCATARAIDSTATUS, &status) < 0) err(1, "ioctl(IOCATARAIDSTATUS)"); - printf("ar%d: ATA ", config.lun); - switch (config.type) { + printf("ar%d: ATA ", status.lun); + switch (status.type) { case AR_RAID0: - printf("RAID0 stripesize=%d", config.interleave); + printf("RAID0 stripesize=%d", status.interleave); break; case AR_RAID1: printf("RAID1"); break; case AR_RAID01: - printf("RAID0+1 stripesize=%d", config.interleave); + printf("RAID0+1 stripesize=%d", status.interleave); break; case AR_RAID5: - printf("RAID5 stripesize=%d", config.interleave); + printf("RAID5 stripesize=%d", status.interleave); break; case AR_JBOD: printf("JBOD"); @@ -559,15 +559,8 @@ main(int argc, char **argv) printf("SPAN"); break; } - printf(" subdisks: "); - for (i = 0; i < config.total_disks; i++) { - if (config.disks[i] >= 0) - printf("ad%d ", config.disks[i]); - else - printf("DOWN "); - } - printf("status: "); - switch (config.status) { + printf(" status: "); + switch (status.status) { case AR_READY: printf("READY\n"); break; @@ -576,11 +569,30 @@ main(int argc, char **argv) break; case AR_READY | AR_DEGRADED | AR_REBUILDING: printf("REBUILDING %d%% completed\n", - config.progress); + status.progress); break; default: printf("BROKEN\n"); } + printf(" subdisks:\n"); + for (i = 0; i < status.total_disks; i++) { + printf(" %2d ", i); + lun = status.disks[i].lun; + state = status.disks[i].state; + if (lun < 0) + printf("---- "); + else + printf("ad%-2d ", lun); + if (state & AR_DISK_ONLINE) + printf("ONLINE"); + else if (state & AR_DISK_SPARE) + printf("SPARE"); + else if (state & AR_DISK_PRESENT) + printf("OFFLINE"); + else + printf("MISSING"); + printf("\n"); + } exit(EX_OK); } usage(); diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c index 4501f5a..2356d23 100644 --- a/sys/dev/ata/ata-raid.c +++ b/sys/dev/ata/ata-raid.c @@ -56,7 +56,7 @@ __FBSDID("$FreeBSD$"); /* prototypes */ static void ata_raid_done(struct ata_request *request); static void ata_raid_config_changed(struct ar_softc *rdp, int writeback); -static int ata_raid_status(struct ata_ioc_raid_config *config); +static int ata_raid_status(struct ata_ioc_raid_status *status); static int ata_raid_create(struct ata_ioc_raid_config *config); static int ata_raid_delete(int array); static int ata_raid_addspare(struct ata_ioc_raid_config *config); @@ -216,13 +216,14 @@ ata_raid_attach(struct ar_softc *rdp, int writeback) static int ata_raid_ioctl(u_long cmd, caddr_t data) { + struct ata_ioc_raid_status *status = (struct ata_ioc_raid_status *)data; struct ata_ioc_raid_config *config = (struct ata_ioc_raid_config *)data; int *lun = (int *)data; int error = EOPNOTSUPP; switch (cmd) { case IOCATARAIDSTATUS: - error = ata_raid_status(config); + error = ata_raid_status(status); break; case IOCATARAIDCREATE: @@ -929,25 +930,32 @@ ata_raid_config_changed(struct ar_softc *rdp, int writeback) } static int -ata_raid_status(struct ata_ioc_raid_config *config) +ata_raid_status(struct ata_ioc_raid_status *status) { struct ar_softc *rdp; int i; - if (!(rdp = ata_raid_arrays[config->lun])) + if (!(rdp = ata_raid_arrays[status->lun])) return ENXIO; - config->type = rdp->type; - config->total_disks = rdp->total_disks; + status->type = rdp->type; + status->total_disks = rdp->total_disks; for (i = 0; i < rdp->total_disks; i++ ) { - if ((rdp->disks[i].flags & AR_DF_PRESENT) && rdp->disks[i].dev) - config->disks[i] = device_get_unit(rdp->disks[i].dev); - else - config->disks[i] = -1; - } - config->interleave = rdp->interleave; - config->status = rdp->status; - config->progress = 100 * rdp->rebuild_lba / rdp->total_sectors; + status->disks[i].state = 0; + if ((rdp->disks[i].flags & AR_DF_PRESENT) && rdp->disks[i].dev) { + status->disks[i].lun = device_get_unit(rdp->disks[i].dev); + if (rdp->disks[i].flags & AR_DF_PRESENT) + status->disks[i].state |= AR_DISK_PRESENT; + if (rdp->disks[i].flags & AR_DF_ONLINE) + status->disks[i].state |= AR_DISK_ONLINE; + if (rdp->disks[i].flags & AR_DF_SPARE) + status->disks[i].state |= AR_DISK_SPARE; + } else + status->disks[i].lun = -1; + } + status->interleave = rdp->interleave; + status->status = rdp->status; + status->progress = 100 * rdp->rebuild_lba / rdp->total_sectors; return 0; } diff --git a/sys/sys/ata.h b/sys/sys/ata.h index 43b8e83..4eab64d 100644 --- a/sys/sys/ata.h +++ b/sys/sys/ata.h @@ -447,10 +447,26 @@ struct ata_ioc_raid_config { int disks[16]; }; +struct ata_ioc_raid_status { + int lun; + int type; + int interleave; + int status; + int progress; + int total_disks; + struct { + int state; +#define AR_DISK_ONLINE 0x01 +#define AR_DISK_PRESENT 0x02 +#define AR_DISK_SPARE 0x04 + int lun; + } disks[16]; +}; + /* ATA RAID ioctl calls */ #define IOCATARAIDCREATE _IOWR('a', 200, struct ata_ioc_raid_config) #define IOCATARAIDDELETE _IOW('a', 201, int) -#define IOCATARAIDSTATUS _IOWR('a', 202, struct ata_ioc_raid_config) +#define IOCATARAIDSTATUS _IOWR('a', 202, struct ata_ioc_raid_status) #define IOCATARAIDADDSPARE _IOW('a', 203, struct ata_ioc_raid_config) #define IOCATARAIDREBUILD _IOW('a', 204, int) |