4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <libdevinfo.h>
31 #include <sys/sunddi.h>
32 #include <sys/types.h>
34 #include "libdiskmgt.h"
35 #include "disks_private.h"
37 static int add_path_state(descriptor_t
*dp
, nvlist_t
*attrs
);
38 static int add_wwn(descriptor_t
*dp
, nvlist_t
*attrs
);
39 static descriptor_t
**get_assoc_drives(descriptor_t
*desc
, int *errp
);
40 static descriptor_t
**get_assoc_controllers(descriptor_t
*desc
, int *errp
);
41 static char *path_state_name(di_path_state_t st
);
44 path_get_assoc_descriptors(descriptor_t
*desc
, dm_desc_type_t type
, int *errp
)
48 return (get_assoc_drives(desc
, errp
));
50 return (get_assoc_controllers(desc
, errp
));
58 path_get_attributes(descriptor_t
*dp
, int *errp
)
61 nvlist_t
*attrs
= NULL
;
65 if (nvlist_alloc(&attrs
, NVATTRS
, 0) != 0) {
70 if (nvlist_add_string(attrs
, DM_CTYPE
, pp
->ctype
) != 0) {
77 * We add the path state and wwn attributes only for descriptors that
78 * we got via their association to a specific drive (since these
79 * attributes are drive specific).
81 if (dp
->name
!= NULL
) {
82 if (add_path_state(dp
, attrs
) != 0) {
87 if (add_wwn(dp
, attrs
) != 0) {
99 path_get_descriptor_by_name(char *name
, int *errp
)
101 descriptor_t
**paths
;
103 descriptor_t
*path
= NULL
;
105 paths
= cache_get_descriptors(DM_PATH
, errp
);
110 for (i
= 0; paths
[i
]; i
++) {
111 if (libdiskmgt_str_eq(name
, paths
[i
]->p
.path
->name
)) {
114 /* clean up the unused descriptors */
115 cache_free_descriptor(paths
[i
]);
129 path_get_descriptors(int filter
[], int *errp
)
131 return (cache_get_descriptors(DM_PATH
, errp
));
135 path_get_name(descriptor_t
*desc
)
137 return (desc
->p
.path
->name
);
142 path_get_stats(descriptor_t
*dp
, int stat_type
, int *errp
)
144 /* There are no stat types defined for paths */
150 path_make_descriptors()
155 cp
= cache_get_controllerlist();
157 if (cp
->paths
!= NULL
) {
160 for (i
= 0; cp
->paths
[i
]; i
++) {
161 cache_load_desc(DM_PATH
, cp
->paths
[i
], NULL
, NULL
, &error
);
174 * This is called when we have a name in the descriptor name field. That
175 * only will be the case when the descriptor was created by getting the
176 * association from a drive to the path. Since we filled in the name with
177 * the drive device id in that case, we can use the device id to look up the
181 add_path_state(descriptor_t
*dp
, nvlist_t
*attrs
)
188 if (devid_str_decode(dp
->name
, &devid
, NULL
) != 0) {
192 /* find the index of the correct drive assoc. */
194 for (i
= 0; pp
->disks
[i
] && pp
->states
[i
] != -1; i
++) {
195 if (pp
->disks
[i
]->devid
!= NULL
&&
196 devid_compare(pp
->disks
[i
]->devid
, devid
) == 0) {
198 /* add the corresponding state */
199 if (nvlist_add_string(attrs
, DM_PATH_STATE
,
200 path_state_name(pp
->states
[i
])) != 0) {
212 * This is called when we have a name in the descriptor name field. That
213 * only will be the case when the descriptor was created by getting the
214 * association from a drive to the path. Since we filled in the name with
215 * the drive device id in that case, we can use the device id to look up the
219 add_wwn(descriptor_t
*dp
, nvlist_t
*attrs
)
226 if (devid_str_decode(dp
->name
, &devid
, NULL
) != 0) {
230 /* find the index of the correct drive assoc. */
232 for (i
= 0; pp
->disks
[i
] && pp
->states
[i
] != -1; i
++) {
233 if (pp
->disks
[i
]->devid
!= NULL
&&
234 devid_compare(pp
->disks
[i
]->devid
, devid
) == 0) {
236 /* add the corresponding state */
237 if (nvlist_add_string(attrs
, DM_WWN
, pp
->wwns
[i
]) != 0) {
248 static descriptor_t
**
249 get_assoc_controllers(descriptor_t
*desc
, int *errp
)
252 descriptor_t
**controllers
;
257 /* a path can have just one controller */
259 controllers
= (descriptor_t
**)calloc(2, sizeof (descriptor_t
*));
260 if (controllers
== NULL
) {
266 if (pp
->controller
!= NULL
) {
267 controllers
[i
++] = cache_get_desc(DM_CONTROLLER
,
268 pp
->controller
, NULL
, NULL
, errp
);
270 cache_free_descriptors(controllers
);
275 controllers
[i
] = NULL
;
278 return (controllers
);
281 static descriptor_t
**
282 get_assoc_drives(descriptor_t
*desc
, int *errp
)
285 descriptor_t
**drives
;
291 /* Count how many we have. */
292 for (cnt
= 0; pp
->disks
[cnt
]; cnt
++);
294 /* make the snapshot */
295 drives
= (descriptor_t
**)calloc(cnt
+ 1, sizeof (descriptor_t
*));
296 if (drives
== NULL
) {
301 for (i
= 0; pp
->disks
[i
]; i
++) {
302 drives
[i
] = cache_get_desc(DM_DRIVE
, pp
->disks
[i
], NULL
, NULL
,
305 cache_free_descriptors(drives
);
316 path_state_name(di_path_state_t st
)
319 case DI_PATH_STATE_ONLINE
:
321 case DI_PATH_STATE_STANDBY
:
323 case DI_PATH_STATE_OFFLINE
:
325 case DI_PATH_STATE_FAULT
: