Deleted Added
full compact
mpt_config.c (196212) mpt_config.c (215046)
1/*-
2 * Copyright (c) 2008 Yahoo!, Inc.
3 * All rights reserved.
4 * Written by: John Baldwin <jhb@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 15 unchanged lines hidden (view full) ---

24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2008 Yahoo!, Inc.
3 * All rights reserved.
4 * Written by: John Baldwin <jhb@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 15 unchanged lines hidden (view full) ---

24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
32__RCSID("$FreeBSD: head/usr.sbin/mptutil/mpt_config.c 196212 2009-08-14 13:13:12Z scottl $");
32__RCSID("$FreeBSD: head/usr.sbin/mptutil/mpt_config.c 215046 2010-11-09 19:28:06Z jhb $");
33
34#include <sys/param.h>
35#include <sys/errno.h>
36#include <err.h>
37#include <fcntl.h>
38#include <libutil.h>
39#include <paths.h>
40#ifdef DEBUG

--- 56 unchanged lines hidden (view full) ---

97 if (error == ENOENT)
98 /*
99 * This means there isn't a CAM device associated with
100 * the volume, and thus it is already implicitly
101 * locked, so just return.
102 */
103 return (0);
104 if (error) {
33
34#include <sys/param.h>
35#include <sys/errno.h>
36#include <err.h>
37#include <fcntl.h>
38#include <libutil.h>
39#include <paths.h>
40#ifdef DEBUG

--- 56 unchanged lines hidden (view full) ---

97 if (error == ENOENT)
98 /*
99 * This means there isn't a CAM device associated with
100 * the volume, and thus it is already implicitly
101 * locked, so just return.
102 */
103 return (0);
104 if (error) {
105 errno = error;
106 warn("Unable to lookup volume device name");
107 return (-1);
105 warnc(error, "Unable to lookup volume device name");
106 return (error);
108 }
109 snprintf(path, sizeof(path), "%s%s", _PATH_DEV, qd.devname);
110 vfd = open(path, O_RDWR);
111 if (vfd < 0) {
107 }
108 snprintf(path, sizeof(path), "%s%s", _PATH_DEV, qd.devname);
109 vfd = open(path, O_RDWR);
110 if (vfd < 0) {
111 error = errno;
112 warn("Unable to lock volume %s", qd.devname);
112 warn("Unable to lock volume %s", qd.devname);
113 return (-1);
113 return (error);
114 }
115 return (0);
116}
117
118static int
119mpt_lock_physdisk(struct mpt_standalone_disk *disk)
120{
121 char path[MAXPATHLEN];
114 }
115 return (0);
116}
117
118static int
119mpt_lock_physdisk(struct mpt_standalone_disk *disk)
120{
121 char path[MAXPATHLEN];
122 int dfd;
122 int dfd, error;
123
124 snprintf(path, sizeof(path), "%s%s", _PATH_DEV, disk->devname);
125 dfd = open(path, O_RDWR);
126 if (dfd < 0) {
123
124 snprintf(path, sizeof(path), "%s%s", _PATH_DEV, disk->devname);
125 dfd = open(path, O_RDWR);
126 if (dfd < 0) {
127 error = errno;
127 warn("Unable to lock disk %s", disk->devname);
128 warn("Unable to lock disk %s", disk->devname);
128 return (-1);
129 return (error);
129 }
130 return (0);
131}
132
133static int
134mpt_lookup_standalone_disk(const char *name, struct mpt_standalone_disk *disks,
135 int ndisks, int *index)
136{
137 char *cp;
138 long bus, id;
139 int i;
140
141 /* Check for a raw <bus>:<id> string. */
142 bus = strtol(name, &cp, 0);
143 if (*cp == ':') {
144 id = strtol(cp + 1, &cp, 0);
145 if (*cp == '\0') {
146 if (bus < 0 || bus > 0xff || id < 0 || id > 0xff) {
130 }
131 return (0);
132}
133
134static int
135mpt_lookup_standalone_disk(const char *name, struct mpt_standalone_disk *disks,
136 int ndisks, int *index)
137{
138 char *cp;
139 long bus, id;
140 int i;
141
142 /* Check for a raw <bus>:<id> string. */
143 bus = strtol(name, &cp, 0);
144 if (*cp == ':') {
145 id = strtol(cp + 1, &cp, 0);
146 if (*cp == '\0') {
147 if (bus < 0 || bus > 0xff || id < 0 || id > 0xff) {
147 errno = EINVAL;
148 return (-1);
148 return (EINVAL);
149 }
150 for (i = 0; i < ndisks; i++) {
151 if (disks[i].bus == (U8)bus &&
152 disks[i].target == (U8)id) {
153 *index = i;
154 return (0);
155 }
156 }
149 }
150 for (i = 0; i < ndisks; i++) {
151 if (disks[i].bus == (U8)bus &&
152 disks[i].target == (U8)id) {
153 *index = i;
154 return (0);
155 }
156 }
157 errno = ENOENT;
158 return (-1);
157 return (ENOENT);
159 }
160 }
161
162 if (name[0] == 'd' && name[1] == 'a') {
163 for (i = 0; i < ndisks; i++) {
164 if (strcmp(name, disks[i].devname) == 0) {
165 *index = i;
166 return (0);
167 }
168 }
158 }
159 }
160
161 if (name[0] == 'd' && name[1] == 'a') {
162 for (i = 0; i < ndisks; i++) {
163 if (strcmp(name, disks[i].devname) == 0) {
164 *index = i;
165 return (0);
166 }
167 }
169 errno = ENOENT;
170 return (-1);
168 return (ENOENT);
171 }
172
169 }
170
173 errno = EINVAL;
174 return (-1);
171 return (EINVAL);
175}
176
177/*
178 * Mark a standalone disk as being a physical disk.
179 */
180static int
181mpt_create_physdisk(int fd, struct mpt_standalone_disk *disk, U8 *PhysDiskNum)
182{
183 CONFIG_PAGE_HEADER header;
184 CONFIG_PAGE_RAID_PHYS_DISK_0 *config_page;
172}
173
174/*
175 * Mark a standalone disk as being a physical disk.
176 */
177static int
178mpt_create_physdisk(int fd, struct mpt_standalone_disk *disk, U8 *PhysDiskNum)
179{
180 CONFIG_PAGE_HEADER header;
181 CONFIG_PAGE_RAID_PHYS_DISK_0 *config_page;
182 int error;
185 U32 ActionData;
186
183 U32 ActionData;
184
187 if (mpt_read_config_page_header(fd, MPI_CONFIG_PAGETYPE_RAID_PHYSDISK,
188 0, 0, &header, NULL) < 0)
189 return (-1);
185 error = mpt_read_config_page_header(fd, MPI_CONFIG_PAGETYPE_RAID_PHYSDISK,
186 0, 0, &header, NULL);
187 if (error)
188 return (error);
190 if (header.PageVersion > MPI_RAIDPHYSDISKPAGE0_PAGEVERSION) {
191 warnx("Unsupported RAID physdisk page 0 version %d",
192 header.PageVersion);
189 if (header.PageVersion > MPI_RAIDPHYSDISKPAGE0_PAGEVERSION) {
190 warnx("Unsupported RAID physdisk page 0 version %d",
191 header.PageVersion);
193 errno = EOPNOTSUPP;
194 return (-1);
192 return (EOPNOTSUPP);
195 }
196 config_page = calloc(1, sizeof(CONFIG_PAGE_RAID_PHYS_DISK_0));
197 config_page->Header.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
198 config_page->Header.PageNumber = 0;
199 config_page->Header.PageLength = sizeof(CONFIG_PAGE_RAID_PHYS_DISK_0) /
200 4;
201 config_page->PhysDiskIOC = 0; /* XXX */
202 config_page->PhysDiskBus = disk->bus;
203 config_page->PhysDiskID = disk->target;
204
205 /* XXX: Enclosure info for PhysDiskSettings? */
193 }
194 config_page = calloc(1, sizeof(CONFIG_PAGE_RAID_PHYS_DISK_0));
195 config_page->Header.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
196 config_page->Header.PageNumber = 0;
197 config_page->Header.PageLength = sizeof(CONFIG_PAGE_RAID_PHYS_DISK_0) /
198 4;
199 config_page->PhysDiskIOC = 0; /* XXX */
200 config_page->PhysDiskBus = disk->bus;
201 config_page->PhysDiskID = disk->target;
202
203 /* XXX: Enclosure info for PhysDiskSettings? */
206 if (mpt_raid_action(fd, MPI_RAID_ACTION_CREATE_PHYSDISK, 0, 0, 0, 0,
204 error = mpt_raid_action(fd, MPI_RAID_ACTION_CREATE_PHYSDISK, 0, 0, 0, 0,
207 config_page, sizeof(CONFIG_PAGE_RAID_PHYS_DISK_0), NULL,
205 config_page, sizeof(CONFIG_PAGE_RAID_PHYS_DISK_0), NULL,
208 &ActionData, sizeof(ActionData), NULL, NULL, 1) < 0)
209 return (-1);
206 &ActionData, sizeof(ActionData), NULL, NULL, 1);
207 if (error)
208 return (error);
210 *PhysDiskNum = ActionData & 0xff;
211 return (0);
212}
213
214static int
215mpt_delete_physdisk(int fd, U8 PhysDiskNum)
216{
217

--- 9 unchanged lines hidden (view full) ---

227clear_config(int ac, char **av)
228{
229 CONFIG_PAGE_IOC_2 *ioc2;
230 CONFIG_PAGE_IOC_2_RAID_VOL *vol;
231 CONFIG_PAGE_IOC_3 *ioc3;
232 IOC_3_PHYS_DISK *disk;
233 CONFIG_PAGE_IOC_5 *ioc5;
234 IOC_5_HOT_SPARE *spare;
209 *PhysDiskNum = ActionData & 0xff;
210 return (0);
211}
212
213static int
214mpt_delete_physdisk(int fd, U8 PhysDiskNum)
215{
216

--- 9 unchanged lines hidden (view full) ---

226clear_config(int ac, char **av)
227{
228 CONFIG_PAGE_IOC_2 *ioc2;
229 CONFIG_PAGE_IOC_2_RAID_VOL *vol;
230 CONFIG_PAGE_IOC_3 *ioc3;
231 IOC_3_PHYS_DISK *disk;
232 CONFIG_PAGE_IOC_5 *ioc5;
233 IOC_5_HOT_SPARE *spare;
235 int ch, fd, i;
234 int ch, error, fd, i;
236
237 fd = mpt_open(mpt_unit);
238 if (fd < 0) {
235
236 fd = mpt_open(mpt_unit);
237 if (fd < 0) {
238 error = errno;
239 warn("mpt_open");
239 warn("mpt_open");
240 return (errno);
240 return (error);
241 }
242
243 ioc2 = mpt_read_ioc_page(fd, 2, NULL);
244 if (ioc2 == NULL) {
241 }
242
243 ioc2 = mpt_read_ioc_page(fd, 2, NULL);
244 if (ioc2 == NULL) {
245 error = errno;
245 warn("Failed to fetch volume list");
246 warn("Failed to fetch volume list");
246 return (errno);
247 return (error);
247 }
248
249 /* Lock all the volumes first. */
250 vol = ioc2->RaidVolume;
251 for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) {
252 if (mpt_lock_volume(vol->VolumeBus, vol->VolumeID) < 0) {
253 warnx("Volume %s is busy and cannot be deleted",
254 mpt_volume_name(vol->VolumeBus, vol->VolumeID));

--- 7 unchanged lines hidden (view full) ---

262 ch = getchar();
263 if (ch != 'y' && ch != 'Y') {
264 printf("\nAborting\n");
265 return (0);
266 }
267
268 /* Delete all the volumes. */
269 vol = ioc2->RaidVolume;
248 }
249
250 /* Lock all the volumes first. */
251 vol = ioc2->RaidVolume;
252 for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) {
253 if (mpt_lock_volume(vol->VolumeBus, vol->VolumeID) < 0) {
254 warnx("Volume %s is busy and cannot be deleted",
255 mpt_volume_name(vol->VolumeBus, vol->VolumeID));

--- 7 unchanged lines hidden (view full) ---

263 ch = getchar();
264 if (ch != 'y' && ch != 'Y') {
265 printf("\nAborting\n");
266 return (0);
267 }
268
269 /* Delete all the volumes. */
270 vol = ioc2->RaidVolume;
270 for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++)
271 if (mpt_raid_action(fd, MPI_RAID_ACTION_DELETE_VOLUME,
271 for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) {
272 error = mpt_raid_action(fd, MPI_RAID_ACTION_DELETE_VOLUME,
272 vol->VolumeBus, vol->VolumeID, 0,
273 MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS |
274 MPI_RAID_ACTION_ADATA_ZERO_LBA0, NULL, 0, NULL, NULL, 0,
273 vol->VolumeBus, vol->VolumeID, 0,
274 MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS |
275 MPI_RAID_ACTION_ADATA_ZERO_LBA0, NULL, 0, NULL, NULL, 0,
275 NULL, NULL, 0) < 0)
276 warn("Failed to delete volume %s",
276 NULL, NULL, 0);
277 if (error)
278 warnc(error, "Failed to delete volume %s",
277 mpt_volume_name(vol->VolumeBus, vol->VolumeID));
279 mpt_volume_name(vol->VolumeBus, vol->VolumeID));
280 }
278 free(ioc2);
279
280 /* Delete all the spares. */
281 ioc5 = mpt_read_ioc_page(fd, 5, NULL);
282 if (ioc5 == NULL)
283 warn("Failed to fetch spare list");
284 else {
285 spare = ioc5->HotSpare;

--- 120 unchanged lines hidden (view full) ---

406 if (dinfo->info == NULL)
407 return (errno);
408 continue;
409 }
410
411 /* See if it is a standalone disk. */
412 if (mpt_lookup_standalone_disk(cp, state->sdisks,
413 state->nsdisks, &i) < 0) {
281 free(ioc2);
282
283 /* Delete all the spares. */
284 ioc5 = mpt_read_ioc_page(fd, 5, NULL);
285 if (ioc5 == NULL)
286 warn("Failed to fetch spare list");
287 else {
288 spare = ioc5->HotSpare;

--- 120 unchanged lines hidden (view full) ---

409 if (dinfo->info == NULL)
410 return (errno);
411 continue;
412 }
413
414 /* See if it is a standalone disk. */
415 if (mpt_lookup_standalone_disk(cp, state->sdisks,
416 state->nsdisks, &i) < 0) {
417 error = errno;
414 warn("Unable to lookup drive %s", cp);
418 warn("Unable to lookup drive %s", cp);
415 return (errno);
419 return (error);
416 }
417 dinfo->sdisk = &state->sdisks[i];
418
419 /* Lock the disk, we will create phys disk pages later. */
420 if (mpt_lock_physdisk(dinfo->sdisk) < 0)
421 return (errno);
422 }
423

--- 4 unchanged lines hidden (view full) ---

428 * Add RAID physdisk pages for any standalone disks that a volume is
429 * going to use.
430 */
431static int
432add_drives(int fd, struct volume_info *info, int verbose)
433{
434 struct drive_info *dinfo;
435 U8 PhysDiskNum;
420 }
421 dinfo->sdisk = &state->sdisks[i];
422
423 /* Lock the disk, we will create phys disk pages later. */
424 if (mpt_lock_physdisk(dinfo->sdisk) < 0)
425 return (errno);
426 }
427

--- 4 unchanged lines hidden (view full) ---

432 * Add RAID physdisk pages for any standalone disks that a volume is
433 * going to use.
434 */
435static int
436add_drives(int fd, struct volume_info *info, int verbose)
437{
438 struct drive_info *dinfo;
439 U8 PhysDiskNum;
436 int i;
440 int error, i;
437
438 for (i = 0, dinfo = info->drives; i < info->drive_count;
439 i++, dinfo++) {
440 if (dinfo->info == NULL) {
441 if (mpt_create_physdisk(fd, dinfo->sdisk,
442 &PhysDiskNum) < 0) {
441
442 for (i = 0, dinfo = info->drives; i < info->drive_count;
443 i++, dinfo++) {
444 if (dinfo->info == NULL) {
445 if (mpt_create_physdisk(fd, dinfo->sdisk,
446 &PhysDiskNum) < 0) {
447 error = errno;
443 warn(
444 "Failed to create physical disk page for %s",
445 dinfo->sdisk->devname);
448 warn(
449 "Failed to create physical disk page for %s",
450 dinfo->sdisk->devname);
446 return (errno);
451 return (error);
447 }
448 if (verbose)
449 printf("Added drive %s with PhysDiskNum %u\n",
450 dinfo->sdisk->devname, PhysDiskNum);
451
452 dinfo->info = mpt_pd_info(fd, PhysDiskNum, NULL);
453 if (dinfo->info == NULL)
454 return (errno);

--- 40 unchanged lines hidden (view full) ---

495{
496 CONFIG_PAGE_HEADER header;
497 CONFIG_PAGE_RAID_VOL_0 *vol;
498 RAID_VOL0_PHYS_DISK *rdisk;
499 struct drive_info *dinfo;
500 U32 MinLBA;
501 uint64_t MaxLBA;
502 size_t page_size;
452 }
453 if (verbose)
454 printf("Added drive %s with PhysDiskNum %u\n",
455 dinfo->sdisk->devname, PhysDiskNum);
456
457 dinfo->info = mpt_pd_info(fd, PhysDiskNum, NULL);
458 if (dinfo->info == NULL)
459 return (errno);

--- 40 unchanged lines hidden (view full) ---

500{
501 CONFIG_PAGE_HEADER header;
502 CONFIG_PAGE_RAID_VOL_0 *vol;
503 RAID_VOL0_PHYS_DISK *rdisk;
504 struct drive_info *dinfo;
505 U32 MinLBA;
506 uint64_t MaxLBA;
507 size_t page_size;
503 int i;
508 int error, i;
504
509
505 if (mpt_read_config_page_header(fd, MPI_CONFIG_PAGETYPE_RAID_VOLUME,
506 0, 0, &header, NULL) < 0)
510 error = mpt_read_config_page_header(fd, MPI_CONFIG_PAGETYPE_RAID_VOLUME,
511 0, 0, &header, NULL);
512 if (error) {
513 errno = error;
507 return (NULL);
514 return (NULL);
515 }
508 if (header.PageVersion > MPI_RAIDVOLPAGE0_PAGEVERSION) {
509 warnx("Unsupported RAID volume page 0 version %d",
510 header.PageVersion);
511 errno = EOPNOTSUPP;
512 return (NULL);
513 }
514 page_size = sizeof(CONFIG_PAGE_RAID_VOL_0) +
515 sizeof(RAID_VOL0_PHYS_DISK) * (info->drive_count - 1);
516 vol = calloc(1, page_size);
516 if (header.PageVersion > MPI_RAIDVOLPAGE0_PAGEVERSION) {
517 warnx("Unsupported RAID volume page 0 version %d",
518 header.PageVersion);
519 errno = EOPNOTSUPP;
520 return (NULL);
521 }
522 page_size = sizeof(CONFIG_PAGE_RAID_VOL_0) +
523 sizeof(RAID_VOL0_PHYS_DISK) * (info->drive_count - 1);
524 vol = calloc(1, page_size);
525 if (vol == NULL)
526 return (NULL);
517
518 /* Header */
519 vol->Header.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
520 vol->Header.PageNumber = 0;
521 vol->Header.PageLength = page_size / 4;
522
523 /* Properties */
524 vol->VolumeID = find_next_volume(state);

--- 77 unchanged lines hidden (view full) ---

602}
603
604static int
605create_volume(int ac, char **av)
606{
607 CONFIG_PAGE_RAID_VOL_0 *vol;
608 struct config_id_state state;
609 struct volume_info *info;
527
528 /* Header */
529 vol->Header.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
530 vol->Header.PageNumber = 0;
531 vol->Header.PageLength = page_size / 4;
532
533 /* Properties */
534 vol->VolumeID = find_next_volume(state);

--- 77 unchanged lines hidden (view full) ---

612}
613
614static int
615create_volume(int ac, char **av)
616{
617 CONFIG_PAGE_RAID_VOL_0 *vol;
618 struct config_id_state state;
619 struct volume_info *info;
610 int ch, error, fd, i, raid_type, verbose, quick;
611 long stripe_size;
620 long stripe_size;
621 int ch, error, fd, i, quick, raid_type, verbose;
612#ifdef DEBUG
613 int dump;
614#endif
615
616 if (ac < 2) {
617 warnx("create: volume type required");
618 return (EINVAL);
619 }
620
621 fd = mpt_open(mpt_unit);
622 if (fd < 0) {
622#ifdef DEBUG
623 int dump;
624#endif
625
626 if (ac < 2) {
627 warnx("create: volume type required");
628 return (EINVAL);
629 }
630
631 fd = mpt_open(mpt_unit);
632 if (fd < 0) {
633 error = errno;
623 warn("mpt_open");
634 warn("mpt_open");
624 return (errno);
635 return (error);
625 }
626
627 /* Lookup the RAID type first. */
628 raid_type = -1;
629 for (i = 0; raid_type_table[i].name != NULL; i++)
630 if (strcasecmp(raid_type_table[i].name, av[1]) == 0) {
631 raid_type = raid_type_table[i].raid_type;
632 break;

--- 39 unchanged lines hidden (view full) ---

672 }
673 }
674 ac -= optind;
675 av += optind;
676
677 /* Fetch existing config data. */
678 state.ioc2 = mpt_read_ioc_page(fd, 2, NULL);
679 if (state.ioc2 == NULL) {
636 }
637
638 /* Lookup the RAID type first. */
639 raid_type = -1;
640 for (i = 0; raid_type_table[i].name != NULL; i++)
641 if (strcasecmp(raid_type_table[i].name, av[1]) == 0) {
642 raid_type = raid_type_table[i].raid_type;
643 break;

--- 39 unchanged lines hidden (view full) ---

683 }
684 }
685 ac -= optind;
686 av += optind;
687
688 /* Fetch existing config data. */
689 state.ioc2 = mpt_read_ioc_page(fd, 2, NULL);
690 if (state.ioc2 == NULL) {
691 error = errno;
680 warn("Failed to read volume list");
692 warn("Failed to read volume list");
681 return (errno);
693 return (error);
682 }
683 state.list = mpt_pd_list(fd);
684 if (state.list == NULL)
685 return (errno);
686 error = mpt_fetch_disks(fd, &state.nsdisks, &state.sdisks);
687 if (error) {
688 warn("Failed to fetch standalone disk list");
689 return (error);
690 }
691 state.target_id = 0xff;
692
693 /* Parse the drive list. */
694 if (ac != 1) {
695 warnx("Exactly one drive list is required");
696 return (EINVAL);
697 }
698 info = calloc(1, sizeof(*info));
694 }
695 state.list = mpt_pd_list(fd);
696 if (state.list == NULL)
697 return (errno);
698 error = mpt_fetch_disks(fd, &state.nsdisks, &state.sdisks);
699 if (error) {
700 warn("Failed to fetch standalone disk list");
701 return (error);
702 }
703 state.target_id = 0xff;
704
705 /* Parse the drive list. */
706 if (ac != 1) {
707 warnx("Exactly one drive list is required");
708 return (EINVAL);
709 }
710 info = calloc(1, sizeof(*info));
711 if (info == NULL)
712 return (ENOMEM);
699 error = parse_volume(fd, raid_type, &state, av[0], info);
700 if (error)
701 return (error);
702
703 /* Create RAID physdisk pages for standalone disks. */
704 error = add_drives(fd, info, verbose);
705 if (error)
706 return (error);
707
708 /* Build the volume. */
709 vol = build_volume(fd, info, raid_type, stripe_size, &state, verbose);
713 error = parse_volume(fd, raid_type, &state, av[0], info);
714 if (error)
715 return (error);
716
717 /* Create RAID physdisk pages for standalone disks. */
718 error = add_drives(fd, info, verbose);
719 if (error)
720 return (error);
721
722 /* Build the volume. */
723 vol = build_volume(fd, info, raid_type, stripe_size, &state, verbose);
724 if (vol == NULL)
725 return (errno);
710
711#ifdef DEBUG
712 if (dump) {
713 dump_config(vol);
714 goto skip;
715 }
716#endif
717
718 /* Send the new volume to the controller. */
726
727#ifdef DEBUG
728 if (dump) {
729 dump_config(vol);
730 goto skip;
731 }
732#endif
733
734 /* Send the new volume to the controller. */
719 if (mpt_raid_action(fd, MPI_RAID_ACTION_CREATE_VOLUME, vol->VolumeBus,
735 error = mpt_raid_action(fd, MPI_RAID_ACTION_CREATE_VOLUME, vol->VolumeBus,
720 vol->VolumeID, 0, quick ? MPI_RAID_ACTION_ADATA_DO_NOT_SYNC : 0,
736 vol->VolumeID, 0, quick ? MPI_RAID_ACTION_ADATA_DO_NOT_SYNC : 0,
721 vol, vol->Header.PageLength * 4, NULL, NULL, 0, NULL, NULL, 1) <
722 0) {
737 vol, vol->Header.PageLength * 4, NULL, NULL, 0, NULL, NULL, 1);
738 if (error) {
739 errno = error;
723 warn("Failed to add volume");
740 warn("Failed to add volume");
724 return (errno);
741 return (error);
725 }
726
727#ifdef DEBUG
728skip:
729#endif
730 mpt_rescan_bus(vol->VolumeBus, vol->VolumeID);
731
732 /* Clean up. */

--- 7 unchanged lines hidden (view full) ---

740 return (0);
741}
742MPT_COMMAND(top, create, create_volume);
743
744static int
745delete_volume(int ac, char **av)
746{
747 U8 VolumeBus, VolumeID;
742 }
743
744#ifdef DEBUG
745skip:
746#endif
747 mpt_rescan_bus(vol->VolumeBus, vol->VolumeID);
748
749 /* Clean up. */

--- 7 unchanged lines hidden (view full) ---

757 return (0);
758}
759MPT_COMMAND(top, create, create_volume);
760
761static int
762delete_volume(int ac, char **av)
763{
764 U8 VolumeBus, VolumeID;
748 int fd;
765 int error, fd;
749
750 if (ac != 2) {
751 warnx("delete: volume required");
752 return (EINVAL);
753 }
754
755 fd = mpt_open(mpt_unit);
756 if (fd < 0) {
766
767 if (ac != 2) {
768 warnx("delete: volume required");
769 return (EINVAL);
770 }
771
772 fd = mpt_open(mpt_unit);
773 if (fd < 0) {
774 error = errno;
757 warn("mpt_open");
775 warn("mpt_open");
758 return (errno);
776 return (error);
759 }
760
777 }
778
761 if (mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID) < 0) {
762 warn("Invalid volume %s", av[1]);
763 return (errno);
779 error = mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID);
780 if (error) {
781 warnc(error, "Invalid volume %s", av[1]);
782 return (error);
764 }
765
766 if (mpt_lock_volume(VolumeBus, VolumeID) < 0)
767 return (errno);
768
783 }
784
785 if (mpt_lock_volume(VolumeBus, VolumeID) < 0)
786 return (errno);
787
769 if (mpt_raid_action(fd, MPI_RAID_ACTION_DELETE_VOLUME, VolumeBus,
788 error = mpt_raid_action(fd, MPI_RAID_ACTION_DELETE_VOLUME, VolumeBus,
770 VolumeID, 0, MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS |
771 MPI_RAID_ACTION_ADATA_ZERO_LBA0, NULL, 0, NULL, NULL, 0, NULL,
789 VolumeID, 0, MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS |
790 MPI_RAID_ACTION_ADATA_ZERO_LBA0, NULL, 0, NULL, NULL, 0, NULL,
772 NULL, 0) < 0) {
773 warn("Failed to delete volume");
774 return (errno);
791 NULL, 0);
792 if (error) {
793 warnc(error, "Failed to delete volume");
794 return (error);
775 }
776
777 mpt_rescan_bus(-1, -1);
778 close(fd);
779
780 return (0);
781}
782MPT_COMMAND(top, delete, delete_volume);
783
784static int
785find_volume_spare_pool(int fd, const char *name, int *pool)
786{
787 CONFIG_PAGE_RAID_VOL_0 *info;
788 CONFIG_PAGE_IOC_2 *ioc2;
789 CONFIG_PAGE_IOC_2_RAID_VOL *vol;
790 U8 VolumeBus, VolumeID;
795 }
796
797 mpt_rescan_bus(-1, -1);
798 close(fd);
799
800 return (0);
801}
802MPT_COMMAND(top, delete, delete_volume);
803
804static int
805find_volume_spare_pool(int fd, const char *name, int *pool)
806{
807 CONFIG_PAGE_RAID_VOL_0 *info;
808 CONFIG_PAGE_IOC_2 *ioc2;
809 CONFIG_PAGE_IOC_2_RAID_VOL *vol;
810 U8 VolumeBus, VolumeID;
791 int i, j, new_pool, pool_count[7];
811 int error, i, j, new_pool, pool_count[7];
792
812
793 if (mpt_lookup_volume(fd, name, &VolumeBus, &VolumeID) < 0) {
794 warn("Invalid volume %s", name);
795 return (-1);
813 error = mpt_lookup_volume(fd, name, &VolumeBus, &VolumeID);
814 if (error) {
815 warnc(error, "Invalid volume %s", name);
816 return (error);
796 }
797
798 info = mpt_vol_info(fd, VolumeBus, VolumeID, NULL);
799 if (info == NULL)
817 }
818
819 info = mpt_vol_info(fd, VolumeBus, VolumeID, NULL);
820 if (info == NULL)
800 return (-1);
821 return (errno);
801
802 /*
803 * Check for an existing pool other than pool 0 (used for
804 * global spares).
805 */
806 if ((info->VolumeSettings.HotSparePool & ~MPI_RAID_HOT_SPARE_POOL_0) !=
807 0) {
808 *pool = 1 << (ffs(info->VolumeSettings.HotSparePool &
809 ~MPI_RAID_HOT_SPARE_POOL_0) - 1);
810 return (0);
811 }
812 free(info);
813
814 /*
815 * Try to find a free pool. First, figure out which pools are
816 * in use.
817 */
818 ioc2 = mpt_read_ioc_page(fd, 2, NULL);
819 if (ioc2 == NULL) {
822
823 /*
824 * Check for an existing pool other than pool 0 (used for
825 * global spares).
826 */
827 if ((info->VolumeSettings.HotSparePool & ~MPI_RAID_HOT_SPARE_POOL_0) !=
828 0) {
829 *pool = 1 << (ffs(info->VolumeSettings.HotSparePool &
830 ~MPI_RAID_HOT_SPARE_POOL_0) - 1);
831 return (0);
832 }
833 free(info);
834
835 /*
836 * Try to find a free pool. First, figure out which pools are
837 * in use.
838 */
839 ioc2 = mpt_read_ioc_page(fd, 2, NULL);
840 if (ioc2 == NULL) {
841 error = errno;
820 warn("Failed to fetch volume list");
842 warn("Failed to fetch volume list");
821 return (-1);
843 return (error);
822 }
823 bzero(pool_count, sizeof(pool_count));
824 vol = ioc2->RaidVolume;
825 for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) {
826 info = mpt_vol_info(fd, vol->VolumeBus, vol->VolumeID, NULL);
827 if (info == NULL)
844 }
845 bzero(pool_count, sizeof(pool_count));
846 vol = ioc2->RaidVolume;
847 for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) {
848 info = mpt_vol_info(fd, vol->VolumeBus, vol->VolumeID, NULL);
849 if (info == NULL)
828 return (-1);
850 return (errno);
829 for (j = 0; j < 7; j++)
830 if (info->VolumeSettings.HotSparePool & (1 << (j + 1)))
831 pool_count[j]++;
832 free(info);
833 }
834 free(ioc2);
835
836 /* Find the pool with the lowest use count. */
837 new_pool = 0;
838 for (i = 1; i < 7; i++)
839 if (pool_count[i] < pool_count[new_pool])
840 new_pool = i;
841 new_pool++;
842
843 /* Add this pool to the volume. */
844 info = mpt_vol_info(fd, VolumeBus, VolumeID, NULL);
845 if (info == NULL)
851 for (j = 0; j < 7; j++)
852 if (info->VolumeSettings.HotSparePool & (1 << (j + 1)))
853 pool_count[j]++;
854 free(info);
855 }
856 free(ioc2);
857
858 /* Find the pool with the lowest use count. */
859 new_pool = 0;
860 for (i = 1; i < 7; i++)
861 if (pool_count[i] < pool_count[new_pool])
862 new_pool = i;
863 new_pool++;
864
865 /* Add this pool to the volume. */
866 info = mpt_vol_info(fd, VolumeBus, VolumeID, NULL);
867 if (info == NULL)
846 return (-1);
868 return (error);
847 info->VolumeSettings.HotSparePool |= (1 << new_pool);
869 info->VolumeSettings.HotSparePool |= (1 << new_pool);
848 if (mpt_raid_action(fd, MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS,
870 error = mpt_raid_action(fd, MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS,
849 VolumeBus, VolumeID, 0, *(U32 *)&info->VolumeSettings, NULL, 0,
871 VolumeBus, VolumeID, 0, *(U32 *)&info->VolumeSettings, NULL, 0,
850 NULL, NULL, 0, NULL, NULL, 0) < 0) {
872 NULL, NULL, 0, NULL, NULL, 0);
873 if (error) {
851 warnx("Failed to add spare pool %d to %s", new_pool,
852 mpt_volume_name(VolumeBus, VolumeID));
874 warnx("Failed to add spare pool %d to %s", new_pool,
875 mpt_volume_name(VolumeBus, VolumeID));
853 return (-1);
876 return (error);
854 }
855 free(info);
856
857 *pool = (1 << new_pool);
858 return (0);
859}
860
861static int

--- 11 unchanged lines hidden (view full) ---

873 }
874 if (ac > 3) {
875 warnx("add spare: extra arguments");
876 return (EINVAL);
877 }
878
879 fd = mpt_open(mpt_unit);
880 if (fd < 0) {
877 }
878 free(info);
879
880 *pool = (1 << new_pool);
881 return (0);
882}
883
884static int

--- 11 unchanged lines hidden (view full) ---

896 }
897 if (ac > 3) {
898 warnx("add spare: extra arguments");
899 return (EINVAL);
900 }
901
902 fd = mpt_open(mpt_unit);
903 if (fd < 0) {
904 error = errno;
881 warn("mpt_open");
905 warn("mpt_open");
882 return (errno);
906 return (error);
883 }
884
885 if (ac == 3) {
907 }
908
909 if (ac == 3) {
886 if (find_volume_spare_pool(fd, av[2], &pool) < 0)
887 return (errno);
910 error = find_volume_spare_pool(fd, av[2], &pool);
911 if (error)
912 return (error);
888 } else
889 pool = MPI_RAID_HOT_SPARE_POOL_0;
890
891 list = mpt_pd_list(fd);
892 if (list == NULL)
893 return (errno);
894
895 error = mpt_lookup_drive(list, av[1], &PhysDiskNum);
896 if (error) {
897 error = mpt_fetch_disks(fd, &nsdisks, &sdisks);
898 if (error != 0) {
899 warn("Failed to fetch standalone disk list");
900 return (error);
901 }
902
903 if (mpt_lookup_standalone_disk(av[1], sdisks, nsdisks, &i) <
904 0) {
913 } else
914 pool = MPI_RAID_HOT_SPARE_POOL_0;
915
916 list = mpt_pd_list(fd);
917 if (list == NULL)
918 return (errno);
919
920 error = mpt_lookup_drive(list, av[1], &PhysDiskNum);
921 if (error) {
922 error = mpt_fetch_disks(fd, &nsdisks, &sdisks);
923 if (error != 0) {
924 warn("Failed to fetch standalone disk list");
925 return (error);
926 }
927
928 if (mpt_lookup_standalone_disk(av[1], sdisks, nsdisks, &i) <
929 0) {
930 error = errno;
905 warn("Unable to lookup drive %s", av[1]);
931 warn("Unable to lookup drive %s", av[1]);
906 return (errno);
932 return (error);
907 }
908
909 if (mpt_lock_physdisk(&sdisks[i]) < 0)
910 return (errno);
911
912 if (mpt_create_physdisk(fd, &sdisks[i], &PhysDiskNum) < 0) {
933 }
934
935 if (mpt_lock_physdisk(&sdisks[i]) < 0)
936 return (errno);
937
938 if (mpt_create_physdisk(fd, &sdisks[i], &PhysDiskNum) < 0) {
939 error = errno;
913 warn("Failed to create physical disk page");
940 warn("Failed to create physical disk page");
914 return (errno);
941 return (error);
915 }
916 free(sdisks);
917 }
918 mpt_free_pd_list(list);
919
920 info = mpt_pd_info(fd, PhysDiskNum, NULL);
921 if (info == NULL) {
942 }
943 free(sdisks);
944 }
945 mpt_free_pd_list(list);
946
947 info = mpt_pd_info(fd, PhysDiskNum, NULL);
948 if (info == NULL) {
949 error = errno;
922 warn("Failed to fetch drive info");
950 warn("Failed to fetch drive info");
923 return (errno);
951 return (error);
924 }
925
926 info->PhysDiskSettings.HotSparePool = pool;
927 error = mpt_raid_action(fd, MPI_RAID_ACTION_CHANGE_PHYSDISK_SETTINGS, 0,
928 0, PhysDiskNum, *(U32 *)&info->PhysDiskSettings, NULL, 0, NULL,
929 NULL, 0, NULL, NULL, 0);
930 if (error) {
952 }
953
954 info->PhysDiskSettings.HotSparePool = pool;
955 error = mpt_raid_action(fd, MPI_RAID_ACTION_CHANGE_PHYSDISK_SETTINGS, 0,
956 0, PhysDiskNum, *(U32 *)&info->PhysDiskSettings, NULL, 0, NULL,
957 NULL, 0, NULL, NULL, 0);
958 if (error) {
931 warn("Failed to assign spare");
932 return (errno);
959 warnc(error, "Failed to assign spare");
960 return (error);
933 }
934
935 free(info);
936 close(fd);
937
938 return (0);
939}
940MPT_COMMAND(top, add, add_spare);

