From owner-freebsd-bugs@FreeBSD.ORG Fri Jun 25 10:50:51 2004 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C91ED16A4D2 for ; Fri, 25 Jun 2004 10:50:51 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id BA54343D54 for ; Fri, 25 Jun 2004 10:50:51 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.11/8.12.11) with ESMTP id i5PAoUNB043464 for ; Fri, 25 Jun 2004 10:50:30 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.11/8.12.11/Submit) id i5PAoUI6043463; Fri, 25 Jun 2004 10:50:30 GMT (envelope-from gnats) Resent-Date: Fri, 25 Jun 2004 10:50:30 GMT Resent-Message-Id: <200406251050.i5PAoUI6043463@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Rene de Vries Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E1BBA16A4CE for ; Fri, 25 Jun 2004 10:46:00 +0000 (GMT) Received: from bastix.tunix.nl (bastix.tunix.nl [193.79.201.39]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8A0EB43D53 for ; Fri, 25 Jun 2004 10:45:59 +0000 (GMT) (envelope-from rene@tunix.nl) Received: (from root@localhost) by bastix.tunix.nl (8.9.3c/8.6.12) id MAA96700 for ; Fri, 25 Jun 2004 12:45:35 +0200 (CEST) Received: by bastix.tunix.nl (TUNIX txp2/smap) for id sma095708; Fri, 25 Jun 04 12:44:19 +0200 Received: from upsilix.tunix.nl (upsilix.tunix.nl [172.16.2.22]) by fix.tunix.nl (8.10.2+Sun/8.10.2) with ESMTP id i5PAiJo27552 for ; Fri, 25 Jun 2004 12:44:19 +0200 (MEST) Received: from upsilix.tunix.nl (localhost.tunix.nl [127.0.0.1]) by upsilix.tunix.nl (8.12.8p2/8.12.6) with ESMTP id i5PAiID2063276 for ; Fri, 25 Jun 2004 12:44:19 +0200 (CEST) (envelope-from rene@upsilix.tunix.nl) Received: (from rene@localhost) by upsilix.tunix.nl (8.12.8p2/8.12.6/Submit) id i5PAiI3e063275; Fri, 25 Jun 2004 12:44:18 +0200 (CEST) (envelope-from rene) Message-Id: <200406251044.i5PAiI3e063275@upsilix.tunix.nl> Date: Fri, 25 Jun 2004 12:44:18 +0200 (CEST) From: Rene de Vries To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: kern/68315: atacontrol addspare for 4.x X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Rene de Vries List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Jun 2004 10:50:52 -0000 >Number: 68315 >Category: kern >Synopsis: atacontrol addspare for 4.x >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Fri Jun 25 10:50:30 GMT 2004 >Closed-Date: >Last-Modified: >Originator: Rene de Vries >Release: FreeBSD 4.8 i386 >Organization: Tunix Internet Security & Training >Environment: System: FreeBSD upsilix.tunix.nl 4.8 FreeBSD 4.8-RELEASE-p16 #7: Wed Mar 3 15:00:31 CET 2004 rene@upsilix.tunix.nl:/usr/obj/usr/src/sys/UPSILIX i386 >Description: When an ata mirror is lost and a new disk needs to be added as spare the command allows the system manager to do so. UI modeled after 5.x version, code is different. Diff against FreeBSD 4.8: Index: sbin/atacontrol/atacontrol.c =================================================================== RCS file: sbin/atacontrol/atacontrol.c,v retrieving revision 1.1.1.3 retrieving revision 1.3 diff -u -r1.1.1.3 -r1.3 --- sbin/atacontrol/atacontrol.c 2002/10/15 10:21:01 1.1.1.3 +++ sbin/atacontrol/atacontrol.c 2004/04/13 09:13:18 1.3 @@ -251,7 +251,8 @@ if (!strcmp(argv[1], "delete") || !strcmp(argv[1], "status") || - !strcmp(argv[1], "rebuild")) { + !strcmp(argv[1], "rebuild") || + !strcmp(argv[1], "addspare")) { if (!(sscanf(argv[2], "%d", &chan) == 1 || sscanf(argv[2], "ar%d", &chan) == 1)) usage(); @@ -338,6 +339,21 @@ err(1, "ioctl(ATARAIDCREATE)"); else printf("ar%d created\n", iocmd.u.raid_setup.unit); + } + else if (!strcmp(argv[1], "addspare")) { + int disk, dev; + iocmd.cmd = ATARAIDADD; + for (disk = 0; disk < 16 && (3 + disk) < argc; disk++) { + if (!(sscanf(argv[3 + disk], "%d", &dev) == 1 || + sscanf(argv[3 + disk], "ad%d", &dev) == 1)) + usage(); + iocmd.u.raid_setup.disks[disk] = dev; + } + iocmd.u.raid_setup.total_disks = disk; + if (ioctl(fd, IOCATA, &iocmd) < 0) + err(1, "ioctl(ATARAIDADD)"); + else + printf("ar%d modified\n", iocmd.u.raid_setup.unit); } else if (!strcmp(argv[1], "delete") && argc == 3) { iocmd.cmd = ATARAIDDELETE; Index: sys/dev/ata/ata-all.c =================================================================== RCS file: /usr/local/cvs/cvsroot/fw/os/freebsd/sys/dev/ata/ata-all.c,v retrieving revision 1.1.1.6 retrieving revision 1.2 diff -u -r1.1.1.6 -r1.2 --- sys/dev/ata/ata-all.c 2003/04/17 15:43:54 1.1.1.6 +++ sys/dev/ata/ata-all.c 2004/03/02 13:52:28 1.2 @@ -417,6 +417,9 @@ case ATARAIDSTATUS: return ata_raid_status(iocmd->channel, &iocmd->u.raid_status); + + case ATARAIDADD: + return ata_raid_add(iocmd->channel, &iocmd->u.raid_setup); #endif #if DEV_ATAPIALL case ATAPICMD: { Index: sys/dev/ata/ata-raid.c =================================================================== RCS file: /usr/local/cvs/cvsroot/fw/os/freebsd/sys/dev/ata/ata-raid.c,v retrieving revision 1.1.1.6 retrieving revision 1.2 diff -u -r1.1.1.6 -r1.2 --- sys/dev/ata/ata-raid.c 2003/04/17 15:43:54 1.1.1.6 +++ sys/dev/ata/ata-raid.c 2004/03/02 13:52:28 1.2 @@ -466,6 +466,93 @@ return ar_rebuild(rdp); } +int ata_raid_add(int array, struct raid_setup *setup) +{ + struct ata_device *atadev; + struct ar_softc *rdp; + int disk, rdisk; + int ctlr = 0, total_disks = 0; + + if (!ar_table) { + printf("ar: no memory for ATA raid array\n"); + return 0; + } + if (!(rdp = ar_table[array])) + return ENXIO; + + if (!(rdp->flags & AR_F_RAID1)) + return EINVAL; + + total_disks = rdp->total_disks; + for (disk = 0; disk < setup->total_disks; disk++) { + for (rdisk = 0; rdisk < total_disks; rdisk++) { + if (!((rdp->disks[rdisk].flags & AR_DF_PRESENT) && rdp->disks[rdisk].device)) + break; + } + + if ((rdisk + 1) > total_disks) + total_disks = rdisk + 1; + else + total_disks = rdp->total_disks; + + if ((atadev = ar_locate_disk(setup->disks[disk]))) { + rdp->disks[rdisk].device = atadev; + if (AD_SOFTC(rdp->disks[rdisk])->flags & AD_F_RAID_SUBDISK) { + setup->disks[disk] = -1; + return EBUSY; + } + + switch (rdp->disks[rdisk].device->channel->chiptype & 0xffff) { + case 0x1103: + ctlr |= AR_F_HIGHPOINT_RAID; + rdp->disks[rdisk].disk_sectors = + AD_SOFTC(rdp->disks[rdisk])->total_secs; + break; + + default: + ctlr |= AR_F_FREEBSD_RAID; + /* FALLTHROUGH */ + + case 0x105a: + ctlr |= AR_F_PROMISE_RAID; + rdp->disks[rdisk].disk_sectors = + PR_LBA(AD_SOFTC(rdp->disks[rdisk])); + break; + } + if ((rdp->flags & (AR_F_PROMISE_RAID|AR_F_HIGHPOINT_RAID)) && + (rdp->flags & (AR_F_PROMISE_RAID|AR_F_HIGHPOINT_RAID)) != + (ctlr & (AR_F_PROMISE_RAID|AR_F_HIGHPOINT_RAID))) { + return EXDEV; + } + else + rdp->flags |= ctlr; + + if (rdp->disks[rdisk].disk_sectors < rdp->total_sectors) { + ata_prtdev(rdp->disks[rdisk].device, + "ar%d: too small for mirror\n", array); + setup->disks[disk] = -1; + return EINVAL; + } + rdp->disks[rdisk].flags = (AR_DF_PRESENT | AR_DF_SPARE); + AD_SOFTC(rdp->disks[rdisk])->flags = AD_F_RAID_SUBDISK; + ata_prtdev(rdp->disks[rdisk].device, + "inserted into ar%d disk%d as spare\n", array, rdisk); + } + else { + setup->disks[disk] = -1; + return ENXIO; + } + } + if (!total_disks) { + return ENODEV; + } + rdp->total_disks = total_disks; + ar_config_changed(rdp, 1); + setup->unit = array; + return 0; +} + + static int aropen(dev_t dev, int flags, int fmt, struct proc *p) { Index: sys/dev/ata/ata-raid.h =================================================================== RCS file: /usr/local/cvs/cvsroot/fw/os/freebsd/sys/dev/ata/ata-raid.h,v retrieving revision 1.1.1.4 retrieving revision 1.2 diff -u -r1.1.1.4 -r1.2 --- sys/dev/ata/ata-raid.h 2002/08/28 08:58:38 1.1.1.4 +++ sys/dev/ata/ata-raid.h 2004/03/02 13:52:28 1.2 @@ -230,4 +230,5 @@ int ata_raid_delete(int); int ata_raid_status(int array, struct raid_status *); int ata_raid_rebuild(int); +int ata_raid_add(int array, struct raid_setup *); Index: sys/sys/ata.h =================================================================== RCS file: /usr/local/cvs/cvsroot/fw/os/freebsd/sys/sys/ata.h,v retrieving revision 1.1.1.3 retrieving revision 1.2 diff -u -r1.1.1.3 -r1.2 --- sys/sys/ata.h 2002/08/28 08:59:31 1.1.1.3 +++ sys/sys/ata.h 2004/03/02 14:27:16 1.2 @@ -238,6 +238,7 @@ #define ATARAIDDELETE 10 #define ATARAIDSTATUS 11 #define ATAENCSTAT 12 +#define ATARAIDADD 1000 union { struct { >How-To-Repeat: >Fix: >Release-Note: >Audit-Trail: >Unformatted: