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 <string.h>
34*7c478bd9Sstevel@tonic-gate #include <strings.h>
35*7c478bd9Sstevel@tonic-gate #include <stropts.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/dkio.h>
37*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
38*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
39*7c478bd9Sstevel@tonic-gate #include <unistd.h>
40*7c478bd9Sstevel@tonic-gate #include <sys/vtoc.h>
41*7c478bd9Sstevel@tonic-gate #include <volmgt.h>
42*7c478bd9Sstevel@tonic-gate #include <sys/efi_partition.h>
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate #include "libdiskmgt.h"
45*7c478bd9Sstevel@tonic-gate #include "disks_private.h"
46*7c478bd9Sstevel@tonic-gate #include "partition.h"
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate #define	IOCTLRETRIES		2
49*7c478bd9Sstevel@tonic-gate #define	IOCTLRETRYINTERVAL	1
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate static descriptor_t	**apply_filter(descriptor_t **media, int filter[],
52*7c478bd9Sstevel@tonic-gate 			    int *errp);
53*7c478bd9Sstevel@tonic-gate static int		get_attrs(disk_t *dp, int fd, nvlist_t *attrs);
54*7c478bd9Sstevel@tonic-gate static int		get_non_volm_name(disk_t *dp, char *mname, int size);
55*7c478bd9Sstevel@tonic-gate static int		get_media_type(uint_t media_type);
56*7c478bd9Sstevel@tonic-gate static int		desc_ok(descriptor_t *dp);
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate /*
59*7c478bd9Sstevel@tonic-gate  * This function gets the descriptors we are associated with.
60*7c478bd9Sstevel@tonic-gate  */
61*7c478bd9Sstevel@tonic-gate descriptor_t **
62*7c478bd9Sstevel@tonic-gate media_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type,
63*7c478bd9Sstevel@tonic-gate     int *errp)
64*7c478bd9Sstevel@tonic-gate {
65*7c478bd9Sstevel@tonic-gate 	if (!desc_ok(desc)) {
66*7c478bd9Sstevel@tonic-gate 	    *errp = ENODEV;
67*7c478bd9Sstevel@tonic-gate 	    return (NULL);
68*7c478bd9Sstevel@tonic-gate 	}
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate 	switch (type) {
71*7c478bd9Sstevel@tonic-gate 	case DM_DRIVE:
72*7c478bd9Sstevel@tonic-gate 	    return (drive_get_assocs(desc, errp));
73*7c478bd9Sstevel@tonic-gate 	case DM_PARTITION:
74*7c478bd9Sstevel@tonic-gate 	    return (partition_get_assocs(desc, errp));
75*7c478bd9Sstevel@tonic-gate 	case DM_SLICE:
76*7c478bd9Sstevel@tonic-gate 	    return (slice_get_assocs(desc, errp));
77*7c478bd9Sstevel@tonic-gate 	}
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate 	*errp = EINVAL;
80*7c478bd9Sstevel@tonic-gate 	return (NULL);
81*7c478bd9Sstevel@tonic-gate }
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate /*
84*7c478bd9Sstevel@tonic-gate  * Get the media descriptors for the given drive/partition/slice.
85*7c478bd9Sstevel@tonic-gate  */
86*7c478bd9Sstevel@tonic-gate descriptor_t **
87*7c478bd9Sstevel@tonic-gate media_get_assocs(descriptor_t *dp, int *errp)
88*7c478bd9Sstevel@tonic-gate {
89*7c478bd9Sstevel@tonic-gate 	descriptor_t	**media;
90*7c478bd9Sstevel@tonic-gate 	char		mname[MAXPATHLEN];
91*7c478bd9Sstevel@tonic-gate 
92*7c478bd9Sstevel@tonic-gate 	if (!media_read_name(dp->p.disk, mname, sizeof (mname))) {
93*7c478bd9Sstevel@tonic-gate 	    /* For drives, this means no media but slice/part. require media. */
94*7c478bd9Sstevel@tonic-gate 	    if (dp->type == DM_DRIVE) {
95*7c478bd9Sstevel@tonic-gate 		return (libdiskmgt_empty_desc_array(errp));
96*7c478bd9Sstevel@tonic-gate 	    } else {
97*7c478bd9Sstevel@tonic-gate 		*errp = ENODEV;
98*7c478bd9Sstevel@tonic-gate 		return (NULL);
99*7c478bd9Sstevel@tonic-gate 	    }
100*7c478bd9Sstevel@tonic-gate 	}
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate 	/* make the snapshot */
103*7c478bd9Sstevel@tonic-gate 	media = (descriptor_t **)calloc(2, sizeof (descriptor_t *));
104*7c478bd9Sstevel@tonic-gate 	if (media == NULL) {
105*7c478bd9Sstevel@tonic-gate 	    *errp = ENOMEM;
106*7c478bd9Sstevel@tonic-gate 	    return (NULL);
107*7c478bd9Sstevel@tonic-gate 	}
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate 	media[0] = cache_get_desc(DM_MEDIA, dp->p.disk, mname, NULL, errp);
110*7c478bd9Sstevel@tonic-gate 	if (*errp != 0) {
111*7c478bd9Sstevel@tonic-gate 	    free(media);
112*7c478bd9Sstevel@tonic-gate 	    return (NULL);
113*7c478bd9Sstevel@tonic-gate 	}
114*7c478bd9Sstevel@tonic-gate 	media[1] = NULL;
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate 	*errp = 0;
117*7c478bd9Sstevel@tonic-gate 	return (media);
118*7c478bd9Sstevel@tonic-gate }
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate nvlist_t *
121*7c478bd9Sstevel@tonic-gate media_get_attributes(descriptor_t *dp, int *errp)
122*7c478bd9Sstevel@tonic-gate {
123*7c478bd9Sstevel@tonic-gate 	nvlist_t	*attrs = NULL;
124*7c478bd9Sstevel@tonic-gate 	int		fd;
125*7c478bd9Sstevel@tonic-gate 
126*7c478bd9Sstevel@tonic-gate 	if (!desc_ok(dp)) {
127*7c478bd9Sstevel@tonic-gate 	    *errp = ENODEV;
128*7c478bd9Sstevel@tonic-gate 	    return (NULL);
129*7c478bd9Sstevel@tonic-gate 	}
130*7c478bd9Sstevel@tonic-gate 
131*7c478bd9Sstevel@tonic-gate 	if (nvlist_alloc(&attrs, NVATTRS, 0) != 0) {
132*7c478bd9Sstevel@tonic-gate 	    *errp = ENOMEM;
133*7c478bd9Sstevel@tonic-gate 	    return (NULL);
134*7c478bd9Sstevel@tonic-gate 	}
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate 	fd = drive_open_disk(dp->p.disk, NULL, 0);
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate 	if ((*errp = get_attrs(dp->p.disk, fd, attrs)) != 0) {
139*7c478bd9Sstevel@tonic-gate 	    nvlist_free(attrs);
140*7c478bd9Sstevel@tonic-gate 	    attrs = NULL;
141*7c478bd9Sstevel@tonic-gate 	}
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate 	if (fd >= 0) {
144*7c478bd9Sstevel@tonic-gate 	    (void) close(fd);
145*7c478bd9Sstevel@tonic-gate 	}
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate 	return (attrs);
148*7c478bd9Sstevel@tonic-gate }
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate descriptor_t *
151*7c478bd9Sstevel@tonic-gate media_get_descriptor_by_name(char *name, int *errp)
152*7c478bd9Sstevel@tonic-gate {
153*7c478bd9Sstevel@tonic-gate 	descriptor_t	**media;
154*7c478bd9Sstevel@tonic-gate 	int		i;
155*7c478bd9Sstevel@tonic-gate 	descriptor_t	*medium = NULL;
156*7c478bd9Sstevel@tonic-gate 
157*7c478bd9Sstevel@tonic-gate 	media = cache_get_descriptors(DM_MEDIA, errp);
158*7c478bd9Sstevel@tonic-gate 	if (*errp != 0) {
159*7c478bd9Sstevel@tonic-gate 	    return (NULL);
160*7c478bd9Sstevel@tonic-gate 	}
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate 	for (i = 0; media[i]; i++) {
163*7c478bd9Sstevel@tonic-gate 	    if (libdiskmgt_str_eq(name, media[i]->name)) {
164*7c478bd9Sstevel@tonic-gate 		medium = media[i];
165*7c478bd9Sstevel@tonic-gate 	    } else {
166*7c478bd9Sstevel@tonic-gate 		/* clean up the unused descriptors */
167*7c478bd9Sstevel@tonic-gate 		cache_free_descriptor(media[i]);
168*7c478bd9Sstevel@tonic-gate 	    }
169*7c478bd9Sstevel@tonic-gate 	}
170*7c478bd9Sstevel@tonic-gate 	free(media);
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate 	if (medium == NULL) {
173*7c478bd9Sstevel@tonic-gate 	    *errp = ENODEV;
174*7c478bd9Sstevel@tonic-gate 	}
175*7c478bd9Sstevel@tonic-gate 
176*7c478bd9Sstevel@tonic-gate 	return (medium);
177*7c478bd9Sstevel@tonic-gate }
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate descriptor_t **
180*7c478bd9Sstevel@tonic-gate media_get_descriptors(int filter[], int *errp)
181*7c478bd9Sstevel@tonic-gate {
182*7c478bd9Sstevel@tonic-gate 	descriptor_t	**media;
183*7c478bd9Sstevel@tonic-gate 
184*7c478bd9Sstevel@tonic-gate 	media = cache_get_descriptors(DM_MEDIA, errp);
185*7c478bd9Sstevel@tonic-gate 	if (*errp != 0) {
186*7c478bd9Sstevel@tonic-gate 	    return (NULL);
187*7c478bd9Sstevel@tonic-gate 	}
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate 	if (filter != NULL && filter[0] != DM_FILTER_END) {
190*7c478bd9Sstevel@tonic-gate 	    descriptor_t	**found;
191*7c478bd9Sstevel@tonic-gate 
192*7c478bd9Sstevel@tonic-gate 	    found = apply_filter(media, filter, errp);
193*7c478bd9Sstevel@tonic-gate 	    if (*errp != 0) {
194*7c478bd9Sstevel@tonic-gate 		media = NULL;
195*7c478bd9Sstevel@tonic-gate 	    } else {
196*7c478bd9Sstevel@tonic-gate 		media = found;
197*7c478bd9Sstevel@tonic-gate 	    }
198*7c478bd9Sstevel@tonic-gate 	}
199*7c478bd9Sstevel@tonic-gate 
200*7c478bd9Sstevel@tonic-gate 	return (media);
201*7c478bd9Sstevel@tonic-gate }
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate char *
204*7c478bd9Sstevel@tonic-gate media_get_name(descriptor_t *desc)
205*7c478bd9Sstevel@tonic-gate {
206*7c478bd9Sstevel@tonic-gate 	return (desc->name);
207*7c478bd9Sstevel@tonic-gate }
208*7c478bd9Sstevel@tonic-gate 
209*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
210*7c478bd9Sstevel@tonic-gate nvlist_t *
211*7c478bd9Sstevel@tonic-gate media_get_stats(descriptor_t *dp, int stat_type, int *errp)
212*7c478bd9Sstevel@tonic-gate {
213*7c478bd9Sstevel@tonic-gate 	/* There are no stat types defined for media */
214*7c478bd9Sstevel@tonic-gate 	*errp = EINVAL;
215*7c478bd9Sstevel@tonic-gate 	return (NULL);
216*7c478bd9Sstevel@tonic-gate }
217*7c478bd9Sstevel@tonic-gate 
218*7c478bd9Sstevel@tonic-gate /*
219*7c478bd9Sstevel@tonic-gate  * Get the removable media volume manager devpath for the disk.  This is the
220*7c478bd9Sstevel@tonic-gate  * name we need to open that will work with vold.
221*7c478bd9Sstevel@tonic-gate  * Return 1 if under volm control, 0 if not under volm control.
222*7c478bd9Sstevel@tonic-gate  * The string in mediapath will be empty if the drive is under volm control
223*7c478bd9Sstevel@tonic-gate  * but there is no media loaded.
224*7c478bd9Sstevel@tonic-gate  */
225*7c478bd9Sstevel@tonic-gate int
226*7c478bd9Sstevel@tonic-gate media_get_volm_path(disk_t *diskp, char *mediapath, int size)
227*7c478bd9Sstevel@tonic-gate {
228*7c478bd9Sstevel@tonic-gate 	char	vname[MAXPATHLEN];
229*7c478bd9Sstevel@tonic-gate 	char	*volname;
230*7c478bd9Sstevel@tonic-gate 	char	*media_name;
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 	if (!diskp->removable || !volmgt_running()) {
233*7c478bd9Sstevel@tonic-gate 	    return (0);
234*7c478bd9Sstevel@tonic-gate 	}
235*7c478bd9Sstevel@tonic-gate 
236*7c478bd9Sstevel@tonic-gate 	/*
237*7c478bd9Sstevel@tonic-gate 	 * The volume manager is running, so we have to check if this removable
238*7c478bd9Sstevel@tonic-gate 	 * drive is under volm control or not.
239*7c478bd9Sstevel@tonic-gate 	 */
240*7c478bd9Sstevel@tonic-gate 
241*7c478bd9Sstevel@tonic-gate 	/*
242*7c478bd9Sstevel@tonic-gate 	 * We must check if this drive is under volume management control and
243*7c478bd9Sstevel@tonic-gate 	 * what devpath to use.
244*7c478bd9Sstevel@tonic-gate 	 * Note that we have to do this every time for drives that are not
245*7c478bd9Sstevel@tonic-gate 	 * under the control of the volume manager, since the volume manager
246*7c478bd9Sstevel@tonic-gate 	 * might have taken control since the last time we checked.
247*7c478bd9Sstevel@tonic-gate 	 */
248*7c478bd9Sstevel@tonic-gate 	if (diskp->volm_path_set == 0) {
249*7c478bd9Sstevel@tonic-gate 	    alias_t	*ap;
250*7c478bd9Sstevel@tonic-gate 	    slice_t	*dp;
251*7c478bd9Sstevel@tonic-gate 
252*7c478bd9Sstevel@tonic-gate 	    if ((ap = diskp->aliases) == NULL) {
253*7c478bd9Sstevel@tonic-gate 		return (0);
254*7c478bd9Sstevel@tonic-gate 	    }
255*7c478bd9Sstevel@tonic-gate 
256*7c478bd9Sstevel@tonic-gate 	    /* Check each devpath to see if it is under volm control. */
257*7c478bd9Sstevel@tonic-gate 	    dp = ap->devpaths;
258*7c478bd9Sstevel@tonic-gate 	    while (dp != NULL) {
259*7c478bd9Sstevel@tonic-gate 		slice_rdsk2dsk(dp->devpath, vname, sizeof (vname));
260*7c478bd9Sstevel@tonic-gate 		if (volmgt_inuse(vname)) {
261*7c478bd9Sstevel@tonic-gate 		    break;
262*7c478bd9Sstevel@tonic-gate 		}
263*7c478bd9Sstevel@tonic-gate 
264*7c478bd9Sstevel@tonic-gate 		dp = dp->next;
265*7c478bd9Sstevel@tonic-gate 	    }
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 	    if (dp != NULL) {
268*7c478bd9Sstevel@tonic-gate 		/* Volume manager is managing the devpath that dp points to. */
269*7c478bd9Sstevel@tonic-gate 		diskp->volm_path = dp->devpath;
270*7c478bd9Sstevel@tonic-gate 		diskp->volm_path_set = 1;
271*7c478bd9Sstevel@tonic-gate 	    }
272*7c478bd9Sstevel@tonic-gate 	}
273*7c478bd9Sstevel@tonic-gate 
274*7c478bd9Sstevel@tonic-gate 	if (diskp->volm_path_set == 0) {
275*7c478bd9Sstevel@tonic-gate 	    /* The volume manager is not managing any of the devpaths. */
276*7c478bd9Sstevel@tonic-gate 	    return (0);
277*7c478bd9Sstevel@tonic-gate 	}
278*7c478bd9Sstevel@tonic-gate 
279*7c478bd9Sstevel@tonic-gate 	if (dm_debug > 1) {
280*7c478bd9Sstevel@tonic-gate 	    (void) fprintf(stderr, "INFO: chk vol: %s\n", diskp->volm_path);
281*7c478bd9Sstevel@tonic-gate 	}
282*7c478bd9Sstevel@tonic-gate 
283*7c478bd9Sstevel@tonic-gate 	slice_rdsk2dsk(diskp->volm_path, vname, sizeof (vname));
284*7c478bd9Sstevel@tonic-gate 	volname = volmgt_symname(vname);
285*7c478bd9Sstevel@tonic-gate 	if (volname == NULL) {
286*7c478bd9Sstevel@tonic-gate 	    mediapath[0] = 0;
287*7c478bd9Sstevel@tonic-gate 	    return (1);
288*7c478bd9Sstevel@tonic-gate 	}
289*7c478bd9Sstevel@tonic-gate 
290*7c478bd9Sstevel@tonic-gate 	media_name = media_findname(volname);
291*7c478bd9Sstevel@tonic-gate 	free(volname);
292*7c478bd9Sstevel@tonic-gate 	if (media_name == NULL) {
293*7c478bd9Sstevel@tonic-gate 	    mediapath[0] = 0;
294*7c478bd9Sstevel@tonic-gate 	    return (1);
295*7c478bd9Sstevel@tonic-gate 	}
296*7c478bd9Sstevel@tonic-gate 
297*7c478bd9Sstevel@tonic-gate 	(void) strlcpy(mediapath, media_name, size);
298*7c478bd9Sstevel@tonic-gate 	free(media_name);
299*7c478bd9Sstevel@tonic-gate 	return (1);
300*7c478bd9Sstevel@tonic-gate }
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate int
303*7c478bd9Sstevel@tonic-gate media_make_descriptors()
304*7c478bd9Sstevel@tonic-gate {
305*7c478bd9Sstevel@tonic-gate 	int		error;
306*7c478bd9Sstevel@tonic-gate 	disk_t		*dp;
307*7c478bd9Sstevel@tonic-gate 	char		mname[MAXPATHLEN];
308*7c478bd9Sstevel@tonic-gate 
309*7c478bd9Sstevel@tonic-gate 	dp = cache_get_disklist();
310*7c478bd9Sstevel@tonic-gate 	while (dp != NULL) {
311*7c478bd9Sstevel@tonic-gate 	    if (media_read_name(dp, mname, sizeof (mname))) {
312*7c478bd9Sstevel@tonic-gate 		cache_load_desc(DM_MEDIA, dp, mname, NULL, &error);
313*7c478bd9Sstevel@tonic-gate 		if (error != 0) {
314*7c478bd9Sstevel@tonic-gate 		    return (error);
315*7c478bd9Sstevel@tonic-gate 		}
316*7c478bd9Sstevel@tonic-gate 	    }
317*7c478bd9Sstevel@tonic-gate 
318*7c478bd9Sstevel@tonic-gate 	    dp = dp->next;
319*7c478bd9Sstevel@tonic-gate 	}
320*7c478bd9Sstevel@tonic-gate 
321*7c478bd9Sstevel@tonic-gate 	return (0);
322*7c478bd9Sstevel@tonic-gate }
323*7c478bd9Sstevel@tonic-gate 
324*7c478bd9Sstevel@tonic-gate /*
325*7c478bd9Sstevel@tonic-gate  * Read the media information.
326*7c478bd9Sstevel@tonic-gate  */
327*7c478bd9Sstevel@tonic-gate int
328*7c478bd9Sstevel@tonic-gate media_read_info(int fd, struct dk_minfo *minfo)
329*7c478bd9Sstevel@tonic-gate {
330*7c478bd9Sstevel@tonic-gate 	int	status;
331*7c478bd9Sstevel@tonic-gate 	int	tries = 0;
332*7c478bd9Sstevel@tonic-gate 
333*7c478bd9Sstevel@tonic-gate 	minfo->dki_media_type = 0;
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate 	/*
336*7c478bd9Sstevel@tonic-gate 	 * This ioctl can fail if the media is not loaded or spun up.
337*7c478bd9Sstevel@tonic-gate 	 * Retrying can sometimes succeed since the first ioctl will have
338*7c478bd9Sstevel@tonic-gate 	 * started the media before the ioctl timed out so the media may be
339*7c478bd9Sstevel@tonic-gate 	 * spun up on the subsequent attempt.
340*7c478bd9Sstevel@tonic-gate 	 */
341*7c478bd9Sstevel@tonic-gate 	while ((status = ioctl(fd, DKIOCGMEDIAINFO, minfo)) < 0) {
342*7c478bd9Sstevel@tonic-gate 	    tries++;
343*7c478bd9Sstevel@tonic-gate 	    if (tries >= IOCTLRETRIES) {
344*7c478bd9Sstevel@tonic-gate 		break;
345*7c478bd9Sstevel@tonic-gate 	    }
346*7c478bd9Sstevel@tonic-gate 	    (void) sleep(IOCTLRETRYINTERVAL);
347*7c478bd9Sstevel@tonic-gate 	}
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate 	if (status < 0) {
350*7c478bd9Sstevel@tonic-gate 	    return (0);
351*7c478bd9Sstevel@tonic-gate 	}
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate 	return (1);
354*7c478bd9Sstevel@tonic-gate }
355*7c478bd9Sstevel@tonic-gate 
356*7c478bd9Sstevel@tonic-gate /* return 1 if there is media, 0 if not. */
357*7c478bd9Sstevel@tonic-gate int
358*7c478bd9Sstevel@tonic-gate media_read_name(disk_t *dp, char *mname, int size)
359*7c478bd9Sstevel@tonic-gate {
360*7c478bd9Sstevel@tonic-gate 	int	under_volm;
361*7c478bd9Sstevel@tonic-gate 	char	rmmedia_devpath[MAXPATHLEN];
362*7c478bd9Sstevel@tonic-gate 
363*7c478bd9Sstevel@tonic-gate 	mname[0] = 0;
364*7c478bd9Sstevel@tonic-gate 
365*7c478bd9Sstevel@tonic-gate 	if (!dp->removable) {
366*7c478bd9Sstevel@tonic-gate 	    /* not removable, so media name is devid */
367*7c478bd9Sstevel@tonic-gate 	    if (dp->device_id != NULL) {
368*7c478bd9Sstevel@tonic-gate 		(void) strlcpy(mname, dp->device_id, size);
369*7c478bd9Sstevel@tonic-gate 	    }
370*7c478bd9Sstevel@tonic-gate 	    return (1);
371*7c478bd9Sstevel@tonic-gate 	}
372*7c478bd9Sstevel@tonic-gate 
373*7c478bd9Sstevel@tonic-gate 	/* This is a removable media drive. */
374*7c478bd9Sstevel@tonic-gate 
375*7c478bd9Sstevel@tonic-gate 	/* Get 1 if under volm control, 0 if not */
376*7c478bd9Sstevel@tonic-gate 	under_volm = media_get_volm_path(dp, rmmedia_devpath,
377*7c478bd9Sstevel@tonic-gate 	    sizeof (rmmedia_devpath));
378*7c478bd9Sstevel@tonic-gate 
379*7c478bd9Sstevel@tonic-gate 	if (under_volm) {
380*7c478bd9Sstevel@tonic-gate 	    /* under volm control */
381*7c478bd9Sstevel@tonic-gate 	    if (rmmedia_devpath[0] == 0) {
382*7c478bd9Sstevel@tonic-gate 		/* no media */
383*7c478bd9Sstevel@tonic-gate 		return (0);
384*7c478bd9Sstevel@tonic-gate 	    }
385*7c478bd9Sstevel@tonic-gate 	    (void) strlcpy(mname, rmmedia_devpath, size);
386*7c478bd9Sstevel@tonic-gate 	    return (1);
387*7c478bd9Sstevel@tonic-gate 
388*7c478bd9Sstevel@tonic-gate 	} else {
389*7c478bd9Sstevel@tonic-gate 	    /* not under volm control */
390*7c478bd9Sstevel@tonic-gate 	    return (get_non_volm_name(dp, mname, size));
391*7c478bd9Sstevel@tonic-gate 	}
392*7c478bd9Sstevel@tonic-gate }
393*7c478bd9Sstevel@tonic-gate 
394*7c478bd9Sstevel@tonic-gate static descriptor_t **
395*7c478bd9Sstevel@tonic-gate apply_filter(descriptor_t **media, int filter[], int *errp)
396*7c478bd9Sstevel@tonic-gate {
397*7c478bd9Sstevel@tonic-gate 	descriptor_t	**found;
398*7c478bd9Sstevel@tonic-gate 	int		i;
399*7c478bd9Sstevel@tonic-gate 	int		cnt = 0;
400*7c478bd9Sstevel@tonic-gate 	int		pos;
401*7c478bd9Sstevel@tonic-gate 
402*7c478bd9Sstevel@tonic-gate 	/* count the number of media in the snapshot */
403*7c478bd9Sstevel@tonic-gate 	for (i = 0; media[i]; i++) {
404*7c478bd9Sstevel@tonic-gate 	    cnt++;
405*7c478bd9Sstevel@tonic-gate 	}
406*7c478bd9Sstevel@tonic-gate 
407*7c478bd9Sstevel@tonic-gate 	found = (descriptor_t **)calloc(cnt + 1, sizeof (descriptor_t *));
408*7c478bd9Sstevel@tonic-gate 	if (found == NULL) {
409*7c478bd9Sstevel@tonic-gate 	    *errp = ENOMEM;
410*7c478bd9Sstevel@tonic-gate 	    cache_free_descriptors(media);
411*7c478bd9Sstevel@tonic-gate 	    return (NULL);
412*7c478bd9Sstevel@tonic-gate 	}
413*7c478bd9Sstevel@tonic-gate 
414*7c478bd9Sstevel@tonic-gate 	pos = 0;
415*7c478bd9Sstevel@tonic-gate 	for (i = 0; media[i]; i++) {
416*7c478bd9Sstevel@tonic-gate 	    int			fd;
417*7c478bd9Sstevel@tonic-gate 	    struct dk_minfo	minfo;
418*7c478bd9Sstevel@tonic-gate 
419*7c478bd9Sstevel@tonic-gate 	    if ((fd = drive_open_disk(media[i]->p.disk, NULL, 0)) < 0) {
420*7c478bd9Sstevel@tonic-gate 		continue;
421*7c478bd9Sstevel@tonic-gate 	    }
422*7c478bd9Sstevel@tonic-gate 
423*7c478bd9Sstevel@tonic-gate 	    if (media_read_info(fd, &minfo)) {
424*7c478bd9Sstevel@tonic-gate 		int	mtype;
425*7c478bd9Sstevel@tonic-gate 		int	j;
426*7c478bd9Sstevel@tonic-gate 		int	match;
427*7c478bd9Sstevel@tonic-gate 
428*7c478bd9Sstevel@tonic-gate 		mtype = get_media_type(minfo.dki_media_type);
429*7c478bd9Sstevel@tonic-gate 
430*7c478bd9Sstevel@tonic-gate 		match = 0;
431*7c478bd9Sstevel@tonic-gate 		for (j = 0; filter[j] != DM_FILTER_END; j++) {
432*7c478bd9Sstevel@tonic-gate 		    if (mtype == filter[j]) {
433*7c478bd9Sstevel@tonic-gate 			found[pos++] = media[i];
434*7c478bd9Sstevel@tonic-gate 			match = 1;
435*7c478bd9Sstevel@tonic-gate 			break;
436*7c478bd9Sstevel@tonic-gate 		    }
437*7c478bd9Sstevel@tonic-gate 		}
438*7c478bd9Sstevel@tonic-gate 
439*7c478bd9Sstevel@tonic-gate 		if (!match) {
440*7c478bd9Sstevel@tonic-gate 		    cache_free_descriptor(media[i]);
441*7c478bd9Sstevel@tonic-gate 		}
442*7c478bd9Sstevel@tonic-gate 	    }
443*7c478bd9Sstevel@tonic-gate #ifdef i386
444*7c478bd9Sstevel@tonic-gate 	    /* XXX Work around bug 4725434 */
445*7c478bd9Sstevel@tonic-gate 	    else if (!media[i]->p.disk->removable) {
446*7c478bd9Sstevel@tonic-gate 		int	j;
447*7c478bd9Sstevel@tonic-gate 		int	match;
448*7c478bd9Sstevel@tonic-gate 
449*7c478bd9Sstevel@tonic-gate 		match = 0;
450*7c478bd9Sstevel@tonic-gate 		for (j = 0; filter[j] != DM_FILTER_END; j++) {
451*7c478bd9Sstevel@tonic-gate 		    if (DM_MT_FIXED == filter[j]) {
452*7c478bd9Sstevel@tonic-gate 			found[pos++] = media[i];
453*7c478bd9Sstevel@tonic-gate 			match = 1;
454*7c478bd9Sstevel@tonic-gate 			break;
455*7c478bd9Sstevel@tonic-gate 		    }
456*7c478bd9Sstevel@tonic-gate 		}
457*7c478bd9Sstevel@tonic-gate 
458*7c478bd9Sstevel@tonic-gate 		if (!match) {
459*7c478bd9Sstevel@tonic-gate 		    cache_free_descriptor(media[i]);
460*7c478bd9Sstevel@tonic-gate 		}
461*7c478bd9Sstevel@tonic-gate 	    }
462*7c478bd9Sstevel@tonic-gate #endif
463*7c478bd9Sstevel@tonic-gate 
464*7c478bd9Sstevel@tonic-gate 	    (void) close(fd);
465*7c478bd9Sstevel@tonic-gate 	}
466*7c478bd9Sstevel@tonic-gate 	found[pos] = NULL;
467*7c478bd9Sstevel@tonic-gate 	free(media);
468*7c478bd9Sstevel@tonic-gate 
469*7c478bd9Sstevel@tonic-gate 	*errp = 0;
470*7c478bd9Sstevel@tonic-gate 	return (found);
471*7c478bd9Sstevel@tonic-gate }
472*7c478bd9Sstevel@tonic-gate 
473*7c478bd9Sstevel@tonic-gate /* return 1 if the media descriptor is still valid, 0 if not. */
474*7c478bd9Sstevel@tonic-gate static int
475*7c478bd9Sstevel@tonic-gate desc_ok(descriptor_t *dp)
476*7c478bd9Sstevel@tonic-gate {
477*7c478bd9Sstevel@tonic-gate 	/* First verify the media name for removable media */
478*7c478bd9Sstevel@tonic-gate 	if (dp->p.disk->removable) {
479*7c478bd9Sstevel@tonic-gate 	    char	mname[MAXPATHLEN];
480*7c478bd9Sstevel@tonic-gate 
481*7c478bd9Sstevel@tonic-gate 	    if (!media_read_name(dp->p.disk, mname, sizeof (mname))) {
482*7c478bd9Sstevel@tonic-gate 		return (0);
483*7c478bd9Sstevel@tonic-gate 	    }
484*7c478bd9Sstevel@tonic-gate 
485*7c478bd9Sstevel@tonic-gate 	    if (mname[0] == 0) {
486*7c478bd9Sstevel@tonic-gate 		return (libdiskmgt_str_eq(dp->name, NULL));
487*7c478bd9Sstevel@tonic-gate 	    } else {
488*7c478bd9Sstevel@tonic-gate 		return (libdiskmgt_str_eq(dp->name, mname));
489*7c478bd9Sstevel@tonic-gate 	    }
490*7c478bd9Sstevel@tonic-gate 	}
491*7c478bd9Sstevel@tonic-gate 
492*7c478bd9Sstevel@tonic-gate 	return (1);
493*7c478bd9Sstevel@tonic-gate }
494*7c478bd9Sstevel@tonic-gate 
495*7c478bd9Sstevel@tonic-gate static int
496*7c478bd9Sstevel@tonic-gate get_attrs(disk_t *dp, int fd, nvlist_t *attrs)
497*7c478bd9Sstevel@tonic-gate {
498*7c478bd9Sstevel@tonic-gate 	struct dk_minfo	minfo;
499*7c478bd9Sstevel@tonic-gate 	struct dk_geom	geometry;
500*7c478bd9Sstevel@tonic-gate 
501*7c478bd9Sstevel@tonic-gate 	if (fd < 0) {
502*7c478bd9Sstevel@tonic-gate 	    return (ENODEV);
503*7c478bd9Sstevel@tonic-gate 	}
504*7c478bd9Sstevel@tonic-gate 
505*7c478bd9Sstevel@tonic-gate 	bzero(&minfo, sizeof (struct dk_minfo));
506*7c478bd9Sstevel@tonic-gate 
507*7c478bd9Sstevel@tonic-gate 	/* The first thing to do is read the media */
508*7c478bd9Sstevel@tonic-gate 	if (!media_read_info(fd, &minfo)) {
509*7c478bd9Sstevel@tonic-gate 	    /* XXX Work around bug 4725434 */
510*7c478bd9Sstevel@tonic-gate #ifdef i386
511*7c478bd9Sstevel@tonic-gate 	    if (dp->removable)
512*7c478bd9Sstevel@tonic-gate #endif
513*7c478bd9Sstevel@tonic-gate 	    return (ENODEV);
514*7c478bd9Sstevel@tonic-gate 	}
515*7c478bd9Sstevel@tonic-gate 
516*7c478bd9Sstevel@tonic-gate 	if (partition_has_fdisk(dp, fd)) {
517*7c478bd9Sstevel@tonic-gate 	    if (nvlist_add_boolean(attrs, DM_FDISK) != 0) {
518*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
519*7c478bd9Sstevel@tonic-gate 	    }
520*7c478bd9Sstevel@tonic-gate 	}
521*7c478bd9Sstevel@tonic-gate 
522*7c478bd9Sstevel@tonic-gate 	if (dp->removable) {
523*7c478bd9Sstevel@tonic-gate 	    if (nvlist_add_boolean(attrs, DM_REMOVABLE) != 0) {
524*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
525*7c478bd9Sstevel@tonic-gate 	    }
526*7c478bd9Sstevel@tonic-gate 
527*7c478bd9Sstevel@tonic-gate 	    if (nvlist_add_boolean(attrs, DM_LOADED) != 0) {
528*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
529*7c478bd9Sstevel@tonic-gate 	    }
530*7c478bd9Sstevel@tonic-gate 	}
531*7c478bd9Sstevel@tonic-gate 
532*7c478bd9Sstevel@tonic-gate 	if (nvlist_add_uint64(attrs, DM_SIZE, minfo.dki_capacity) != 0) {
533*7c478bd9Sstevel@tonic-gate 	    return (ENOMEM);
534*7c478bd9Sstevel@tonic-gate 	}
535*7c478bd9Sstevel@tonic-gate 
536*7c478bd9Sstevel@tonic-gate 	if (nvlist_add_uint32(attrs, DM_BLOCKSIZE, minfo.dki_lbsize) != 0) {
537*7c478bd9Sstevel@tonic-gate 	    return (ENOMEM);
538*7c478bd9Sstevel@tonic-gate 	}
539*7c478bd9Sstevel@tonic-gate 
540*7c478bd9Sstevel@tonic-gate 	if (nvlist_add_uint32(attrs, DM_MTYPE,
541*7c478bd9Sstevel@tonic-gate 	    get_media_type(minfo.dki_media_type)) != 0) {
542*7c478bd9Sstevel@tonic-gate 	    return (ENOMEM);
543*7c478bd9Sstevel@tonic-gate 	}
544*7c478bd9Sstevel@tonic-gate 
545*7c478bd9Sstevel@tonic-gate 	/* only for disks < 1TB */
546*7c478bd9Sstevel@tonic-gate 	if (ioctl(fd, DKIOCGGEOM, &geometry) >= 0) {
547*7c478bd9Sstevel@tonic-gate 	    struct vtoc	vtoc;
548*7c478bd9Sstevel@tonic-gate 
549*7c478bd9Sstevel@tonic-gate 	    if (nvlist_add_uint64(attrs, DM_START, 0) != 0) {
550*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
551*7c478bd9Sstevel@tonic-gate 	    }
552*7c478bd9Sstevel@tonic-gate 	    if (nvlist_add_uint64(attrs, DM_NACCESSIBLE,
553*7c478bd9Sstevel@tonic-gate 		geometry.dkg_ncyl * geometry.dkg_nhead * geometry.dkg_nsect)
554*7c478bd9Sstevel@tonic-gate 		!= 0) {
555*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
556*7c478bd9Sstevel@tonic-gate 	    }
557*7c478bd9Sstevel@tonic-gate 	    if (nvlist_add_uint32(attrs, DM_NCYLINDERS, geometry.dkg_ncyl)
558*7c478bd9Sstevel@tonic-gate 		!= 0) {
559*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
560*7c478bd9Sstevel@tonic-gate 	    }
561*7c478bd9Sstevel@tonic-gate 	    if (nvlist_add_uint32(attrs, DM_NPHYSCYLINDERS, geometry.dkg_pcyl)
562*7c478bd9Sstevel@tonic-gate 		!= 0) {
563*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
564*7c478bd9Sstevel@tonic-gate 	    }
565*7c478bd9Sstevel@tonic-gate 	    if (nvlist_add_uint32(attrs, DM_NALTCYLINDERS, geometry.dkg_acyl)
566*7c478bd9Sstevel@tonic-gate 		!= 0) {
567*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
568*7c478bd9Sstevel@tonic-gate 	    }
569*7c478bd9Sstevel@tonic-gate 	    if (nvlist_add_uint32(attrs, DM_NHEADS, geometry.dkg_nhead) != 0) {
570*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
571*7c478bd9Sstevel@tonic-gate 	    }
572*7c478bd9Sstevel@tonic-gate 	    if (nvlist_add_uint32(attrs, DM_NSECTORS, geometry.dkg_nsect)
573*7c478bd9Sstevel@tonic-gate 		!= 0) {
574*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
575*7c478bd9Sstevel@tonic-gate 	    }
576*7c478bd9Sstevel@tonic-gate 
577*7c478bd9Sstevel@tonic-gate 	    if (read_vtoc(fd, &vtoc) >= 0 && vtoc.v_volume[0] != 0) {
578*7c478bd9Sstevel@tonic-gate 		char	label[LEN_DKL_VVOL + 1];
579*7c478bd9Sstevel@tonic-gate 
580*7c478bd9Sstevel@tonic-gate 		(void) snprintf(label, sizeof (label), "%.*s", LEN_DKL_VVOL,
581*7c478bd9Sstevel@tonic-gate 		    vtoc.v_volume);
582*7c478bd9Sstevel@tonic-gate 		if (nvlist_add_string(attrs, DM_LABEL, label) != 0) {
583*7c478bd9Sstevel@tonic-gate 		    return (ENOMEM);
584*7c478bd9Sstevel@tonic-gate 		}
585*7c478bd9Sstevel@tonic-gate 	    }
586*7c478bd9Sstevel@tonic-gate 
587*7c478bd9Sstevel@tonic-gate 	} else {
588*7c478bd9Sstevel@tonic-gate 	    /* check for disks > 1TB for accessible size */
589*7c478bd9Sstevel@tonic-gate 	    struct dk_gpt	*efip;
590*7c478bd9Sstevel@tonic-gate 
591*7c478bd9Sstevel@tonic-gate 	    if (efi_alloc_and_read(fd, &efip) >= 0) {
592*7c478bd9Sstevel@tonic-gate 		diskaddr_t	p8size = 0;
593*7c478bd9Sstevel@tonic-gate 
594*7c478bd9Sstevel@tonic-gate 		if (nvlist_add_boolean(attrs, DM_EFI) != 0) {
595*7c478bd9Sstevel@tonic-gate 		    return (ENOMEM);
596*7c478bd9Sstevel@tonic-gate 		}
597*7c478bd9Sstevel@tonic-gate 		if (nvlist_add_uint64(attrs, DM_START, efip->efi_first_u_lba)
598*7c478bd9Sstevel@tonic-gate 		    != 0) {
599*7c478bd9Sstevel@tonic-gate 		    return (ENOMEM);
600*7c478bd9Sstevel@tonic-gate 		}
601*7c478bd9Sstevel@tonic-gate 		/* partition 8 is reserved on EFI labels */
602*7c478bd9Sstevel@tonic-gate 		if (efip->efi_nparts >= 9) {
603*7c478bd9Sstevel@tonic-gate 		    p8size = efip->efi_parts[8].p_size;
604*7c478bd9Sstevel@tonic-gate 		}
605*7c478bd9Sstevel@tonic-gate 		if (nvlist_add_uint64(attrs, DM_NACCESSIBLE,
606*7c478bd9Sstevel@tonic-gate 		    (efip->efi_last_u_lba - p8size) - efip->efi_first_u_lba)
607*7c478bd9Sstevel@tonic-gate 		    != 0) {
608*7c478bd9Sstevel@tonic-gate 		    efi_free(efip);
609*7c478bd9Sstevel@tonic-gate 		    return (ENOMEM);
610*7c478bd9Sstevel@tonic-gate 		}
611*7c478bd9Sstevel@tonic-gate 		efi_free(efip);
612*7c478bd9Sstevel@tonic-gate 	    }
613*7c478bd9Sstevel@tonic-gate 	}
614*7c478bd9Sstevel@tonic-gate 
615*7c478bd9Sstevel@tonic-gate 	/* This ioctl seems to be mainly for intel-based drives. */
616*7c478bd9Sstevel@tonic-gate 	if (ioctl(fd, DKIOCG_PHYGEOM, &geometry) >= 0) {
617*7c478bd9Sstevel@tonic-gate 	    if (nvlist_add_uint32(attrs, DM_NACTUALCYLINDERS, geometry.dkg_ncyl)
618*7c478bd9Sstevel@tonic-gate 		!= 0) {
619*7c478bd9Sstevel@tonic-gate 		return (ENOMEM);
620*7c478bd9Sstevel@tonic-gate 	    }
621*7c478bd9Sstevel@tonic-gate 	}
622*7c478bd9Sstevel@tonic-gate 
623*7c478bd9Sstevel@tonic-gate 	return (0);
624*7c478bd9Sstevel@tonic-gate }
625*7c478bd9Sstevel@tonic-gate 
626*7c478bd9Sstevel@tonic-gate static int
627*7c478bd9Sstevel@tonic-gate get_media_type(uint_t media_type)
628*7c478bd9Sstevel@tonic-gate {
629*7c478bd9Sstevel@tonic-gate 	switch (media_type) {
630*7c478bd9Sstevel@tonic-gate 	case DK_UNKNOWN:
631*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_UNKNOWN);
632*7c478bd9Sstevel@tonic-gate 	case DK_MO_ERASABLE:
633*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_MO_ERASABLE);
634*7c478bd9Sstevel@tonic-gate 	case DK_MO_WRITEONCE:
635*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_MO_WRITEONCE);
636*7c478bd9Sstevel@tonic-gate 	case DK_AS_MO:
637*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_AS_MO);
638*7c478bd9Sstevel@tonic-gate 	case DK_CDROM:
639*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_CDROM);
640*7c478bd9Sstevel@tonic-gate 	case DK_CDR:
641*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_CDR);
642*7c478bd9Sstevel@tonic-gate 	case DK_CDRW:
643*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_CDRW);
644*7c478bd9Sstevel@tonic-gate 	case DK_DVDROM:
645*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_DVDROM);
646*7c478bd9Sstevel@tonic-gate 	case DK_DVDR:
647*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_DVDR);
648*7c478bd9Sstevel@tonic-gate 	case DK_DVDRAM:
649*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_DVDRAM);
650*7c478bd9Sstevel@tonic-gate 	case DK_FIXED_DISK:
651*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_FIXED);
652*7c478bd9Sstevel@tonic-gate 	case DK_FLOPPY:
653*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_FLOPPY);
654*7c478bd9Sstevel@tonic-gate 	case DK_ZIP:
655*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_ZIP);
656*7c478bd9Sstevel@tonic-gate 	case DK_JAZ:
657*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_JAZ);
658*7c478bd9Sstevel@tonic-gate 	default:
659*7c478bd9Sstevel@tonic-gate 	    return (DM_MT_UNKNOWN);
660*7c478bd9Sstevel@tonic-gate 	}
661*7c478bd9Sstevel@tonic-gate }
662*7c478bd9Sstevel@tonic-gate 
663*7c478bd9Sstevel@tonic-gate /*
664*7c478bd9Sstevel@tonic-gate  * This function handles removable media not under volume management.
665*7c478bd9Sstevel@tonic-gate  */
666*7c478bd9Sstevel@tonic-gate static int
667*7c478bd9Sstevel@tonic-gate get_non_volm_name(disk_t *dp, char *mname, int size)
668*7c478bd9Sstevel@tonic-gate {
669*7c478bd9Sstevel@tonic-gate 	int		loaded;
670*7c478bd9Sstevel@tonic-gate 	int		fd;
671*7c478bd9Sstevel@tonic-gate 
672*7c478bd9Sstevel@tonic-gate 	loaded = 0;
673*7c478bd9Sstevel@tonic-gate 
674*7c478bd9Sstevel@tonic-gate 	if ((fd = drive_open_disk(dp, NULL, 0)) >= 0) {
675*7c478bd9Sstevel@tonic-gate 	    struct dk_minfo minfo;
676*7c478bd9Sstevel@tonic-gate 
677*7c478bd9Sstevel@tonic-gate 	    if ((loaded = media_read_info(fd, &minfo))) {
678*7c478bd9Sstevel@tonic-gate 		struct vtoc vtoc;
679*7c478bd9Sstevel@tonic-gate 
680*7c478bd9Sstevel@tonic-gate 		if (read_vtoc(fd, &vtoc) >= 0) {
681*7c478bd9Sstevel@tonic-gate 		    if (vtoc.v_volume[0] != NULL) {
682*7c478bd9Sstevel@tonic-gate 			if (LEN_DKL_VVOL < size) {
683*7c478bd9Sstevel@tonic-gate 			    (void) strlcpy(mname, vtoc.v_volume, LEN_DKL_VVOL);
684*7c478bd9Sstevel@tonic-gate 			} else {
685*7c478bd9Sstevel@tonic-gate 			    (void) strlcpy(mname, vtoc.v_volume, size);
686*7c478bd9Sstevel@tonic-gate 			}
687*7c478bd9Sstevel@tonic-gate 		    }
688*7c478bd9Sstevel@tonic-gate 		}
689*7c478bd9Sstevel@tonic-gate 	    }
690*7c478bd9Sstevel@tonic-gate 
691*7c478bd9Sstevel@tonic-gate 	    (void) close(fd);
692*7c478bd9Sstevel@tonic-gate 	}
693*7c478bd9Sstevel@tonic-gate 
694*7c478bd9Sstevel@tonic-gate 	return (loaded);
695*7c478bd9Sstevel@tonic-gate }
696