1763fae79SScott Long /*- 2763fae79SScott Long * Copyright (c) 2008, 2009 Yahoo!, Inc. 3763fae79SScott Long * All rights reserved. 4763fae79SScott Long * 5763fae79SScott Long * Redistribution and use in source and binary forms, with or without 6763fae79SScott Long * modification, are permitted provided that the following conditions 7763fae79SScott Long * are met: 8763fae79SScott Long * 1. Redistributions of source code must retain the above copyright 9763fae79SScott Long * notice, this list of conditions and the following disclaimer. 10763fae79SScott Long * 2. Redistributions in binary form must reproduce the above copyright 11763fae79SScott Long * notice, this list of conditions and the following disclaimer in the 12763fae79SScott Long * documentation and/or other materials provided with the distribution. 13763fae79SScott Long * 3. The names of the authors may not be used to endorse or promote 14763fae79SScott Long * products derived from this software without specific prior written 15763fae79SScott Long * permission. 16763fae79SScott Long * 17763fae79SScott Long * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18763fae79SScott Long * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19763fae79SScott Long * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20763fae79SScott Long * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21763fae79SScott Long * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22763fae79SScott Long * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23763fae79SScott Long * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24763fae79SScott Long * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25763fae79SScott Long * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26763fae79SScott Long * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27763fae79SScott Long * SUCH DAMAGE. 28763fae79SScott Long * 29763fae79SScott Long * $FreeBSD$ 30763fae79SScott Long */ 31763fae79SScott Long 32763fae79SScott Long #include <sys/errno.h> 33763fae79SScott Long #include <err.h> 34763fae79SScott Long #include <stdio.h> 35763fae79SScott Long #include <stdlib.h> 36763fae79SScott Long #include <string.h> 37763fae79SScott Long #include <unistd.h> 38763fae79SScott Long #include "mfiutil.h" 39763fae79SScott Long 40763fae79SScott Long SET_DECLARE(MFI_DATASET(top), struct mfiutil_command); 41763fae79SScott Long 42763fae79SScott Long MFI_TABLE(top, start); 43763fae79SScott Long MFI_TABLE(top, stop); 44763fae79SScott Long MFI_TABLE(top, abort); 45763fae79SScott Long 46763fae79SScott Long int mfi_unit; 477bbae305SBjoern A. Zeeb u_int mfi_opts; 48*186475e2SEd Schouten static int fw_name_width, fw_version_width, fw_date_width, fw_time_width; 497bbae305SBjoern A. Zeeb 50763fae79SScott Long static void 51763fae79SScott Long usage(void) 52763fae79SScott Long { 53763fae79SScott Long 547bbae305SBjoern A. Zeeb fprintf(stderr, "usage: mfiutil [-de] [-u unit] <command> ...\n\n"); 55763fae79SScott Long fprintf(stderr, "Commands include:\n"); 56763fae79SScott Long fprintf(stderr, " version\n"); 57763fae79SScott Long fprintf(stderr, " show adapter - display controller information\n"); 58763fae79SScott Long fprintf(stderr, " show battery - display battery information\n"); 59763fae79SScott Long fprintf(stderr, " show config - display RAID configuration\n"); 60763fae79SScott Long fprintf(stderr, " show drives - list physical drives\n"); 61763fae79SScott Long fprintf(stderr, " show events - display event log\n"); 62763fae79SScott Long fprintf(stderr, " show firmware - list firmware images\n"); 6330d1616eSBjoern A. Zeeb fprintf(stderr, " show logstate - display event log sequence numbers\n"); 64763fae79SScott Long fprintf(stderr, " show volumes - list logical volumes\n"); 65763fae79SScott Long fprintf(stderr, " show patrol - display patrol read status\n"); 6698be0dfeSJohn Baldwin fprintf(stderr, " show progress - display status of active operations\n"); 67763fae79SScott Long fprintf(stderr, " fail <drive> - fail a physical drive\n"); 68763fae79SScott Long fprintf(stderr, " good <drive> - mark a bad physical drive as good\n"); 69763fae79SScott Long fprintf(stderr, " rebuild <drive> - mark failed drive ready for rebuild\n"); 70763fae79SScott Long fprintf(stderr, " drive progress <drive> - display status of active operations\n"); 71763fae79SScott Long fprintf(stderr, " drive clear <drive> <start|stop> - clear a drive with all 0x00\n"); 72763fae79SScott Long fprintf(stderr, " start rebuild <drive>\n"); 73763fae79SScott Long fprintf(stderr, " abort rebuild <drive>\n"); 74763fae79SScott Long fprintf(stderr, " locate <drive> <on|off> - toggle drive LED\n"); 75763fae79SScott Long fprintf(stderr, " cache <volume> [command [setting]]\n"); 76763fae79SScott Long fprintf(stderr, " name <volume> <name>\n"); 77763fae79SScott Long fprintf(stderr, " volume progress <volume> - display status of active operations\n"); 78763fae79SScott Long fprintf(stderr, " clear - clear volume configuration\n"); 79763fae79SScott Long fprintf(stderr, " create <type> [-v] <drive>[,<drive>[,...]] [<drive>[,<drive>[,...]]\n"); 80763fae79SScott Long fprintf(stderr, " delete <volume>\n"); 81763fae79SScott Long fprintf(stderr, " add <drive> [volume] - add a hot spare\n"); 82763fae79SScott Long fprintf(stderr, " remove <drive> - remove a hot spare\n"); 83763fae79SScott Long fprintf(stderr, " patrol <disable|auto|manual> [interval [start]]\n"); 84763fae79SScott Long fprintf(stderr, " start patrol - start a patrol read\n"); 85763fae79SScott Long fprintf(stderr, " stop patrol - stop a patrol read\n"); 86763fae79SScott Long fprintf(stderr, " flash <firmware>\n"); 87763fae79SScott Long #ifdef DEBUG 88763fae79SScott Long fprintf(stderr, " debug - debug 'show config'\n"); 89763fae79SScott Long fprintf(stderr, " dump - display 'saved' config\n"); 90763fae79SScott Long #endif 91763fae79SScott Long exit(1); 92763fae79SScott Long } 93763fae79SScott Long 94763fae79SScott Long static int 9541b8cbdaSEitan Adler version(int ac __unused, char **av __unused) 96763fae79SScott Long { 97763fae79SScott Long 98bf4ec4dfSEitan Adler printf("mfiutil version 1.0.14"); 99763fae79SScott Long #ifdef DEBUG 100763fae79SScott Long printf(" (DEBUG)"); 101763fae79SScott Long #endif 102763fae79SScott Long printf("\n"); 103763fae79SScott Long return (0); 104763fae79SScott Long } 105763fae79SScott Long MFI_COMMAND(top, version, version); 106763fae79SScott Long 107763fae79SScott Long int 108763fae79SScott Long main(int ac, char **av) 109763fae79SScott Long { 110763fae79SScott Long struct mfiutil_command **cmd; 111763fae79SScott Long int ch; 112763fae79SScott Long 1137bbae305SBjoern A. Zeeb while ((ch = getopt(ac, av, "deu:")) != -1) { 114763fae79SScott Long switch (ch) { 1157bbae305SBjoern A. Zeeb case 'd': 1167bbae305SBjoern A. Zeeb mfi_opts |= MFI_DNAME_DEVICE_ID; 1177bbae305SBjoern A. Zeeb break; 1187bbae305SBjoern A. Zeeb case 'e': 1197bbae305SBjoern A. Zeeb mfi_opts |= MFI_DNAME_ES; 1207bbae305SBjoern A. Zeeb break; 121763fae79SScott Long case 'u': 122763fae79SScott Long mfi_unit = atoi(optarg); 123763fae79SScott Long break; 124763fae79SScott Long case '?': 125763fae79SScott Long usage(); 126763fae79SScott Long } 127763fae79SScott Long } 128763fae79SScott Long 129763fae79SScott Long av += optind; 130763fae79SScott Long ac -= optind; 131763fae79SScott Long 132763fae79SScott Long /* getopt() eats av[0], so we can't use mfi_table_handler() directly. */ 133763fae79SScott Long if (ac == 0) 134763fae79SScott Long usage(); 135763fae79SScott Long 136763fae79SScott Long SET_FOREACH(cmd, MFI_DATASET(top)) { 137763fae79SScott Long if (strcmp((*cmd)->name, av[0]) == 0) { 1384ee8bfc5SRandi Harper if ((*cmd)->handler(ac, av)) 1394ee8bfc5SRandi Harper return (1); 1404ee8bfc5SRandi Harper else 141763fae79SScott Long return (0); 142763fae79SScott Long } 143763fae79SScott Long } 144763fae79SScott Long warnx("Unknown command %s.", av[0]); 1454ee8bfc5SRandi Harper return (1); 146763fae79SScott Long } 147*186475e2SEd Schouten 148*186475e2SEd Schouten void 149*186475e2SEd Schouten scan_firmware(struct mfi_info_component *comp) 150*186475e2SEd Schouten { 151*186475e2SEd Schouten int len; 152*186475e2SEd Schouten 153*186475e2SEd Schouten len = strlen(comp->name); 154*186475e2SEd Schouten if (fw_name_width < len) 155*186475e2SEd Schouten fw_name_width = len; 156*186475e2SEd Schouten len = strlen(comp->version); 157*186475e2SEd Schouten if (fw_version_width < len) 158*186475e2SEd Schouten fw_version_width = len; 159*186475e2SEd Schouten len = strlen(comp->build_date); 160*186475e2SEd Schouten if (fw_date_width < len) 161*186475e2SEd Schouten fw_date_width = len; 162*186475e2SEd Schouten len = strlen(comp->build_time); 163*186475e2SEd Schouten if (fw_time_width < len) 164*186475e2SEd Schouten fw_time_width = len; 165*186475e2SEd Schouten } 166*186475e2SEd Schouten 167*186475e2SEd Schouten void 168*186475e2SEd Schouten display_firmware(struct mfi_info_component *comp, const char *tag) 169*186475e2SEd Schouten { 170*186475e2SEd Schouten 171*186475e2SEd Schouten printf("%-*s %-*s %-*s %-*s %s\n", fw_name_width, comp->name, 172*186475e2SEd Schouten fw_version_width, comp->version, fw_date_width, comp->build_date, 173*186475e2SEd Schouten fw_time_width, comp->build_time, tag); 174*186475e2SEd Schouten } 175