Add mrsasutil(8) as alias to mfiutil(8)

mfiutil(8) in theory can work on devices attached to mrsas(4) but
mrsas(4) is missing the FreeBSD mfi(4) ioctl support.  Once that
support is added to mrsas(4) then mrsasutil(8) can manage mrsas(4)
attached devices.  So this commit depends on that.  When mrsasutil(8)
is run it automatically opens /dev/mrsas0 instead of /dev/mfi0.
Add -D <device> and -t <type> flag to optionally specify mrsas or mfi to
work with the existing -u <unit>.  Device is the device node with or
without /dev/

PR:			https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=265794
Differential Revision:	https://reviews.freebsd.org/D36343
Tested by:		Dan Mahoney <freebsd@gushi.org>
Reviewed by:		jhb
This commit is contained in:
Doug Ambrisko 2022-08-24 15:38:43 -07:00
parent 2df58f1907
commit 7e0f8b79b7
15 changed files with 294 additions and 143 deletions

View File

@ -1,10 +1,12 @@
# $FreeBSD$
PROG= mfiutil
LINKS= ${BINDIR}/mfiutil ${BINDIR}/mrsasutil
SRCS= mfiutil.c mfi_bbu.c mfi_cmd.c mfi_config.c mfi_drive.c mfi_evt.c \
mfi_flash.c mfi_patrol.c mfi_show.c mfi_volume.c mfi_foreign.c \
mfi_properties.c
MAN8= mfiutil.8
MLINKS= mfiutil.8 mrsasutil.8
CFLAGS.gcc+= -fno-builtin-strftime

View File

