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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Just in case we're not in a build environment, make sure that 29 * TEXT_DOMAIN gets set to something. 30 */ 31 #if !defined(TEXT_DOMAIN) 32 #define TEXT_DOMAIN "SYS_TEST" 33 #endif 34 35 /* 36 * Return the values of runtime parameters stored in 37 * /etc/lvm/runtime.cf, converting them to data 38 * types appropriate for use by functions whose behavior 39 * is affected by those values. 40 */ 41 42 /* 43 * system include files 44 */ 45 46 #include <libintl.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <syslog.h> 51 52 /* 53 * SUNWmd include files 54 */ 55 56 #include <meta.h> /* for MDD_DOMAIN */ 57 #include <meta_runtime.h> /* external interface definition */ 58 #include <sdssc.h> 59 60 /* 61 * The following lines define the runtime parameter configuration file. 62 */ 63 64 static const char *param_file_namep = "/etc/lvm/runtime.cf"; 65 66 /* 67 * The runtime parameter configuration file is an ascii text file. 68 * Each text line in the file has a maximum length of 80 four-byte 69 * wide characters. The line buffer size defined below accomodates 70 * the maximum line length plus the newline character at the end of 71 * the line and the null character that fgets() adds at the end of 72 * the line when it writes the line to the buffer. 73 */ 74 75 static const int line_buffer_size = 325; 76 77 /* 78 * The format for parameter entries in the file is "name=value". 79 * Each "name=value" string must begin a line of the file. 80 * The "name" and "value" tokens may be preceded or followed by 81 * spaces. Lines beginning with "#" are comment lines. 82 */ 83 84 static const char *token_separator_listp = " ="; 85 86 /* 87 * If a runtime parameter that can be set in the file is not set, 88 * or is set to an invalid value, or if the file can't be opened, 89 * the parameter takes on the default value given in the comments 90 * below. 91 */ 92 93 /* 94 * The following string constant declarations name the runtime 95 * configuration parameters that can be set in the runtime parameter 96 * configuration file. The allowed values of parameters that 97 * range over small sets of discrete values are also declared below 98 * as string constants. 99 * 100 * CAUTION: When adding new runtime parameters to the runtime 101 * parameter configuration file, declare their names 102 * as string constants below, and check for conflicts 103 * with the names of existing parameters. 104 */ 105 106 static const char *ownerioctls_namep = "ownerioctls"; 107 108 /* 109 * allowed values: 110 */ 111 112 static const char *ownerioctls_onp = "on"; /* default value */ 113 static const char *ownerioctls_offp = "off"; 114 115 /* 116 * The "ownerioctls" parameter controls whether the metaset -t and 117 * metaset -r commands issue the MHIOCTKOWN, MHIOCRELEASE, and 118 * MHIOCENFAILFAST ioctls when taking or releasing ownership of disksets. 119 * The allowed parameter values are "on" and "off". 120 * 121 * If the line "ownerioctls=off" appears in the runtime configuration file, 122 * the metaset -t command doesn't issue the MHIOCTKOWN ioctl when taking 123 * ownership of disksets, and the metaset -r command doesn't issue the 124 * MHIOCRELEASE and MHIOCENFAILFAST ioctls when releasing ownership of 125 * disksets. 126 * 127 * If the line "ownerioctls=on" appears in the file, the metaset -t 128 * command issues the MHIOCTKOWN ioctl when taking ownership of disksets, 129 * and the metaset -r command issues the MHIOCRELEASE AND MHIOCENFAILFAST 130 * icotls when releasing ownership of disksets. 131 * 132 * The default value of "ownerioctls" is "on". 133 */ 134 135 /* 136 * The following lines make forward declarations of private functions. 137 */ 138 139 static 140 char * 141 meta_get_rt_param(const char *param_namep, boolean_t warn_if_not_found); 142 143 /* 144 * The following lines define public functions. 145 */ 146 147 boolean_t 148 do_owner_ioctls(void) 149 { 150 const char *function_namep = "do_owner_ioctls()"; 151 char *param_valuep; 152 boolean_t return_value = B_TRUE; /* default behavior */ 153 sdssc_version_t version; 154 155 if ((sdssc_version(&version) == SDSSC_OKAY) && (version.major >= 3)) { 156 /* 157 * If we're bound to a cluster machine never do ioctls. 158 * The SC3.0 cluster code will always deal with disk 159 * reservation. 160 */ 161 162 return_value = B_FALSE; 163 } else { 164 param_valuep = meta_get_rt_param(ownerioctls_namep, B_TRUE); 165 if (param_valuep != NULL) { 166 if (strcmp(param_valuep, ownerioctls_offp) == 0) { 167 return_value = B_FALSE; 168 } else if (strcmp(param_valuep, 169 ownerioctls_onp) != 0) { 170 (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 171 "%s: illegal value for %s: %s.\n"), 172 function_namep, ownerioctls_namep, 173 param_valuep); 174 syslog(LOG_ERR, dgettext(TEXT_DOMAIN, 175 "%s: illegal value for %s: %s.\n"), 176 function_namep, 177 ownerioctls_namep, 178 param_valuep); 179 } 180 free(param_valuep); 181 } 182 } 183 return (return_value); 184 } 185 186 /* 187 * Retrieve the verbosity level for rpc.mdcommd from the config file. 188 * If none is specified, don't print a warning and return 0 189 */ 190 uint_t 191 commd_get_verbosity(void) 192 { 193 char *param_valuep; 194 uint_t retval = 0; 195 param_valuep = meta_get_rt_param("commd_verbosity", B_FALSE); 196 if (param_valuep != NULL) { 197 retval = (uint_t)strtol(param_valuep, NULL, 16); 198 free(param_valuep); 199 } 200 return (retval); 201 } 202 203 /* 204 * Retrieve the debug output file for rpc.mdcommd from the config file. 205 * If none is specified, don't print a warning. 206 * Note that if returning non-NULL, the caller is responsible for freeing 207 * the result pointer. 208 */ 209 char * 210 commd_get_outfile(void) 211 { 212 return (meta_get_rt_param("commd_out_file", B_FALSE)); 213 } 214 215 /* 216 * This controls what type of RPC errors are sent to syslog(). 217 * It is used as a bitmask against the clnt_stat list, which defines 218 * 0 as RPC_SUCCESS, so likely shouldn't be set. 219 * 220 * The #define below provides a default of all errors in the list. 221 * The default can then be modified to reduce the amount of traffic 222 * going to syslog in the event of RPC errors. 223 */ 224 225 #define DEFAULT_ERRMASK (UINT_MAX & ~(1 << RPC_SUCCESS)) 226 227 uint_t 228 meta_rpc_err_mask(void) 229 { 230 char *param_valuep; 231 uint_t retval = DEFAULT_ERRMASK; 232 233 param_valuep = meta_get_rt_param("commd_RPC_errors", B_FALSE); 234 if (param_valuep != NULL) { 235 retval = (uint_t)strtol(param_valuep, NULL, 16); 236 free(param_valuep); 237 } 238 return (retval); 239 } 240 241 /* 242 * The following lines define private functions 243 */ 244 245 static char * 246 meta_get_rt_param(const char *param_namep, boolean_t warn_if_not_found) 247 { 248 const char *function_namep = "meta_get_rt_param()"; 249 char *line_bufferp = NULL; 250 char *newlinep = NULL; 251 FILE *param_filep = NULL; 252 char *param_name_tokenp = NULL; 253 char *param_valuep = NULL; 254 char *param_value_tokenp = NULL; 255 256 line_bufferp = (char *)malloc(line_buffer_size); 257 if (line_bufferp == NULL) { 258 (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 259 "%s: malloc failed\n"), function_namep); 260 syslog(LOG_ERR, dgettext(TEXT_DOMAIN, "%s: malloc failed\n"), 261 function_namep); 262 return (param_valuep); 263 } 264 param_filep = fopen(param_file_namep, "r"); 265 if (param_filep == NULL) { 266 (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 267 "%s: can't open %s\n"), function_namep, param_file_namep); 268 syslog(LOG_ERR, dgettext(TEXT_DOMAIN, "%s: can't open %s\n"), 269 function_namep, param_file_namep); 270 free(line_bufferp); 271 return (param_valuep); 272 } 273 while ((fgets(line_bufferp, line_buffer_size, param_filep) != NULL) && 274 (param_valuep == NULL)) { 275 276 newlinep = strchr(line_bufferp, '\n'); 277 if (newlinep != NULL) { 278 *newlinep = '\0'; 279 newlinep = NULL; 280 } 281 param_name_tokenp = strtok(line_bufferp, token_separator_listp); 282 if ((param_name_tokenp != NULL) && 283 (strcmp(param_namep, param_name_tokenp) == 0)) { 284 285 param_value_tokenp = strtok(NULL, 286 token_separator_listp); 287 } 288 if (param_value_tokenp != NULL) { 289 param_valuep = strdup(param_value_tokenp); 290 if (param_valuep == NULL) { 291 (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 292 "%s: strdup failed\n"), 293 function_namep); 294 syslog(LOG_ERR, dgettext(TEXT_DOMAIN, 295 "%s: strdup failed\n"), 296 function_namep); 297 free(line_bufferp); 298 (void) fclose(param_filep); 299 return (param_valuep); 300 } 301 } 302 } 303 if ((param_valuep == NULL) && (warn_if_not_found == B_TRUE)) { 304 (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 305 "%s: value of %s not set or error in %s\n"), 306 function_namep, param_namep, param_file_namep); 307 syslog(LOG_ERR, dgettext(TEXT_DOMAIN, 308 "%s: value of %s not set or error in %s\n"), 309 function_namep, param_namep, param_file_namep); 310 } 311 free(line_bufferp); 312 (void) fclose(param_filep); 313 return (param_valuep); 314 } 315