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