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) 2002, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A/* specify which disk links to use in the /dev directory */ 2N/A * The functions in this file do a dev tree walk to build up a model of the 2N/A * disks, controllers and paths on the system. This model is returned in the 2N/A * args->disk_listp and args->controller_listp members of the args param. 2N/A * There is no global data for this file so it is thread safe. It is up to 2N/A * the caller to merge the resulting model with any existing model that is 2N/A * cached. The caller must also free the memory for this model when it is 2N/A * Have to make several passes at this with the new devfs caching. 2N/A * devices. Finally, we get cluster devices. 2N/A /* do another pass to clean up cluster devpaths */ 2N/A * Definitions of private functions 2N/A /* Special handling for root node. */ 2N/A /* if parent node is a bus, get its name */ 2N/A /* This is all just debugging code */ 2N/A * Fix the devpaths for the cluster drive. 2N/A * We will come through here once for each raw slice device name. 2N/A /* Walk the /dev tree to get the cluster devlinks. */ 2N/A /* Special handling for fp attachment node. */ 2N/A /* not in the list, create it */ 2N/A * Get the diskp value from calling have_disk. Can either be found 2N/A * by kernel name or devid. 2N/A * On Intel we would also get each fdisk partition as well 2N/A * Add other controllers for multipath disks. 2N/A * This will have no effect if the controller 2N/A * relationship is already set up. 2N/A * It is possible that we have already added this 2N/A * devpath. Do not add it again. new_devpath will 2N/A * return a 0 if found, and not add the path. 2N/A /* This is all just debugging code */ 2N/A "INFO: dev: %s, node: %s%d, minor: 0x%x, type: %s\n",
2N/A * Check if we already got this disk and 2N/A * this is another slice. 2N/A * This is a newly found disk, create the 2N/A /* add the controller relationship */ 2N/A * It is possible that we have already added 2N/A * Do not add it again. new_devpath will 2N/A * return a 0 if found, and not add the path. 2N/A /* Add the devpaths for the drive. */ 2N/A * We will come through here once for each of 2N/A * the raw slice device names. 2N/A /* Walk the /dev tree to get the devlinks. */ 2N/A /* check if the disk <-> ctrl assoc is already there */ 2N/A /* this is a new controller for this disk */ 2N/A /* add the disk to the controlller */ 2N/A /* add the controlller to the disk */ 2N/A * Set up paths for mpxio controlled drives. 2N/A /* note: mpxio di_path stuff is all consolidation private */ 2N/A /* get the node wwn */ 2N/A * A byte is only 2 hex chars + null. 2N/A /* add the disk to the path */ 2N/A /* add the path to the disk */ 2N/A /* add the path state for this disk */ 2N/A /* add the path state for this disk */ 2N/A /* copy the existing array */ 2N/A /* copy the existing array */ 2N/A * If we have a controller in the list that is really a path then we need to 2N/A * take that controller out of the list since nodes that are paths are not 2N/A * considered to be controllers. 2N/A * DVD, CD-ROM, CD-RW, MO, etc. are all reported as CD-ROMS. 2N/A * We try to use uscsi later to determine the real type. 2N/A * The cd_rom flag tells us that the kernel categorized the drive 2N/A * as a CD-ROM. We leave the drv_type as UKNOWN for now. 2N/A * The combination of the cd_rom flag being set with the drv_type of 2N/A * unknown is what triggers the uscsi probe in drive.c. 2N/A /* not a "CD-ROM" or Floppy */ 2N/A * x86 does not have removable property. 2N/A * Check for common removable drives, zip & jaz, 2N/A * and mark those correctly. 2N/A * For removable jaz or zip drives there is no way 2N/A * to get the drive type unless media is inserted,so 2N/A * we look at the product-id for a hint. 2N/A /* IDE disks use SCSI nexus as the type, so handle this special case */ 2N/A /* Find the disk by the deviceid we read from the cluster disk. */ 2N/A * This really shouldn't happen, since 2N/A * we should have found all of the disks 2N/A * during our first pass through 2N/A * the dev tree, but just in case... 2N/A "INFO: cluster create" 2N/A /* add the controller relationship */ 2N/A * NOTE: if ap->next != NULL have cluster 2N/A * disks w/ multiple paths. 2N/A * update the alias_did info with the new alias name. 2N/A /* get the new cluster alias name */ 2N/A * Check if we have the drive in our list, based upon the device id. 2N/A * We got the device id from the dev tree walk. This is encoded 2N/A * using devid_str_encode(3DEVID). In order to check the device ids we need 2N/A * to use the devid_compare(3DEVID) function, so we need to decode the 2N/A * string representation of the device id. 2N/A * Get the base disk name with no path prefix and no slice (if there is one). 2N/A * The name parameter should be big enough to hold the name. 2N/A * and converts the raw diskette name. 2N/A * But, we don't know how to strip off the slice from third party drive 2N/A * names. That just means that their drive name will include a slice on 2N/A * a floppy, convert rdiskette name to diskette name, 2N/A * by skipping over the 'r' for raw diskette 2N/A /* not a ctds name, just copy it */ 2N/A char bstr[
8];
/* a byte is only 2 hex chars + null */ 2N/A * Get one of the positive int or boolean properties. 2N/A * If we find a string, we return it here. If we get more than one 2N/A * string, then we're returning a pointer to the whole buffer, even 2N/A * though the caller will only 'see' the first string. This is OK 2N/A * though, because we only care about the first one. 2N/A * Check if we have the drive in our list, based upon the device id, if the 2N/A * drive has a device id, or the kernel name, if it doesn't have a device id. 2N/A /* no devid, try matching the kernel names on the drives */ 2N/A * If the input name is in c[t]ds format then return 1, otherwise return 0. 2N/A /* skip controller digits */ 2N/A /* handle optional target */ 2N/A /* skip over target */ 2N/A /* check the slice number */ 2N/A * Append the new devpath to the end of the devpath list. This is important 2N/A * since we may want to use the order of the devpaths to match up the vtoc 2N/A * First, search the alias list to be sure that this devpath is 2N/A * not already there. 2N/A * Otherwise, not found so add this new devpath to the list. 2N/A /* append the devpath to the end of the list */ 2N/A /* Special handling for fp attachment node. */ 2N/A /* check if the path is already there */ 2N/A /* the path exists, add this disk to it */ 2N/A /* create a new path */ 2N/A /* add the disk to the path */ 2N/A /* add the path to the controller */ 2N/A /* add the controller to the path */ 2N/A * remove pointer to invalid controller. 2N/A * We pass in the current controller pointer (currp) so we can double check 2N/A * that we aren't corrupting the list by removing the element we are on. This 2N/A * should never happen, but it doesn't hurt to double check. 2N/A * loop through the disks and remove the reference to the 2N/A * controller for this disk structure. The disk itself 2N/A * is still a valid device, the controller being removed 2N/A * is a 'path' so any disk that has a reference to it 2N/A * as a controller needs to have this reference removed. 2N/A * loop through the controllers and remove the controller itself. 2N/A * The controller being removed is a 'path'. 2N/A "ERROR: Removing current " 2N/A "controller %s from list\n",
2N/A "INFO: Removed controller %s from list\n",
2N/A * This is the standard strstr code modified for case independence. 2N/A /* If the length of the second string is 0, return the first arg. */