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 #include <fcntl.h> 30 #include <libdevinfo.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <sys/dkio.h> 34 #include <sys/sunddi.h> 35 #include <sys/types.h> 36 #include <unistd.h> 37 38 #include "libdiskmgt.h" 39 #include "disks_private.h" 40 41 static int get_status(disk_t *diskp, int fd, nvlist_t *attrs); 42 43 descriptor_t ** 44 alias_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type, 45 int *errp) 46 { 47 switch (type) { 48 case DM_DRIVE: 49 return (drive_get_assocs(desc, errp)); 50 } 51 52 *errp = EINVAL; 53 return (NULL); 54 } 55 56 nvlist_t * 57 alias_get_attributes(descriptor_t *dp, int *errp) 58 { 59 alias_t *ap; 60 nvlist_t *attrs = NULL; 61 62 /* Find the alias for this descriptor */ 63 64 *errp = ENODEV; 65 for (ap = dp->p.disk->aliases; ap != NULL; ap = ap->next) { 66 if (libdiskmgt_str_eq(dp->name, ap->alias)) { 67 /* we found the alias for this descriptor */ 68 69 if (nvlist_alloc(&attrs, NVATTRS, 0) != 0) { 70 *errp = ENOMEM; 71 return (NULL); 72 } 73 74 if (ap->target >= 0) { 75 if (nvlist_add_uint32(attrs, DM_LUN, ap->lun) != 0) { 76 nvlist_free(attrs); 77 *errp = ENOMEM; 78 return (NULL); 79 } 80 81 if (nvlist_add_uint32(attrs, DM_TARGET, ap->target) != 0) { 82 nvlist_free(attrs); 83 *errp = ENOMEM; 84 return (NULL); 85 } 86 } 87 88 if (ap->wwn != NULL) { 89 if (nvlist_add_string(attrs, DM_WWN, ap->wwn) != 0) { 90 nvlist_free(attrs); 91 *errp = ENOMEM; 92 return (NULL); 93 } 94 } 95 96 if (ap->devpaths != NULL) { 97 /* get the status for this alias */ 98 int fd; 99 100 fd = open(ap->devpaths->devpath, O_RDONLY|O_NDELAY); 101 102 if ((*errp = get_status(dp->p.disk, fd, attrs)) != 0) { 103 nvlist_free(attrs); 104 attrs = NULL; 105 } 106 107 if (fd >= 0) { 108 (void) close(fd); 109 } 110 } 111 112 *errp = 0; 113 break; 114 } 115 } 116 117 return (attrs); 118 } 119 120 descriptor_t * 121 alias_get_descriptor_by_name(char *name, int *errp) 122 { 123 descriptor_t **aliases; 124 int i; 125 descriptor_t *alias = NULL; 126 127 aliases = cache_get_descriptors(DM_ALIAS, errp); 128 if (*errp != 0) { 129 return (NULL); 130 } 131 132 for (i = 0; aliases[i]; i++) { 133 if (libdiskmgt_str_eq(name, aliases[i]->name)) { 134 alias = aliases[i]; 135 } else { 136 /* clean up the unused descriptors */ 137 cache_free_descriptor(aliases[i]); 138 } 139 } 140 free(aliases); 141 142 if (alias == NULL) { 143 *errp = ENODEV; 144 } 145 146 return (alias); 147 } 148 149 /* ARGSUSED */ 150 descriptor_t ** 151 alias_get_descriptors(int filter[], int *errp) 152 { 153 return (cache_get_descriptors(DM_ALIAS, errp)); 154 } 155 156 char * 157 alias_get_name(descriptor_t *desc) 158 { 159 return (desc->name); 160 } 161 162 /* ARGSUSED */ 163 nvlist_t * 164 alias_get_stats(descriptor_t *dp, int stat_type, int *errp) 165 { 166 /* There are no stat types defined for aliases */ 167 *errp = EINVAL; 168 return (NULL); 169 } 170 171 int 172 alias_make_descriptors() 173 { 174 int error; 175 disk_t *dp; 176 177 dp = cache_get_disklist(); 178 while (dp != NULL) { 179 alias_t *ap; 180 181 ap = dp->aliases; 182 while (ap != NULL) { 183 if (ap->alias != NULL) { 184 cache_load_desc(DM_ALIAS, dp, ap->alias, NULL, &error); 185 if (error != 0) { 186 return (error); 187 } 188 } 189 ap = ap->next; 190 } 191 dp = dp->next; 192 } 193 194 return (0); 195 } 196 197 static int 198 get_status(disk_t *diskp, int fd, nvlist_t *attrs) 199 { 200 struct dk_minfo minfo; 201 202 /* Make sure media is inserted and spun up. */ 203 if (fd >= 0 && media_read_info(fd, &minfo)) { 204 205 if (nvlist_add_uint32(attrs, DM_STATUS, DM_DISK_UP) != 0) { 206 return (ENOMEM); 207 } 208 209 } else { 210 /* Not ready, so either no media or dead. */ 211 212 if (diskp->removable) { 213 /* This is a removable drive with no media. */ 214 if (nvlist_add_uint32(attrs, DM_STATUS, DM_DISK_UP) != 0) { 215 return (ENOMEM); 216 } 217 } else { 218 /* not removable, so must be dead */ 219 if (nvlist_add_uint32(attrs, DM_STATUS, DM_DISK_DOWN) != 0) { 220 return (ENOMEM); 221 } 222 } 223 } 224 225 return (0); 226 } 227