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