Home | History | Annotate | Download | only in diskomizer
      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