@ -134,7 +134,7 @@ start_bbu_learn(int ac, char **av __unused)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -171,7 +171,7 @@ update_bbu_props(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");

View File

@ -44,6 +44,7 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <paths.h>
#include "mfiutil.h"
#include <dev/mfi/mfi_ioctl.h>
@ -209,15 +210,23 @@ mfi_volume_busy(int fd, uint8_t target_id)
* configuration of the mfi controller.
*/
int
mfi_reconfig_supported(void)
mfi_reconfig_supported(const char *dev)
{
char mibname[64];
const char *cp;
size_t len;
int dummy;
int dummy, mfi_unit;
cp = dev + strlen(_PATH_DEV);
if (strncmp(cp, MRSAS_TYPE, strlen(MRSAS_TYPE)) == 0)
return (1);
cp += strlen(MFI_TYPE);
mfi_unit = strtol(cp, NULL, 10);;
len = sizeof(dummy);
snprintf(mibname, sizeof(mibname), "dev.mfi.%d.delete_busy_volumes",
mfi_unit);
snprintf(mibname, sizeof(mibname),
"dev.mfi.%d.delete_busy_volumes", mfi_unit);
return (sysctlbyname(mibname, &dummy, &len, NULL, 0) == 0);
}
@ -239,7 +248,7 @@ mfi_lookup_volume(int fd, const char *name, uint8_t *target_id)
if (mfi_dcmd_command(fd, MFI_DCMD_LD_GET_LIST, &list, sizeof(list),
NULL, 0, NULL) < 0)
return (-1);
return (-1);
for (i = 0; i < list.ld_count; i++) {
if (mfi_query_disk(fd, list.ld_list[i].ld.v.target_id,
@ -304,12 +313,14 @@ mfi_ctrl_get_info(int fd, struct mfi_ctrl_info *info, uint8_t *statusp)
}
int
mfi_open(int unit, int acs)
mfi_open(char *dev, int acs)
{
char path[MAXPATHLEN];
int ret;
snprintf(path, sizeof(path), "/dev/mfi%d", unit);
return (open(path, acs));
ret = open(dev, acs);
if (ret < 0)
warn("Couldn't open %s", dev);
return (ret);
}
static void

View File

@ -35,6 +35,7 @@
#ifdef DEBUG
#include <sys/sysctl.h>
#endif
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@ -52,30 +53,30 @@ static int remove_spare(int ac, char **av);
static long
dehumanize(const char *value)
{
char *vtp;
long iv;
if (value == NULL)
return (0);
iv = strtoq(value, &vtp, 0);
if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) {
return (0);
}
switch (vtp[0]) {
case 't': case 'T':
iv *= 1024;
case 'g': case 'G':
iv *= 1024;
case 'm': case 'M':
iv *= 1024;
case 'k': case 'K':
iv *= 1024;
case '\0':
break;
default:
return (0);
}
return (iv);
char *vtp;
long iv;
if (value == NULL)
return (0);
iv = strtoq(value, &vtp, 0);
if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) {
return (0);
}
switch (vtp[0]) {
case 't': case 'T':
iv *= 1024;
case 'g': case 'G':
iv *= 1024;
case 'm': case 'M':
iv *= 1024;
case 'k': case 'K':
iv *= 1024;
case '\0':
break;
default:
return (0);
}
return (iv);
}
int
@ -162,16 +163,16 @@ clear_config(int ac __unused, char **av __unused)
int ch, error, fd;
u_int i;
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
return (error);
}
if (!mfi_reconfig_supported()) {
warnx("The current mfi(4) driver does not support "
"configuration changes.");
if (!mfi_reconfig_supported(mfi_device)) {
warnx("The current %s driver does not support "
"configuration changes.", mfi_device);
close(fd);
return (EOPNOTSUPP);
}
@ -193,8 +194,8 @@ clear_config(int ac __unused, char **av __unused)
}
printf(
"Are you sure you wish to clear the configuration on mfi%u? [y/N] ",
mfi_unit);
"Are you sure you wish to clear the configuration on %s? [y/N] ",
mfi_device);
ch = getchar();
if (ch != 'y' && ch != 'Y') {
printf("\nAborting\n");
@ -209,7 +210,7 @@ clear_config(int ac __unused, char **av __unused)
return (error);
}
printf("mfi%d: Configuration cleared\n", mfi_unit);
printf("%s: Configuration cleared\n", mfi_device);
close(fd);
return (0);
@ -587,16 +588,16 @@ create_volume(int ac, char **av)
narrays = 0;
error = 0;
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
return (error);
}
if (!mfi_reconfig_supported()) {
warnx("The current mfi(4) driver does not support "
"configuration changes.");
if (!mfi_reconfig_supported(mfi_device)) {
warnx("The current %s(4) driver does not support "
"configuration changes.", mfi_device);
error = EOPNOTSUPP;
goto error;
}
@ -869,16 +870,16 @@ delete_volume(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
return (error);
}
if (!mfi_reconfig_supported()) {
warnx("The current mfi(4) driver does not support "
"configuration changes.");
if (!mfi_reconfig_supported(mfi_device)) {
warnx("The current %s(4) driver does not support "
"configuration changes.", mfi_device);
close(fd);
return (EOPNOTSUPP);
}
@ -937,7 +938,7 @@ add_spare(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -1027,7 +1028,7 @@ add_spare(int ac, char **av)
ar->array_ref);
error = EINVAL;
goto error;
}
}
spare->array_ref[i] = ar->array_ref;
}
}
@ -1062,7 +1063,7 @@ remove_spare(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -1120,7 +1121,7 @@ dump_config(int fd, struct mfi_config_data *config, const char *msg_prefix)
msg_prefix = "Configuration (Debug)";
printf(
"mfi%d %s: %d arrays, %d volumes, %d spares\n", mfi_unit,
"%s %s: %d arrays, %d volumes, %d spares\n", mfi_device,
msg_prefix, config->array_count, config->log_drv_count,
config->spares_count);
printf(" array size: %u\n", config->array_size);
@ -1211,7 +1212,7 @@ debug_config(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -1248,7 +1249,7 @@ dump(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");

View File

@ -74,7 +74,7 @@ mfi_drive_name(struct mfi_pd_info *pinfo, uint16_t device_id, uint32_t def)
else
snprintf(buf, sizeof(buf), "%2u", device_id);
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
warn("mfi_open");
return (buf);
@ -388,7 +388,7 @@ drive_set_state(char *drive, uint16_t new_state)
uint8_t mbox[6];
int error, fd;
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -503,7 +503,7 @@ start_rebuild(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -560,7 +560,7 @@ abort_rebuild(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -616,7 +616,7 @@ drive_progress(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -682,7 +682,7 @@ drive_clear(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -742,7 +742,7 @@ drive_locate(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");

View File

@ -77,7 +77,7 @@ show_logstate(int ac, char **av __unused)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -91,13 +91,13 @@ show_logstate(int ac, char **av __unused)
return (error);
}
printf("mfi%d Event Log Sequence Numbers:\n", mfi_unit);
printf("%s Event Log Sequence Numbers:\n", mfi_device);
printf(" Newest Seq #: %u\n", info.newest_seq_num);
printf(" Oldest Seq #: %u\n", info.oldest_seq_num);
printf(" Clear Seq #: %u\n", info.clear_seq_num);
printf("Shutdown Seq #: %u\n", info.shutdown_seq_num);
printf(" Boot Seq #: %u\n", info.boot_seq_num);
close(fd);
return (0);
@ -547,7 +547,7 @@ show_events(int ac, char **av)
int ch, error, fd, num_events, verbose;
u_int i;
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -691,7 +691,7 @@ show_events(int ac, char **av)
* need to know the size of the buffer somehow.
*/
seq = list->event[list->count - 1].seq + 1;
}
finish:
if (first)

View File

@ -58,7 +58,7 @@ display_pending_firmware(int fd)
return (error);
}
printf("mfi%d Pending Firmware Images:\n", mfi_unit);
printf("%s Pending Firmware Images:\n", mfi_device);
strcpy(header.name, "Name");
strcpy(header.version, "Version");
strcpy(header.build_date, "Date");
@ -122,7 +122,7 @@ flash_adapter(int ac, char **av)
goto error;
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");

View File

@ -48,7 +48,7 @@ foreign_clear(__unused int ac, __unused char **av)
{
int ch, error, fd;
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -57,7 +57,7 @@ foreign_clear(__unused int ac, __unused char **av)
printf(
"Are you sure you wish to clear ALL foreign configurations"
" on mfi%u? [y/N] ", mfi_unit);
" on %s? [y/N] ", mfi_device);
ch = getchar();
if (ch != 'y' && ch != 'Y') {
@ -74,7 +74,7 @@ foreign_clear(__unused int ac, __unused char **av)
return (error);
}
printf("mfi%d: Foreign configuration cleared\n", mfi_unit);
printf("%s: Foreign configuration cleared\n", mfi_device);
close(fd);
return (0);
}
@ -86,7 +86,7 @@ foreign_scan(__unused int ac, __unused char **av)
struct mfi_foreign_scan_info info;
int error, fd;
fd = mfi_open(mfi_unit, O_RDONLY);
fd = mfi_open(mfi_device, O_RDONLY);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -101,7 +101,7 @@ foreign_scan(__unused int ac, __unused char **av)
return (error);
}
printf("mfi%d: Found %d foreign configurations\n", mfi_unit,
printf("%s: Found %d foreign configurations\n", mfi_device,
info.count);
close(fd);
return (0);
@ -143,7 +143,7 @@ foreign_show_cfg(int fd, uint32_t opcode, uint8_t cfgidx, int diagnostic)
ld_list = (char *)(config->array);
printf("%s: %d arrays, %d volumes, %d spares\n", prefix,
printf("%s: %d arrays, %d volumes, %d spares\n", prefix,
config->array_count, config->log_drv_count,
config->spares_count);
@ -152,28 +152,28 @@ foreign_show_cfg(int fd, uint32_t opcode, uint8_t cfgidx, int diagnostic)
ld_list += config->array_size;
for (i = 0; i < config->log_drv_count; i++) {
const char *level;
char size[6], stripe[5];
const char *level;
char size[6], stripe[5];
struct mfi_ld_config *ld;
ld = (struct mfi_ld_config *)ld_list;
format_stripe(stripe, sizeof(stripe),
ld->params.stripe_size);
format_stripe(stripe, sizeof(stripe),
ld->params.stripe_size);
/*
* foreign configs don't seem to have a secondary raid level
* but, we can use span depth here as if a LD spans multiple
* arrays of disks (2 raid 1 sets for example), we will have an
* indication based on the spam depth. swb
*/
level = mfi_raid_level(ld->params.primary_raid_level,
(ld->params.span_depth - 1));
*/
level = mfi_raid_level(ld->params.primary_raid_level,
(ld->params.span_depth - 1));
humanize_number(size, sizeof(size), ld->span[0].num_blocks * 512,
"", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
humanize_number(size, sizeof(size), ld->span[0].num_blocks * 512,
"", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
printf(" ID%d ", i);
printf("(%6s) %-8s |",
printf("(%6s) %-8s |",
size, level);
printf("volume spans %d %s\n", ld->params.span_depth,
(ld->params.span_depth > 1) ? "arrays" : "array");
@ -183,9 +183,9 @@ foreign_show_cfg(int fd, uint32_t opcode, uint8_t cfgidx, int diagnostic)
uint16_t device_id;
printf(" array %u @ ", ld->span[j].array_ref);
humanize_number(size, sizeof(size), ld->span[j].num_blocks * 512,
"", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
humanize_number(size, sizeof(size), ld->span[j].num_blocks * 512,
"", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
printf("(%6s)\n",size);
ar_list = (char *)config->array + (ld->span[j].array_ref * config->array_size);
@ -196,7 +196,7 @@ foreign_show_cfg(int fd, uint32_t opcode, uint8_t cfgidx, int diagnostic)
printf(" drive MISSING\n");
else {
printf(" drive %u %s\n", device_id,
mfi_pdstate(ar->pd[k].fw_state));
mfi_pdstate(ar->pd[k].fw_state));
}
}
@ -222,7 +222,7 @@ display_format(int ac, char **av, int diagnostic, mfi_dcmd_t display_cmd)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDONLY);
fd = mfi_open(mfi_device, O_RDONLY);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -262,7 +262,7 @@ display_format(int ac, char **av, int diagnostic, mfi_dcmd_t display_cmd)
return (error);
}
}
close(fd);
return (0);
}
@ -294,7 +294,7 @@ foreign_import(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -318,7 +318,7 @@ foreign_import(int ac, char **av)
if (ac == 1) {
cfgidx = 0xff;
printf("Are you sure you wish to import ALL foreign "
"configurations on mfi%u? [y/N] ", mfi_unit);
"configurations on %s? [y/N] ", mfi_device);
} else {
/*
* While this is docmmented for MegaCli this failed with
@ -334,7 +334,7 @@ foreign_import(int ac, char **av)
return (EINVAL);
}
printf("Are you sure you wish to import the foreign "
"configuration %d on mfi%u? [y/N] ", cfgidx, mfi_unit);
"configuration %d on %s? [y/N] ", cfgidx, mfi_device);
}
ch = getchar();
@ -355,11 +355,11 @@ foreign_import(int ac, char **av)
}
if (ac == 1)
printf("mfi%d: All foreign configurations imported\n",
mfi_unit);
printf("%s: All foreign configurations imported\n",
mfi_device);
else
printf("mfi%d: Foreign configuration %d imported\n", mfi_unit,
cfgidx);
printf("%s: Foreign configuration %d imported\n",
mfi_device, cfgidx);
close(fd);
return (0);
}

View File

@ -89,7 +89,7 @@ show_patrol(int ac __unused, char **av __unused)
int error, fd;
u_int i;
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -199,7 +199,7 @@ start_patrol(int ac __unused, char **av __unused)
{
int error, fd;
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -225,7 +225,7 @@ stop_patrol(int ac __unused, char **av __unused)
{
int error, fd;
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -295,7 +295,7 @@ patrol_config(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");

View File

@ -3,7 +3,7 @@
*
* Copyright (c) 2013 Yahoo!, Inc.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -64,7 +64,7 @@ mfi_ctrl_set_properties(int fd, struct mfi_ctrl_props *info)
}
/*
* aquite the controller properties data structure modify the
* aquire the controller properties data structure modify the
* rebuild rate if requested and then retun
*/
static int
@ -77,8 +77,8 @@ mfi_ctrl_rebuild_rate(int ac, char **av)
warn("mfi_ctrl_set_rebuild_rate");
return(-1);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -129,8 +129,8 @@ mfi_ctrl_alarm_enable(int ac, char **av)
warn("mfi_ctrl_alarm_enable");
return(-1);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");

View File

@ -50,7 +50,7 @@ void
format_stripe(char *buf, size_t buflen, uint8_t stripe)
{
humanize_number(buf, buflen, (1 << stripe) * 512, "", HN_AUTOSCALE,
humanize_number(buf, buflen, (1 << stripe) * 512, "", HN_AUTOSCALE,
HN_B | HN_NOSPACE);
}
@ -66,7 +66,7 @@ show_adapter(int ac, char **av __unused)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDONLY);
fd = mfi_open(mfi_device, O_RDONLY);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -79,7 +79,7 @@ show_adapter(int ac, char **av __unused)
close(fd);
return (error);
}
printf("mfi%d Adapter:\n", mfi_unit);
printf("%s Adapter:\n", mfi_device);
printf(" Product Name: %.80s\n", info.product_name);
printf(" Serial Number: %.32s\n", info.serial_number);
if (info.package_version[0] != '\0')
@ -155,7 +155,7 @@ show_battery(int ac, char **av __unused)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDONLY);
fd = mfi_open(mfi_device, O_RDONLY);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -170,7 +170,7 @@ show_battery(int ac, char **av __unused)
return (error);
}
if (status == MFI_STAT_NO_HW_PRESENT) {
printf("mfi%d: No battery present\n", mfi_unit);
printf("%s: No battery present\n", mfi_device);
close(fd);
return (0);
}
@ -200,7 +200,7 @@ show_battery(int ac, char **av __unused)
}
show_props = (status == MFI_STAT_OK);
printf("mfi%d: Battery State:\n", mfi_unit);
printf("%s: Battery State:\n", mfi_device);
printf(" Manufacture Date: %d/%d/%d\n", design.mfg_date >> 5 & 0x0f,
design.mfg_date & 0x1f, design.mfg_date >> 9 & 0xffff);
printf(" Serial Number: %d\n", design.serial_number);
@ -357,7 +357,7 @@ show_config(int ac, char **av __unused)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDONLY);
fd = mfi_open(mfi_device, O_RDONLY);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -373,8 +373,8 @@ show_config(int ac, char **av __unused)
}
/* Dump out the configuration. */
printf("mfi%d Configuration: %d arrays, %d volumes, %d spares\n",
mfi_unit, config->array_count, config->log_drv_count,
printf("%s Configuration: %d arrays, %d volumes, %d spares\n",
mfi_device, config->array_count, config->log_drv_count,
config->spares_count);
p = (char *)config->array;
@ -458,7 +458,7 @@ show_volumes(int ac, char **av __unused)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDONLY);
fd = mfi_open(mfi_device, O_RDONLY);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -474,7 +474,7 @@ show_volumes(int ac, char **av __unused)
}
/* List the volumes. */
printf("mfi%d Volumes:\n", mfi_unit);
printf("%s Volumes:\n", mfi_device);
state_len = strlen("State");
for (i = 0; i < list.ld_count; i++) {
len = strlen(mfi_ldstate(list.ld_list[i].state));
@ -541,7 +541,7 @@ show_drives(int ac, char **av __unused)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDONLY);
fd = mfi_open(mfi_device, O_RDONLY);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -576,7 +576,7 @@ show_drives(int ac, char **av __unused)
}
/* List the drives. */
printf("mfi%d Physical Drives:\n", mfi_unit);
printf("%s Physical Drives:\n", mfi_device);
for (i = 0; i < list->count; i++) {
/* Skip non-hard disks. */
@ -621,7 +621,7 @@ show_firmware(int ac, char **av __unused)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDONLY);
fd = mfi_open(mfi_device, O_RDONLY);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -636,9 +636,9 @@ show_firmware(int ac, char **av __unused)
}
if (info.package_version[0] != '\0')
printf("mfi%d Firmware Package Version: %s\n", mfi_unit,
printf("%s Firmware Package Version: %s\n", mfi_device,
info.package_version);
printf("mfi%d Firmware Images:\n", mfi_unit);
printf("%s Firmware Images:\n", mfi_device);
strcpy(header.name, "Name");
strcpy(header.version, "Version");
strcpy(header.build_date, "Date");
@ -681,7 +681,7 @@ show_progress(int ac, char **av __unused)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDONLY);
fd = mfi_open(mfi_device, O_RDONLY);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -776,7 +776,8 @@ show_progress(int ac, char **av __unused)
close(fd);
if (!busy)
printf("No activity in progress for adapter mfi%d\n", mfi_unit);
printf("No activity in progress for adapter %s\n",
mfi_device);
return (0);
}