--- 8 unchanged lines hidden (view full) ---

949
950 if (ac != 2) {
951 warnx("remove spare: drive required");
952 return (EINVAL);
953 }
954
955 fd = mpt_open(mpt_unit);
956 if (fd < 0) {
961 }
962
963 free(info);
964 close(fd);
965
966 return (0);
967}
968MPT_COMMAND(top, add, add_spare);

--- 8 unchanged lines hidden (view full) ---

977
978 if (ac != 2) {
979 warnx("remove spare: drive required");
980 return (EINVAL);
981 }
982
983 fd = mpt_open(mpt_unit);
984 if (fd < 0) {
985 error = errno;
957 warn("mpt_open");
986 warn("mpt_open");
958 return (errno);
987 return (error);
959 }
960
961 list = mpt_pd_list(fd);
962 if (list == NULL)
963 return (errno);
964
965 error = mpt_lookup_drive(list, av[1], &PhysDiskNum);
966 if (error) {
967 warn("Failed to find drive %s", av[1]);
968 return (error);
969 }
970 mpt_free_pd_list(list);
971
972
973 info = mpt_pd_info(fd, PhysDiskNum, NULL);
974 if (info == NULL) {
988 }
989
990 list = mpt_pd_list(fd);
991 if (list == NULL)
992 return (errno);
993
994 error = mpt_lookup_drive(list, av[1], &PhysDiskNum);
995 if (error) {
996 warn("Failed to find drive %s", av[1]);
997 return (error);
998 }
999 mpt_free_pd_list(list);
1000
1001
1002 info = mpt_pd_info(fd, PhysDiskNum, NULL);
1003 if (info == NULL) {
1004 error = errno;
975 warn("Failed to fetch drive info");
1005 warn("Failed to fetch drive info");
976 return (errno);
1006 return (error);
977 }
978
979 if (info->PhysDiskSettings.HotSparePool == 0) {
980 warnx("Drive %u is not a hot spare", PhysDiskNum);
981 return (EINVAL);
982 }
983
984 if (mpt_delete_physdisk(fd, PhysDiskNum) < 0) {
1007 }
1008
1009 if (info->PhysDiskSettings.HotSparePool == 0) {
1010 warnx("Drive %u is not a hot spare", PhysDiskNum);
1011 return (EINVAL);
1012 }
1013
1014 if (mpt_delete_physdisk(fd, PhysDiskNum) < 0) {
1015 error = errno;
985 warn("Failed to delete physical disk page");
1016 warn("Failed to delete physical disk page");
986 return (errno);
1017 return (error);
987 }
988
989 mpt_rescan_bus(info->PhysDiskBus, info->PhysDiskID);
990 free(info);
991 close(fd);
992
993 return (0);
994}

