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"
34 #include <sys/errno.h>
35 #include <sys/types.h>
37 #include <sys/vfstab.h>
40 #include <sys/fs/ufs_fs.h>
42 #include "libdiskmgt.h"
43 #include "disks_private.h"
46 * The list of filesystem heuristic programs.
49 struct heuristic
*next
;
57 struct vfstab_list
*next
;
60 static struct vfstab_list
*vfstab_listp
= NULL
;
61 static mutex_t vfstab_lock
= DEFAULTMUTEX
;
63 static time_t timestamp
= 0;
65 static struct heuristic
*hlist
= NULL
;
66 static int initialized
= 0;
67 static mutex_t init_lock
= DEFAULTMUTEX
;
69 static int has_fs(char *prog
, char *slice
);
70 static int load_heuristics();
71 static int add_use_record(struct vfstab
*vp
);
72 static int load_vfstab();
73 static void free_vfstab(struct vfstab_list
*listp
);
76 * Use the heuristics to check for a filesystem on the slice.
79 inuse_fs(char *slice
, nvlist_t
*attrs
, int *errp
)
93 * We get the list of heuristic programs one time.
95 (void) mutex_lock(&init_lock
);
97 *errp
= load_heuristics();
103 (void) mutex_unlock(&init_lock
);
105 /* Run each of the heuristics. */
106 for (hp
= hlist
; hp
; hp
= hp
->next
) {
107 if (has_fs(hp
->prog
, slice
)) {
108 libdiskmgt_add_str(attrs
, DM_USED_BY
, DM_USE_FS
, errp
);
109 libdiskmgt_add_str(attrs
, DM_USED_NAME
, hp
->type
, errp
);
118 * Second heuristic used is the check for an entry in vfstab
121 (void) mutex_lock(&vfstab_lock
);
122 curr_time
= time(NULL
);
124 if (timestamp
< curr_time
&& (curr_time
- timestamp
) > 60) {
125 free_vfstab(vfstab_listp
);
126 *errp
= load_vfstab();
127 timestamp
= curr_time
;
131 struct vfstab_list
*listp
;
132 listp
= vfstab_listp
;
134 while (listp
!= NULL
) {
135 if (strcmp(slice
, listp
->special
) == 0) {
138 if (listp
->mountp
!= NULL
)
139 mountp
= listp
->mountp
;
141 libdiskmgt_add_str(attrs
, DM_USED_BY
, DM_USE_VFSTAB
, errp
);
142 libdiskmgt_add_str(attrs
, DM_USED_NAME
, mountp
, errp
);
148 (void) mutex_unlock(&vfstab_lock
);
153 has_fs(char *prog
, char *slice
)
157 mode_t mode
= S_IRUSR
| S_IWUSR
;
159 switch ((pid
= fork1())) {
164 (void) open("/dev/null", O_WRONLY
, mode
);
165 (void) open("/dev/null", O_WRONLY
, mode
);
166 (void) execl(prog
, "fstyp", slice
, NULL
);
178 (void) waitpid(pid
, &loc
, 0);
180 if (WIFEXITED(loc
) && WEXITSTATUS(loc
) == 0) {
188 * Create a list of filesystem heuristic programs.
195 if ((dirp
= opendir("/usr/lib/fs")) != NULL
) {
198 while ((dp
= readdir(dirp
)) != NULL
) {
199 char path
[MAXPATHLEN
];
203 /* skip known dirs */
204 if (strcmp(dp
->d_name
, ".") == 0 ||
205 strcmp(dp
->d_name
, "..") == 0) {
210 * Skip checking for ZFS filesystems. We know that
211 * inuse_zpool() will have already been called, which does a
212 * better job of checking anyway. More importantly, an unused
213 * hot spare will still claim to have a ZFS filesystem because
214 * it doesn't do the same level of checks.
216 if (strcmp(dp
->d_name
, "zfs") == 0)
219 (void) snprintf(path
, sizeof (path
), "/usr/lib/fs/%s",
222 if (stat(path
, &buf
) != 0 || !S_ISDIR(buf
.st_mode
)) {
226 if ((subdirp
= opendir(path
)) != NULL
) {
229 while ((sdp
= readdir(subdirp
)) != NULL
) {
231 if (strcmp(sdp
->d_name
, "fstyp") == 0) {
232 char progpath
[MAXPATHLEN
];
234 (void) snprintf(progpath
, sizeof (progpath
),
235 "/usr/lib/fs/%s/fstyp", dp
->d_name
);
237 if (stat(progpath
, &buf
) == 0 &&
238 S_ISREG(buf
.st_mode
)) {
240 struct heuristic
*hp
;
242 hp
= (struct heuristic
*)
243 malloc(sizeof (struct heuristic
));
246 (void) closedir(subdirp
);
247 (void) closedir(dirp
);
251 if ((hp
->prog
= strdup(progpath
)) == NULL
) {
252 (void) closedir(subdirp
);
253 (void) closedir(dirp
);
257 if ((hp
->type
= strdup(dp
->d_name
)) == NULL
) {
258 (void) closedir(subdirp
);
259 (void) closedir(dirp
);
271 (void) closedir(subdirp
);
275 (void) closedir(dirp
);
288 fp
= fopen(VFSTAB
, "r");
290 (void) memset(&vp
, 0, sizeof (struct vfstab
));
291 while (getvfsent(fp
, &vp
) == 0) {
292 status
= add_use_record(&vp
);
297 (void) memset(&vp
, 0, sizeof (struct vfstab
));
307 add_use_record(struct vfstab
*vp
)
309 struct vfstab_list
*vfsp
;
311 vfsp
= (struct vfstab_list
*)malloc(sizeof (struct vfstab_list
));
316 vfsp
->special
= strdup(vp
->vfs_special
);
317 if (vfsp
->special
== NULL
) {
322 if (vp
->vfs_mountp
!= NULL
) {
323 vfsp
->mountp
= strdup(vp
->vfs_mountp
);
324 if (vfsp
->mountp
== NULL
) {
332 vfsp
->next
= vfstab_listp
;
339 free_vfstab(struct vfstab_list
*listp
)
341 struct vfstab_list
*nextp
;
343 while (listp
!= NULL
) {
345 free((void *)listp
->special
);
346 free((void *)listp
->mountp
);