10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*8452SJohn.Wren.Kennedy@Sun.COM  * Common Development and Distribution License (the "License").
6*8452SJohn.Wren.Kennedy@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*8452SJohn.Wren.Kennedy@Sun.COM 
220Sstevel@tonic-gate /*
23*8452SJohn.Wren.Kennedy@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*
280Sstevel@tonic-gate  * Just in case we're not in a build environment, make sure that
290Sstevel@tonic-gate  * TEXT_DOMAIN gets set to something.
300Sstevel@tonic-gate  */
310Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
320Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
330Sstevel@tonic-gate #endif
340Sstevel@tonic-gate 
350Sstevel@tonic-gate /*
360Sstevel@tonic-gate  * Return the values of runtime parameters stored in
370Sstevel@tonic-gate  * /etc/lvm/runtime.cf, converting them to data
380Sstevel@tonic-gate  * types appropriate for use by functions whose behavior
390Sstevel@tonic-gate  * is affected by those values.
400Sstevel@tonic-gate  */
410Sstevel@tonic-gate 
420Sstevel@tonic-gate /*
430Sstevel@tonic-gate  * system include files
440Sstevel@tonic-gate  */
450Sstevel@tonic-gate 
460Sstevel@tonic-gate #include <libintl.h>
470Sstevel@tonic-gate #include <stdio.h>
480Sstevel@tonic-gate #include <stdlib.h>
490Sstevel@tonic-gate #include <string.h>
500Sstevel@tonic-gate #include <syslog.h>
510Sstevel@tonic-gate 
520Sstevel@tonic-gate /*
530Sstevel@tonic-gate  * SUNWmd include files
540Sstevel@tonic-gate  */
550Sstevel@tonic-gate 
560Sstevel@tonic-gate #include <meta.h>		/* for MDD_DOMAIN */
570Sstevel@tonic-gate #include <meta_runtime.h>	/* external interface definition */
580Sstevel@tonic-gate #include <sdssc.h>
590Sstevel@tonic-gate 
600Sstevel@tonic-gate /*
610Sstevel@tonic-gate  * The following lines define the runtime parameter configuration file.
620Sstevel@tonic-gate  */
630Sstevel@tonic-gate 
640Sstevel@tonic-gate static const char *param_file_namep = "/etc/lvm/runtime.cf";
650Sstevel@tonic-gate 
660Sstevel@tonic-gate /*
670Sstevel@tonic-gate  * The runtime parameter configuration file is an ascii text file.
680Sstevel@tonic-gate  * Each text line in the file has a maximum length of 80 four-byte
690Sstevel@tonic-gate  * wide characters.  The line buffer size defined below accomodates
700Sstevel@tonic-gate  * the maximum line length plus the newline character at the end of
710Sstevel@tonic-gate  * the line and the null character that fgets() adds at the end of
720Sstevel@tonic-gate  * the line when it writes the line to the buffer.
730Sstevel@tonic-gate  */
740Sstevel@tonic-gate 
750Sstevel@tonic-gate static const int line_buffer_size = 325;
760Sstevel@tonic-gate 
770Sstevel@tonic-gate /*
780Sstevel@tonic-gate  * The format for parameter entries in the file is "name=value".
790Sstevel@tonic-gate  * Each "name=value" string must begin a line of the file.
800Sstevel@tonic-gate  * The "name" and "value" tokens may be preceded or followed by
810Sstevel@tonic-gate  * spaces.  Lines beginning with "#" are comment lines.
820Sstevel@tonic-gate  */
830Sstevel@tonic-gate 
840Sstevel@tonic-gate static const char *token_separator_listp = " =";
850Sstevel@tonic-gate 
860Sstevel@tonic-gate /*
870Sstevel@tonic-gate  * If a runtime parameter that can be set in the file is not set,
880Sstevel@tonic-gate  * or is set to an invalid value, or if the file can't be opened,
890Sstevel@tonic-gate  * the parameter takes on the default value given in the comments
900Sstevel@tonic-gate  * below.
910Sstevel@tonic-gate  */
920Sstevel@tonic-gate 
930Sstevel@tonic-gate /*
940Sstevel@tonic-gate  * The following string constant declarations name the runtime
950Sstevel@tonic-gate  * configuration parameters that can be set in the runtime parameter
960Sstevel@tonic-gate  * configuration file.  The allowed values of parameters that
970Sstevel@tonic-gate  * range over small sets of discrete values are also declared below
980Sstevel@tonic-gate  * as string constants.
990Sstevel@tonic-gate  *
1000Sstevel@tonic-gate  * CAUTION: When adding new runtime parameters to the runtime
1010Sstevel@tonic-gate  *          parameter configuration file, declare their names
1020Sstevel@tonic-gate  *          as string constants below, and check for conflicts
1030Sstevel@tonic-gate  *          with the names of existing parameters.
1040Sstevel@tonic-gate  */
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate static const char *ownerioctls_namep = "ownerioctls";
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate /*
1090Sstevel@tonic-gate  * allowed values:
1100Sstevel@tonic-gate  */
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate static const char *ownerioctls_onp = "on"; /* default value */
1130Sstevel@tonic-gate static const char *ownerioctls_offp = "off";
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate /*
1160Sstevel@tonic-gate  * The "ownerioctls" parameter controls whether the metaset -t and
1170Sstevel@tonic-gate  * metaset -r commands issue the MHIOCTKOWN, MHIOCRELEASE, and
1180Sstevel@tonic-gate  * MHIOCENFAILFAST ioctls when taking or releasing ownership of disksets.
1190Sstevel@tonic-gate  * The allowed parameter values are "on" and "off".
1200Sstevel@tonic-gate  *
1210Sstevel@tonic-gate  * If the line "ownerioctls=off" appears in the runtime configuration file,
1220Sstevel@tonic-gate  * the metaset -t command doesn't issue the MHIOCTKOWN ioctl when taking
1230Sstevel@tonic-gate  * ownership of disksets, and the metaset -r command doesn't issue the
1240Sstevel@tonic-gate  * MHIOCRELEASE and MHIOCENFAILFAST ioctls when releasing ownership of
1250Sstevel@tonic-gate  * disksets.
1260Sstevel@tonic-gate  *
1270Sstevel@tonic-gate  * If the line "ownerioctls=on" appears in the file, the metaset -t
1280Sstevel@tonic-gate  * command issues the MHIOCTKOWN ioctl when taking ownership of disksets,
1290Sstevel@tonic-gate  * and the metaset -r command issues the MHIOCRELEASE AND MHIOCENFAILFAST
1300Sstevel@tonic-gate  * icotls when releasing ownership of disksets.
1310Sstevel@tonic-gate  *
1320Sstevel@tonic-gate  * The default value of "ownerioctls" is "on".
1330Sstevel@tonic-gate  */
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate /*
1360Sstevel@tonic-gate  * The following lines make forward declarations of private functions.
1370Sstevel@tonic-gate  */
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate static
1400Sstevel@tonic-gate char *
1410Sstevel@tonic-gate meta_get_rt_param(const char *param_namep, boolean_t warn_if_not_found);
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate /*
1440Sstevel@tonic-gate  * The following lines define public functions.
1450Sstevel@tonic-gate  */
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate boolean_t
1480Sstevel@tonic-gate do_owner_ioctls(void)
1490Sstevel@tonic-gate {
1500Sstevel@tonic-gate 	const char	*function_namep = "do_owner_ioctls()";
1510Sstevel@tonic-gate 	char		*param_valuep;
1520Sstevel@tonic-gate 	boolean_t	return_value = B_TRUE; /* default behavior */
1530Sstevel@tonic-gate 	sdssc_version_t	version;
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate 	if ((sdssc_version(&version) == SDSSC_OKAY) && (version.major >= 3)) {
1560Sstevel@tonic-gate 		/*
1570Sstevel@tonic-gate 		 * If we're bound to a cluster machine never do ioctls.
1580Sstevel@tonic-gate 		 * The SC3.0 cluster code will always deal with disk
1590Sstevel@tonic-gate 		 * reservation.
1600Sstevel@tonic-gate 		 */
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate 		return_value = B_FALSE;
1630Sstevel@tonic-gate 	} else {
1640Sstevel@tonic-gate 		param_valuep = meta_get_rt_param(ownerioctls_namep, B_TRUE);
1650Sstevel@tonic-gate 		if (param_valuep != NULL) {
1660Sstevel@tonic-gate 			if (strcmp(param_valuep, ownerioctls_offp) == 0) {
1670Sstevel@tonic-gate 				return_value = B_FALSE;
1680Sstevel@tonic-gate 			} else if (strcmp(param_valuep,
1690Sstevel@tonic-gate 			    ownerioctls_onp) != 0) {
1700Sstevel@tonic-gate 				(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1710Sstevel@tonic-gate 				    "%s: illegal value for %s: %s.\n"),
172*8452SJohn.Wren.Kennedy@Sun.COM 				    function_namep, ownerioctls_namep,
173*8452SJohn.Wren.Kennedy@Sun.COM 				    param_valuep);
1740Sstevel@tonic-gate 				syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
1750Sstevel@tonic-gate 				    "%s: illegal value for %s: %s.\n"),
1760Sstevel@tonic-gate 				    function_namep,
1770Sstevel@tonic-gate 				    ownerioctls_namep,
1780Sstevel@tonic-gate 				    param_valuep);
1790Sstevel@tonic-gate 			}
1800Sstevel@tonic-gate 			free(param_valuep);
1810Sstevel@tonic-gate 		}
1820Sstevel@tonic-gate 	}
1830Sstevel@tonic-gate 	return (return_value);
1840Sstevel@tonic-gate }
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate /*
1870Sstevel@tonic-gate  * Retrieve the verbosity level for rpc.mdcommd from the config file.
1880Sstevel@tonic-gate  * If none is specified, don't print a warning and return 0
1890Sstevel@tonic-gate  */
1900Sstevel@tonic-gate uint_t
1910Sstevel@tonic-gate commd_get_verbosity(void)
1920Sstevel@tonic-gate {
1930Sstevel@tonic-gate 	char		*param_valuep;
1940Sstevel@tonic-gate 	uint_t retval	= 0;
1950Sstevel@tonic-gate 	param_valuep = meta_get_rt_param("commd_verbosity", B_FALSE);
1960Sstevel@tonic-gate 	if (param_valuep != NULL) {
1970Sstevel@tonic-gate 		retval = (uint_t)strtol(param_valuep, NULL, 16);
1980Sstevel@tonic-gate 		free(param_valuep);
1990Sstevel@tonic-gate 	}
2000Sstevel@tonic-gate 	return (retval);
2010Sstevel@tonic-gate }
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate /*
2040Sstevel@tonic-gate  * Retrieve the debug output file for rpc.mdcommd from the config file.
2050Sstevel@tonic-gate  * If none is specified, don't print a warning.
2060Sstevel@tonic-gate  * Note that if returning non-NULL, the caller is responsible for freeing
2070Sstevel@tonic-gate  * the result pointer.
2080Sstevel@tonic-gate  */
2090Sstevel@tonic-gate char *
2100Sstevel@tonic-gate commd_get_outfile(void)
2110Sstevel@tonic-gate {
2120Sstevel@tonic-gate 	return (meta_get_rt_param("commd_out_file", B_FALSE));
2130Sstevel@tonic-gate }
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate /*
216*8452SJohn.Wren.Kennedy@Sun.COM  * This controls what type of RPC errors are sent to syslog().
217*8452SJohn.Wren.Kennedy@Sun.COM  * It is used as a bitmask against the clnt_stat list, which defines
218*8452SJohn.Wren.Kennedy@Sun.COM  * 0 as RPC_SUCCESS, so likely shouldn't be set.
219*8452SJohn.Wren.Kennedy@Sun.COM  *
220*8452SJohn.Wren.Kennedy@Sun.COM  * The #define below provides a default of all errors in the list.
221*8452SJohn.Wren.Kennedy@Sun.COM  * The default can then be modified to reduce the amount of traffic
222*8452SJohn.Wren.Kennedy@Sun.COM  * going to syslog in the event of RPC errors.
223*8452SJohn.Wren.Kennedy@Sun.COM  */
224*8452SJohn.Wren.Kennedy@Sun.COM 
225*8452SJohn.Wren.Kennedy@Sun.COM #define	DEFAULT_ERRMASK	(UINT_MAX & ~(1 << RPC_SUCCESS))
226*8452SJohn.Wren.Kennedy@Sun.COM 
227*8452SJohn.Wren.Kennedy@Sun.COM uint_t
228*8452SJohn.Wren.Kennedy@Sun.COM meta_rpc_err_mask(void)
229*8452SJohn.Wren.Kennedy@Sun.COM {
230*8452SJohn.Wren.Kennedy@Sun.COM 	char		*param_valuep;
231*8452SJohn.Wren.Kennedy@Sun.COM 	uint_t retval   = DEFAULT_ERRMASK;
232*8452SJohn.Wren.Kennedy@Sun.COM 
233*8452SJohn.Wren.Kennedy@Sun.COM 	param_valuep = meta_get_rt_param("commd_RPC_errors", B_FALSE);
234*8452SJohn.Wren.Kennedy@Sun.COM 	if (param_valuep != NULL) {
235*8452SJohn.Wren.Kennedy@Sun.COM 		retval = (uint_t)strtol(param_valuep, NULL, 16);
236*8452SJohn.Wren.Kennedy@Sun.COM 		free(param_valuep);
237*8452SJohn.Wren.Kennedy@Sun.COM 	}
238*8452SJohn.Wren.Kennedy@Sun.COM 	return (retval);
239*8452SJohn.Wren.Kennedy@Sun.COM }
240*8452SJohn.Wren.Kennedy@Sun.COM 
241*8452SJohn.Wren.Kennedy@Sun.COM /*
2420Sstevel@tonic-gate  * The following lines define private functions
2430Sstevel@tonic-gate  */
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate static char *
2460Sstevel@tonic-gate meta_get_rt_param(const char *param_namep, boolean_t warn_if_not_found)
2470Sstevel@tonic-gate {
2480Sstevel@tonic-gate 	const char *function_namep = "meta_get_rt_param()";
2490Sstevel@tonic-gate 	char *line_bufferp = NULL;
2500Sstevel@tonic-gate 	char *newlinep = NULL;
2510Sstevel@tonic-gate 	FILE *param_filep = NULL;
2520Sstevel@tonic-gate 	char *param_name_tokenp = NULL;
2530Sstevel@tonic-gate 	char *param_valuep = NULL;
2540Sstevel@tonic-gate 	char *param_value_tokenp = NULL;
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate 	line_bufferp = (char *)malloc(line_buffer_size);
2570Sstevel@tonic-gate 	if (line_bufferp == NULL) {
258*8452SJohn.Wren.Kennedy@Sun.COM 		(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
259*8452SJohn.Wren.Kennedy@Sun.COM 		    "%s: malloc failed\n"), function_namep);
260*8452SJohn.Wren.Kennedy@Sun.COM 		syslog(LOG_ERR, dgettext(TEXT_DOMAIN, "%s: malloc failed\n"),
261*8452SJohn.Wren.Kennedy@Sun.COM 		    function_namep);
2620Sstevel@tonic-gate 		return (param_valuep);
2630Sstevel@tonic-gate 	}
2640Sstevel@tonic-gate 	param_filep = fopen(param_file_namep, "r");
2650Sstevel@tonic-gate 	if (param_filep == NULL) {
266*8452SJohn.Wren.Kennedy@Sun.COM 		(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
267*8452SJohn.Wren.Kennedy@Sun.COM 		    "%s: can't open %s\n"), function_namep, param_file_namep);
268*8452SJohn.Wren.Kennedy@Sun.COM 		syslog(LOG_ERR, dgettext(TEXT_DOMAIN, "%s: can't open %s\n"),
269*8452SJohn.Wren.Kennedy@Sun.COM 		    function_namep, param_file_namep);
2700Sstevel@tonic-gate 		free(line_bufferp);
2710Sstevel@tonic-gate 		return (param_valuep);
2720Sstevel@tonic-gate 	}
2730Sstevel@tonic-gate 	while ((fgets(line_bufferp, line_buffer_size, param_filep) != NULL) &&
274*8452SJohn.Wren.Kennedy@Sun.COM 	    (param_valuep == NULL)) {
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate 		newlinep = strchr(line_bufferp, '\n');
2770Sstevel@tonic-gate 		if (newlinep != NULL) {
2780Sstevel@tonic-gate 			*newlinep = '\0';
2790Sstevel@tonic-gate 			newlinep = NULL;
2800Sstevel@tonic-gate 		}
2810Sstevel@tonic-gate 		param_name_tokenp = strtok(line_bufferp, token_separator_listp);
2820Sstevel@tonic-gate 		if ((param_name_tokenp != NULL) &&
283*8452SJohn.Wren.Kennedy@Sun.COM 		    (strcmp(param_namep, param_name_tokenp) == 0)) {
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate 			param_value_tokenp = strtok(NULL,
286*8452SJohn.Wren.Kennedy@Sun.COM 			    token_separator_listp);
2870Sstevel@tonic-gate 		}
2880Sstevel@tonic-gate 		if (param_value_tokenp != NULL) {
2890Sstevel@tonic-gate 			param_valuep = strdup(param_value_tokenp);
2900Sstevel@tonic-gate 			if (param_valuep == NULL) {
2910Sstevel@tonic-gate 				(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
2920Sstevel@tonic-gate 				    "%s: strdup failed\n"),
2930Sstevel@tonic-gate 				    function_namep);
2940Sstevel@tonic-gate 				syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
2950Sstevel@tonic-gate 				    "%s: strdup failed\n"),
2960Sstevel@tonic-gate 				    function_namep);
2970Sstevel@tonic-gate 				free(line_bufferp);
2980Sstevel@tonic-gate 				(void) fclose(param_filep);
2990Sstevel@tonic-gate 				return (param_valuep);
3000Sstevel@tonic-gate 			}
3010Sstevel@tonic-gate 		}
3020Sstevel@tonic-gate 	}
3030Sstevel@tonic-gate 	if ((param_valuep == NULL) && (warn_if_not_found == B_TRUE)) {
304*8452SJohn.Wren.Kennedy@Sun.COM 		(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
305*8452SJohn.Wren.Kennedy@Sun.COM 		    "%s: value of %s not set or error in %s\n"),
306*8452SJohn.Wren.Kennedy@Sun.COM 		    function_namep, param_namep, param_file_namep);
307*8452SJohn.Wren.Kennedy@Sun.COM 		syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
308*8452SJohn.Wren.Kennedy@Sun.COM 		    "%s: value of %s not set or error in %s\n"),
309*8452SJohn.Wren.Kennedy@Sun.COM 		    function_namep, param_namep, param_file_namep);
3100Sstevel@tonic-gate 	}
3110Sstevel@tonic-gate 	free(line_bufferp);
3120Sstevel@tonic-gate 	(void) fclose(param_filep);
3130Sstevel@tonic-gate 	return (param_valuep);
3140Sstevel@tonic-gate }
315