--- 11 unchanged lines hidden (view full) ---

1006
1007 if (ac != 2) {
1008 warnx("pd create: drive required");
1009 return (EINVAL);
1010 }
1011
1012 fd = mpt_open(mpt_unit);
1013 if (fd < 0) {
1018 }
1019
1020 mpt_rescan_bus(info->PhysDiskBus, info->PhysDiskID);
1021 free(info);
1022 close(fd);
1023
1024 return (0);
1025}

--- 11 unchanged lines hidden (view full) ---

1037
1038 if (ac != 2) {
1039 warnx("pd create: drive required");
1040 return (EINVAL);
1041 }
1042
1043 fd = mpt_open(mpt_unit);
1044 if (fd < 0) {
1045 error = errno;
1014 warn("mpt_open");
1046 warn("mpt_open");
1015 return (errno);
1047 return (error);
1016 }
1017
1018 error = mpt_fetch_disks(fd, &ndisks, &disks);
1019 if (error != 0) {
1020 warn("Failed to fetch standalone disk list");
1021 return (error);
1022 }
1023
1024 if (mpt_lookup_standalone_disk(av[1], disks, ndisks, &i) < 0) {
1048 }
1049
1050 error = mpt_fetch_disks(fd, &ndisks, &disks);
1051 if (error != 0) {
1052 warn("Failed to fetch standalone disk list");
1053 return (error);
1054 }
1055
1056 if (mpt_lookup_standalone_disk(av[1], disks, ndisks, &i) < 0) {
1057 error = errno;
1025 warn("Unable to lookup drive");
1058 warn("Unable to lookup drive");
1026 return (errno);
1059 return (error);
1027 }
1028
1029 if (mpt_lock_physdisk(&disks[i]) < 0)
1030 return (errno);
1031
1032 if (mpt_create_physdisk(fd, &disks[i], &PhysDiskNum) < 0) {
1060 }
1061
1062 if (mpt_lock_physdisk(&disks[i]) < 0)
1063 return (errno);
1064
1065 if (mpt_create_physdisk(fd, &disks[i], &PhysDiskNum) < 0) {
1066 error = errno;
1033 warn("Failed to create physical disk page");
1067 warn("Failed to create physical disk page");
1034 return (errno);
1068 return (error);
1035 }
1036 free(disks);
1037
1038 printf("Added drive %s with PhysDiskNum %u\n", av[1], PhysDiskNum);
1039
1040 close(fd);
1041
1042 return (0);
1043}
1044MPT_COMMAND(pd, create, pd_create);
1045
1046static int
1047pd_delete(int ac, char **av)
1048{
1049 CONFIG_PAGE_RAID_PHYS_DISK_0 *info;
1050 struct mpt_drive_list *list;
1069 }
1070 free(disks);
1071
1072 printf("Added drive %s with PhysDiskNum %u\n", av[1], PhysDiskNum);
1073
1074 close(fd);
1075
1076 return (0);
1077}
1078MPT_COMMAND(pd, create, pd_create);
1079
1080static int
1081pd_delete(int ac, char **av)
1082{
1083 CONFIG_PAGE_RAID_PHYS_DISK_0 *info;
1084 struct mpt_drive_list *list;
1051 int fd;
1085 int error, fd;
1052 U8 PhysDiskNum;
1053
1054 if (ac != 2) {
1055 warnx("pd delete: drive required");
1056 return (EINVAL);
1057 }
1058
1059 fd = mpt_open(mpt_unit);
1060 if (fd < 0) {
1086 U8 PhysDiskNum;
1087
1088 if (ac != 2) {
1089 warnx("pd delete: drive required");
1090 return (EINVAL);
1091 }
1092
1093 fd = mpt_open(mpt_unit);
1094 if (fd < 0) {
1095 error = errno;
1061 warn("mpt_open");
1096 warn("mpt_open");
1062 return (errno);
1097 return (error);
1063 }
1064
1065 list = mpt_pd_list(fd);
1066 if (list == NULL)
1067 return (errno);
1068
1069 if (mpt_lookup_drive(list, av[1], &PhysDiskNum) < 0) {
1098 }
1099
1100 list = mpt_pd_list(fd);
1101 if (list == NULL)
1102 return (errno);
1103
1104 if (mpt_lookup_drive(list, av[1], &PhysDiskNum) < 0) {
1105 error = errno;
1070 warn("Failed to find drive %s", av[1]);
1106 warn("Failed to find drive %s", av[1]);
1071 return (errno);
1107 return (error);
1072 }
1073 mpt_free_pd_list(list);
1074
1075 info = mpt_pd_info(fd, PhysDiskNum, NULL);
1076 if (info == NULL) {
1108 }
1109 mpt_free_pd_list(list);
1110
1111 info = mpt_pd_info(fd, PhysDiskNum, NULL);
1112 if (info == NULL) {
1113 error = errno;
1077 warn("Failed to fetch drive info");
1114 warn("Failed to fetch drive info");
1078 return (errno);
1115 return (error);
1079 }
1080
1081 if (mpt_delete_physdisk(fd, PhysDiskNum) < 0) {
1116 }
1117
1118 if (mpt_delete_physdisk(fd, PhysDiskNum) < 0) {
1119 error = errno;
1082 warn("Failed to delete physical disk page");
1120 warn("Failed to delete physical disk page");
1083 return (errno);
1121 return (error);
1084 }
1085
1086 mpt_rescan_bus(info->PhysDiskBus, info->PhysDiskID);
1087 free(info);
1088 close(fd);
1089
1090 return (0);
1091}

--- 29 unchanged lines hidden (view full) ---

1121 vol->PhysDisk[i].PhysDiskNum, vol->PhysDisk[i].PhysDiskMap);
1122}
1123
1124static int
1125debug_config(int ac, char **av)
1126{
1127 CONFIG_PAGE_RAID_VOL_0 *vol;
1128 U8 VolumeBus, VolumeID;
1122 }
1123
1124 mpt_rescan_bus(info->PhysDiskBus, info->PhysDiskID);
1125 free(info);
1126 close(fd);
1127
1128 return (0);
1129}

