Add ioctl to add a spare disk to a RAID array.

Fix the discovery of RAID's to not grap unused disks.
Change the probe printing of a RAID a bit.
This commit is contained in:
Søren Schmidt 2003-05-02 12:41:44 +00:00
parent bdf54b2fc4
commit 31de970e72
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=114529
4 changed files with 90 additions and 33 deletions

View file

@ -383,6 +383,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 ATARAIDADDSPARE:
return ata_raid_addspare(iocmd->channel, iocmd->u.raid_spare.disk);
case ATARAIDSTATUS:
return ata_raid_status(iocmd->channel, &iocmd->u.raid_status);
#endif

View file

@ -202,11 +202,9 @@ ad_attach(struct ata_device *atadev)
atadev->flags = 0;
ata_enclosure_print(atadev);
/* only print probe banner if we are not part of a RAID array */
if (!ata_raiddisk_attach(adp))
if (atadev->driver)
ad_print(adp);
if (atadev->driver)
ad_print(adp);
ata_raiddisk_attach(adp);
}
void
@ -248,9 +246,9 @@ adopen(struct disk *dp)
struct ad_softc *adp = dp->d_drv1;
if (adp->flags & AD_F_RAID_SUBDISK)
return EBUSY;
return EPERM;
/* hold off access to we are fully attached */
/* hold off access until we are fully attached */
while (ata_delayed_attach)
tsleep(&ata_delayed_attach, PRIBIO, "adopn", 1);
return 0;

View file

