2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A/*
2N/A * Just in case we're not in a build environment, make sure that
2N/A * TEXT_DOMAIN gets set to something.
2N/A */
2N/A#if !defined(TEXT_DOMAIN)
2N/A#define TEXT_DOMAIN "SYS_TEST"
2N/A#endif
2N/A
2N/A/*
2N/A * Return the values of runtime parameters stored in
2N/A * /etc/lvm/runtime.cf, converting them to data
2N/A * types appropriate for use by functions whose behavior
2N/A * is affected by those values.
2N/A */
2N/A
2N/A/*
2N/A * system include files
2N/A */
2N/A
2N/A#include <libintl.h>
2N/A#include <stdio.h>
2N/A#include <stdlib.h>
2N/A#include <string.h>
2N/A#include <syslog.h>
2N/A
2N/A/*
2N/A * SUNWmd include files
2N/A */
2N/A
2N/A#include <meta.h> /* for MDD_DOMAIN */
2N/A#include <meta_runtime.h> /* external interface definition */
2N/A#include <sdssc.h>
2N/A
2N/A/*
2N/A * The following lines define the runtime parameter configuration file.
2N/A */
2N/A
2N/Astatic const char *param_file_namep = "/etc/lvm/runtime.cf";
2N/A
2N/A/*
2N/A * The runtime parameter configuration file is an ascii text file.
2N/A * Each text line in the file has a maximum length of 80 four-byte
2N/A * wide characters. The line buffer size defined below accomodates
2N/A * the maximum line length plus the newline character at the end of
2N/A * the line and the null character that fgets() adds at the end of
2N/A * the line when it writes the line to the buffer.
2N/A */
2N/A
2N/Astatic const int line_buffer_size = 325;
2N/A
2N/A/*
2N/A * The format for parameter entries in the file is "name=value".
2N/A * Each "name=value" string must begin a line of the file.
2N/A * The "name" and "value" tokens may be preceded or followed by
2N/A * spaces. Lines beginning with "#" are comment lines.
2N/A */
2N/A
2N/Astatic const char *token_separator_listp = " =";
2N/A
2N/A/*
2N/A * If a runtime parameter that can be set in the file is not set,
2N/A * or is set to an invalid value, or if the file can't be opened,
2N/A * the parameter takes on the default value given in the comments
2N/A * below.
2N/A */
2N/A
2N/A/*
2N/A * The following string constant declarations name the runtime
2N/A * configuration parameters that can be set in the runtime parameter
2N/A * configuration file. The allowed values of parameters that
2N/A * range over small sets of discrete values are also declared below
2N/A * as string constants.
2N/A *
2N/A * CAUTION: When adding new runtime parameters to the runtime
2N/A * parameter configuration file, declare their names
2N/A * as string constants below, and check for conflicts
2N/A * with the names of existing parameters.
2N/A */
2N/A
2N/Astatic const char *ownerioctls_namep = "ownerioctls";
2N/A
2N/A/*
2N/A * allowed values:
2N/A */
2N/A
2N/Astatic const char *ownerioctls_onp = "on"; /* default value */
2N/Astatic const char *ownerioctls_offp = "off";
2N/A
2N/A/*
2N/A * The "ownerioctls" parameter controls whether the metaset -t and
2N/A * metaset -r commands issue the MHIOCTKOWN, MHIOCRELEASE, and
2N/A * MHIOCENFAILFAST ioctls when taking or releasing ownership of disksets.
2N/A * The allowed parameter values are "on" and "off".
2N/A *
2N/A * If the line "ownerioctls=off" appears in the runtime configuration file,
2N/A * the metaset -t command doesn't issue the MHIOCTKOWN ioctl when taking
2N/A * ownership of disksets, and the metaset -r command doesn't issue the
2N/A * MHIOCRELEASE and MHIOCENFAILFAST ioctls when releasing ownership of
2N/A * disksets.
2N/A *
2N/A * If the line "ownerioctls=on" appears in the file, the metaset -t
2N/A * command issues the MHIOCTKOWN ioctl when taking ownership of disksets,
2N/A * and the metaset -r command issues the MHIOCRELEASE AND MHIOCENFAILFAST
2N/A * icotls when releasing ownership of disksets.
2N/A *
2N/A * The default value of "ownerioctls" is "on".
2N/A */
2N/A
2N/A/*
2N/A * The following lines make forward declarations of private functions.
2N/A */
2N/A
2N/Astatic
2N/Achar *
2N/Ameta_get_rt_param(const char *param_namep, boolean_t warn_if_not_found);
2N/A
2N/A/*
2N/A * The following lines define public functions.
2N/A */
2N/A
2N/Aboolean_t
2N/Ado_owner_ioctls(void)
2N/A{
2N/A const char *function_namep = "do_owner_ioctls()";
2N/A char *param_valuep;
2N/A boolean_t return_value = B_TRUE; /* default behavior */
2N/A sdssc_version_t version;
2N/A
2N/A if ((sdssc_version(&version) == SDSSC_OKAY) && (version.major >= 3)) {
2N/A /*
2N/A * If we're bound to a cluster machine never do ioctls.
2N/A * The SC3.0 cluster code will always deal with disk
2N/A * reservation.
2N/A */
2N/A
2N/A return_value = B_FALSE;
2N/A } else {
2N/A param_valuep = meta_get_rt_param(ownerioctls_namep, B_TRUE);
2N/A if (param_valuep != NULL) {
2N/A if (strcmp(param_valuep, ownerioctls_offp) == 0) {
2N/A return_value = B_FALSE;
2N/A } else if (strcmp(param_valuep,
2N/A ownerioctls_onp) != 0) {
2N/A (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
2N/A "%s: illegal value for %s: %s.\n"),
2N/A function_namep, ownerioctls_namep,
2N/A param_valuep);
2N/A syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
2N/A "%s: illegal value for %s: %s.\n"),
2N/A function_namep,
2N/A ownerioctls_namep,
2N/A param_valuep);
2N/A }
2N/A free(param_valuep);
2N/A }
2N/A }
2N/A return (return_value);
2N/A}
2N/A
2N/A/*
2N/A * Retrieve the verbosity level for rpc.mdcommd from the config file.
2N/A * If none is specified, don't print a warning and return 0
2N/A */
2N/Auint_t
2N/Acommd_get_verbosity(void)
2N/A{
2N/A char *param_valuep;
2N/A uint_t retval = 0;
2N/A param_valuep = meta_get_rt_param("commd_verbosity", B_FALSE);
2N/A if (param_valuep != NULL) {
2N/A retval = (uint_t)strtol(param_valuep, NULL, 16);
2N/A free(param_valuep);
2N/A }
2N/A return (retval);
2N/A}
2N/A
2N/A/*
2N/A * Retrieve the debug output file for rpc.mdcommd from the config file.
2N/A * If none is specified, don't print a warning.
2N/A * Note that if returning non-NULL, the caller is responsible for freeing
2N/A * the result pointer.
2N/A */
2N/Achar *
2N/Acommd_get_outfile(void)
2N/A{
2N/A return (meta_get_rt_param("commd_out_file", B_FALSE));
2N/A}
2N/A
2N/A/*
2N/A * This controls what type of RPC errors are sent to syslog().
2N/A * It is used as a bitmask against the clnt_stat list, which defines
2N/A * 0 as RPC_SUCCESS, so likely shouldn't be set.
2N/A *
2N/A * The #define below provides a default of all errors in the list.
2N/A * The default can then be modified to reduce the amount of traffic
2N/A * going to syslog in the event of RPC errors.
2N/A */
2N/A
2N/A#define DEFAULT_ERRMASK (UINT_MAX & ~(1 << RPC_SUCCESS))
2N/A
2N/Auint_t
2N/Ameta_rpc_err_mask(void)
2N/A{
2N/A char *param_valuep;
2N/A uint_t retval = DEFAULT_ERRMASK;
2N/A
2N/A param_valuep = meta_get_rt_param("commd_RPC_errors", B_FALSE);
2N/A if (param_valuep != NULL) {
2N/A retval = (uint_t)strtol(param_valuep, NULL, 16);
2N/A free(param_valuep);
2N/A }
2N/A return (retval);
2N/A}
2N/A
2N/A/*
2N/A * The "disk_devid_check" parameter controls how disks are identified
2N/A * between the nodes when added to a disk set.
2N/A *
2N/A * By default "disk_devid_check=on" (or not set) a corresponding disk is
2N/A * located on the remote node by searching for the local disks device id.
2N/A * If no device id is available we fall back to using either the EFI device
2N/A * id or the dev_t and device time stamp for VTOC disks.
2N/A *
2N/A * When "disk_devid_check" is defined and not set to "on" only the fall back
2N/A * method is used. For this method to work device names must be constant
2N/A * between all nodes.
2N/A */
2N/Aboolean_t
2N/Adisk_do_devid_check(void)
2N/A{
2N/A char *param_valuep;
2N/A boolean_t return_value = B_TRUE; /* default behavior */
2N/A
2N/A param_valuep = meta_get_rt_param("disk_devid_check", B_FALSE);
2N/A if (param_valuep != NULL) {
2N/A if (strcmp(param_valuep, "on") != 0) {
2N/A return_value = B_FALSE;
2N/A }
2N/A }
2N/A return (return_value);
2N/A}
2N/A
2N/A/*
2N/A * The following lines define private functions
2N/A */
2N/A
2N/Astatic char *
2N/Ameta_get_rt_param(const char *param_namep, boolean_t warn_if_not_found)
2N/A{
2N/A const char *function_namep = "meta_get_rt_param()";
2N/A char *line_bufferp = NULL;
2N/A char *newlinep = NULL;
2N/A FILE *param_filep = NULL;
2N/A char *param_name_tokenp = NULL;
2N/A char *param_valuep = NULL;
2N/A char *param_value_tokenp = NULL;
2N/A
2N/A line_bufferp = (char *)malloc(line_buffer_size);
2N/A if (line_bufferp == NULL) {
2N/A (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
2N/A "%s: malloc failed\n"), function_namep);
2N/A syslog(LOG_ERR, dgettext(TEXT_DOMAIN, "%s: malloc failed\n"),
2N/A function_namep);
2N/A return (param_valuep);
2N/A }
2N/A param_filep = fopen(param_file_namep, "r");
2N/A if (param_filep == NULL) {
2N/A (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
2N/A "%s: can't open %s\n"), function_namep, param_file_namep);
2N/A syslog(LOG_ERR, dgettext(TEXT_DOMAIN, "%s: can't open %s\n"),
2N/A function_namep, param_file_namep);
2N/A free(line_bufferp);
2N/A return (param_valuep);
2N/A }
2N/A while ((fgets(line_bufferp, line_buffer_size, param_filep) != NULL) &&
2N/A (param_valuep == NULL)) {
2N/A
2N/A newlinep = strchr(line_bufferp, '\n');
2N/A if (newlinep != NULL) {
2N/A *newlinep = '\0';
2N/A newlinep = NULL;
2N/A }
2N/A param_name_tokenp = strtok(line_bufferp, token_separator_listp);
2N/A if ((param_name_tokenp != NULL) &&
2N/A (strcmp(param_namep, param_name_tokenp) == 0)) {
2N/A
2N/A param_value_tokenp = strtok(NULL,
2N/A token_separator_listp);
2N/A }
2N/A if (param_value_tokenp != NULL) {
2N/A param_valuep = strdup(param_value_tokenp);
2N/A if (param_valuep == NULL) {
2N/A (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
2N/A "%s: strdup failed\n"),
2N/A function_namep);
2N/A syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
2N/A "%s: strdup failed\n"),
2N/A function_namep);
2N/A free(line_bufferp);
2N/A (void) fclose(param_filep);
2N/A return (param_valuep);
2N/A }
2N/A }
2N/A }
2N/A if ((param_valuep == NULL) && (warn_if_not_found == B_TRUE)) {
2N/A (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
2N/A "%s: value of %s not set or error in %s\n"),
2N/A function_namep, param_namep, param_file_namep);
2N/A syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
2N/A "%s: value of %s not set or error in %s\n"),
2N/A function_namep, param_namep, param_file_namep);
2N/A }
2N/A free(line_bufferp);
2N/A (void) fclose(param_filep);
2N/A return (param_valuep);
2N/A}