summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/atacontrol/atacontrol.c50
-rw-r--r--sys/dev/ata/ata-raid.c36
-rw-r--r--sys/sys/ata.h18
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)
OpenPOWER on IntegriCloud