Add get-status to the ATA RAID subsystem.

This commit is contained in:
Søren Schmidt 2002-04-02 13:48:17 +00:00
parent 246a3f534a
commit 3348c0092c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=93662
6 changed files with 125 additions and 12 deletions

View File

@ -55,6 +55,9 @@
.Ic rebuild
.Ar raid
.Nm
.Ic status
.Ar raid
.Nm
.Ic mode
.Ar channel
.Op Ar mastermode slavemode
@ -124,6 +127,8 @@ reside on the first disk in the SPAN.
Deletes a RAID array on a RAID capable ATA controller.
.It Ic rebuild
Rebuild a RAID1 array on a RAID capable ATA controller.
.It Ic status
Get the status of an ATA RAID.
.It Ic mode
Without the two mode arguments the current transfer modes of both
devices are printed.

View File

@ -248,6 +248,7 @@ main(int argc, char **argv)
int chan;
if (!strcmp(argv[1], "delete") ||
!strcmp(argv[1], "status") ||
!strcmp(argv[1], "rebuild")) {
if (!(sscanf(argv[2], "%d", &chan) == 1 ||
sscanf(argv[2], "ar%d", &chan) == 1))
@ -300,16 +301,6 @@ main(int argc, char **argv)
warn("ioctl(ATAREINIT)");
info_print(fd, iocmd.channel, 0);
}
else if (!strcmp(argv[1], "rebuild") && argc == 3) {
iocmd.cmd = ATARAIDREBUILD;
if (ioctl(fd, IOCATA, &iocmd) < 0)
warn("ioctl(ATARAIDREBUILD)");
}
else if (!strcmp(argv[1], "delete") && argc == 3) {
iocmd.cmd = ATARAIDDELETE;
if (ioctl(fd, IOCATA, &iocmd) < 0)
warn("ioctl(ATARAIDDELETE)");
}
else if (!strcmp(argv[1], "create")) {
int disk, dev, offset;
@ -342,10 +333,64 @@ main(int argc, char **argv)
}
iocmd.u.raid_setup.total_disks = disk;
if (ioctl(fd, IOCATA, &iocmd) < 0)
warn("ioctl(ATARAIDCREATE)");
err(1, "ioctl(ATARAIDCREATE)");
else
printf("ar%d created\n", iocmd.u.raid_setup.unit);
}
else if (!strcmp(argv[1], "delete") && argc == 3) {
iocmd.cmd = ATARAIDDELETE;
if (ioctl(fd, IOCATA, &iocmd) < 0)
warn("ioctl(ATARAIDDELETE)");
}
else if (!strcmp(argv[1], "rebuild") && argc == 3) {
iocmd.cmd = ATARAIDREBUILD;
if (ioctl(fd, IOCATA, &iocmd) < 0)
warn("ioctl(ATARAIDREBUILD)");
}
else if (!strcmp(argv[1], "status") && argc == 3) {
int i;
iocmd.cmd = ATARAIDSTATUS;
if (ioctl(fd, IOCATA, &iocmd) < 0)
err(1, "ioctl(ATARAIDSTATUS)");
printf("ar%d: ATA ", iocmd.channel);
switch (iocmd.u.raid_status.type) {
case AR_RAID0:
printf("RAID0");
break;
case AR_RAID1:
printf("RAID1");
break;
case AR_RAID0 | AR_RAID1:
printf("RAID0+1");
break;
case AR_SPAN:
printf("SPAN");
break;
}
printf(" subdisks: ");
for (i = 0; i < iocmd.u.raid_status.total_disks; i++) {
if (iocmd.u.raid_status.disks[i] >= 0)
printf("ad%d ", iocmd.u.raid_status.disks[i]);
else
printf("DOWN ");
}
printf("status: ");
switch (iocmd.u.raid_status.status) {
case AR_READY:
printf("READY\n");
break;
case AR_READY | AR_DEGRADED:
printf("DEGRADED\n");
break;
case AR_READY | AR_DEGRADED | AR_REBUILDING:
printf("REBUILDING %d%% completed\n",
iocmd.u.raid_status.progress);
break;
default:
printf("BROKEN\n");
}
}
else if (!strcmp(argv[1], "mode") && (argc == 3 || argc == 5)) {
if (argc == 5) {
iocmd.cmd = ATASMODE;

View File

@ -415,6 +415,9 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *td)
case ATARAIDDELETE:
return ata_raid_delete(iocmd->channel);
case ATARAIDSTATUS:
return ata_raid_status(iocmd->channel, &iocmd->u.raid_status);
#endif
#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST)
case ATAPICMD: {

View File

@ -404,7 +404,50 @@ ata_raid_delete(int array)
ar_table[array] = NULL;
return 0;
}
int
ata_raid_status(int array, struct raid_status *status)
{
struct ar_softc *rdp;
int i;
if (!ar_table || !(rdp = ar_table[array]))
return ENXIO;
switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) {
case AR_F_RAID0:
status->type = AR_RAID0;
break;
case AR_F_RAID1:
status->type = AR_RAID1;
break;
case AR_F_RAID0 | AR_F_RAID1:
status->type = AR_RAID0 | AR_RAID1;
break;
case AR_F_SPAN:
status->type = AR_SPAN;
break;
}
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].device)
status->disks[i] = AD_SOFTC(rdp->disks[i])->lun;
else
status->disks[i] = -1;
}
status->interleave = rdp->interleave;
status->status = 0;
if (rdp->flags & AR_F_READY)
status->status |= AR_READY;
if (rdp->flags & AR_F_DEGRADED)
status->status |= AR_DEGRADED;
if (rdp->flags & AR_F_REBUILDING) {
status->status |= AR_REBUILDING;
status->progress = 100*rdp->lock_start/(rdp->total_sectors/rdp->width);
}
return 0;
}
int
ata_raid_rebuild(int array)
{

View File

@ -228,4 +228,5 @@ int ata_raiddisk_detach(struct ad_softc *);
void ata_raid_attach(void);
int ata_raid_create(struct raid_setup *);
int ata_raid_delete(int);
int ata_raid_status(int array, struct raid_status *);
int ata_raid_rebuild(int);

View File

@ -250,11 +250,27 @@ struct ata_cmd {
} param;
struct raid_setup {
int type;
#define AR_RAID0 1
#define AR_RAID1 2
#define AR_SPAN 4
int total_disks;
int disks[16];
int interleave;
int unit;
} raid_setup;
struct raid_status {
int type;
int total_disks;
int disks[16];
int interleave;
int status;
#define AR_READY 1
#define AR_DEGRADED 2
#define AR_REBUILDING 4
int progress;
} raid_status;
struct {
int fan;
int temp;