@ -208,22 +208,65 @@ ar_attach_raid(struct ar_softc *rdp, int update)
}
printf(" subdisks:\n");
for (disk = 0; disk < rdp->total_disks; disk++) {
if (rdp->disks[disk].flags & AR_DF_PRESENT) {
if (rdp->disks[disk].flags & AR_DF_ONLINE)
printf(" %d READY ", disk);
else if (rdp->disks[disk].flags & AR_DF_SPARE)
printf(" %d SPARE ", disk);
if (rdp->disks[disk].device &&
AD_SOFTC(rdp->disks[disk])->flags & AD_F_RAID_SUBDISK) {
if (rdp->disks[disk].flags & AR_DF_PRESENT) {
if (rdp->disks[disk].flags & AR_DF_ONLINE)
printf(" disk%d READY ", disk);
else if (rdp->disks[disk].flags & AR_DF_SPARE)
printf(" disk%d SPARE ", disk);
else
printf(" disk%d FREE ", disk);
printf("on %s at ata%d-%s\n", rdp->disks[disk].device->name,
device_get_unit(rdp->disks[disk].device->channel->dev),
(rdp->disks[disk].device->unit == ATA_MASTER) ?
"master" : "slave");
}
else if (rdp->disks[disk].flags & AR_DF_ASSIGNED)
printf(" disk%d DOWN\n", disk);
else
printf(" %d FREE ", disk);
ad_print(AD_SOFTC(rdp->disks[disk]));
printf(" disk%d INVALID no RAID config on this disk\n", disk);
}
else if (rdp->disks[disk].flags & AR_DF_ASSIGNED)
printf(" %d DOWN\n", disk);
else
printf(" %d INVALID no RAID config info on this disk\n", disk);
printf(" disk%d DOWN no device found for this disk\n", disk);
}
}
int
ata_raid_addspare(int array, int disk)
{
struct ar_softc *rdp;
struct ata_device *atadev;
int i;
if (!ar_table || !(rdp = ar_table[array]))
return ENXIO;
if (!(rdp->flags & AR_F_RAID1))
return EPERM;
if (rdp->flags & AR_F_REBUILDING)
return EBUSY;
if (!(rdp->flags & AR_F_DEGRADED) || !(rdp->flags & AR_F_READY))
return ENXIO;
for (i = 0; i < rdp->total_disks; i++ ) {
if (((rdp->disks[i].flags & (AR_DF_PRESENT | AR_DF_ONLINE)) ==
(AR_DF_PRESENT | AR_DF_ONLINE)) && rdp->disks[i].device)
continue;
if ((atadev = ar_locate_disk(disk))) {
if (((struct ad_softc*)(atadev->driver))->flags & AD_F_RAID_SUBDISK)
return EBUSY;
rdp->disks[i].device = atadev;
rdp->disks[i].flags |= (AR_DF_PRESENT|AR_DF_ASSIGNED|AR_DF_SPARE);
AD_SOFTC(rdp->disks[i])->flags |= AD_F_RAID_SUBDISK;
ata_prtdev(rdp->disks[i].device,
"inserted into ar%d disk%d as spare\n", array, i);
ar_config_changed(rdp, 1);
return 0;
}
}
return ENXIO;
}
int
ata_raid_create(struct raid_setup *setup)
{
@ -362,12 +405,13 @@ ata_raid_create(struct raid_setup *setup)
rdp->flags |= AR_F_READY;
ar_table[array] = rdp;
#if 0
/* kick off rebuild here */
if (setup->type == 2) {
rdp->disks[1].flags &= ~AR_DF_ONLINE;
rdp->disks[1].flags |= AR_DF_SPARE;
}
#endif
ar_attach_raid(rdp, 1);
ata_raid_rebuild(array);
setup->unit = array;
@ -1238,14 +1282,20 @@ ar_promise_read_conf(struct ad_softc *adp, struct ar_softc **raidp, int local)
goto promise_out;
}
}
if (raid->disks[info->raid.disk_number].flags && adp->device) {
raid->disks[info->raid.disk_number].device = adp->device;
raid->disks[info->raid.disk_number].flags |= AR_DF_PRESENT;
raid->disks[info->raid.disk_number].disk_sectors =
info->raid.disk_sectors;
AD_SOFTC(raid->disks[info->raid.disk_number])->flags |=
AD_F_RAID_SUBDISK;
retval = 1;
if (info->raid.generation >= raid->generation) {
if (raid->disks[info->raid.disk_number].flags && adp->device) {
raid->disks[info->raid.disk_number].device = adp->device;
raid->disks[info->raid.disk_number].flags |= AR_DF_PRESENT;
raid->disks[info->raid.disk_number].disk_sectors =
info->raid.disk_sectors;
if ((raid->disks[info->raid.disk_number].flags &
(AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE)) ==
(AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE)) {
AD_SOFTC(raid->disks[info->raid.disk_number])->flags |=
AD_F_RAID_SUBDISK;
retval = 1;
}
}
}
break;
}
@ -1276,10 +1326,6 @@ ar_promise_write_conf(struct ar_softc *rdp)
for (count = 0; count < sizeof(struct promise_raid_conf); count++)
*(((u_int8_t *)config) + count) = 255 - (count % 256);
if (local)
bcopy(ATA_MAGIC, config->promise_id, sizeof(ATA_MAGIC));
else
bcopy(PR_MAGIC, config->promise_id, sizeof(PR_MAGIC));
config->dummy_0 = 0x00020000;
config->magic_0 = PR_MAGIC0(rdp->disks[disk]) | timestamp.tv_sec;
config->magic_1 = timestamp.tv_sec >> 16;
@ -1362,11 +1408,20 @@ ar_promise_write_conf(struct ar_softc *rdp)
PR_MAGIC0(rdp->disks[drive]) | timestamp.tv_sec;
}
config->checksum = 0;
for (ckptr = (int32_t *)config, count = 0; count < 511; count++)
config->checksum += *ckptr++;
if (rdp->disks[disk].device && rdp->disks[disk].device->driver &&
!(rdp->disks[disk].device->flags & ATA_D_DETACHING)) {
if ((rdp->disks[disk].flags & (AR_DF_PRESENT | AR_DF_ONLINE)) ==
(AR_DF_PRESENT | AR_DF_ONLINE)) {
if (local)
bcopy(ATA_MAGIC, config->promise_id, sizeof(ATA_MAGIC));
else
bcopy(PR_MAGIC, config->promise_id, sizeof(PR_MAGIC));
}
else
bzero(config->promise_id, sizeof(config->promise_id));
config->checksum = 0;
for (ckptr = (int32_t *)config, count = 0; count < 511; count++)
config->checksum += *ckptr++;
if (ar_rw(AD_SOFTC(rdp->disks[disk]),
PR_LBA(AD_SOFTC(rdp->disks[disk])),
sizeof(struct promise_raid_conf),

View file

@ -227,4 +227,5 @@ void ata_raid_attach(void);
int ata_raid_create(struct raid_setup *);
int ata_raid_delete(int);
int ata_raid_status(int, struct raid_status *);
int ata_raid_addspare(int, int);
int ata_raid_rebuild(int);