--- 29 unchanged lines hidden (view full) ---

1159 vol->PhysDisk[i].PhysDiskNum, vol->PhysDisk[i].PhysDiskMap);
1160}
1161
1162static int
1163debug_config(int ac, char **av)
1164{
1165 CONFIG_PAGE_RAID_VOL_0 *vol;
1166 U8 VolumeBus, VolumeID;
1129 int fd;
1167 int error, fd;
1130
1131 if (ac != 2) {
1132 warnx("debug: volume required");
1133 return (EINVAL);
1134 }
1135
1136 fd = mpt_open(mpt_unit);
1137 if (fd < 0) {
1168
1169 if (ac != 2) {
1170 warnx("debug: volume required");
1171 return (EINVAL);
1172 }
1173
1174 fd = mpt_open(mpt_unit);
1175 if (fd < 0) {
1176 error = errno;
1138 warn("mpt_open");
1177 warn("mpt_open");
1139 return (errno);
1178 return (error);
1140 }
1141
1179 }
1180
1142 if (mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID) < 0) {
1143 warn("Invalid volume: %s", av[1]);
1144 return (errno);
1181 error = mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID);
1182 if (error) {
1183 warnc(error, "Invalid volume: %s", av[1]);
1184 return (error);
1145 }
1146
1147 vol = mpt_vol_info(fd, VolumeBus, VolumeID, NULL);
1148 if (vol == NULL) {
1185 }
1186
1187 vol = mpt_vol_info(fd, VolumeBus, VolumeID, NULL);
1188 if (vol == NULL) {
1189 error = errno;
1149 warn("Failed to get volume info");
1190 warn("Failed to get volume info");
1150 return (errno);
1191 return (error);
1151 }
1152
1153 dump_config(vol);
1154 free(vol);
1155 close(fd);
1156
1157 return (0);
1158}
1159MPT_COMMAND(top, debug, debug_config);
1160#endif
1192 }
1193
1194 dump_config(vol);
1195 free(vol);
1196 close(fd);
1197
1198 return (0);
1199}
1200MPT_COMMAND(top, debug, debug_config);
1201#endif