1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 30*7c478bd9Sstevel@tonic-gate #include <libdevinfo.h> 31*7c478bd9Sstevel@tonic-gate #include <stdio.h> 32*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/dkio.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 36*7c478bd9Sstevel@tonic-gate #include <unistd.h> 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #include "libdiskmgt.h" 39*7c478bd9Sstevel@tonic-gate #include "disks_private.h" 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate static int get_status(disk_t *diskp, int fd, nvlist_t *attrs); 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate descriptor_t ** 44*7c478bd9Sstevel@tonic-gate alias_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type, 45*7c478bd9Sstevel@tonic-gate int *errp) 46*7c478bd9Sstevel@tonic-gate { 47*7c478bd9Sstevel@tonic-gate switch (type) { 48*7c478bd9Sstevel@tonic-gate case DM_DRIVE: 49*7c478bd9Sstevel@tonic-gate return (drive_get_assocs(desc, errp)); 50*7c478bd9Sstevel@tonic-gate } 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate *errp = EINVAL; 53*7c478bd9Sstevel@tonic-gate return (NULL); 54*7c478bd9Sstevel@tonic-gate } 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate nvlist_t * 57*7c478bd9Sstevel@tonic-gate alias_get_attributes(descriptor_t *dp, int *errp) 58*7c478bd9Sstevel@tonic-gate { 59*7c478bd9Sstevel@tonic-gate alias_t *ap; 60*7c478bd9Sstevel@tonic-gate nvlist_t *attrs = NULL; 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate /* Find the alias for this descriptor */ 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 65*7c478bd9Sstevel@tonic-gate for (ap = dp->p.disk->aliases; ap != NULL; ap = ap->next) { 66*7c478bd9Sstevel@tonic-gate if (libdiskmgt_str_eq(dp->name, ap->alias)) { 67*7c478bd9Sstevel@tonic-gate /* we found the alias for this descriptor */ 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate if (nvlist_alloc(&attrs, NVATTRS, 0) != 0) { 70*7c478bd9Sstevel@tonic-gate *errp = ENOMEM; 71*7c478bd9Sstevel@tonic-gate return (NULL); 72*7c478bd9Sstevel@tonic-gate } 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate if (ap->target >= 0) { 75*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_LUN, ap->lun) != 0) { 76*7c478bd9Sstevel@tonic-gate nvlist_free(attrs); 77*7c478bd9Sstevel@tonic-gate *errp = ENOMEM; 78*7c478bd9Sstevel@tonic-gate return (NULL); 79*7c478bd9Sstevel@tonic-gate } 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_TARGET, ap->target) != 0) { 82*7c478bd9Sstevel@tonic-gate nvlist_free(attrs); 83*7c478bd9Sstevel@tonic-gate *errp = ENOMEM; 84*7c478bd9Sstevel@tonic-gate return (NULL); 85*7c478bd9Sstevel@tonic-gate } 86*7c478bd9Sstevel@tonic-gate } 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate if (ap->wwn != NULL) { 89*7c478bd9Sstevel@tonic-gate if (nvlist_add_string(attrs, DM_WWN, ap->wwn) != 0) { 90*7c478bd9Sstevel@tonic-gate nvlist_free(attrs); 91*7c478bd9Sstevel@tonic-gate *errp = ENOMEM; 92*7c478bd9Sstevel@tonic-gate return (NULL); 93*7c478bd9Sstevel@tonic-gate } 94*7c478bd9Sstevel@tonic-gate } 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate if (ap->devpaths != NULL) { 97*7c478bd9Sstevel@tonic-gate /* get the status for this alias */ 98*7c478bd9Sstevel@tonic-gate int fd; 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate fd = open(ap->devpaths->devpath, O_RDONLY|O_NDELAY); 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate if ((*errp = get_status(dp->p.disk, fd, attrs)) != 0) { 103*7c478bd9Sstevel@tonic-gate nvlist_free(attrs); 104*7c478bd9Sstevel@tonic-gate attrs = NULL; 105*7c478bd9Sstevel@tonic-gate } 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate if (fd >= 0) { 108*7c478bd9Sstevel@tonic-gate (void) close(fd); 109*7c478bd9Sstevel@tonic-gate } 110*7c478bd9Sstevel@tonic-gate } 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate *errp = 0; 113*7c478bd9Sstevel@tonic-gate break; 114*7c478bd9Sstevel@tonic-gate } 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate return (attrs); 118*7c478bd9Sstevel@tonic-gate } 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate descriptor_t * 121*7c478bd9Sstevel@tonic-gate alias_get_descriptor_by_name(char *name, int *errp) 122*7c478bd9Sstevel@tonic-gate { 123*7c478bd9Sstevel@tonic-gate descriptor_t **aliases; 124*7c478bd9Sstevel@tonic-gate int i; 125*7c478bd9Sstevel@tonic-gate descriptor_t *alias = NULL; 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate aliases = cache_get_descriptors(DM_ALIAS, errp); 128*7c478bd9Sstevel@tonic-gate if (*errp != 0) { 129*7c478bd9Sstevel@tonic-gate return (NULL); 130*7c478bd9Sstevel@tonic-gate } 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate for (i = 0; aliases[i]; i++) { 133*7c478bd9Sstevel@tonic-gate if (libdiskmgt_str_eq(name, aliases[i]->name)) { 134*7c478bd9Sstevel@tonic-gate alias = aliases[i]; 135*7c478bd9Sstevel@tonic-gate } else { 136*7c478bd9Sstevel@tonic-gate /* clean up the unused descriptors */ 137*7c478bd9Sstevel@tonic-gate cache_free_descriptor(aliases[i]); 138*7c478bd9Sstevel@tonic-gate } 139*7c478bd9Sstevel@tonic-gate } 140*7c478bd9Sstevel@tonic-gate free(aliases); 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate if (alias == NULL) { 143*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 144*7c478bd9Sstevel@tonic-gate } 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate return (alias); 147*7c478bd9Sstevel@tonic-gate } 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 150*7c478bd9Sstevel@tonic-gate descriptor_t ** 151*7c478bd9Sstevel@tonic-gate alias_get_descriptors(int filter[], int *errp) 152*7c478bd9Sstevel@tonic-gate { 153*7c478bd9Sstevel@tonic-gate return (cache_get_descriptors(DM_ALIAS, errp)); 154*7c478bd9Sstevel@tonic-gate } 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate char * 157*7c478bd9Sstevel@tonic-gate alias_get_name(descriptor_t *desc) 158*7c478bd9Sstevel@tonic-gate { 159*7c478bd9Sstevel@tonic-gate return (desc->name); 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 163*7c478bd9Sstevel@tonic-gate nvlist_t * 164*7c478bd9Sstevel@tonic-gate alias_get_stats(descriptor_t *dp, int stat_type, int *errp) 165*7c478bd9Sstevel@tonic-gate { 166*7c478bd9Sstevel@tonic-gate /* There are no stat types defined for aliases */ 167*7c478bd9Sstevel@tonic-gate *errp = EINVAL; 168*7c478bd9Sstevel@tonic-gate return (NULL); 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate int 172*7c478bd9Sstevel@tonic-gate alias_make_descriptors() 173*7c478bd9Sstevel@tonic-gate { 174*7c478bd9Sstevel@tonic-gate int error; 175*7c478bd9Sstevel@tonic-gate disk_t *dp; 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate dp = cache_get_disklist(); 178*7c478bd9Sstevel@tonic-gate while (dp != NULL) { 179*7c478bd9Sstevel@tonic-gate alias_t *ap; 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate ap = dp->aliases; 182*7c478bd9Sstevel@tonic-gate while (ap != NULL) { 183*7c478bd9Sstevel@tonic-gate if (ap->alias != NULL) { 184*7c478bd9Sstevel@tonic-gate cache_load_desc(DM_ALIAS, dp, ap->alias, NULL, &error); 185*7c478bd9Sstevel@tonic-gate if (error != 0) { 186*7c478bd9Sstevel@tonic-gate return (error); 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate ap = ap->next; 190*7c478bd9Sstevel@tonic-gate } 191*7c478bd9Sstevel@tonic-gate dp = dp->next; 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate return (0); 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate static int 198*7c478bd9Sstevel@tonic-gate get_status(disk_t *diskp, int fd, nvlist_t *attrs) 199*7c478bd9Sstevel@tonic-gate { 200*7c478bd9Sstevel@tonic-gate struct dk_minfo minfo; 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate /* Make sure media is inserted and spun up. */ 203*7c478bd9Sstevel@tonic-gate if (fd >= 0 && media_read_info(fd, &minfo)) { 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_STATUS, DM_DISK_UP) != 0) { 206*7c478bd9Sstevel@tonic-gate return (ENOMEM); 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate } else { 210*7c478bd9Sstevel@tonic-gate /* Not ready, so either no media or dead. */ 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate if (diskp->removable) { 213*7c478bd9Sstevel@tonic-gate /* This is a removable drive with no media. */ 214*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_STATUS, DM_DISK_UP) != 0) { 215*7c478bd9Sstevel@tonic-gate return (ENOMEM); 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate } else { 218*7c478bd9Sstevel@tonic-gate /* not removable, so must be dead */ 219*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_STATUS, DM_DISK_DOWN) != 0) { 220*7c478bd9Sstevel@tonic-gate return (ENOMEM); 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate } 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate return (0); 226*7c478bd9Sstevel@tonic-gate } 227