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 * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 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 * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A * Macros to produce a quoted string containing the value of a 2N/A * preprocessor macro. For example, if SIZE is defined to be 256, 2N/A * VAL2STR(SIZE) is "256". This is used to construct format 2N/A * strings for scanf-family functions below. 2N/A/* structure to hold entries with mpxio-disable property in driver.conf file */ 2N/A * Leave NEWLINE as the next character. 2N/A/* ignore parsing errors */ 2N/A/* return the next token from the given driver.conf file, or -1 on error */ 2N/A /* escape the character */ 2N/A /* check for character overflow? */ 2N/A "overflow detected.\n");
2N/A * detect a lone '-' (including at the end of a line), and 2N/A * identify it as a 'name' 2N/A }
else if (
ch ==
'~' ||
ch ==
'-') {
2N/A * if the character was a backslash, 2N/A * back up so we can overwrite it with 2N/A * the next (i.e. escaped) character. 2N/A * Parse the next entry from the driver.conf file and return in the form of 2N/A * a pointer to the conf_entry. 2N/A "'parent' property already specified\n");
2N/A "'name' property already specified\n");
2N/A "'class' property already specified\n");
2N/A "'unit-address' property already specified\n");
2N/A "'mpxio-disable' property already specified\n");
2N/A "'mpxio-disable' property setting is invalid. " 2N/A "The value must be either \"yes\" or \"no\"\n");
2N/A "'port' property already specified\n");
2N/A * Parse all entries with mpxio-disable property in the given driver.conf 2N/A * confent_list on return *confent_list will contain the list of 2N/A * mpxio_disable on return *mpxio_disable is set to the setting of the 2N/A * driver global mpxio-dissable property as follows. 2N/A * 0 if driver mpxio-disable="no" 2N/A * 1 if driver mpxio-disable="yes" 2N/A * -1 if driver mpxio-disable property isn't specified. 2N/A * No name indicates global property. 2N/A * Make sure parent and class not NULL. 2N/A "missing name attribute\n");
2N/A "'mpxio-disable' property already specified\n");
2N/A * This is a node spec, either parent or class 2N/A * must be specified. 2N/A "missing parent or class attribute\n");
2N/A /* only need entries with mpxio_disable property */ 2N/A * Return the driver class of the given driver_name. 2N/A * The memory for the driver class is allocated by this function and the 2N/A * caller must free it. 2N/A logdmsg((
"get_driver_class: rootdir = %s, driver name = %s\n",
2N/A logdmsg((
"get_driver_class: failed to open %s: %s\n",
2N/A /* LINTED - unbounded string specifier */ 2N/A logdmsg((
"lookup_in_confent_list: %s = \"%s\", unit_addr = \"%s\", " 2N/A * lookup mpxio-disabled property setting for the given path in the given 2N/A * driver.conf file. Match the entries from most specific to least specific. 2N/A * path /devices node path without the /devices prefix. 2N/A * If the conf_file is fp.conf, path must be a fp node path 2N/A * if the conf_file is qlc.conf, path must be a qlc node path. 2N/A * ex: /pci@8,600000/SUNW,qlc@4/fp@0,0 2N/A * /pci@8,600000/SUNW,qlc@4 2N/A * 0 if mpxio-disable="no" 2N/A * 1 if mpxio-disable="yes" 2N/A * -1 if mpxio-disable property isn't specified. 2N/A logdmsg((
"lookup_in_conf_file: rootdir = \"%s\", conf_file = \"%s\", " 2N/A /* if path is NULL, return driver global mpxio-disable setting */ 2N/A /* get port number; encoded in the node addr as a hex number */ 2N/A * Match from most specific to least specific; 2N/A * first, start the lookup based on full path. 2N/A /* lookup nodename@address */ 2N/A /* di_init() doesn't work when 0 is passed in flags */ 2N/A /* lookup bindingname@address */ 2N/A /* lookup binding name */ 2N/A /* lookup driver name */ 2N/A /* finally, lookup class name */ 2N/A * use the driver global mpxio-disable setting if exists. 2N/A * Given client_name return whether it is a phci or vhci based name. 2N/A * client_name is /devices name of a client without the /devices prefix. 2N/A * client_name Return value 2N/A * other CLIENT_TYPE_UNKNOWN 2N/A * Compare controller name portion of dev1 and dev2. 2N/A * rootdir root directory of the target environment 2N/A * dev1 can be either a /dev link or /devices name in the target 2N/A * dev2 /devices name of a device without the /devices prefix 2N/A * 0 if controller names match 2N/A * 1 if controller names don't match 2N/A * -1 an error occurred. 2N/A logdmsg((
"compare_controller: rootdir = %s, dev1 = %s, dev2 = %s\n",
2N/A /* strip the device portion */ 2N/A logdmsg((
"compare_controller: path1 = %s, path2 = %s\n",
2N/A * Check if the specified device path is on the root controller. 2N/A * rootdir root directory of the target environment 2N/A * path /devices name of a device without the /devices prefix 2N/A * 1 if the path is on the root controller 2N/A * 0 if the path is not on the root controller 2N/A * -1 if an error occurs 2N/A logdmsg((
"is_root_controller: failed to open %s: %s\n",
2N/A logdmsg((
"is_root_controller: getvfsfile: failed to read " 2N/A "vfstab entry for mount point \"/\": %s\n",
2N/A /* check if the root is an svm metadisk */ 2N/A logdmsg((
"is_root_controller: tempnam: failed: %s\n",
2N/A /* get metadisk components using metastat command */ 2N/A * Check if mpxio is enabled or disabled on the specified device path. 2N/A * Looks through the .conf files to determine the mpxio setting. 2N/A * rootdir root directory of the target environment 2N/A * path /devices name of a device without the /devices prefix and 2N/A * minor name component. 2N/A * 1 if mpxio is disabled 2N/A * 0 if mpxio is enabled 2N/A * -1 if an error occurs 2N/A logdmsg((
"is_mpxio_disabled: rootdir = %s, path = %s\n",
2N/A * if upgrading from a pre solaris 9 release. or 2N/A * if this function is called during fresh or flash install 2N/A /* upgrading from pre solaris 9 */ 2N/A /* fresh or flash install */ 2N/A * s8+sfkpatch. This property is no longer present from s10 onwards. 2N/A /* upgrading from s8 or s9 with mpxio globally disabled */ 2N/A /* upgrading from s8 or s9 with mpxio globally enabled */ 2N/A * We are looking at the s10 version of the file. This is 2N/A * the case if this function is called after installing the 2N/A * mpxio-disable setting is not found in the .conf files. 2N/A * The default is to enable mpxio, except if the path is on the root 2N/A * In s8 and s9 mpxio is not supported on the root controller. 2N/A * NWS supplies a patch to enable root controller support in s8 and s9. 2N/A * If the system had the patch installed, the fp.conf file would have 2N/A * explicit "mpxio-disable=no" for the root controller. So we would 2N/A * have found the mpxio-disable setting when we looked up this property 2N/A logdmsg((
"is_mpxio_disabled: is_root_controller returned %d\n",
2N/A * Convert a phci client name to vhci client name. 2N/A * phci_name phci client /devices name without the /devices prefix and 2N/A * minor name component. 2N/A * ex: /pci@8,600000/SUNW,qlc@4/fp@0,0/ssd@w2100002037cd9f72,0 2N/A * Returns on success, vhci client name is returned. The memory for 2N/A * the vhci name is allocated by this function and the caller 2N/A * on failure, NULL is returned. 2N/A * Convert a vhci client name to phci client names. 2N/A * vhci_name vhci client /devices name without the /devices prefix and 2N/A * minor name component. 2N/A * num_paths On return, *num_paths is set to the number paths in the 2N/A * returned path list. 2N/A * Returns NULL terminated path list containing phci client paths is 2N/A * returned on success. The memory for the path list is 2N/A * allocated by this function and the caller must free it by 2N/A * calling free_pathlist(). 2N/A * NULL is returned on failure. 2N/A /* first get the number paths */ 2N/A logdmsg((
"vhci_to_phci: vhci_ctl failed to get npaths: %s\n",
2N/A /* now allocate memory for the path information and get all paths */ 2N/A /* allocate one more (than npaths) for the terminating NULL pointer */ 2N/A * add only online paths as non-online paths may not be accessible 2N/A * in the target environment. 2N/A * build list of paths accessible from the target environment 2N/A * mpxio is enabled on this phci path. 2N/A * So use vhci path instead of phci path. 2N/A /* keep vhci path at beginning of the list */ 2N/A for (j = i; j > 0; j--)
2N/A /* compensate for i++ in the for loop */ 2N/A * Check if the specified device is refenced in the vfstab file. 2N/A * Return 1 if referenced, 0 if not. 2N/A * rootdir root directory of the target environment 2N/A * nodepath /devices path of a device in the target environment without 2N/A * the /devices prefix and minor component. 2N/A logdmsg((
"is_dev_in_vfstab: rootdir = %s, nodepath = %s\n",
2N/A * read device specials from vfstab and compare names at physical 2N/A /* point to / after /devices */ 2N/A /* strip minor component */ 2N/A * Get the /dev name in the install environment corresponding to physpath. 2N/A * physpath /devices path in the install environment without the /devices 2N/A * buf caller supplied buffer where the /dev name is placed on return 2N/A * bufsz length of the buffer 2N/A * Returns strlen of the /dev name on success, -1 on failure. 2N/A int sleeptime =
2;
/* number of seconds to sleep between retries */ 2N/A * devlink_db sync happens after MINOR_FINI_TIMEOUT_DEFAULT secs 2N/A * after dev link creation. So wait for minimum that amout of time. 2N/A logdmsg((
"get_install_devlink: di_devlink_init() failed: %s\n",
2N/A logdmsg((
"get_install_devlink: di_devlink_walk failed: %s\n",
2N/A * Get the /dev name in the target environment corresponding to physpath. 2N/A * rootdir root directory of the target environment 2N/A * physpath /devices path in the target environment without the /devices 2N/A * buf caller supplied buffer where the /dev name is placed on return 2N/A * bufsz length of the buffer 2N/A * Returns strlen of the /dev name on success, -1 on failure. 2N/A logdmsg((
"get_target_devlink: rootdir = %s, physpath = %s\n",
2N/A * Convert device name to physpath. 2N/A * rootdir root directory 2N/A * devname a /dev name or /devices name under rootdir 2N/A * physpath caller supplied buffer where the /devices path will be placed 2N/A * on return (without the /devices prefix). 2N/A * physpathlen length of the physpath buffer 2N/A * Returns 0 on success, -1 on failure. 2N/A logdmsg((
"devname2physpath: rootdir = %s, devname = %s\n",
2N/A * Map a device name (devname) from the target environment to the 2N/A * install environment. 2N/A * rootdir root directory of the target environment 2N/A * devname /dev or /devices name under the target environment 2N/A * buf caller supplied buffer where the mapped /dev name is placed 2N/A * bufsz length of the buffer 2N/A * Returns strlen of the mapped /dev name on success, -1 on failure. 2N/A logdmsg((
"devfs_target2install: rootdir = %s, devname = %s\n",
2N/A /* strip minor component if present */ 2N/A logdmsg((
"devfs_target2install: mapped physpath: %s\n",
2N/A * Map a device name (devname) from the install environment to the target 2N/A * rootdir root directory of the target environment 2N/A * devname /dev or /devices name under the install environment 2N/A * buf caller supplied buffer where the mapped /dev name is placed 2N/A * bufsz length of the buffer 2N/A * Returns strlen of the mapped /dev name on success, -1 on failure. 2N/A logdmsg((
"devfs_install2target: rootdir = %s, devname = %s\n",
2N/A /* strip minor component if present */ 2N/A * in case of more than one path, try to use the path 2N/A * referenced in the vfstab file, otherwise use the first path. 2N/A * The user-supplied callback is called once for each entry in the file. 2N/A * Callback may return DI_WALK_TERMINATE to terminate the walk, 2N/A * otherwise DI_WALK_CONTINUE. 2N/A * Walk the minor nodes of all children below the specified device 2N/A * by calling the provided callback with the path to each minor. 2N/A * Return the path to each minor node for a device by 2N/A * calling the provided callback. 2N/A * Perform a walk of all minor nodes for the specified device, 2N/A * and minor nodes below the device. 2N/A return (
"not specified");