From ea0d9570186e15380db57e767fd2b7209225d1dd Mon Sep 17 00:00:00 2001 From: ad Date: Sun, 4 Feb 2001 17:30:35 +0000 Subject: [PATCH] Add a control utility for `mlx' devices. Derived from FreeBSD's `mlxcontrol'. --- distrib/sets/lists/base/mi | 3 +- distrib/sets/lists/man/mi | 3 +- usr.sbin/Makefile | 4 +- usr.sbin/mlxctl/Makefile | 10 + usr.sbin/mlxctl/cmds.c | 406 +++++++++++++++++++++++++++++++++++++ usr.sbin/mlxctl/config.c | 237 ++++++++++++++++++++++ usr.sbin/mlxctl/dklist.c | 234 +++++++++++++++++++++ usr.sbin/mlxctl/extern.h | 88 ++++++++ usr.sbin/mlxctl/main.c | 160 +++++++++++++++ usr.sbin/mlxctl/mlxctl.8 | 176 ++++++++++++++++ usr.sbin/mlxctl/util.c | 287 ++++++++++++++++++++++++++ 11 files changed, 1604 insertions(+), 4 deletions(-) create mode 100644 usr.sbin/mlxctl/Makefile create mode 100644 usr.sbin/mlxctl/cmds.c create mode 100644 usr.sbin/mlxctl/config.c create mode 100644 usr.sbin/mlxctl/dklist.c create mode 100644 usr.sbin/mlxctl/extern.h create mode 100644 usr.sbin/mlxctl/main.c create mode 100644 usr.sbin/mlxctl/mlxctl.8 create mode 100644 usr.sbin/mlxctl/util.c diff --git a/distrib/sets/lists/base/mi b/distrib/sets/lists/base/mi index 6330fab94b3c..33f669878eb9 100644 --- a/distrib/sets/lists/base/mi +++ b/distrib/sets/lists/base/mi @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.224 2001/02/03 02:57:12 jwise Exp $ +# $NetBSD: mi,v 1.225 2001/02/04 17:30:36 ad Exp $ . base-sys-root ./altroot base-sys-root ./bin base-sys-root @@ -646,6 +646,7 @@ ./usr/sbin/mkalias base-nis-bin ./usr/sbin/mknetid base-nis-bin ./usr/sbin/mld6query base-netutil-bin +./usr/sbin/mlxctl base-sysutil-bin ./usr/sbin/mopa.out base-bootserver-bin ./usr/sbin/mopchk base-bootserver-bin ./usr/sbin/mopd base-bootserver-bin diff --git a/distrib/sets/lists/man/mi b/distrib/sets/lists/man/mi index 554e18303f00..d9454905720a 100644 --- a/distrib/sets/lists/man/mi +++ b/distrib/sets/lists/man/mi @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.319 2001/02/04 17:05:14 ad Exp $ +# $NetBSD: mi,v 1.320 2001/02/04 17:30:36 ad Exp $ ./usr/share/info/am-utils.info man-amd-info ./usr/share/info/as.info man-computil-info ./usr/share/info/awk.info man-util-info @@ -2718,6 +2718,7 @@ ./usr/share/man/man8/mknetid.8 man-nis-man ./usr/share/man/man8/mknod.8 man-sysutil-man ./usr/share/man/man8/mld6query.8 man-netutil-man +./usr/share/man/man8/mlxctl.8 man-sysutil-man ./usr/share/man/man8/modload.8 man-sysutil-man ./usr/share/man/man8/modstat.8 man-sysutil-man ./usr/share/man/man8/modunload.8 man-sysutil-man diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 46ab4b93646e..168bc097faf2 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.154 2001/01/06 13:03:49 martin Exp $ +# $NetBSD: Makefile,v 1.155 2001/02/04 17:30:35 ad Exp $ # from: @(#)Makefile 5.20 (Berkeley) 6/12/93 .include @@ -10,7 +10,7 @@ SUBDIR= ac accton altq amd apm apmd arp bad144 bind bootp catman \ grfconfig grfinfo gspa hilinfo inetd iopctl iostat ipf isdn iteconfig \ kgmon kvm_mkdb lastlogin link lpr mailwrapper map-mbone \ mdconfig mdsetimage \ - memswitch mopd mountd mrinfo mrouted mtrace mtree \ + memswitch mlxctl mopd mountd mrinfo mrouted mtrace mtree \ netgroup_mkdb nfsd ntp pkg_install pppd pstat \ pwd_mkdb quot quotacheck quotaon rarpd rbootd rdate \ repquota rmt rpc.bootparamd rpc.lockd rpc.pcnfsd \ diff --git a/usr.sbin/mlxctl/Makefile b/usr.sbin/mlxctl/Makefile new file mode 100644 index 000000000000..3a5ed46436a5 --- /dev/null +++ b/usr.sbin/mlxctl/Makefile @@ -0,0 +1,10 @@ +# $NetBSD: Makefile,v 1.1 2001/02/04 17:30:37 ad Exp $ + +PROG= mlxctl +SRCS= cmds.c config.c dklist.c main.c util.c +MAN= mlxctl.8 + +LDADD= -lkvm +DPADD= ${LIBKVM} + +.include diff --git a/usr.sbin/mlxctl/cmds.c b/usr.sbin/mlxctl/cmds.c new file mode 100644 index 000000000000..990076012f34 --- /dev/null +++ b/usr.sbin/mlxctl/cmds.c @@ -0,0 +1,406 @@ +/* $NetBSD: cmds.c,v 1.1 2001/02/04 17:30:37 ad Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Doran. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c) 1999 Michael Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from FreeBSD: command.c,v 1.2 2000/04/11 23:04:17 msmith Exp + */ + +#ifndef lint +#include +__RCSID("$NetBSD: cmds.c,v 1.1 2001/02/04 17:30:37 ad Exp $"); +#endif /* not lint */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "extern.h" + +static void cmd_status0(struct mlx_disk *); +static void cmd_check0(struct mlx_disk *); +static void cmd_detach0(struct mlx_disk *); + +static struct mlx_rebuild_status rs; +static int rstatus; + +struct { + int hwid; + const char *name; +} static const mlx_ctlr_names[] = { + { 0x01, "960P/PD" }, + { 0x02, "960PL" }, + { 0x10, "960PG" }, + { 0x11, "960PJ" }, + { 0x12, "960PR" }, + { 0x13, "960PT" }, + { 0x14, "960PTL0" }, + { 0x15, "960PRL" } , + { 0x16, "960PTL1" }, + { 0x20, "1100PVX" }, + { -1, NULL }, +}; + +/* + * Status output + */ +static void +cmd_status0(struct mlx_disk *md) +{ + const char *statusfmt; + int result; + + result = md->hwunit; + if (ioctl(mlxfd, MLXD_STATUS, &result) < 0) + err(EXIT_FAILURE, "ioctl(MLXD_STATUS)"); + + switch(result) { + case MLX_SYSD_ONLINE: + statusfmt = "%s: online\n"; + break; + + case MLX_SYSD_CRITICAL: + statusfmt = "%s: critical\n"; + if (!rstatus) + rstatus = 1; + break; + + case MLX_SYSD_OFFLINE: + statusfmt = "%s: offline\n"; + rstatus = 2; + break; + + default: + statusfmt = "%s: unknown status 0x%02x\n"; + break; + } + + printf(statusfmt, md->name, result); + + /* Rebuild/check in progress on this drive? */ + if (rs.rs_drive == md->hwunit && + rs.rs_code != MLX_REBUILDSTAT_IDLE) { + switch(rs.rs_code) { + case MLX_REBUILDSTAT_REBUILDCHECK: + printf(" [consistency check"); + break; + + case MLX_REBUILDSTAT_ADDCAPACITY: + printf(" [add capacity"); + break; + + case MLX_REBUILDSTAT_ADDCAPACITYINIT: + printf(" [add capacity init"); + break; + + default: + printf(" [unknown operation"); + break; + } + + printf(": %d/%d, %d%% complete]\n", rs.rs_remaining, rs.rs_size, + ((rs.rs_size - rs.rs_remaining) / (rs.rs_size / 100))); + } +} + +int +cmd_status(char **argv) +{ + + if (ioctl(mlxfd, MLX_REBUILDSTAT, &rs) < 0) + err(EXIT_FAILURE, "ioctl(MLX_REBUILDSTAT)"); + + mlx_disk_iterate(cmd_status0); + return (rstatus); +} + +/* + * Display controller status. + */ +int +cmd_cstatus(char **argv) +{ + struct mlx_enquiry2 enq; + struct mlx_phys_drv pd; + static char buf[80]; + const char *model; + int i, channel, target; + + mlx_enquiry(&enq); + + for (i = 0; i < sizeof(mlx_ctlr_names) / sizeof(mlx_ctlr_names[0]); i++) + if (enq.me_hardware_id[0] == mlx_ctlr_names[i].hwid) { + model = mlx_ctlr_names[i].name; + break; + } + + if (i == sizeof(mlx_ctlr_names) / sizeof(mlx_ctlr_names[0])) { + sprintf(buf, " model 0x%x", enq.me_hardware_id[0]); + model = buf; + } + + printf("DAC%s, %d channel%s, firmware %d.%02d-%c-%02d, %dMB RAM\n", + model, enq.me_actual_channels, + enq.me_actual_channels > 1 ? "s" : "", + enq.me_firmware_id[0], enq.me_firmware_id[1], + enq.me_firmware_id[2], enq.me_firmware_id[3], + le32toh(enq.me_mem_size) / (1024 * 1024)); + + if (verbosity > 0) { + printf(" Hardware ID\t\t\t0x%08x\n", + le32toh(*(u_int32_t *)enq.me_hardware_id)); + printf(" Firmware ID\t\t\t0x%08x\n", + le32toh(*(u_int32_t *)enq.me_firmware_id)); + printf(" Configured/Actual channels\t%d/%d\n", + enq.me_configured_channels, enq.me_actual_channels); + printf(" Max Targets\t\t\t%d\n", enq.me_max_targets); + printf(" Max Tags\t\t\t%d\n", enq.me_max_tags); + printf(" Max System Drives\t\t%d\n", enq.me_max_sys_drives); + printf(" Max Arms\t\t\t%d\n", enq.me_max_arms); + printf(" Max Spans\t\t\t%d\n", enq.me_max_spans); + printf(" DRAM/cache/flash/NVRAM size\t%d/%d/%d/%d\n", + le32toh(enq.me_mem_size), le32toh(enq.me_cache_size), + le32toh(enq.me_flash_size), le32toh(enq.me_nvram_size)); + printf(" DRAM type\t\t\t%d\n", le16toh(enq.me_mem_type)); + printf(" Clock Speed\t\t\t%dns\n", + le16toh(enq.me_clock_speed)); + printf(" Hardware Speed\t\t%dns\n", + le16toh(enq.me_hardware_speed)); + printf(" Max Commands\t\t\t%d\n", + le16toh(enq.me_max_commands)); + printf(" Max SG Entries\t\t%d\n", le16toh(enq.me_max_sg)); + printf(" Max DP\t\t\t%d\n", le16toh(enq.me_max_dp)); + printf(" Max IOD\t\t\t%d\n", le16toh(enq.me_max_iod)); + printf(" Max Comb\t\t\t%d\n", le16toh(enq.me_max_comb)); + printf(" Latency\t\t\t%ds\n", enq.me_latency); + printf(" SCSI Timeout\t\t\t%ds\n", enq.me_scsi_timeout); + printf(" Min Free Lines\t\t%d\n", + le16toh(enq.me_min_freelines)); + printf(" Rate Constant\t\t\t%d\n", enq.me_rate_const); + printf(" MAXBLK\t\t\t%d\n", le16toh(enq.me_maxblk)); + printf(" Blocking Factor\t\t%d sectors\n", + le16toh(enq.me_blocking_factor)); + printf(" Cache Line Size\t\t%d blocks\n", + le16toh(enq.me_cacheline)); + printf(" SCSI Capability\t\t%s%dMHz, %d bit\n", + enq.me_scsi_cap & (1<<4) ? "differential " : "", + (1 << ((enq.me_scsi_cap >> 2) & 3)) * 10, + 8 << (enq.me_scsi_cap & 0x3)); + printf(" Firmware Build Number\t\t%d\n", + le16toh(enq.me_firmware_build)); + printf(" Fault Management Type\t\t%d\n", + enq.me_fault_mgmt_type); +#if 0 + printf(" Features\t\t\t%b\n", enq.me_firmware_features, + "\20\4Background Init\3Read Ahead\2MORE\1Cluster\n"); +#endif + } + + fflush(stdout); + + /* + * Fetch and print physical drive data. + */ + for (channel = 0; channel < enq.me_configured_channels; channel++) { + for (target = 0; target < enq.me_max_targets; target++) + if (mlx_get_device_state(channel, target, &pd) == 0 && + (pd.pd_flags1 & MLX_PHYS_DRV_PRESENT) != 0) + mlx_print_phys_drv(&pd, channel, target, " "); + } + + return (0); +} + +/* + * Recscan for new or changed system drives. + */ +int +cmd_rescan(char **argv) +{ + + if (ioctl(mlxfd, MLX_RESCAN_DRIVES) < 0) + err(EXIT_FAILURE, "rescan failed"); + return (0); +} + +/* + * Detach one or more system drives from a controller. + */ +static void +cmd_detach0(struct mlx_disk *md) +{ + + if (ioctl(mlxfd, MLXD_DETACH, &md->hwunit) < 0) + warn("can't detach %s", md->name); +} + +int +cmd_detach(char **argv) +{ + + mlx_disk_iterate(cmd_detach0); + return (0); +} + +/* + * Initiate a consistency check on a system drive. + */ +static void +cmd_check0(struct mlx_disk *md) +{ + int result; + + if (ioctl(mlxfd, MLXD_CHECKASYNC, &result) == 0) + return; + + switch (result) { + case 0x0002: + warnx("one or more of the SCSI disks on which %s", md->name); + warnx("depends is DEAD.", md->name); + break; + + case 0x0105: + warnx("drive %s is invalid, or not a drive which ", md->name); + warnx("can be checked."); + break; + + case 0x0106: + warnx("drive rebuild or consistency check is already "); + warnx("in progress on this controller."); + break; + + default: + err(EXIT_FAILURE, "ioctl(MLXD_CHECKASYNC)"); + /* NOTREACHED */ + } +} + +int +cmd_check(char **argv) +{ + + mlx_disk_iterate(cmd_check0); + return (0); +} + +/* + * Initiate a physical drive rebuild. + */ +int +cmd_rebuild(char **argv) +{ + struct mlx_rebuild_request rb; + char *p; + + if (argv[0] == NULL || argv[1] != NULL) + usage(); + + rb.rr_channel = strtol(*argv, &p, 0); + if (p[0] != ':' || p[1] == '\0') + usage(); + + rb.rr_target = strtol(*argv, &p, 0); + if (p[0] != '\0') + usage(); + + if (ioctl(mlxfd, MLX_REBUILDASYNC, &rb) == 0) + return (0); + + switch (rb.rr_status) { + case 0x0002: + warnx("the drive at %d:%d is already ONLINE", rb.rr_channel, + rb.rr_target); + break; + + case 0x0004: + warnx("drive failed during rebuild"); + break; + + case 0x0105: + warnx("there is no drive at %d:%d", rb.rr_channel, + rb.rr_target); + break; + + case 0x0106: + warnx("drive rebuild or consistency check is already in "); + warnx("progress on this controller"); + break; + + default: + err(EXIT_FAILURE, "ioctl(MLXD_CHECKASYNC)"); + /* NOTREACHED */ + } + + return(0); +} diff --git a/usr.sbin/mlxctl/config.c b/usr.sbin/mlxctl/config.c new file mode 100644 index 000000000000..d932a630e74c --- /dev/null +++ b/usr.sbin/mlxctl/config.c @@ -0,0 +1,237 @@ +/* $NetBSD: config.c,v 1.1 2001/02/04 17:30:37 ad Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Doran. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c) 1999 Michael Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from FreeBSD: config.c,v 1.2 2000/04/11 23:04:17 msmith Exp + */ + +#ifndef lint +#include +__RCSID("$NetBSD: config.c,v 1.1 2001/02/04 17:30:37 ad Exp $"); +#endif /* not lint */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "extern.h" + +struct conf_phys_drv { + TAILQ_ENTRY(conf_phys_drv) pd_link; + int pd_bus; + int pd_target; + struct mlx_phys_drv pd_drv; +}; + +struct conf_span { + TAILQ_ENTRY(conf_span) s_link; + struct conf_phys_drv *s_drvs[8]; + struct mlx_sys_drv_span s_span; +}; + +struct conf_sys_drv { + TAILQ_ENTRY(conf_sys_drv) sd_link; + struct conf_span *sd_spans[4]; + struct mlx_sys_drv sd_drv; +}; + +struct conf_config { + TAILQ_HEAD(,conf_phys_drv) cc_phys_drvs; + TAILQ_HEAD(,conf_span) cc_spans; + TAILQ_HEAD(,conf_sys_drv) cc_sys_drvs; + struct conf_sys_drv *cc_drives[32]; + struct mlx_core_cfg cc_cfg; +}; + +static void print_span(struct mlx_sys_drv_span *, int); +static void print_sys_drive(struct conf_config *, int); +static void print_phys_drive(struct conf_config *, int, int); + +/* + * Get the configuration from the selected controller. + * + * config + * Print the configuration for + * + * XXX update to support adding/deleting drives. + */ +int +cmd_config(char **argv) +{ + char hostname[MAXHOSTNAMELEN]; + struct conf_config conf; + int i, j; + + memset(&conf.cc_cfg, 0, sizeof(conf.cc_cfg)); + mlx_configuration(&conf.cc_cfg, 0); + + gethostname(hostname, sizeof(hostname)); + printf("# controller %s on %s\n", mlxname, hostname); + + printf("#\n# physical devices connected:\n"); + for (i = 0; i < 5; i++) + for (j = 0; j < 16; j++) + print_phys_drive(&conf, i, j); + + printf("#\n# system drives defined:\n"); + for (i = 0; i < conf.cc_cfg.cc_num_sys_drives; i++) + print_sys_drive(&conf, i); + + return(0); +} + +/* + * Print details for the system drive (drvno) in a format that we will be + * able to parse later. + * + * drive?? + * span? 0x????????-0x???????? ????blks on [...] + * ... + */ +static void +print_span(struct mlx_sys_drv_span *span, int arms) +{ + int i; + + printf("0x%08x-0x%08x %u blks on", span->sp_start_lba, + span->sp_start_lba + span->sp_nblks, span->sp_nblks); + + for (i = 0; i < arms; i++) + printf(" disk%02d%02d", span->sp_arm[i] >> 4, + span->sp_arm[i] & 0x0f); + + printf("\n"); +} + +static void +print_sys_drive(struct conf_config *conf, int drvno) +{ + struct mlx_sys_drv *drv; + int i; + + drv = &conf->cc_cfg.cc_sys_drives[drvno]; + + printf("drive%02d ", drvno); + + switch(drv->sd_raidlevel & 0xf) { + case MLX_SYS_DRV_RAID0: + printf("RAID0"); + break; + case MLX_SYS_DRV_RAID1: + printf("RAID1"); + break; + case MLX_SYS_DRV_RAID3: + printf("RAID3"); + break; + case MLX_SYS_DRV_RAID5: + printf("RAID5"); + break; + case MLX_SYS_DRV_RAID6: + printf("RAID6"); + break; + case MLX_SYS_DRV_JBOD: + printf("JBOD"); + break; + default: + printf("RAID?"); + break; + } + + printf(" write%s\n", + drv->sd_raidlevel & MLX_SYS_DRV_WRITEBACK ? "back" : "through"); + + for (i = 0; i < drv->sd_valid_spans; i++) { + printf(" span%d ", i); + print_span(&drv->sd_span[i], drv->sd_valid_arms); + } +} + +/* + * Print details for the physical drive at chn/targ in a format suitable for + * human consumption. + */ +static void +print_phys_drive(struct conf_config *conf, int chn, int targ) +{ + struct mlx_phys_drv *pd; + + pd = &conf->cc_cfg.cc_phys_drives[chn * 16 + targ]; + + /* If the drive isn't present, don't print it. */ + if ((pd->pd_flags1 & MLX_PHYS_DRV_PRESENT) == 0) + return; + + mlx_print_phys_drv(pd, chn, targ, "# "); +} diff --git a/usr.sbin/mlxctl/dklist.c b/usr.sbin/mlxctl/dklist.c new file mode 100644 index 000000000000..48c508988e9a --- /dev/null +++ b/usr.sbin/mlxctl/dklist.c @@ -0,0 +1,234 @@ +/* $NetBSD: dklist.c,v 1.1 2001/02/04 17:30:37 ad Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Doran. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1996 John M. Vinopal + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project + * by John M. Vinopal. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +#include +__RCSID("$NetBSD: dklist.c,v 1.1 2001/02/04 17:30:37 ad Exp $"); +#endif /* not lint */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "extern.h" + +static SIMPLEQ_HEAD(, mlx_disk) mlx_disks; + +static struct nlist namelist[] = { +#define X_DISK_COUNT 4 + { "_disk_count" }, /* number of disks */ +#define X_DISKLIST 5 + { "_disklist" }, /* TAILQ of disks */ + { NULL }, +}; + +#define KVM_ERROR(_string) { \ + warnx("%s", (_string)); \ + errx(1, "%s", kvm_geterr(kd)); \ +} + +/* + * Dereference the namelist pointer `v' and fill in the local copy + * 'p' which is of size 's'. + */ +#define deref_nl(kd, v, p, s) \ + deref_kptr(kd, (void *)namelist[(v)].n_value, (p), (s)); + +static void deref_kptr(kvm_t *, void *, void *, size_t); + +void +mlx_disk_init(void) +{ + + SIMPLEQ_INIT(&mlx_disks); +} + +int +mlx_disk_empty(void) +{ + + return (SIMPLEQ_FIRST(&mlx_disks) == NULL); +} + +void +mlx_disk_iterate(void (*func)(struct mlx_disk *)) +{ + struct mlx_disk *md; + + SIMPLEQ_FOREACH(md, &mlx_disks, chain) + (*func)(md); +} + +static int +mlx_disk_add0(const char *name) +{ + struct mlx_disk *md; + int unit; + + if (name[0] != 'l' || name[1] != 'd' || !isdigit(name[2])) + return (-1); + + SIMPLEQ_FOREACH(md, &mlx_disks, chain) + if (strcmp(md->name, name) == 0) + return (0); + + unit = atoi(name + 2); + if (ioctl(mlxfd, MLX_GET_SYSDRIVE, &unit) < 0) + return (-1); + + if ((md = malloc(sizeof(*md))) == NULL) + err(EXIT_FAILURE, "mlx_disk_add()"); + + strlcpy(md->name, name, sizeof(md->name)); + md->hwunit = unit; + SIMPLEQ_INSERT_TAIL(&mlx_disks, md, chain); + return (0); +} + +void +mlx_disk_add(const char *name) +{ + + if (mlx_disk_add0(name) != 0) + errx(EXIT_FAILURE, "%s is not attached to %s", name, mlxname); +} + +void +mlx_disk_add_all(void) +{ + struct disklist_head disk_head; + struct disk cur_disk, *dk; + char errbuf[_POSIX2_LINE_MAX]; + char buf[12]; + int i, ndrives; + kvm_t *kd; + + /* Open the kernel. */ + if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf)) == NULL) + errx(1, "kvm_openfiles: %s", errbuf); + + /* Obtain the namelist symbols from the kernel. */ + if (kvm_nlist(kd, namelist)) + KVM_ERROR("kvm_nlist failed to read symbols."); + + /* Get the number of attached drives. */ + deref_nl(kd, X_DISK_COUNT, &ndrives, sizeof(ndrives)); + + if (ndrives < 0) + errx(EXIT_FAILURE, "invalid _disk_count %d.", ndrives); + if (ndrives == 0) + errx(EXIT_FAILURE, "no drives attached."); + + /* Get a pointer to the first disk. */ + deref_nl(kd, X_DISKLIST, &disk_head, sizeof(disk_head)); + dk = TAILQ_FIRST(&disk_head); + + /* Try to add each disk to the list. */ + for (i = 0; i < ndrives; i++) { + deref_kptr(kd, dk, &cur_disk, sizeof(cur_disk)); + deref_kptr(kd, cur_disk.dk_name, buf, sizeof(buf)); + mlx_disk_add0(buf); + dk = TAILQ_NEXT(dk, dk_link); + } + + kvm_close(kd); +} + +/* + * Dereference the kernel pointer `kptr' and fill in the local copy pointed + * to by `ptr'. The storage space must be pre-allocated, and the size of + * the copy passed in `len'. + */ +static void +deref_kptr(kvm_t *kd, void *kptr, void *ptr, size_t len) +{ + char buf[128]; + + if (kvm_read(kd, (u_long)kptr, (char *)ptr, len) != len) { + memset(buf, 0, sizeof(buf)); + snprintf(buf, sizeof buf, "can't dereference kptr 0x%lx", + (u_long)kptr); + KVM_ERROR(buf); + } +} diff --git a/usr.sbin/mlxctl/extern.h b/usr.sbin/mlxctl/extern.h new file mode 100644 index 000000000000..2f1673938a5c --- /dev/null +++ b/usr.sbin/mlxctl/extern.h @@ -0,0 +1,88 @@ +/* $NetBSD: extern.h,v 1.1 2001/02/04 17:30:37 ad Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Doran. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * main.c + */ +extern int mlxfd; +extern const char *mlxname; +extern const char *nlistf; +extern const char *memf; +extern int verbosity; + +void usage(void) __attribute__ ((__noreturn__)); + +/* + * dklist.c + */ +struct mlx_disk { + SIMPLEQ_ENTRY(mlx_disk) chain; + int hwunit; + char name[8]; +}; + +void mlx_disk_init(void); +int mlx_disk_empty(void); +void mlx_disk_add(const char *); +void mlx_disk_add_all(void); +void mlx_disk_iterate(void (*)(struct mlx_disk *)); + +/* + * util.c + */ +int mlx_command(struct mlx_usercommand *, int); +void mlx_enquiry(struct mlx_enquiry2 *enq); +void mlx_configuration(struct mlx_core_cfg *, int); +int mlx_scsi_inquiry(int, int, char **, char **, char **); +int mlx_get_device_state(int, int, struct mlx_phys_drv *); +void mlx_print_phys_drv(struct mlx_phys_drv *, int, int, const char *); + +/* + * cmds.c + */ +int cmd_check(char **); +int cmd_cstatus(char **); +int cmd_detach(char **); +int cmd_rebuild(char **); +int cmd_rescan(char **); +int cmd_status(char **); + +/* + * config.c + */ +int cmd_config(char **); diff --git a/usr.sbin/mlxctl/main.c b/usr.sbin/mlxctl/main.c new file mode 100644 index 000000000000..04f97c356103 --- /dev/null +++ b/usr.sbin/mlxctl/main.c @@ -0,0 +1,160 @@ +/* $NetBSD: main.c,v 1.1 2001/02/04 17:30:37 ad Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Doran. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef lint +#include +__RCSID("$NetBSD: main.c,v 1.1 2001/02/04 17:30:37 ad Exp $"); +#endif /* not lint */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "extern.h" + +const char *mlxname; +const char *memf; +const char *nlistf; +int mlxfd = -1; +int verbosity; + +struct cmd { + const char *label; + int flags; + int (*func)(char **); +}; +#define CMD_DISKS 0x01 +#define CMD_NOARGS 0x02 + +static const struct cmd cmdtab[] = { + { "check", CMD_DISKS, cmd_check }, + { "config", CMD_NOARGS, cmd_config }, + { "cstatus", CMD_NOARGS, cmd_cstatus }, + { "detach", CMD_DISKS, cmd_detach }, + { "rebuild", 0, cmd_rebuild }, + { "rescan", CMD_NOARGS, cmd_rescan }, + { "status", CMD_DISKS, cmd_status }, +}; + +int +main(int argc, char **argv) +{ + const struct cmd *cmd, *maxcmd; + const char *cmdname, *dv; + int ch, i, rv; + + dv = "/dev/mlx0"; + mlx_disk_init(); + + while ((ch = getopt(argc, argv, "af:v")) != -1) { + switch (ch) { + case 'a': + mlx_disk_add_all(); + break; + + case 'f': + dv = optarg; + break; + + case 'v': + verbosity++; + break; + + default: + usage(); + /* NOTREACHED */ + } + } + + if ((cmdname = argv[optind++]) == NULL) + usage(); + + for (i = 0; dv[i] != '\0'; i++) + if (dv[i] == '/') + mlxname = &dv[i + 1]; + + if ((mlxfd = open(dv, O_RDWR)) < 0) + err(EXIT_FAILURE, "%s", dv); + + cmd = &cmdtab[0]; + maxcmd = &cmdtab[sizeof(cmdtab) / sizeof(cmdtab[0])]; + while (cmd < maxcmd) { + if (strcmp(cmdname, cmd->label) == 0) + break; + cmd++; + } + if (cmd == maxcmd) + usage(); + + if ((cmd->flags & CMD_DISKS) != 0) { + while (argv[optind] != NULL) + mlx_disk_add(argv[optind++]); + if (mlx_disk_empty()) + usage(); + } else if ((cmd->flags & CMD_NOARGS) != 0) + if (argv[optind] != NULL) + usage(); + + rv = (*cmd->func)(&argv[optind]); + close(mlxfd); + exit(rv); + /* NOTREACHED */ +} + +void +usage(void) +{ + extern char *__progname; + + (void)fprintf(stderr, "usage: %s [-f dev] [-av] command [...]\n", + __progname); + exit(EXIT_FAILURE); + /* NOTREACHED */ +} diff --git a/usr.sbin/mlxctl/mlxctl.8 b/usr.sbin/mlxctl/mlxctl.8 new file mode 100644 index 000000000000..cfcc4ec70f3a --- /dev/null +++ b/usr.sbin/mlxctl/mlxctl.8 @@ -0,0 +1,176 @@ +.\" $NetBSD: mlxctl.8,v 1.1 2001/02/04 17:30:37 ad Exp $ +.\" +.\" Copyright (c) 2001 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Andrew Doran. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the NetBSD +.\" Foundation, Inc. and its contributors. +.\" 4. Neither the name of The NetBSD Foundation nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" Copyright (c) 2000 Michael Smith +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" from FreeBSD: mlxcontrol.8,v 1.6 2000/11/20 20:10:07 ru Exp +.\" +.Dd April 10, 2000 +.Dt MLXCTL 8 +.Os +.Sh NAME +.Nm mlxctl +.Nd Mylex DAC960 family management utility +.Sh SYNOPSIS +.Nm mlxctl +.Op Fl f Ar dev +.Op Fl v +.Op Fl a +status +.Op Ar drive +.Op Ar ... +.Nm mlxctl +.Op Fl f Ar dev +.Op Fl a +detach +.Op Ar drive +.Op Ar ... +.Nm mlxctl +.Op Fl f Ar dev +.Op Fl a +check +.Op Ar drive +.Op Ar ... +.Nm mlxctl +.Op Fl f Ar dev +rebuild +.Ar channel:target +.Nm mlxctl +.Op Fl f Ar dev +cstatus +.Nm mlxctl +.Op Fl f Ar dev +rescan +.Nm mlxctl +.Op Fl f Ar dev +config +.Sh DESCRIPTION +The +.Nm +utility performs status monitoring and management functions for Mylex DAC960 +RAID controllers and attached devices. +.Pp +The following options are available: +.Bl -tag -width xxxxxxx +.It Fl a +Apply the action to all drives attached to the controller. +.It Fl f Ar dev +Specify the control device to use. The default is +.Pa /dev/mlx0 . +.It Fl v +Incresed verbosity. +.El +.Pp +The following commands are available: +.Bl -tag -width rebuild +.It cstatus +Display the controller's current status. +.It status +Display the status of the specified drives. +This command returns +0 if all drives tested are online, +1 if one or more drives are critical and +2 if one or more are offline. +.It rescan +Rescan the controller for new, unattached or changed drives. +.It detach +Detach the specified drives. Drives must be unmounted and unopened for this +command to succeed. +.It check +Initiate a consistency check and repair pass on a redundant drive +(eg. RAID1 or RAID5). +The controller will scan the drive and repair any inconsistencies. This +command returns immediately. The +.Ar status +command can be used to monitor the progress of the check. +.It rebuild +Rebuild onto the specified physical drive. Note that there can be only one +running rebuild operation per controller at any given time. +This command returns immediately. The +.Ar cstatus +command can be used to monitor the progress of the rebuild. +.It config +Write the current system drive configuration to stdout. +.El +.Sh EXAMPLES +Display the status of drive ld3 attached to the controller mlx1: +.sp +.D1 Li "mlxctl -f /dev/mlx1 -v status ld3" +.Sh SEE ALSO +.Xr ld 4 , +.Xr mlx 4 +.Sh HISTORY +The +.Nm +command first appeared in +.Nx 1.6 . +.Sh AUTHORS +The +.Nm +command was written by Micheal Smith +.Aq msmith@freebsd.org , +and appeared in FreeBSD under the guise of +.Nm mlxcontrol . +It was modified for +.Nx +by Andrew Doran +.Aq ad@netbsd.org . +.Sh BUGS +Modifying drive configuration is not yet supported. +.Pp +The cstatus and config commands don't work with all firmware revisions. +.Pp +Error log extraction is not yet supported. diff --git a/usr.sbin/mlxctl/util.c b/usr.sbin/mlxctl/util.c new file mode 100644 index 000000000000..a1a0176f85b4 --- /dev/null +++ b/usr.sbin/mlxctl/util.c @@ -0,0 +1,287 @@ +/* $NetBSD: util.c,v 1.1 2001/02/04 17:30:37 ad Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Doran. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c) 1999 Michael Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +#include +__RCSID("$NetBSD: util.c,v 1.1 2001/02/04 17:30:37 ad Exp $"); +#endif /* not lint */ + +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +#include "extern.h" + +int +mlx_command(struct mlx_usercommand *mu, int bomb) +{ + int rv; + + if ((rv = ioctl(mlxfd, MLX_COMMAND, mu)) != 0 && bomb) + err(EXIT_FAILURE, "cmd 0x%02x failed", + mu->mu_command[0]); + + return (rv); +} + +void +mlx_enquiry(struct mlx_enquiry2 *enq) +{ + struct mlx_usercommand mu; + struct mlx_enquiry_old meo; + + memset(&mu, 0, sizeof(mu)); + + mu.mu_datasize = sizeof(*enq); + mu.mu_buf = enq; + mu.mu_bufptr = 8; + mu.mu_bufdir = MU_XFER_IN; + mu.mu_command[0] = MLX_CMD_ENQUIRY2; + + mlx_command(&mu, 1); + + /* + * If we get back a firmware major of 0, this is (probably) an old + * controller, so we need to pull the firmware version from the old + * enquiry structure. + */ + if (enq->me_firmware_id[0] == 0) { + memset(&mu, 0, sizeof(mu)); + + mu.mu_datasize = sizeof(meo); + mu.mu_buf = &meo; + mu.mu_bufptr = 8; + mu.mu_bufdir = MU_XFER_IN; + mu.mu_command[0] = MLX_CMD_ENQUIRY_OLD; + + mlx_command(&mu, 1); + + enq->me_firmware_id[0] = meo.me_fwmajor; + enq->me_firmware_id[1] = meo.me_fwminor; + enq->me_firmware_id[2] = '0'; + enq->me_firmware_id[3] = 0; + } +} + +void +mlx_configuration(struct mlx_core_cfg *cfg, int wr) +{ + struct mlx_usercommand mu; + + memset(&mu, 0, sizeof(mu)); + + mu.mu_datasize = sizeof(*cfg); + mu.mu_buf = cfg; + mu.mu_bufptr = 8; + mu.mu_bufdir = (wr ? MU_XFER_OUT : MU_XFER_IN); + mu.mu_command[0] = (wr ? MLX_CMD_WRITE_CONFIG : MLX_CMD_READ_CONFIG); + + mlx_command(&mu, 1); +} + +int +mlx_get_device_state(int chan, int targ, struct mlx_phys_drv *pd) +{ + struct mlx_usercommand mu; + + memset(&mu, 0, sizeof(mu)); + + mu.mu_datasize = sizeof(*pd); + mu.mu_buf = pd; + mu.mu_bufptr = 8; + mu.mu_bufdir = MU_XFER_IN; + mu.mu_command[0] = MLX_CMD_DEVICE_STATE; + mu.mu_command[2] = chan; + mu.mu_command[3] = targ; + + return (mlx_command(&mu, 0)); +} + +int +mlx_scsi_inquiry(int chan, int targ, char **vendor, char **device, + char **revision) +{ + struct mlx_usercommand mu; + static struct { + struct mlx_dcdb dcdb; + struct scsipi_inquiry_data inq; + } __attribute__ ((__packed__)) dcdb_cmd; + struct scsipi_inquiry *inq_cmd; + int rv; + + inq_cmd = (struct scsipi_inquiry *)&dcdb_cmd.dcdb.dcdb_cdb[0]; + + memset(&mu, 0, sizeof(mu)); + mu.mu_datasize = sizeof(dcdb_cmd); + mu.mu_buf = &dcdb_cmd; + mu.mu_command[0] = MLX_CMD_DIRECT_CDB; + mu.mu_bufdir = MU_XFER_IN | MU_XFER_OUT; + + memset(&dcdb_cmd, 0, sizeof(dcdb_cmd)); + dcdb_cmd.dcdb.dcdb_target = (chan << 4) | targ; + dcdb_cmd.dcdb.dcdb_flags = MLX_DCDB_DATA_IN | MLX_DCDB_TIMEOUT_10S; + dcdb_cmd.dcdb.dcdb_datasize = sizeof(dcdb_cmd.inq); + dcdb_cmd.dcdb.dcdb_length = 6; + dcdb_cmd.dcdb.dcdb_sense_length = 40; + + inq_cmd->opcode = INQUIRY; + inq_cmd->length = sizeof(dcdb_cmd.inq); + + if ((rv = mlx_command(&mu, 0)) == 0) { + *vendor = &dcdb_cmd.inq.vendor[0]; + *device = &dcdb_cmd.inq.product[0]; + *revision = &dcdb_cmd.inq.revision[0]; + } + + return (rv); +} + +void +mlx_print_phys_drv(struct mlx_phys_drv *pd, int chn, int targ, + const char *prefix) +{ + char *type, *device, *vendor, *revision; + + switch(pd->pd_flags2 & 0x03) { + case MLX_PHYS_DRV_DISK: + type = "disk"; + break; + + case MLX_PHYS_DRV_SEQUENTIAL: + type = "tape"; + break; + + case MLX_PHYS_DRV_CDROM: + type= "cdrom"; + break; + + case MLX_PHYS_DRV_OTHER: + default: + type = "unknown"; + break; + } + + printf("%s%s%02d%02d ", prefix, type, chn, targ); + + switch(pd->pd_status) { + case MLX_PHYS_DRV_DEAD: + printf(" (dead) "); + break; + + case MLX_PHYS_DRV_WRONLY: + printf(" (write-only) "); + break; + + case MLX_PHYS_DRV_ONLINE: + printf(" (online) "); + break; + + case MLX_PHYS_DRV_STANDBY: + printf(" (standby) "); + break; + + default: + printf(" (0x%02x) ", pd->pd_status); + break; + } + + printf("\n"); + if (verbosity == 0) + return; + + printf("%s ", prefix); + if (!mlx_scsi_inquiry(chn, targ, &vendor, &device, &revision)) + printf("'%8.8s' '%16.16s' '%4.4s'", vendor, device, revision); + else + printf(""); + + printf(" %dMB ", pd->pd_config_size / 2048); + + if ((pd->pd_flags2 & MLX_PHYS_DRV_FAST20) != 0) + printf(" ultra"); + else if ((pd->pd_flags2 & MLX_PHYS_DRV_FAST) != 0) + printf(" fast"); + + if ((pd->pd_flags2 & MLX_PHYS_DRV_WIDE) != 0) + printf(" wide"); + + if ((pd->pd_flags2 & MLX_PHYS_DRV_SYNC) != 0) + printf(" sync"); + + if ((pd->pd_flags2 & MLX_PHYS_DRV_TAG) != 0) + printf(" tag-enabled"); + + printf("\n"); +} +