View File

@ -297,7 +297,7 @@ volume_cache(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -319,7 +319,7 @@ volume_cache(int ac, char **av)
}
if (ac == 2) {
printf("mfi%u volume %s cache settings:\n", mfi_unit,
printf("%s volume %s cache settings:\n", mfi_device,
mfi_volume_name(fd, target_id));
printf(" I/O caching: ");
switch (props.default_cache_policy &
@ -406,7 +406,7 @@ volume_name(int ac, char **av)
return (ENOSPC);
}
fd = mfi_open(mfi_unit, O_RDWR);
fd = mfi_open(mfi_device, O_RDWR);
if (fd < 0) {
error = errno;
warn("mfi_open");
@ -427,7 +427,7 @@ volume_name(int ac, char **av)
return (error);
}
printf("mfi%u volume %s name changed from \"%s\" to \"%s\"\n", mfi_unit,
printf("%s volume %s name changed from \"%s\" to \"%s\"\n", mfi_device,
mfi_volume_name(fd, target_id), props.name, av[2]);
bzero(props.name, sizeof(props.name));
strcpy(props.name, av[2]);
@ -457,7 +457,7 @@ volume_progress(int ac, char **av)
return (EINVAL);
}
fd = mfi_open(mfi_unit, O_RDONLY);
fd = mfi_open(mfi_device, O_RDONLY);
if (fd < 0) {
error = errno;
warn("mfi_open");

View File

@ -31,26 +31,37 @@
.Dt MFIUTIL 8
.Os
.Sh NAME
.Nm mfiutil
.Nm mfiutil ,
.Nm mrsasutil
.Nd Utility for managing LSI MegaRAID SAS controllers
.Sh SYNOPSIS
.Nm
.Cm version
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm show adapter
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm show battery
.Nm
.Op Fl d
.Op Fl e
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm show config
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm show drives
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm show events
.Op Fl c Ar class
@ -59,67 +70,107 @@
.Op Fl v
.Op Ar start Op Ar stop
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm show firmware
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm show foreign Op Ar volume
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm show logstate
.Nm
.Op Fl d
.Op Fl e
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm show patrol
.Nm
.Op Fl d
.Op Fl e
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm show progress
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm show volumes
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm fail Ar drive
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm good Ar drive
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm rebuild Ar drive
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm syspd Ar drive
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm drive progress Ar drive
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm drive clear Ar drive Brq "start | stop"
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm start rebuild Ar drive
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm abort rebuild Ar drive
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm locate Ar drive Brq "on | off"
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm cache Ar volume Op Ar setting Oo Ar value Oc Op ...
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm name Ar volume Ar name
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm volume progress Ar volume
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm clear
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm create Ar type
.Op Fl v
@ -127,51 +178,83 @@
.Ar drive Ns Op \&, Ns Ar drive Ns Op ",..."
.Op Ar drive Ns Op \&, Ns Ar drive Ns Op ",..."
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm delete Ar volume
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm add Ar drive Op Ar volume
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm remove Ar drive
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm start patrol
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm stop patrol
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm patrol Ar command Op Ar interval Op Ar start
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm foreign scan
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm foreign clear Op Ar config
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm foreign diag Op Ar config
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm foreign preview Op Ar config
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm foreign import Op Ar config
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm flash Ar file
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm start learn
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm bbu Ar setting Ar value
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm ctrlprop Ar rebuild Op Ar rate
.Nm
.Op Fl D Ar device
.Op Fl t Ar type
.Op Fl u Ar unit
.Cm ctrlprop Ar alarm Op Ar 0/1
.Sh DESCRIPTION
@ -185,8 +268,22 @@ consists of zero or more global options followed by a command.
Commands may support additional optional or required arguments after the
command.
.Pp
Currently one global option is supported:
Currently three global options are supported:
.Bl -tag -width indent
.It Fl D Ar device
.Ar device
specifies the device node of the controller to use.
'/dev/' will be added to the device node if needed.
If no device node is specified,
then device will be made of the type and device.
.It Fl t Ar type
.Ar type
specifies the type of the controller to work with either
.Xr mfi 4
or
.Xr mrsas 4 .
If no type is specified,
then the name of the invoked tool used to derive the type.
.It Fl u Ar unit
.Ar unit
specifies the unit of the controller to work with.
@ -720,7 +817,8 @@ Display the second detected foreign configuration:
Set the current rebuild rate for volumes to 40%:
.Dl Nm Cm ctrlprop rebuild 40
.Sh SEE ALSO
.Xr mfi 4
.Xr mfi 4 ,
.Xr mrsas 4
.Sh HISTORY
The
.Nm

View File

@ -31,12 +31,15 @@
* $FreeBSD$
*/
#include <sys/errno.h>
#include <sys/param.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <paths.h>
#include "mfiutil.h"
SET_DECLARE(MFI_DATASET(top), struct mfiutil_command);
@ -45,7 +48,7 @@ MFI_TABLE(top, start);
MFI_TABLE(top, stop);
MFI_TABLE(top, abort);
int mfi_unit;
char *mfi_device = NULL;
u_int mfi_opts;
static int fw_name_width, fw_version_width, fw_date_width, fw_time_width;
@ -53,7 +56,7 @@ static void
usage(void)
{
fprintf(stderr, "usage: mfiutil [-de] [-u unit] <command> ...\n\n");
fprintf(stderr, "usage: %s [-de] [-D device] [-u unit] [-t type] <command> ...\n\n", getprogname());
fprintf(stderr, "Commands include:\n");
fprintf(stderr, " version\n");
fprintf(stderr, " show adapter - display controller information\n");
@ -121,10 +124,24 @@ int
main(int ac, char **av)
{
struct mfiutil_command **cmd;
int ch;
int ch, mfi_unit;
const char *pn, *mfi_type;
char *temp;
while ((ch = getopt(ac, av, "deu:")) != -1) {
mfi_unit = 0;
pn = getprogname();
if (strcmp(pn, "mrsasutil") == 0)
mfi_type = MRSAS_TYPE;
else
mfi_type = MFI_TYPE;
while ((ch = getopt(ac, av, "D:det:u:")) != -1) {
switch (ch) {
case 'D':
mfi_device = optarg;
break;
case 'd':
mfi_opts |= MFI_DNAME_DEVICE_ID;
break;
@ -134,11 +151,27 @@ main(int ac, char **av)
case 'u':
mfi_unit = atoi(optarg);
break;
case 't':
mfi_type = optarg;
break;
case '?':
usage();
}
}
if (mfi_device == NULL) {
if (asprintf(&mfi_device, "%s%s%d", _PATH_DEV, mfi_type,
mfi_unit) < 0)
errx(1, "Can't allocate memory for device name\n");
} else {
if (strncmp(mfi_device, _PATH_DEV, strlen(_PATH_DEV)) != 0) {
if (asprintf(&temp, "%s%s%d", _PATH_DEV, mfi_type,
mfi_unit) < 0)
errx(1, "Can't allocate memory for device name\n");
mfi_device = temp;
}
}
av += optind;
ac -= optind;

View File

@ -39,6 +39,9 @@
#include <dev/mfi/mfireg.h>
#define MRSAS_TYPE "mrsas"
#define MFI_TYPE "mfi"
/* 4.x compat */
#ifndef SET_DECLARE
@ -122,7 +125,7 @@ struct mfiutil_command {
#define MFI_DNAME_DEVICE_ID 0x0002 /* %u */
#define MFI_DNAME_HONOR_OPTS 0x8000 /* Allow cmd line to override default */
extern int mfi_unit;
extern char *mfi_device;
extern u_int mfi_opts;
@ -154,7 +157,7 @@ int mfi_lookup_drive(int fd, char *drive, uint16_t *device_id);
int mfi_lookup_volume(int fd, const char *name, uint8_t *target_id);
int mfi_dcmd_command(int fd, uint32_t opcode, void *buf, size_t bufsize,
uint8_t *mbox, size_t mboxlen, uint8_t *statusp);
int mfi_open(int unit, int acs);
int mfi_open(char *dev, int acs);
int mfi_ctrl_get_info(int fd, struct mfi_ctrl_info *info, uint8_t *statusp);
int mfi_ld_get_info(int fd, uint8_t target_id, struct mfi_ld_info *info,
uint8_t *statusp);
@ -162,7 +165,7 @@ int mfi_ld_get_list(int fd, struct mfi_ld_list *list, uint8_t *statusp);
int mfi_pd_get_info(int fd, uint16_t device_id, struct mfi_pd_info *info,
uint8_t *statusp);
int mfi_pd_get_list(int fd, struct mfi_pd_list **listp, uint8_t *statusp);
int mfi_reconfig_supported(void);
int mfi_reconfig_supported(const char *mfi_device);
const char *mfi_status(u_int status_code);
const char *mfi_drive_name(struct mfi_pd_info *pinfo, uint16_t device_id,
uint32_t def);
@ -177,6 +180,8 @@ int mfi_bbu_set_props(int fd, struct mfi_bbu_properties *props,
void mfi_autolearn_period(uint32_t, char *, size_t);
void mfi_next_learn_time(uint32_t, char *, size_t);
void mfi_autolearn_mode(uint8_t, char *, size_t);
int get_mfi_unit(const char *dev);
char *get_mfi_type(const char *dev);
void scan_firmware(struct mfi_info_component *comp);
void display_firmware(struct mfi_info_component *comp, const char *tag);