MFC: Expand the data structure returned by the ATA RAID status ioctl to

include detailed status on each of the backing subdisks.  A binary compat
shim is provided for the original status ioctl.

Approved by:	sos
This commit is contained in:
jhb 2007-08-24 18:43:00 +00:00
parent 1d80780684
commit a432a3d68c
3 changed files with 97 additions and 33 deletions

View File

@ -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();

View File

@ -56,7 +56,8 @@ __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_old(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);
@ -201,13 +202,18 @@ 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_OLD:
error = ata_raid_status_old(config);
break;
case IOCATARAIDSTATUS:
error = ata_raid_status(config);
error = ata_raid_status(status);
break;
case IOCATARAIDCREATE:
@ -863,25 +869,54 @@ ata_raid_config_changed(struct ar_softc *rdp, int writeback)
}
static int
ata_raid_status(struct ata_ioc_raid_config *config)
ata_raid_status_old(struct ata_ioc_raid_config *config)
{
struct ata_ioc_raid_status status;
int error, i;
status.lun = config->lun;
error = ata_raid_status(&status);
if (error)
return error;
config->type = status.type;
config->total_disks = status.total_disks;
config->interleave = status.interleave;
config->status = status.status;
config->progress = status.progress;
for (i = 0; i < config->total_disks; i++)
config->disks[i] = status.disks[i].lun;
return (0);
}
static int
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;
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;
}
config->interleave = rdp->interleave;
config->status = rdp->status;
config->progress = 100 * rdp->rebuild_lba / rdp->total_sectors;
status->interleave = rdp->interleave;
status->status = rdp->status;
status->progress = 100 * rdp->rebuild_lba / rdp->total_sectors;
return 0;
}

View File

@ -447,10 +447,27 @@ 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_OLD _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)