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