1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "@(#)uadmin.c 1.7 09/05/26 SMI" 28 29 #include "args.h" 30 #include <diskomizer/log.h> 31 #include "diskomizer64mpism.h" 32 #include <sys/uadmin.h> 33 #include <stdio.h> 34 #include <errno.h> 35 36 struct ua { 37 int i; 38 char *s; 39 }; 40 41 #ifndef A_DUMP 42 #define A_DUMP 0x5 43 #endif 44 45 #define U(A) { A, #A } 46 static struct ua uadmin_cmd[] = { 47 U(A_SHUTDOWN), 48 U(A_REBOOT), 49 U(A_DUMP), 50 U(A_REMOUNT), 51 U(A_FREEZE), 52 53 }; 54 55 static struct ua uadmin_fcn[] = { 56 U(AD_HALT), 57 U(AD_POWEROFF), 58 U(AD_BOOT), 59 U(AD_IBOOT), 60 U(AD_COMPRESS), 61 U(AD_CHECK), 62 U(AD_FORCE) 63 }; 64 65 static struct { 66 int cmd; 67 int fcn; 68 } uadmin_opts = { 69 A_SHUTDOWN, 70 AD_HALT 71 }; 72 73 static char uadmin_armed = 0; 74 75 #define NOT_NULL(A) (A == NULL ? "NULL" : A) 76 77 static char * 78 uadmin_cmd2str(int cmd) 79 { 80 int i; 81 static char buf[255]; 82 83 for (i = 0; i < ARRAY_LEN(uadmin_cmd); i++) { 84 if (cmd == uadmin_cmd[i].i) { 85 return (uadmin_cmd[i].s); 86 } 87 } 88 snprintf(buf, sizeof (buf), "%d", cmd); 89 return (buf); 90 } 91 92 static char * 93 uadmin_fcn2str(int fcn) 94 { 95 int i; 96 static char buf[255]; 97 98 for (i = 0; i < ARRAY_LEN(uadmin_fcn); i++) { 99 if (fcn == uadmin_fcn[i].i) { 100 return (uadmin_fcn[i].s); 101 } 102 } 103 snprintf(buf, sizeof (buf), "%d", fcn); 104 return (buf); 105 } 106 107 static int 108 init_cmd(void) 109 { 110 int i; 111 long l; 112 113 for (i = 0; i < ARRAY_LEN(uadmin_cmd); i++) { 114 if (strcasecmp(opts.expert_uadmin_cmd, uadmin_cmd[i].s) == 0) { 115 uadmin_opts.cmd = uadmin_cmd[i].i; 116 return (1); 117 } 118 } 119 errno = 0; 120 l = strtol(opts.expert_uadmin_cmd, NULL, 0); 121 if (l != 0 || errno != EINVAL) { 122 for (i = 0; i < ARRAY_LEN(uadmin_cmd); i++) { 123 if (l == uadmin_cmd[i].i) { 124 uadmin_opts.cmd = uadmin_cmd[i].i; 125 return (1); 126 } 127 } 128 } 129 130 plog(LOG_ERR, 131 "Unknown uadmin command \"%s\", using default of \"%s\"\n", 132 opts.expert_uadmin_cmd, uadmin_cmd2str(uadmin_opts.cmd)); 133 return (0); 134 } 135 136 static int 137 init_fcn(void) 138 { 139 int i; 140 long l; 141 142 for (i = 0; i < ARRAY_LEN(uadmin_fcn); i++) { 143 if (strcasecmp(opts.expert_uadmin_fcn, uadmin_fcn[i].s) == 0) { 144 uadmin_opts.fcn = uadmin_fcn[i].i; 145 return (1); 146 } 147 } 148 errno = 0; 149 l = strtol(opts.expert_uadmin_fcn, NULL, 0); 150 if (l != 0 || errno != EINVAL) { 151 for (i = 0; i < ARRAY_LEN(uadmin_fcn); i++) { 152 if (l == uadmin_fcn[i].i) { 153 uadmin_opts.fcn = uadmin_fcn[i].i; 154 return (1); 155 } 156 } 157 } 158 159 plog(LOG_ERR, 160 "Unknown uadmin function \"%s\", using default of \"%s\"\n", 161 opts.expert_uadmin_cmd, uadmin_fcn2str(uadmin_opts.fcn)); 162 return (0); 163 } 164 165 void 166 report_uadmin(void) 167 { 168 if (uadmin_armed) { 169 plog(LOG_INFO, "uadmin error handler set to: " 170 "uadmin(%s, %s, %s)\n", 171 uadmin_cmd2str(uadmin_opts.cmd), 172 uadmin_fcn2str(uadmin_opts.fcn), 173 NOT_NULL(opts.expert_uadmin_mdep)); 174 } 175 } 176 177 int 178 uadmin_init(void) 179 { 180 int c = init_cmd(); 181 int f = init_fcn(); 182 uadmin_armed = 1; 183 184 return (f && c); 185 } 186 187 loop_type 188 on_error_uadmin(ullong_t start, struct aio_str *aiop) 189 { 190 if (uadmin(uadmin_opts.cmd, uadmin_opts.fcn, 191 (intptr_t)opts.expert_uadmin_mdep) < 0) { 192 pperror("uadmin(%s, %s, %s)", uadmin_cmd2str(uadmin_opts.cmd), 193 uadmin_fcn2str(uadmin_opts.fcn), 194 NOT_NULL(opts.expert_uadmin_mdep)); 195 } 196 return (CONTINUE); 197 } 198