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 **
alias_get_assoc_descriptors(descriptor_t * desc,dm_desc_type_t type,int * errp)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 *
alias_get_attributes(descriptor_t * dp,int * errp)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 *
alias_get_descriptor_by_name(char * name,int * errp)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 **
alias_get_descriptors(int filter[],int * errp)149 alias_get_descriptors(int filter[], int *errp)
150 {
151 return (cache_get_descriptors(DM_ALIAS, errp));
152 }
153
154 char *
alias_get_name(descriptor_t * desc)155 alias_get_name(descriptor_t *desc)
156 {
157 return (desc->name);
158 }
159
160 /* ARGSUSED */
161 nvlist_t *
alias_get_stats(descriptor_t * dp,int stat_type,int * errp)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
alias_make_descriptors()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
get_status(disk_t * diskp,int fd,nvlist_t * attrs)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