From 3cac7a127a25eb24d9e9f96cd0e3bac7efedf4bd Mon Sep 17 00:00:00 2001 From: jhb Date: Fri, 19 Nov 2010 17:08:15 +0000 Subject: [PATCH] MFC 204352, 208028, 209266, 209399, 210723, 213672, 215046: - Fixed static linkage. - Document that mptutil/mpt do not support RAID volumes in excess of 2TB. - Report subcommand handler errors so that tools that invoke mptutil can robustly report errors. - Save errno values before calling warn(3) so that errors are correctly reported. - Check for malloc() failures. git-svn-id: svn://svn.freebsd.org/base/stable/8@215534 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- usr.sbin/mptutil/Makefile | 4 +- usr.sbin/mptutil/mpt_cam.c | 18 +-- usr.sbin/mptutil/mpt_cmd.c | 50 ++++---- usr.sbin/mptutil/mpt_config.c | 215 ++++++++++++++++++++-------------- usr.sbin/mptutil/mpt_drive.c | 38 +++--- usr.sbin/mptutil/mpt_evt.c | 10 +- usr.sbin/mptutil/mpt_show.c | 40 ++++--- usr.sbin/mptutil/mpt_volume.c | 66 ++++++----- usr.sbin/mptutil/mptutil.8 | 22 +++- usr.sbin/mptutil/mptutil.c | 8 +- 10 files changed, 277 insertions(+), 194 deletions(-) diff --git a/usr.sbin/mptutil/Makefile b/usr.sbin/mptutil/Makefile index 4abf66e46..53d75b34d 100644 --- a/usr.sbin/mptutil/Makefile +++ b/usr.sbin/mptutil/Makefile @@ -8,8 +8,8 @@ MAN= mptutil.8 WARNS?= 3 -DPADD+= ${LIBCAM} ${LIBUTIL} -LDADD+= -lcam -lutil +DPADD= ${LIBCAM} ${LIBSBUF} ${LIBUTIL} +LDADD= -lcam -lsbuf -lutil # Here be dragons .ifdef DEBUG diff --git a/usr.sbin/mptutil/mpt_cam.c b/usr.sbin/mptutil/mpt_cam.c index b14451a61..3adbed8dd 100644 --- a/usr.sbin/mptutil/mpt_cam.c +++ b/usr.sbin/mptutil/mpt_cam.c @@ -63,6 +63,7 @@ fetch_path_id(path_id_t *path_id) struct bus_match_pattern *b; union ccb ccb; size_t bufsize; + int error; if (xpt_open() < 0) return (ENXIO); @@ -91,9 +92,10 @@ fetch_path_id(path_id_t *path_id) b->flags = BUS_MATCH_NAME | BUS_MATCH_UNIT | BUS_MATCH_BUS_ID; if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) { + error = errno; free(ccb.cdm.matches); free(ccb.cdm.patterns); - return (errno); + return (error); } free(ccb.cdm.patterns); @@ -124,7 +126,7 @@ mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd) union ccb ccb; path_id_t path_id; size_t bufsize; - int error, i; + int error; /* mpt(4) only handles devices on bus 0. */ if (VolumeBus != 0) @@ -164,10 +166,10 @@ mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd) p->flags = PERIPH_MATCH_PATH | PERIPH_MATCH_NAME | PERIPH_MATCH_TARGET; if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) { - i = errno; + error = errno; free(ccb.cdm.matches); free(ccb.cdm.patterns); - return (i); + return (error); } free(ccb.cdm.patterns); @@ -397,8 +399,8 @@ mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp) union ccb ccb; path_id_t path_id; size_t bufsize; - u_int i; int count, error; + uint32_t i; if (xpt_open() < 0) return (ENXIO); @@ -431,10 +433,10 @@ mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp) p->flags = PERIPH_MATCH_PATH | PERIPH_MATCH_NAME; if (ioctl(xptfd, CAMIOCOMMAND, &ccb) < 0) { - i = errno; + error = errno; free(ccb.cdm.matches); free(ccb.cdm.patterns); - return (i); + return (error); } free(ccb.cdm.patterns); @@ -481,6 +483,8 @@ mpt_fetch_disks(int fd, int *ndisks, struct mpt_standalone_disk **disksp) * exclude them from the list. */ ioc2 = mpt_read_ioc_page(fd, 2, NULL); + if (ioc2 == NULL) + return (errno); disks = calloc(ccb.cdm.num_matches, sizeof(*disks)); count = 0; for (i = 0; i < ccb.cdm.num_matches; i++) { diff --git a/usr.sbin/mptutil/mpt_cmd.c b/usr.sbin/mptutil/mpt_cmd.c index 2d6000c77..8104fc9b4 100644 --- a/usr.sbin/mptutil/mpt_cmd.c +++ b/usr.sbin/mptutil/mpt_cmd.c @@ -310,18 +310,15 @@ mpt_lookup_volume(int fd, const char *name, U8 *VolumeBus, U8 *VolumeID) id = strtol(cp + 1, &cp, 0); if (*cp == '\0') { if (bus < 0 || bus > 0xff || id < 0 || id > 0xff) { - errno = EINVAL; - return (-1); + return (EINVAL); } *VolumeBus = bus; *VolumeID = id; return (0); } } else if (*cp == '\0') { - if (bus < 0 || bus > 0xff) { - errno = EINVAL; - return (-1); - } + if (bus < 0 || bus > 0xff) + return (EINVAL); *VolumeBus = 0; *VolumeID = bus; return (0); @@ -329,7 +326,7 @@ mpt_lookup_volume(int fd, const char *name, U8 *VolumeBus, U8 *VolumeID) ioc2 = mpt_read_ioc_page(fd, 2, NULL); if (ioc2 == NULL) - return (-1); + return (errno); vol = ioc2->RaidVolume; for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { @@ -343,8 +340,7 @@ mpt_lookup_volume(int fd, const char *name, U8 *VolumeBus, U8 *VolumeID) } } free(ioc2); - errno = EINVAL; - return (-1); + return (EINVAL); } int @@ -360,15 +356,14 @@ mpt_read_config_page_header(int fd, U8 PageType, U8 PageNumber, U32 PageAddress, req.header.PageNumber = PageNumber; req.page_address = PageAddress; if (ioctl(fd, MPTIO_READ_CFG_HEADER, &req) < 0) - return (-1); + return (errno); if (!IOC_STATUS_SUCCESS(req.ioc_status)) { if (IOCStatus != NULL) *IOCStatus = req.ioc_status; else warnx("Reading config page header failed: %s", mpt_ioc_status(req.ioc_status)); - errno = EIO; - return (-1); + return (EIO); } *header = req.header; return (0); @@ -380,7 +375,7 @@ mpt_read_config_page(int fd, U8 PageType, U8 PageNumber, U32 PageAddress, { struct mpt_cfg_page_req req; void *buf; - int save_errno; + int error; if (IOCStatus != NULL) *IOCStatus = MPI_IOCSTATUS_SUCCESS; @@ -404,9 +399,9 @@ mpt_read_config_page(int fd, U8 PageType, U8 PageNumber, U32 PageAddress, req.buf = buf; bcopy(&req.header, buf, sizeof(req.header)); if (ioctl(fd, MPTIO_READ_CFG_PAGE, &req) < 0) { - save_errno = errno; + error = errno; free(buf); - errno = save_errno; + errno = error; return (NULL); } if (!IOC_STATUS_SUCCESS(req.ioc_status)) { @@ -428,7 +423,7 @@ mpt_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion, { struct mpt_ext_cfg_page_req req; void *buf; - int save_errno; + int error; if (IOCStatus != NULL) *IOCStatus = MPI_IOCSTATUS_SUCCESS; @@ -453,9 +448,9 @@ mpt_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion, req.buf = buf; bcopy(&req.header, buf, sizeof(req.header)); if (ioctl(fd, MPTIO_READ_EXT_CFG_PAGE, &req) < 0) { - save_errno = errno; + error = errno; free(buf); - errno = save_errno; + errno = error; return (NULL); } if (!IOC_STATUS_SUCCESS(req.ioc_status)) { @@ -484,7 +479,7 @@ mpt_write_config_page(int fd, void *buf, U16 *IOCStatus) hdr = buf; req.len = hdr->PageLength * 4; if (ioctl(fd, MPTIO_WRITE_CFG_PAGE, &req) < 0) - return (-1); + return (errno); if (!IOC_STATUS_SUCCESS(req.ioc_status)) { if (IOCStatus != NULL) { *IOCStatus = req.ioc_status; @@ -492,8 +487,7 @@ mpt_write_config_page(int fd, void *buf, U16 *IOCStatus) } warnx("Writing config page failed: %s", mpt_ioc_status(req.ioc_status)); - errno = EIO; - return (-1); + return (EIO); } return (0); } @@ -507,10 +501,8 @@ mpt_raid_action(int fd, U8 Action, U8 VolumeBus, U8 VolumeID, U8 PhysDiskNum, if (IOCStatus != NULL) *IOCStatus = MPI_IOCSTATUS_SUCCESS; - if (datalen < 0 || (unsigned)datalen > sizeof(raid_act.action_data)) { - errno = EINVAL; - return (-1); - } + if (datalen < 0 || (unsigned)datalen > sizeof(raid_act.action_data)) + return (EINVAL); bzero(&raid_act, sizeof(raid_act)); raid_act.action = Action; raid_act.volume_bus = VolumeBus; @@ -524,7 +516,7 @@ mpt_raid_action(int fd, U8 Action, U8 VolumeBus, U8 VolumeID, U8 PhysDiskNum, } if (ioctl(fd, MPTIO_RAID_ACTION, &raid_act) < 0) - return (-1); + return (errno); if (!IOC_STATUS_SUCCESS(raid_act.ioc_status)) { if (IOCStatus != NULL) { @@ -533,8 +525,7 @@ mpt_raid_action(int fd, U8 Action, U8 VolumeBus, U8 VolumeID, U8 PhysDiskNum, } warnx("RAID action failed: %s", mpt_ioc_status(raid_act.ioc_status)); - errno = EIO; - return (-1); + return (EIO); } if (ActionStatus != NULL) @@ -544,8 +535,7 @@ mpt_raid_action(int fd, U8 Action, U8 VolumeBus, U8 VolumeID, U8 PhysDiskNum, return (0); warnx("RAID action failed: %s", mpt_raid_status(raid_act.action_status)); - errno = EIO; - return (-1); + return (EIO); } if (VolumeStatus != NULL) diff --git a/usr.sbin/mptutil/mpt_config.c b/usr.sbin/mptutil/mpt_config.c index 3874df301..6247bb493 100644 --- a/usr.sbin/mptutil/mpt_config.c +++ b/usr.sbin/mptutil/mpt_config.c @@ -102,15 +102,15 @@ mpt_lock_volume(U8 VolumeBus, U8 VolumeID) */ return (0); if (error) { - errno = error; - warn("Unable to lookup volume device name"); - return (-1); + warnc(error, "Unable to lookup volume device name"); + return (error); } snprintf(path, sizeof(path), "%s%s", _PATH_DEV, qd.devname); vfd = open(path, O_RDWR); if (vfd < 0) { + error = errno; warn("Unable to lock volume %s", qd.devname); - return (-1); + return (error); } return (0); } @@ -119,13 +119,14 @@ static int mpt_lock_physdisk(struct mpt_standalone_disk *disk) { char path[MAXPATHLEN]; - int dfd; + int dfd, error; snprintf(path, sizeof(path), "%s%s", _PATH_DEV, disk->devname); dfd = open(path, O_RDWR); if (dfd < 0) { + error = errno; warn("Unable to lock disk %s", disk->devname); - return (-1); + return (error); } return (0); } @@ -144,8 +145,7 @@ mpt_lookup_standalone_disk(const char *name, struct mpt_standalone_disk *disks, id = strtol(cp + 1, &cp, 0); if (*cp == '\0') { if (bus < 0 || bus > 0xff || id < 0 || id > 0xff) { - errno = EINVAL; - return (-1); + return (EINVAL); } for (i = 0; i < ndisks; i++) { if (disks[i].bus == (U8)bus && @@ -154,8 +154,7 @@ mpt_lookup_standalone_disk(const char *name, struct mpt_standalone_disk *disks, return (0); } } - errno = ENOENT; - return (-1); + return (ENOENT); } } @@ -166,12 +165,10 @@ mpt_lookup_standalone_disk(const char *name, struct mpt_standalone_disk *disks, return (0); } } - errno = ENOENT; - return (-1); + return (ENOENT); } - errno = EINVAL; - return (-1); + return (EINVAL); } /* @@ -182,16 +179,17 @@ mpt_create_physdisk(int fd, struct mpt_standalone_disk *disk, U8 *PhysDiskNum) { CONFIG_PAGE_HEADER header; CONFIG_PAGE_RAID_PHYS_DISK_0 *config_page; + int error; U32 ActionData; - if (mpt_read_config_page_header(fd, MPI_CONFIG_PAGETYPE_RAID_PHYSDISK, - 0, 0, &header, NULL) < 0) - return (-1); + error = mpt_read_config_page_header(fd, MPI_CONFIG_PAGETYPE_RAID_PHYSDISK, + 0, 0, &header, NULL); + if (error) + return (error); if (header.PageVersion > MPI_RAIDPHYSDISKPAGE0_PAGEVERSION) { warnx("Unsupported RAID physdisk page 0 version %d", header.PageVersion); - errno = EOPNOTSUPP; - return (-1); + return (EOPNOTSUPP); } config_page = calloc(1, sizeof(CONFIG_PAGE_RAID_PHYS_DISK_0)); config_page->Header.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; @@ -203,10 +201,11 @@ mpt_create_physdisk(int fd, struct mpt_standalone_disk *disk, U8 *PhysDiskNum) config_page->PhysDiskID = disk->target; /* XXX: Enclosure info for PhysDiskSettings? */ - if (mpt_raid_action(fd, MPI_RAID_ACTION_CREATE_PHYSDISK, 0, 0, 0, 0, + error = mpt_raid_action(fd, MPI_RAID_ACTION_CREATE_PHYSDISK, 0, 0, 0, 0, config_page, sizeof(CONFIG_PAGE_RAID_PHYS_DISK_0), NULL, - &ActionData, sizeof(ActionData), NULL, NULL, 1) < 0) - return (-1); + &ActionData, sizeof(ActionData), NULL, NULL, 1); + if (error) + return (error); *PhysDiskNum = ActionData & 0xff; return (0); } @@ -232,18 +231,20 @@ clear_config(int ac, char **av) IOC_3_PHYS_DISK *disk; CONFIG_PAGE_IOC_5 *ioc5; IOC_5_HOT_SPARE *spare; - int ch, fd, i; + int ch, error, fd, i; fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } ioc2 = mpt_read_ioc_page(fd, 2, NULL); if (ioc2 == NULL) { + error = errno; warn("Failed to fetch volume list"); - return (errno); + return (error); } /* Lock all the volumes first. */ @@ -267,14 +268,16 @@ clear_config(int ac, char **av) /* Delete all the volumes. */ vol = ioc2->RaidVolume; - for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) - if (mpt_raid_action(fd, MPI_RAID_ACTION_DELETE_VOLUME, + for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { + error = mpt_raid_action(fd, MPI_RAID_ACTION_DELETE_VOLUME, vol->VolumeBus, vol->VolumeID, 0, MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS | MPI_RAID_ACTION_ADATA_ZERO_LBA0, NULL, 0, NULL, NULL, 0, - NULL, NULL, 0) < 0) - warn("Failed to delete volume %s", + NULL, NULL, 0); + if (error) + warnc(error, "Failed to delete volume %s", mpt_volume_name(vol->VolumeBus, vol->VolumeID)); + } free(ioc2); /* Delete all the spares. */ @@ -411,8 +414,9 @@ parse_volume(int fd, int raid_type, struct config_id_state *state, /* See if it is a standalone disk. */ if (mpt_lookup_standalone_disk(cp, state->sdisks, state->nsdisks, &i) < 0) { + error = errno; warn("Unable to lookup drive %s", cp); - return (errno); + return (error); } dinfo->sdisk = &state->sdisks[i]; @@ -433,17 +437,18 @@ add_drives(int fd, struct volume_info *info, int verbose) { struct drive_info *dinfo; U8 PhysDiskNum; - int i; + int error, i; for (i = 0, dinfo = info->drives; i < info->drive_count; i++, dinfo++) { if (dinfo->info == NULL) { if (mpt_create_physdisk(fd, dinfo->sdisk, &PhysDiskNum) < 0) { + error = errno; warn( "Failed to create physical disk page for %s", dinfo->sdisk->devname); - return (errno); + return (error); } if (verbose) printf("Added drive %s with PhysDiskNum %u\n", @@ -500,11 +505,14 @@ build_volume(int fd, struct volume_info *info, int raid_type, long stripe_size, U32 MinLBA; uint64_t MaxLBA; size_t page_size; - int i; + int error, i; - if (mpt_read_config_page_header(fd, MPI_CONFIG_PAGETYPE_RAID_VOLUME, - 0, 0, &header, NULL) < 0) + error = mpt_read_config_page_header(fd, MPI_CONFIG_PAGETYPE_RAID_VOLUME, + 0, 0, &header, NULL); + if (error) { + errno = error; return (NULL); + } if (header.PageVersion > MPI_RAIDVOLPAGE0_PAGEVERSION) { warnx("Unsupported RAID volume page 0 version %d", header.PageVersion); @@ -514,6 +522,8 @@ build_volume(int fd, struct volume_info *info, int raid_type, long stripe_size, page_size = sizeof(CONFIG_PAGE_RAID_VOL_0) + sizeof(RAID_VOL0_PHYS_DISK) * (info->drive_count - 1); vol = calloc(1, page_size); + if (vol == NULL) + return (NULL); /* Header */ vol->Header.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME; @@ -607,8 +617,8 @@ create_volume(int ac, char **av) CONFIG_PAGE_RAID_VOL_0 *vol; struct config_id_state state; struct volume_info *info; - int ch, error, fd, i, raid_type, verbose, quick; long stripe_size; + int ch, error, fd, i, quick, raid_type, verbose; #ifdef DEBUG int dump; #endif @@ -620,8 +630,9 @@ create_volume(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } /* Lookup the RAID type first. */ @@ -677,8 +688,9 @@ create_volume(int ac, char **av) /* Fetch existing config data. */ state.ioc2 = mpt_read_ioc_page(fd, 2, NULL); if (state.ioc2 == NULL) { + error = errno; warn("Failed to read volume list"); - return (errno); + return (error); } state.list = mpt_pd_list(fd); if (state.list == NULL) @@ -696,6 +708,8 @@ create_volume(int ac, char **av) return (EINVAL); } info = calloc(1, sizeof(*info)); + if (info == NULL) + return (ENOMEM); error = parse_volume(fd, raid_type, &state, av[0], info); if (error) return (error); @@ -707,6 +721,8 @@ create_volume(int ac, char **av) /* Build the volume. */ vol = build_volume(fd, info, raid_type, stripe_size, &state, verbose); + if (vol == NULL) + return (errno); #ifdef DEBUG if (dump) { @@ -716,12 +732,13 @@ create_volume(int ac, char **av) #endif /* Send the new volume to the controller. */ - if (mpt_raid_action(fd, MPI_RAID_ACTION_CREATE_VOLUME, vol->VolumeBus, + error = mpt_raid_action(fd, MPI_RAID_ACTION_CREATE_VOLUME, vol->VolumeBus, vol->VolumeID, 0, quick ? MPI_RAID_ACTION_ADATA_DO_NOT_SYNC : 0, - vol, vol->Header.PageLength * 4, NULL, NULL, 0, NULL, NULL, 1) < - 0) { + vol, vol->Header.PageLength * 4, NULL, NULL, 0, NULL, NULL, 1); + if (error) { + errno = error; warn("Failed to add volume"); - return (errno); + return (error); } #ifdef DEBUG @@ -745,7 +762,7 @@ static int delete_volume(int ac, char **av) { U8 VolumeBus, VolumeID; - int fd; + int error, fd; if (ac != 2) { warnx("delete: volume required"); @@ -754,24 +771,27 @@ delete_volume(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } - if (mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID) < 0) { - warn("Invalid volume %s", av[1]); - return (errno); + error = mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID); + if (error) { + warnc(error, "Invalid volume %s", av[1]); + return (error); } if (mpt_lock_volume(VolumeBus, VolumeID) < 0) return (errno); - if (mpt_raid_action(fd, MPI_RAID_ACTION_DELETE_VOLUME, VolumeBus, + error = mpt_raid_action(fd, MPI_RAID_ACTION_DELETE_VOLUME, VolumeBus, VolumeID, 0, MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS | MPI_RAID_ACTION_ADATA_ZERO_LBA0, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0) < 0) { - warn("Failed to delete volume"); - return (errno); + NULL, 0); + if (error) { + warnc(error, "Failed to delete volume"); + return (error); } mpt_rescan_bus(-1, -1); @@ -788,16 +808,17 @@ find_volume_spare_pool(int fd, const char *name, int *pool) CONFIG_PAGE_IOC_2 *ioc2; CONFIG_PAGE_IOC_2_RAID_VOL *vol; U8 VolumeBus, VolumeID; - int i, j, new_pool, pool_count[7]; + int error, i, j, new_pool, pool_count[7]; - if (mpt_lookup_volume(fd, name, &VolumeBus, &VolumeID) < 0) { - warn("Invalid volume %s", name); - return (-1); + error = mpt_lookup_volume(fd, name, &VolumeBus, &VolumeID); + if (error) { + warnc(error, "Invalid volume %s", name); + return (error); } info = mpt_vol_info(fd, VolumeBus, VolumeID, NULL); if (info == NULL) - return (-1); + return (errno); /* * Check for an existing pool other than pool 0 (used for @@ -817,15 +838,16 @@ find_volume_spare_pool(int fd, const char *name, int *pool) */ ioc2 = mpt_read_ioc_page(fd, 2, NULL); if (ioc2 == NULL) { + error = errno; warn("Failed to fetch volume list"); - return (-1); + return (error); } bzero(pool_count, sizeof(pool_count)); vol = ioc2->RaidVolume; for (i = 0; i < ioc2->NumActiveVolumes; vol++, i++) { info = mpt_vol_info(fd, vol->VolumeBus, vol->VolumeID, NULL); if (info == NULL) - return (-1); + return (errno); for (j = 0; j < 7; j++) if (info->VolumeSettings.HotSparePool & (1 << (j + 1))) pool_count[j]++; @@ -843,14 +865,15 @@ find_volume_spare_pool(int fd, const char *name, int *pool) /* Add this pool to the volume. */ info = mpt_vol_info(fd, VolumeBus, VolumeID, NULL); if (info == NULL) - return (-1); + return (error); info->VolumeSettings.HotSparePool |= (1 << new_pool); - if (mpt_raid_action(fd, MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS, + error = mpt_raid_action(fd, MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS, VolumeBus, VolumeID, 0, *(U32 *)&info->VolumeSettings, NULL, 0, - NULL, NULL, 0, NULL, NULL, 0) < 0) { + NULL, NULL, 0, NULL, NULL, 0); + if (error) { warnx("Failed to add spare pool %d to %s", new_pool, mpt_volume_name(VolumeBus, VolumeID)); - return (-1); + return (error); } free(info); @@ -878,13 +901,15 @@ add_spare(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } if (ac == 3) { - if (find_volume_spare_pool(fd, av[2], &pool) < 0) - return (errno); + error = find_volume_spare_pool(fd, av[2], &pool); + if (error) + return (error); } else pool = MPI_RAID_HOT_SPARE_POOL_0; @@ -902,16 +927,18 @@ add_spare(int ac, char **av) if (mpt_lookup_standalone_disk(av[1], sdisks, nsdisks, &i) < 0) { + error = errno; warn("Unable to lookup drive %s", av[1]); - return (errno); + return (error); } if (mpt_lock_physdisk(&sdisks[i]) < 0) return (errno); if (mpt_create_physdisk(fd, &sdisks[i], &PhysDiskNum) < 0) { + error = errno; warn("Failed to create physical disk page"); - return (errno); + return (error); } free(sdisks); } @@ -919,8 +946,9 @@ add_spare(int ac, char **av) info = mpt_pd_info(fd, PhysDiskNum, NULL); if (info == NULL) { + error = errno; warn("Failed to fetch drive info"); - return (errno); + return (error); } info->PhysDiskSettings.HotSparePool = pool; @@ -928,8 +956,8 @@ add_spare(int ac, char **av) 0, PhysDiskNum, *(U32 *)&info->PhysDiskSettings, NULL, 0, NULL, NULL, 0, NULL, NULL, 0); if (error) { - warn("Failed to assign spare"); - return (errno); + warnc(error, "Failed to assign spare"); + return (error); } free(info); @@ -954,8 +982,9 @@ remove_spare(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } list = mpt_pd_list(fd); @@ -972,8 +1001,9 @@ remove_spare(int ac, char **av) info = mpt_pd_info(fd, PhysDiskNum, NULL); if (info == NULL) { + error = errno; warn("Failed to fetch drive info"); - return (errno); + return (error); } if (info->PhysDiskSettings.HotSparePool == 0) { @@ -982,8 +1012,9 @@ remove_spare(int ac, char **av) } if (mpt_delete_physdisk(fd, PhysDiskNum) < 0) { + error = errno; warn("Failed to delete physical disk page"); - return (errno); + return (error); } mpt_rescan_bus(info->PhysDiskBus, info->PhysDiskID); @@ -1011,8 +1042,9 @@ pd_create(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } error = mpt_fetch_disks(fd, &ndisks, &disks); @@ -1022,16 +1054,18 @@ pd_create(int ac, char **av) } if (mpt_lookup_standalone_disk(av[1], disks, ndisks, &i) < 0) { + error = errno; warn("Unable to lookup drive"); - return (errno); + return (error); } if (mpt_lock_physdisk(&disks[i]) < 0) return (errno); if (mpt_create_physdisk(fd, &disks[i], &PhysDiskNum) < 0) { + error = errno; warn("Failed to create physical disk page"); - return (errno); + return (error); } free(disks); @@ -1048,7 +1082,7 @@ pd_delete(int ac, char **av) { CONFIG_PAGE_RAID_PHYS_DISK_0 *info; struct mpt_drive_list *list; - int fd; + int error, fd; U8 PhysDiskNum; if (ac != 2) { @@ -1058,8 +1092,9 @@ pd_delete(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } list = mpt_pd_list(fd); @@ -1067,20 +1102,23 @@ pd_delete(int ac, char **av) return (errno); if (mpt_lookup_drive(list, av[1], &PhysDiskNum) < 0) { + error = errno; warn("Failed to find drive %s", av[1]); - return (errno); + return (error); } mpt_free_pd_list(list); info = mpt_pd_info(fd, PhysDiskNum, NULL); if (info == NULL) { + error = errno; warn("Failed to fetch drive info"); - return (errno); + return (error); } if (mpt_delete_physdisk(fd, PhysDiskNum) < 0) { + error = errno; warn("Failed to delete physical disk page"); - return (errno); + return (error); } mpt_rescan_bus(info->PhysDiskBus, info->PhysDiskID); @@ -1126,7 +1164,7 @@ debug_config(int ac, char **av) { CONFIG_PAGE_RAID_VOL_0 *vol; U8 VolumeBus, VolumeID; - int fd; + int error, fd; if (ac != 2) { warnx("debug: volume required"); @@ -1135,19 +1173,22 @@ debug_config(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } - if (mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID) < 0) { - warn("Invalid volume: %s", av[1]); - return (errno); + error = mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID); + if (error) { + warnc(error, "Invalid volume: %s", av[1]); + return (error); } vol = mpt_vol_info(fd, VolumeBus, VolumeID, NULL); if (vol == NULL) { + error = errno; warn("Failed to get volume info"); - return (errno); + return (error); } dump_config(vol); diff --git a/usr.sbin/mptutil/mpt_drive.c b/usr.sbin/mptutil/mpt_drive.c index e941b967e..049ce7178 100644 --- a/usr.sbin/mptutil/mpt_drive.c +++ b/usr.sbin/mptutil/mpt_drive.c @@ -129,7 +129,7 @@ mpt_pd_insert(int fd, struct mpt_drive_list *list, U8 PhysDiskNum) list->drives[j + 1] = list->drives[j]; list->drives[i] = mpt_pd_info(fd, PhysDiskNum, NULL); if (list->drives[i] == NULL) - return (-1); + return (errno); list->ndrives++; return (0); } @@ -146,26 +146,32 @@ mpt_pd_list(int fd) CONFIG_PAGE_IOC_5 *ioc5; IOC_5_HOT_SPARE *spare; struct mpt_drive_list *list; - int count, i, j; + int count, error, i, j; ioc2 = mpt_read_ioc_page(fd, 2, NULL); if (ioc2 == NULL) { + error = errno; warn("Failed to fetch volume list"); + errno = error; return (NULL); } ioc3 = mpt_read_ioc_page(fd, 3, NULL); if (ioc3 == NULL) { + error = errno; warn("Failed to fetch drive list"); free(ioc2); + errno = error; return (NULL); } ioc5 = mpt_read_ioc_page(fd, 5, NULL); if (ioc5 == NULL) { + error = errno; warn("Failed to fetch spare list"); free(ioc3); free(ioc2); + errno = error; return (NULL); } @@ -180,7 +186,9 @@ mpt_pd_list(int fd) volumes[i] = mpt_vol_info(fd, vol->VolumeBus, vol->VolumeID, NULL); if (volumes[i] == NULL) { + error = errno; warn("Failed to read volume info"); + errno = error; return (NULL); } count += volumes[i]->NumPhysDisks; @@ -264,13 +272,11 @@ mpt_lookup_drive(struct mpt_drive_list *list, const char *drive, return (0); } } - errno = ENOENT; - return (-1); + return (ENOENT); } bad: - errno = EINVAL; - return (-1); + return (EINVAL); } /* Borrowed heavily from scsi_all.c:scsi_print_inquiry(). */ @@ -306,12 +312,13 @@ drive_set_state(char *drive, U8 Action, U8 State, const char *name) CONFIG_PAGE_RAID_PHYS_DISK_0 *info; struct mpt_drive_list *list; U8 PhysDiskNum; - int fd; + int error, fd; fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } list = mpt_pd_list(fd); @@ -319,16 +326,18 @@ drive_set_state(char *drive, U8 Action, U8 State, const char *name) return (errno); if (mpt_lookup_drive(list, drive, &PhysDiskNum) < 0) { + error = errno; warn("Failed to find drive %s", drive); - return (errno); + return (error); } mpt_free_pd_list(list); /* Get the info for this drive. */ info = mpt_pd_info(fd, PhysDiskNum, NULL); if (info == NULL) { + error = errno; warn("Failed to fetch info for drive %u", PhysDiskNum); - return (errno); + return (error); } /* Try to change the state. */ @@ -337,10 +346,11 @@ drive_set_state(char *drive, U8 Action, U8 State, const char *name) return (EINVAL); } - if (mpt_raid_action(fd, Action, 0, 0, PhysDiskNum, 0, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0) < 0) { - warn("Failed to set drive %u to %s", PhysDiskNum, name); - return (errno); + error = mpt_raid_action(fd, Action, 0, 0, PhysDiskNum, 0, NULL, 0, NULL, + NULL, 0, NULL, NULL, 0); + if (error) { + warnc(error, "Failed to set drive %u to %s", PhysDiskNum, name); + return (error); } free(info); diff --git a/usr.sbin/mptutil/mpt_evt.c b/usr.sbin/mptutil/mpt_evt.c index 4b64352e4..9ccdebd42 100644 --- a/usr.sbin/mptutil/mpt_evt.c +++ b/usr.sbin/mptutil/mpt_evt.c @@ -94,18 +94,20 @@ show_events(int ac, char **av) { CONFIG_PAGE_LOG_0 *log; MPI_LOG_0_ENTRY **entries; - int ch, fd, i, num_events, verbose; + int ch, error, fd, i, num_events, verbose; fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } log = mpt_get_events(fd, NULL); if (log == NULL) { + error = errno; warn("Failed to get event log info"); - return (errno); + return (error); } /* Default settings. */ @@ -128,6 +130,8 @@ show_events(int ac, char **av) /* Build a list of valid entries and sort them by sequence. */ entries = malloc(sizeof(MPI_LOG_0_ENTRY *) * log->NumLogEntries); + if (entries == NULL) + return (ENOMEM); num_events = 0; for (i = 0; i < log->NumLogEntries; i++) { if (log->LogEntry[i].LogEntryQualifier == diff --git a/usr.sbin/mptutil/mpt_show.c b/usr.sbin/mptutil/mpt_show.c index 5a2a9463c..a5e1a899f 100644 --- a/usr.sbin/mptutil/mpt_show.c +++ b/usr.sbin/mptutil/mpt_show.c @@ -79,7 +79,7 @@ show_adapter(int ac, char **av) CONFIG_PAGE_IOC_2 *ioc2; CONFIG_PAGE_IOC_6 *ioc6; U16 IOCStatus; - int fd, comma; + int comma, error, fd; if (ac != 1) { warnx("show adapter: extra arguments"); @@ -88,17 +88,19 @@ show_adapter(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } man0 = mpt_read_man_page(fd, 0, NULL); if (man0 == NULL) { + error = errno; warn("Failed to get controller info"); - return (errno); + return (error); } if (man0->Header.PageLength < sizeof(*man0) / 4) { - warn("Invalid controller info"); + warnx("Invalid controller info"); return (EINVAL); } printf("mpt%d Adapter:\n", mpt_unit); @@ -283,7 +285,7 @@ show_config(int ac, char **av) CONFIG_PAGE_RAID_VOL_1 *vnames; CONFIG_PAGE_RAID_PHYS_DISK_0 *pinfo; struct mpt_standalone_disk *sdisks; - int fd, i, j, nsdisks; + int error, fd, i, j, nsdisks; if (ac != 1) { warnx("show config: extra arguments"); @@ -292,20 +294,23 @@ show_config(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } /* Get the config from the controller. */ ioc2 = mpt_read_ioc_page(fd, 2, NULL); ioc5 = mpt_read_ioc_page(fd, 5, NULL); if (ioc2 == NULL || ioc5 == NULL) { + error = errno; warn("Failed to get config"); - return (errno); + return (error); } if (mpt_fetch_disks(fd, &nsdisks, &sdisks) < 0) { + error = errno; warn("Failed to get standalone drive list"); - return (errno); + return (error); } /* Dump out the configuration. */ @@ -381,7 +386,7 @@ show_volumes(int ac, char **av) CONFIG_PAGE_IOC_2_RAID_VOL *vol; CONFIG_PAGE_RAID_VOL_0 **volumes; CONFIG_PAGE_RAID_VOL_1 *vnames; - int fd, i, len, state_len; + int error, fd, i, len, state_len; if (ac != 1) { warnx("show volumes: extra arguments"); @@ -390,15 +395,17 @@ show_volumes(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } /* Get the volume list from the controller. */ ioc2 = mpt_read_ioc_page(fd, 2, NULL); if (ioc2 == NULL) { + error = errno; warn("Failed to get volume list"); - return (errno); + return (error); } /* @@ -466,7 +473,7 @@ show_drives(int ac, char **av) { struct mpt_drive_list *list; struct mpt_standalone_disk *sdisks; - int fd, i, len, nsdisks, state_len; + int error, fd, i, len, nsdisks, state_len; if (ac != 1) { warnx("show drives: extra arguments"); @@ -475,15 +482,17 @@ show_drives(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } /* Get the drive list. */ list = mpt_pd_list(fd); if (list == NULL) { + error = errno; warn("Failed to get drive list"); - return (errno); + return (error); } /* Fetch the list of standalone disks for this controller. */ @@ -538,8 +547,9 @@ show_physdisks(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } /* Try to find each possible phys disk page. */ diff --git a/usr.sbin/mptutil/mpt_volume.c b/usr.sbin/mptutil/mpt_volume.c index 04adcb7c9..2b273c73c 100644 --- a/usr.sbin/mptutil/mpt_volume.c +++ b/usr.sbin/mptutil/mpt_volume.c @@ -69,7 +69,7 @@ volume_name(int ac, char **av) { CONFIG_PAGE_RAID_VOL_1 *vnames; U8 VolumeBus, VolumeID; - int fd; + int error, fd; if (ac != 3) { warnx("name: volume and name required"); @@ -83,19 +83,22 @@ volume_name(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } - if (mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID) < 0) { - warn("Invalid volume: %s", av[1]); - return (errno); + error = mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID); + if (error) { + warnc(error, "Invalid volume: %s", av[1]); + return (error); } vnames = mpt_vol_names(fd, VolumeBus, VolumeID, NULL); if (vnames == NULL) { + error = errno; warn("Failed to fetch volume names"); - return (errno); + return (error); } if (vnames->Header.PageType != MPI_CONFIG_PAGEATTR_CHANGEABLE) { @@ -109,8 +112,9 @@ volume_name(int ac, char **av) strcpy(vnames->Name, av[2]); if (mpt_write_config_page(fd, vnames, NULL) < 0) { + error = errno; warn("Failed to set volume name"); - return (errno); + return (error); } free(vnames); @@ -128,7 +132,7 @@ volume_status(int ac, char **av) uint64_t total, remaining; float pct; U8 VolumeBus, VolumeID; - int fd; + int error, fd; if (ac != 2) { warnx("volume status: %s", ac > 2 ? "extra arguments" : @@ -138,20 +142,23 @@ volume_status(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } - if (mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID) < 0) { - warn("Invalid volume: %s", av[1]); - return (errno); + error = mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID); + if (error) { + warnc(error, "Invalid volume: %s", av[1]); + return (error); } - if (mpt_raid_action(fd, MPI_RAID_ACTION_INDICATOR_STRUCT, VolumeBus, + error = mpt_raid_action(fd, MPI_RAID_ACTION_INDICATOR_STRUCT, VolumeBus, VolumeID, 0, 0, NULL, 0, &VolumeStatus, (U32 *)&prog, sizeof(prog), - NULL, NULL, 0) < 0) { - warn("Fetching volume status failed"); - return (errno); + NULL, NULL, 0); + if (error) { + warnc(error, "Fetching volume status failed"); + return (error); } printf("Volume %s status:\n", mpt_volume_name(VolumeBus, VolumeID)); @@ -191,11 +198,11 @@ volume_cache(int ac, char **av) U32 Settings, NewSettings; U8 VolumeBus, VolumeID; char *s1; - int fd; + int error, fd; if (ac != 3) { warnx("volume cache: %s", ac > 3 ? "extra arguments" : - "volume required"); + "missing arguments"); return (EINVAL); } @@ -209,18 +216,20 @@ volume_cache(int ac, char **av) fd = mpt_open(mpt_unit); if (fd < 0) { + error = errno; warn("mpt_open"); - return (errno); + return (error); } - if (mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID) < 0) { - warn("Invalid volume: %s", av[1]); - return (errno); + error = mpt_lookup_volume(fd, av[1], &VolumeBus, &VolumeID); + if (error) { + warnc(error, "Invalid volume: %s", av[1]); + return (error); } volume = mpt_vol_info(fd, VolumeBus, VolumeID, NULL); if (volume == NULL) - return (-1); + return (errno); Settings = volume->VolumeSettings.Settings; @@ -231,18 +240,19 @@ volume_cache(int ac, char **av) NewSettings &= ~0x01; if (NewSettings == Settings) { - warnx("volume cache unchanged\n"); + warnx("volume cache unchanged"); close(fd); return (0); } volume->VolumeSettings.Settings = NewSettings; - if (mpt_raid_action(fd, MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS, + error = mpt_raid_action(fd, MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS, VolumeBus, VolumeID, 0, *(U32 *)&volume->VolumeSettings, NULL, 0, - NULL, NULL, 0, NULL, NULL, 0) < 0) - warnx("volume cache change failed, errno= %d\n", errno); + NULL, NULL, 0, NULL, NULL, 0); + if (error) + warnc(error, "volume cache change failed"); close(fd); - return (0); + return (error); } MPT_COMMAND(volume, cache, volume_cache); diff --git a/usr.sbin/mptutil/mptutil.8 b/usr.sbin/mptutil/mptutil.8 index 7acaf3e90..a5b3593f8 100644 --- a/usr.sbin/mptutil/mptutil.8 +++ b/usr.sbin/mptutil/mptutil.8 @@ -123,7 +123,7 @@ where is the bus ID and .Ar yy is the target ID. -If the bus ID is ommitted, +If the bus ID is omitted, the volume is assumed to be on bus 0. Second, on the volume may be specified by the corresponding @@ -348,6 +348,11 @@ as a global hot spare: .Dl Nm Cm add da3 .Sh SEE ALSO .Xr mpt 4 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 8.0 . .Sh BUGS .Pp The handling of spare drives appears to be unreliable. @@ -379,8 +384,15 @@ configurations may not work reliably. .Pp Drive configuration commands result in an excessive flood of messages on the console. -.Sh HISTORY -The +.Pp +The mpt version 1 API that is used by .Nm -utility first appeared in -.Fx 8.0 . +and +.Xr mpt 4 +doesn't support volumes above two terabytes. +This is a limitation of the API. +If you are using this adapter with volumes larger than two terabytes, use the adapter in JBOD mode. +Utilize +.Xr geom 8 , +.Xr zfs 8 , +or another software volume manager to work around this limitation. diff --git a/usr.sbin/mptutil/mptutil.c b/usr.sbin/mptutil/mptutil.c index e7b58060e..63e8efadd 100644 --- a/usr.sbin/mptutil/mptutil.c +++ b/usr.sbin/mptutil/mptutil.c @@ -114,10 +114,12 @@ main(int ac, char **av) SET_FOREACH(cmd, MPT_DATASET(top)) { if (strcmp((*cmd)->name, av[0]) == 0) { - (*cmd)->handler(ac, av); - return (0); + if ((*cmd)->handler(ac, av)) + return (1); + else + return (0); } } warnx("Unknown command %s.", av[0]); - return (0); + return (1); } -- 2.45.0