@BABOLO modify 2005-04-26 Original http://www.ambrisko.com/doug/ata/ --- sbin/atacontrol/Makefile +++ sbin/atacontrol/Makefile @@ -3,5 +3,6 @@ PROG= atacontrol WARNS= 0 MAN= atacontrol.8 +CFLAGS+= -I../../sys .include --- sbin/atacontrol/atacontrol.8 +++ sbin/atacontrol/atacontrol.8 @@ -47,14 +47,20 @@ .Ar channel .Nm .Ic create -.Ar type Oo Ar interleave Oc Ar disk0 ... diskN +.Ar type Oo Ar interleave Oc Oo Ar SECTORS sectors Oc Ar disk0 ... diskN .Nm .Ic delete .Ar raid .Nm +.Ic addspare +.Ar raid disk +.Nm .Ic rebuild .Ar raid .Nm +.Ic rebuildstop +.Ar raid +.Nm .Ic status .Ar raid .Nm @@ -152,8 +158,12 @@ reside on the first disk in the SPAN. .It Ic delete Delete a RAID array on a RAID capable ATA controller. +.It Ic addspare +Add a spare disk to an existing RAID. .It Ic rebuild Rebuild a RAID1 array on a RAID capable ATA controller. +.It Ic rebuildstop +Stop rebuild a RAID1 array on a RAID capable ATA controller. .It Ic status Get the status of an ATA RAID. .It Ic mode --- sbin/atacontrol/atacontrol.c +++ sbin/atacontrol/atacontrol.c @@ -249,9 +249,11 @@ if (argc > 2 && strcmp(argv[1], "create")) { int chan; - if (!strcmp(argv[1], "delete") || - !strcmp(argv[1], "status") || - !strcmp(argv[1], "rebuild")) { + if (!strcmp(argv[1], "addspare") || + !strcmp(argv[1], "delete") || + !strcmp(argv[1], "status") || + !strcmp(argv[1], "rebuild") || + !strcmp(argv[1], "rebuildstop")) { if (!(sscanf(argv[2], "%d", &chan) == 1 || sscanf(argv[2], "ar%d", &chan) == 1)) usage(); @@ -332,6 +334,13 @@ } else offset = 3; + + if (!strcmp(argv[offset], "SECTORS")) { + iocmd.u.raid_setup.disk_size = atoi(argv[offset + 1]); + offset += 2; + } + else + iocmd.u.raid_setup.disk_size = 0; for (disk = 0; disk < 16 && (offset + disk) < argc; disk++) { if (!(sscanf(argv[offset + disk], "%d", &dev) == 1 || @@ -350,11 +359,30 @@ if (ioctl(fd, IOCATA, &iocmd) < 0) warn("ioctl(ATARAIDDELETE)"); } + else if (!strcmp(argv[1], "addspare") && argc == 4) { + int dev; + + iocmd.cmd = ATARAIDADDSPARE; + if (!(sscanf(argv[3], "%d", &dev) == 1 || + sscanf(argv[3], "ad%d", &dev) == 1)) { + fprintf(stderr, + "atacontrol: Invalid device %s\n", argv[3]); + usage(); + } + iocmd.u.raid_spare.disk = dev; + if (ioctl(fd, IOCATA, &iocmd) < 0) + warn("ioctl(ATARAIDADDSPARE)"); + } 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], "rebuildstop") && argc == 3) { + iocmd.cmd = ATARAIDREBUILDSTOP; + if (ioctl(fd, IOCATA, &iocmd) < 0) + warn("ioctl(ATARAIDREBUILDSTOP)"); + } else if (!strcmp(argv[1], "status") && argc == 3) { int i; @@ -379,7 +407,12 @@ 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]); + if (iocmd.u.raid_status.not_okay[i]) + printf("[ad%d] ", + iocmd.u.raid_status.disks[i]); + else + printf("ad%d ", + iocmd.u.raid_status.disks[i]); else printf("DOWN "); }