1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate * Traverses /etc/mnttab in order to find mounted file systems.
31*0Sstevel@tonic-gate */
32*0Sstevel@tonic-gate #include <errno.h>
33*0Sstevel@tonic-gate #include <unistd.h>
34*0Sstevel@tonic-gate #include <stdlib.h>
35*0Sstevel@tonic-gate #include <stdio.h>
36*0Sstevel@tonic-gate #include <sys/mnttab.h>
37*0Sstevel@tonic-gate #include <sys/types.h>
38*0Sstevel@tonic-gate #include <sys/statvfs.h>
39*0Sstevel@tonic-gate #include <strings.h>
40*0Sstevel@tonic-gate #include "libfsmgt.h"
41*0Sstevel@tonic-gate
42*0Sstevel@tonic-gate /*
43*0Sstevel@tonic-gate * Private variables
44*0Sstevel@tonic-gate */
45*0Sstevel@tonic-gate
46*0Sstevel@tonic-gate /*
47*0Sstevel@tonic-gate * Private method declarations
48*0Sstevel@tonic-gate */
49*0Sstevel@tonic-gate
50*0Sstevel@tonic-gate static fs_mntlist_t *create_mntlist_entry(struct mnttab mnttab_entry);
51*0Sstevel@tonic-gate static fs_mntlist_t *create_extmntlist_entry(struct extmnttab mnttab_entry);
52*0Sstevel@tonic-gate static struct mnttab *create_mnttab_filter(char *resource, char *mountp,
53*0Sstevel@tonic-gate char *fstype, char *mntopts, char *time);
54*0Sstevel@tonic-gate static void find_overlayed_filesystems(fs_mntlist_t *mnt_list,
55*0Sstevel@tonic-gate boolean_t filtered_list, int *errp);
56*0Sstevel@tonic-gate static void free_mnttab_entry(struct mnttab *mnttab_entry);
57*0Sstevel@tonic-gate static char *is_option(char *opt_string, char *opt, int *errp);
58*0Sstevel@tonic-gate boolean_t is_overlayed(fs_mntlist_t *complete_mnt_list,
59*0Sstevel@tonic-gate char *mountp);
60*0Sstevel@tonic-gate
61*0Sstevel@tonic-gate
62*0Sstevel@tonic-gate /*
63*0Sstevel@tonic-gate * Public methods
64*0Sstevel@tonic-gate */
65*0Sstevel@tonic-gate
66*0Sstevel@tonic-gate void
fs_free_mount_list(fs_mntlist_t * headp)67*0Sstevel@tonic-gate fs_free_mount_list(fs_mntlist_t *headp) {
68*0Sstevel@tonic-gate fs_mntlist_t *tmp;
69*0Sstevel@tonic-gate
70*0Sstevel@tonic-gate while (headp != NULL) {
71*0Sstevel@tonic-gate tmp = headp->next;
72*0Sstevel@tonic-gate free(headp->resource);
73*0Sstevel@tonic-gate free(headp->mountp);
74*0Sstevel@tonic-gate free(headp->fstype);
75*0Sstevel@tonic-gate free(headp->mntopts);
76*0Sstevel@tonic-gate free(headp->time);
77*0Sstevel@tonic-gate headp->next = NULL;
78*0Sstevel@tonic-gate free(headp);
79*0Sstevel@tonic-gate
80*0Sstevel@tonic-gate headp = tmp;
81*0Sstevel@tonic-gate }
82*0Sstevel@tonic-gate } /* fs_free_mount_list */
83*0Sstevel@tonic-gate
84*0Sstevel@tonic-gate unsigned long long
fs_get_availablesize(char * mntpnt,int * errp)85*0Sstevel@tonic-gate fs_get_availablesize(char *mntpnt, int *errp) {
86*0Sstevel@tonic-gate struct statvfs64 stvfs;
87*0Sstevel@tonic-gate unsigned long long availablesize;
88*0Sstevel@tonic-gate
89*0Sstevel@tonic-gate *errp = 0;
90*0Sstevel@tonic-gate if (mntpnt == NULL) {
91*0Sstevel@tonic-gate /*
92*0Sstevel@tonic-gate * Set errp to invalid parameter - EINVAL
93*0Sstevel@tonic-gate */
94*0Sstevel@tonic-gate *errp = EINVAL;
95*0Sstevel@tonic-gate return (0);
96*0Sstevel@tonic-gate }
97*0Sstevel@tonic-gate
98*0Sstevel@tonic-gate if (statvfs64(mntpnt, &stvfs) != -1) {
99*0Sstevel@tonic-gate availablesize = stvfs.f_bfree;
100*0Sstevel@tonic-gate availablesize = availablesize * stvfs.f_frsize;
101*0Sstevel@tonic-gate } else {
102*0Sstevel@tonic-gate *errp = errno;
103*0Sstevel@tonic-gate return (0);
104*0Sstevel@tonic-gate } /* if (statvfs64(mntpnt, &stvfs) != -1) */
105*0Sstevel@tonic-gate
106*0Sstevel@tonic-gate return (availablesize);
107*0Sstevel@tonic-gate } /* fs_get_availablesize */
108*0Sstevel@tonic-gate
109*0Sstevel@tonic-gate unsigned long long
fs_get_avail_for_nonsuperuser_size(char * mntpnt,int * errp)110*0Sstevel@tonic-gate fs_get_avail_for_nonsuperuser_size(char *mntpnt, int *errp) {
111*0Sstevel@tonic-gate struct statvfs64 stvfs;
112*0Sstevel@tonic-gate unsigned long long avail_for_nonsu_size;
113*0Sstevel@tonic-gate
114*0Sstevel@tonic-gate *errp = 0;
115*0Sstevel@tonic-gate if (mntpnt == NULL) {
116*0Sstevel@tonic-gate /*
117*0Sstevel@tonic-gate * Set errp to invalid parameter - EINVAL
118*0Sstevel@tonic-gate */
119*0Sstevel@tonic-gate *errp = EINVAL;
120*0Sstevel@tonic-gate return (0);
121*0Sstevel@tonic-gate }
122*0Sstevel@tonic-gate
123*0Sstevel@tonic-gate if (statvfs64(mntpnt, &stvfs) != -1) {
124*0Sstevel@tonic-gate avail_for_nonsu_size = stvfs.f_bavail;
125*0Sstevel@tonic-gate avail_for_nonsu_size = avail_for_nonsu_size * stvfs.f_frsize;
126*0Sstevel@tonic-gate } else {
127*0Sstevel@tonic-gate *errp = errno;
128*0Sstevel@tonic-gate return (0);
129*0Sstevel@tonic-gate } /* if (statvfs64(mntpnt, &stvfs) != -1) */
130*0Sstevel@tonic-gate
131*0Sstevel@tonic-gate return (avail_for_nonsu_size);
132*0Sstevel@tonic-gate } /* fs_get_avail_for_nonsuperuser_size(char *mntpnt, int *errp) */
133*0Sstevel@tonic-gate
134*0Sstevel@tonic-gate unsigned long long
fs_get_blocksize(char * mntpnt,int * errp)135*0Sstevel@tonic-gate fs_get_blocksize(char *mntpnt, int *errp) {
136*0Sstevel@tonic-gate struct statvfs64 stvfs;
137*0Sstevel@tonic-gate unsigned long long blocksize;
138*0Sstevel@tonic-gate
139*0Sstevel@tonic-gate *errp = 0;
140*0Sstevel@tonic-gate if (mntpnt == NULL) {
141*0Sstevel@tonic-gate /*
142*0Sstevel@tonic-gate * Set errp to invalid parameter - EINVAL
143*0Sstevel@tonic-gate */
144*0Sstevel@tonic-gate *errp = EINVAL;
145*0Sstevel@tonic-gate return (0);
146*0Sstevel@tonic-gate }
147*0Sstevel@tonic-gate
148*0Sstevel@tonic-gate if (statvfs64(mntpnt, &stvfs) != -1) {
149*0Sstevel@tonic-gate blocksize = stvfs.f_bsize;
150*0Sstevel@tonic-gate } else {
151*0Sstevel@tonic-gate *errp = errno;
152*0Sstevel@tonic-gate return (0);
153*0Sstevel@tonic-gate } /* if (statvfs64(mntpnt, &stvfs) != -1) */
154*0Sstevel@tonic-gate
155*0Sstevel@tonic-gate return (blocksize);
156*0Sstevel@tonic-gate } /* fs_get_blocksize */
157*0Sstevel@tonic-gate
158*0Sstevel@tonic-gate fs_mntlist_t *
fs_get_filtered_mount_list(char * resource,char * mountp,char * fstype,char * mntopts,char * time,boolean_t find_overlays,int * errp)159*0Sstevel@tonic-gate fs_get_filtered_mount_list(char *resource, char *mountp, char *fstype,
160*0Sstevel@tonic-gate char *mntopts, char *time, boolean_t find_overlays, int *errp) {
161*0Sstevel@tonic-gate
162*0Sstevel@tonic-gate fs_mntlist_t *newp;
163*0Sstevel@tonic-gate fs_mntlist_t *headp;
164*0Sstevel@tonic-gate fs_mntlist_t *tailp;
165*0Sstevel@tonic-gate FILE *fp;
166*0Sstevel@tonic-gate
167*0Sstevel@tonic-gate *errp = 0;
168*0Sstevel@tonic-gate headp = NULL;
169*0Sstevel@tonic-gate tailp = NULL;
170*0Sstevel@tonic-gate
171*0Sstevel@tonic-gate if ((fp = fopen(MNTTAB, "r")) != NULL) {
172*0Sstevel@tonic-gate struct mnttab mnttab_entry;
173*0Sstevel@tonic-gate struct mnttab *search_entry;
174*0Sstevel@tonic-gate
175*0Sstevel@tonic-gate search_entry = create_mnttab_filter(resource, mountp, fstype,
176*0Sstevel@tonic-gate mntopts, time);
177*0Sstevel@tonic-gate if (search_entry == NULL) {
178*0Sstevel@tonic-gate /*
179*0Sstevel@tonic-gate * Out of memory
180*0Sstevel@tonic-gate */
181*0Sstevel@tonic-gate fs_free_mount_list(headp);
182*0Sstevel@tonic-gate (void) fclose(fp);
183*0Sstevel@tonic-gate *errp = ENOMEM;
184*0Sstevel@tonic-gate return (NULL);
185*0Sstevel@tonic-gate }
186*0Sstevel@tonic-gate
187*0Sstevel@tonic-gate while (getmntany(fp, &mnttab_entry, search_entry) == 0) {
188*0Sstevel@tonic-gate /* Add to list to be returned */
189*0Sstevel@tonic-gate newp = create_mntlist_entry(mnttab_entry);
190*0Sstevel@tonic-gate
191*0Sstevel@tonic-gate if (newp == NULL) {
192*0Sstevel@tonic-gate /*
193*0Sstevel@tonic-gate * Out of memory
194*0Sstevel@tonic-gate */
195*0Sstevel@tonic-gate fs_free_mount_list(headp);
196*0Sstevel@tonic-gate (void) fclose(fp);
197*0Sstevel@tonic-gate *errp = ENOMEM;
198*0Sstevel@tonic-gate return (NULL);
199*0Sstevel@tonic-gate }
200*0Sstevel@tonic-gate
201*0Sstevel@tonic-gate if (headp == NULL) {
202*0Sstevel@tonic-gate headp = newp;
203*0Sstevel@tonic-gate tailp = newp;
204*0Sstevel@tonic-gate } else {
205*0Sstevel@tonic-gate tailp->next = newp;
206*0Sstevel@tonic-gate tailp = newp;
207*0Sstevel@tonic-gate }
208*0Sstevel@tonic-gate
209*0Sstevel@tonic-gate }
210*0Sstevel@tonic-gate free_mnttab_entry(search_entry);
211*0Sstevel@tonic-gate (void) fclose(fp);
212*0Sstevel@tonic-gate if (find_overlays == B_TRUE)
213*0Sstevel@tonic-gate find_overlayed_filesystems(headp, B_TRUE, errp);
214*0Sstevel@tonic-gate } else {
215*0Sstevel@tonic-gate *errp = errno;
216*0Sstevel@tonic-gate } /* if ((fp = fopen(MNTTAB, "r")) != NULL) */
217*0Sstevel@tonic-gate
218*0Sstevel@tonic-gate return (headp);
219*0Sstevel@tonic-gate } /* fs_get_filtered_mount_list */
220*0Sstevel@tonic-gate
221*0Sstevel@tonic-gate unsigned long
fs_get_fragsize(char * mntpnt,int * errp)222*0Sstevel@tonic-gate fs_get_fragsize(char *mntpnt, int *errp) {
223*0Sstevel@tonic-gate struct statvfs64 stvfs;
224*0Sstevel@tonic-gate unsigned long fragsize;
225*0Sstevel@tonic-gate
226*0Sstevel@tonic-gate *errp = 0;
227*0Sstevel@tonic-gate if (mntpnt == NULL) {
228*0Sstevel@tonic-gate /*
229*0Sstevel@tonic-gate * Set errp to invalid parameter - EINVAL
230*0Sstevel@tonic-gate */
231*0Sstevel@tonic-gate *errp = EINVAL;
232*0Sstevel@tonic-gate return (0);
233*0Sstevel@tonic-gate }
234*0Sstevel@tonic-gate
235*0Sstevel@tonic-gate if (statvfs64(mntpnt, &stvfs) != -1) {
236*0Sstevel@tonic-gate fragsize = stvfs.f_frsize;
237*0Sstevel@tonic-gate } else {
238*0Sstevel@tonic-gate *errp = errno;
239*0Sstevel@tonic-gate return (0);
240*0Sstevel@tonic-gate } /* (statvfs64(mntpnt, &stvfs) != -1) */
241*0Sstevel@tonic-gate
242*0Sstevel@tonic-gate return (fragsize);
243*0Sstevel@tonic-gate } /* fs_get_fragsize(char *mntpnt, int *errp) */
244*0Sstevel@tonic-gate
245*0Sstevel@tonic-gate unsigned long
fs_get_maxfilenamelen(char * mntpnt,int * errp)246*0Sstevel@tonic-gate fs_get_maxfilenamelen(char *mntpnt, int *errp) {
247*0Sstevel@tonic-gate long int returned_val;
248*0Sstevel@tonic-gate unsigned long maxfilenamelen;
249*0Sstevel@tonic-gate
250*0Sstevel@tonic-gate *errp = 0;
251*0Sstevel@tonic-gate if (mntpnt == NULL) {
252*0Sstevel@tonic-gate /*
253*0Sstevel@tonic-gate * Set errp to invalid parameter - EINVAL
254*0Sstevel@tonic-gate */
255*0Sstevel@tonic-gate *errp = EINVAL;
256*0Sstevel@tonic-gate return (0);
257*0Sstevel@tonic-gate }
258*0Sstevel@tonic-gate
259*0Sstevel@tonic-gate returned_val = pathconf(mntpnt, _PC_PATH_MAX);
260*0Sstevel@tonic-gate if (returned_val != -1) {
261*0Sstevel@tonic-gate maxfilenamelen = (unsigned long)returned_val;
262*0Sstevel@tonic-gate } else {
263*0Sstevel@tonic-gate *errp = errno;
264*0Sstevel@tonic-gate return (0);
265*0Sstevel@tonic-gate }
266*0Sstevel@tonic-gate
267*0Sstevel@tonic-gate return (maxfilenamelen);
268*0Sstevel@tonic-gate } /* fs_get_maxfilenamelen */
269*0Sstevel@tonic-gate
270*0Sstevel@tonic-gate fs_mntlist_t *
fs_get_mounts_by_mntopt(char * mntopt,boolean_t find_overlays,int * errp)271*0Sstevel@tonic-gate fs_get_mounts_by_mntopt(char *mntopt, boolean_t find_overlays, int *errp) {
272*0Sstevel@tonic-gate
273*0Sstevel@tonic-gate fs_mntlist_t *newp;
274*0Sstevel@tonic-gate fs_mntlist_t *headp;
275*0Sstevel@tonic-gate fs_mntlist_t *tailp;
276*0Sstevel@tonic-gate FILE *fp;
277*0Sstevel@tonic-gate
278*0Sstevel@tonic-gate *errp = 0;
279*0Sstevel@tonic-gate headp = NULL;
280*0Sstevel@tonic-gate tailp = NULL;
281*0Sstevel@tonic-gate
282*0Sstevel@tonic-gate if (mntopt == NULL)
283*0Sstevel@tonic-gate return (NULL);
284*0Sstevel@tonic-gate
285*0Sstevel@tonic-gate if ((fp = fopen(MNTTAB, "r")) != NULL) {
286*0Sstevel@tonic-gate struct mnttab mnttab_entry;
287*0Sstevel@tonic-gate char *opt_found;
288*0Sstevel@tonic-gate
289*0Sstevel@tonic-gate while (getmntent(fp, &mnttab_entry) == 0) {
290*0Sstevel@tonic-gate opt_found = hasmntopt(&mnttab_entry, mntopt);
291*0Sstevel@tonic-gate if (opt_found != NULL) {
292*0Sstevel@tonic-gate /*
293*0Sstevel@tonic-gate * Add to list to be returned
294*0Sstevel@tonic-gate */
295*0Sstevel@tonic-gate newp = create_mntlist_entry(mnttab_entry);
296*0Sstevel@tonic-gate
297*0Sstevel@tonic-gate if (newp == NULL) {
298*0Sstevel@tonic-gate /*
299*0Sstevel@tonic-gate * Out of memory
300*0Sstevel@tonic-gate */
301*0Sstevel@tonic-gate fs_free_mount_list(headp);
302*0Sstevel@tonic-gate (void) fclose(fp);
303*0Sstevel@tonic-gate *errp = ENOMEM;
304*0Sstevel@tonic-gate return (NULL);
305*0Sstevel@tonic-gate }
306*0Sstevel@tonic-gate
307*0Sstevel@tonic-gate if (headp == NULL) {
308*0Sstevel@tonic-gate headp = newp;
309*0Sstevel@tonic-gate tailp = newp;
310*0Sstevel@tonic-gate } else {
311*0Sstevel@tonic-gate tailp->next = newp;
312*0Sstevel@tonic-gate tailp = newp;
313*0Sstevel@tonic-gate }
314*0Sstevel@tonic-gate } /* if (char != NULL) */
315*0Sstevel@tonic-gate }
316*0Sstevel@tonic-gate (void) fclose(fp);
317*0Sstevel@tonic-gate if (find_overlays == B_TRUE)
318*0Sstevel@tonic-gate find_overlayed_filesystems(headp, B_TRUE, errp);
319*0Sstevel@tonic-gate
320*0Sstevel@tonic-gate } else {
321*0Sstevel@tonic-gate *errp = errno;
322*0Sstevel@tonic-gate } /* if ((fp = fopen(MNTTAB, "r")) != NULL) */
323*0Sstevel@tonic-gate
324*0Sstevel@tonic-gate return (headp);
325*0Sstevel@tonic-gate } /* fs_get_mounts_by_mntpnt */
326*0Sstevel@tonic-gate
327*0Sstevel@tonic-gate fs_mntlist_t *
fs_get_mount_list(boolean_t find_overlays,int * errp)328*0Sstevel@tonic-gate fs_get_mount_list(boolean_t find_overlays, int *errp) {
329*0Sstevel@tonic-gate FILE *fp;
330*0Sstevel@tonic-gate fs_mntlist_t *headp;
331*0Sstevel@tonic-gate fs_mntlist_t *tailp;
332*0Sstevel@tonic-gate fs_mntlist_t *newp;
333*0Sstevel@tonic-gate
334*0Sstevel@tonic-gate *errp = 0;
335*0Sstevel@tonic-gate headp = NULL;
336*0Sstevel@tonic-gate tailp = NULL;
337*0Sstevel@tonic-gate
338*0Sstevel@tonic-gate if ((fp = fopen(MNTTAB, "r")) != NULL) {
339*0Sstevel@tonic-gate struct extmnttab mnttab_entry;
340*0Sstevel@tonic-gate
341*0Sstevel@tonic-gate resetmnttab(fp);
342*0Sstevel@tonic-gate
343*0Sstevel@tonic-gate /*
344*0Sstevel@tonic-gate * getextmntent() Is used here so that we can use mnt_major
345*0Sstevel@tonic-gate * and mnt_minor to get the fsid. The fsid is used when
346*0Sstevel@tonic-gate * getting mount information from kstat.
347*0Sstevel@tonic-gate */
348*0Sstevel@tonic-gate while (getextmntent(fp, &mnttab_entry,
349*0Sstevel@tonic-gate sizeof (struct extmnttab)) == 0) {
350*0Sstevel@tonic-gate
351*0Sstevel@tonic-gate newp = create_extmntlist_entry(mnttab_entry);
352*0Sstevel@tonic-gate
353*0Sstevel@tonic-gate if (newp == NULL) {
354*0Sstevel@tonic-gate /*
355*0Sstevel@tonic-gate * Out of memory
356*0Sstevel@tonic-gate */
357*0Sstevel@tonic-gate fs_free_mount_list(headp);
358*0Sstevel@tonic-gate (void) fclose(fp);
359*0Sstevel@tonic-gate *errp = ENOMEM;
360*0Sstevel@tonic-gate return (NULL);
361*0Sstevel@tonic-gate }
362*0Sstevel@tonic-gate
363*0Sstevel@tonic-gate if (headp == NULL) {
364*0Sstevel@tonic-gate headp = newp;
365*0Sstevel@tonic-gate tailp = newp;
366*0Sstevel@tonic-gate } else {
367*0Sstevel@tonic-gate tailp->next = newp;
368*0Sstevel@tonic-gate tailp = newp;
369*0Sstevel@tonic-gate }
370*0Sstevel@tonic-gate
371*0Sstevel@tonic-gate } /* while (getmntent(fp, &mnttab_entry) == 0) */
372*0Sstevel@tonic-gate (void) fclose(fp);
373*0Sstevel@tonic-gate if (find_overlays)
374*0Sstevel@tonic-gate find_overlayed_filesystems(headp, B_FALSE, errp);
375*0Sstevel@tonic-gate } else {
376*0Sstevel@tonic-gate *errp = errno;
377*0Sstevel@tonic-gate } /* if ((fp = fopen(MNTTAB, "r")) != NULL) */
378*0Sstevel@tonic-gate
379*0Sstevel@tonic-gate /*
380*0Sstevel@tonic-gate * Caller must free the mount list
381*0Sstevel@tonic-gate */
382*0Sstevel@tonic-gate return (headp);
383*0Sstevel@tonic-gate } /* fs_get_mount_list */
384*0Sstevel@tonic-gate
385*0Sstevel@tonic-gate boolean_t
fs_is_readonly(char * mntpnt,int * errp)386*0Sstevel@tonic-gate fs_is_readonly(char *mntpnt, int *errp) {
387*0Sstevel@tonic-gate struct statvfs64 stvfs;
388*0Sstevel@tonic-gate boolean_t readonly;
389*0Sstevel@tonic-gate
390*0Sstevel@tonic-gate *errp = 0;
391*0Sstevel@tonic-gate if (mntpnt == NULL) {
392*0Sstevel@tonic-gate /*
393*0Sstevel@tonic-gate * Set errp to invalid parameter - EINVAL
394*0Sstevel@tonic-gate */
395*0Sstevel@tonic-gate *errp = EINVAL;
396*0Sstevel@tonic-gate return (B_FALSE);
397*0Sstevel@tonic-gate }
398*0Sstevel@tonic-gate
399*0Sstevel@tonic-gate if (statvfs64(mntpnt, &stvfs) != -1) {
400*0Sstevel@tonic-gate readonly = stvfs.f_flag & ST_RDONLY;
401*0Sstevel@tonic-gate } else {
402*0Sstevel@tonic-gate *errp = errno;
403*0Sstevel@tonic-gate return (B_FALSE);
404*0Sstevel@tonic-gate }
405*0Sstevel@tonic-gate
406*0Sstevel@tonic-gate return (readonly);
407*0Sstevel@tonic-gate } /* fs_is_readonly */
408*0Sstevel@tonic-gate
409*0Sstevel@tonic-gate /*
410*0Sstevel@tonic-gate * This method will parse the given comma delimited option list (optlist) for
411*0Sstevel@tonic-gate * the option passed into the function. If the option (opt) to search for
412*0Sstevel@tonic-gate * is one that sets a value such as onerror=, the value to the right of the "="
413*0Sstevel@tonic-gate * character will be returned from the function. This function expects the
414*0Sstevel@tonic-gate * opt parameter to have the "=" character appended when searching for options
415*0Sstevel@tonic-gate * which set a value.
416*0Sstevel@tonic-gate *
417*0Sstevel@tonic-gate * If the option is found in the given optlist, the function will return the
418*0Sstevel@tonic-gate * option as found in the option list.
419*0Sstevel@tonic-gate * If the option is not found in the given optlist, the function will return
420*0Sstevel@tonic-gate * NULL.
421*0Sstevel@tonic-gate * If an error occurs, the function will return NULL and the errp will
422*0Sstevel@tonic-gate * reflect the error that has occurred.
423*0Sstevel@tonic-gate *
424*0Sstevel@tonic-gate * NOTE: The caller must free the space allocated for the return value by using
425*0Sstevel@tonic-gate * free().
426*0Sstevel@tonic-gate */
427*0Sstevel@tonic-gate char *
fs_parse_optlist_for_option(char * optlist,char * opt,int * errp)428*0Sstevel@tonic-gate fs_parse_optlist_for_option(char *optlist, char *opt, int *errp) {
429*0Sstevel@tonic-gate const char *delimiter = ",";
430*0Sstevel@tonic-gate char *token;
431*0Sstevel@tonic-gate char *return_value;
432*0Sstevel@tonic-gate char *optlist_copy;
433*0Sstevel@tonic-gate
434*0Sstevel@tonic-gate *errp = 0;
435*0Sstevel@tonic-gate optlist_copy = strdup(optlist);
436*0Sstevel@tonic-gate if (optlist_copy == NULL) {
437*0Sstevel@tonic-gate *errp = errno;
438*0Sstevel@tonic-gate return (NULL);
439*0Sstevel@tonic-gate }
440*0Sstevel@tonic-gate
441*0Sstevel@tonic-gate token = strtok(optlist_copy, delimiter);
442*0Sstevel@tonic-gate /*
443*0Sstevel@tonic-gate * Check to see if we have found the option.
444*0Sstevel@tonic-gate */
445*0Sstevel@tonic-gate if (token == NULL) {
446*0Sstevel@tonic-gate free(optlist_copy);
447*0Sstevel@tonic-gate return (NULL);
448*0Sstevel@tonic-gate } else if ((return_value = is_option(token, opt, errp)) != NULL) {
449*0Sstevel@tonic-gate free(optlist_copy);
450*0Sstevel@tonic-gate return (return_value);
451*0Sstevel@tonic-gate }
452*0Sstevel@tonic-gate
453*0Sstevel@tonic-gate while (token != NULL) {
454*0Sstevel@tonic-gate token = NULL;
455*0Sstevel@tonic-gate token = strtok(NULL, delimiter);
456*0Sstevel@tonic-gate /*
457*0Sstevel@tonic-gate * If token is NULL then then we are at the end of the list
458*0Sstevel@tonic-gate * and we can return NULL because the option was never found in
459*0Sstevel@tonic-gate * the option list.
460*0Sstevel@tonic-gate */
461*0Sstevel@tonic-gate if (token == NULL) {
462*0Sstevel@tonic-gate free(optlist_copy);
463*0Sstevel@tonic-gate return (NULL);
464*0Sstevel@tonic-gate } else if ((return_value =
465*0Sstevel@tonic-gate is_option(token, opt, errp)) != NULL) {
466*0Sstevel@tonic-gate
467*0Sstevel@tonic-gate free(optlist_copy);
468*0Sstevel@tonic-gate return (return_value);
469*0Sstevel@tonic-gate
470*0Sstevel@tonic-gate }
471*0Sstevel@tonic-gate }
472*0Sstevel@tonic-gate free(optlist_copy);
473*0Sstevel@tonic-gate return (NULL);
474*0Sstevel@tonic-gate }
475*0Sstevel@tonic-gate
476*0Sstevel@tonic-gate unsigned long long
fs_get_totalsize(char * mntpnt,int * errp)477*0Sstevel@tonic-gate fs_get_totalsize(char *mntpnt, int *errp) {
478*0Sstevel@tonic-gate struct statvfs64 stvfs;
479*0Sstevel@tonic-gate unsigned long long totalsize;
480*0Sstevel@tonic-gate
481*0Sstevel@tonic-gate *errp = 0;
482*0Sstevel@tonic-gate if (mntpnt == NULL) {
483*0Sstevel@tonic-gate /*
484*0Sstevel@tonic-gate * Set errp to invalid parameter - EINVAL
485*0Sstevel@tonic-gate */
486*0Sstevel@tonic-gate *errp = EINVAL;
487*0Sstevel@tonic-gate return (0);
488*0Sstevel@tonic-gate }
489*0Sstevel@tonic-gate
490*0Sstevel@tonic-gate if (statvfs64(mntpnt, &stvfs) != -1) {
491*0Sstevel@tonic-gate totalsize = stvfs.f_blocks;
492*0Sstevel@tonic-gate totalsize = totalsize * stvfs.f_frsize;
493*0Sstevel@tonic-gate
494*0Sstevel@tonic-gate } else {
495*0Sstevel@tonic-gate *errp = errno;
496*0Sstevel@tonic-gate return (0);
497*0Sstevel@tonic-gate } /* if (statvfs64(mntpnt, &stvfs) != -1) */
498*0Sstevel@tonic-gate
499*0Sstevel@tonic-gate return (totalsize);
500*0Sstevel@tonic-gate } /* fs_get_totalsize */
501*0Sstevel@tonic-gate
502*0Sstevel@tonic-gate unsigned long long
fs_get_usedsize(char * mntpnt,int * errp)503*0Sstevel@tonic-gate fs_get_usedsize(char *mntpnt, int *errp) {
504*0Sstevel@tonic-gate struct statvfs64 stvfs;
505*0Sstevel@tonic-gate unsigned long long usedsize;
506*0Sstevel@tonic-gate
507*0Sstevel@tonic-gate *errp = 0;
508*0Sstevel@tonic-gate if (mntpnt == NULL) {
509*0Sstevel@tonic-gate /*
510*0Sstevel@tonic-gate * Set errp to invalid parameter - EINVAL
511*0Sstevel@tonic-gate */
512*0Sstevel@tonic-gate *errp = EINVAL;
513*0Sstevel@tonic-gate return (0);
514*0Sstevel@tonic-gate }
515*0Sstevel@tonic-gate
516*0Sstevel@tonic-gate if (statvfs64(mntpnt, &stvfs) != -1) {
517*0Sstevel@tonic-gate usedsize = stvfs.f_blocks - stvfs.f_bfree;
518*0Sstevel@tonic-gate usedsize = usedsize * stvfs.f_frsize;
519*0Sstevel@tonic-gate } else {
520*0Sstevel@tonic-gate *errp = errno;
521*0Sstevel@tonic-gate return (0);
522*0Sstevel@tonic-gate } /* if (statvfs64(mntpnt, &stvfs) != -1) */
523*0Sstevel@tonic-gate
524*0Sstevel@tonic-gate return (usedsize);
525*0Sstevel@tonic-gate } /* fs_get_usedsize */
526*0Sstevel@tonic-gate
527*0Sstevel@tonic-gate /*
528*0Sstevel@tonic-gate * Private methods
529*0Sstevel@tonic-gate */
530*0Sstevel@tonic-gate
531*0Sstevel@tonic-gate static fs_mntlist_t *
create_mntlist_entry(struct mnttab mnttab_entry)532*0Sstevel@tonic-gate create_mntlist_entry(struct mnttab mnttab_entry) {
533*0Sstevel@tonic-gate
534*0Sstevel@tonic-gate fs_mntlist_t *newp;
535*0Sstevel@tonic-gate
536*0Sstevel@tonic-gate newp = (fs_mntlist_t *)calloc((size_t)1,
537*0Sstevel@tonic-gate (size_t)sizeof (fs_mntlist_t));
538*0Sstevel@tonic-gate
539*0Sstevel@tonic-gate if (newp == NULL) {
540*0Sstevel@tonic-gate /*
541*0Sstevel@tonic-gate * Out of memory
542*0Sstevel@tonic-gate */
543*0Sstevel@tonic-gate return (NULL);
544*0Sstevel@tonic-gate }
545*0Sstevel@tonic-gate
546*0Sstevel@tonic-gate newp->resource = strdup(mnttab_entry.mnt_special);
547*0Sstevel@tonic-gate if (newp->resource == NULL) {
548*0Sstevel@tonic-gate /*
549*0Sstevel@tonic-gate * Out of memory
550*0Sstevel@tonic-gate */
551*0Sstevel@tonic-gate fs_free_mount_list(newp);
552*0Sstevel@tonic-gate return (NULL);
553*0Sstevel@tonic-gate }
554*0Sstevel@tonic-gate newp->mountp = strdup(mnttab_entry.mnt_mountp);
555*0Sstevel@tonic-gate if (newp->mountp == NULL) {
556*0Sstevel@tonic-gate /*
557*0Sstevel@tonic-gate * Out of memory
558*0Sstevel@tonic-gate */
559*0Sstevel@tonic-gate fs_free_mount_list(newp);
560*0Sstevel@tonic-gate return (NULL);
561*0Sstevel@tonic-gate }
562*0Sstevel@tonic-gate newp->fstype = strdup(mnttab_entry.mnt_fstype);
563*0Sstevel@tonic-gate if (newp->fstype == NULL) {
564*0Sstevel@tonic-gate /*
565*0Sstevel@tonic-gate * Out of memory
566*0Sstevel@tonic-gate */
567*0Sstevel@tonic-gate fs_free_mount_list(newp);
568*0Sstevel@tonic-gate return (NULL);
569*0Sstevel@tonic-gate }
570*0Sstevel@tonic-gate newp->mntopts = strdup(mnttab_entry.mnt_mntopts);
571*0Sstevel@tonic-gate if (newp->mntopts == NULL) {
572*0Sstevel@tonic-gate /*
573*0Sstevel@tonic-gate * Out of memory
574*0Sstevel@tonic-gate */
575*0Sstevel@tonic-gate fs_free_mount_list(newp);
576*0Sstevel@tonic-gate return (NULL);
577*0Sstevel@tonic-gate }
578*0Sstevel@tonic-gate newp->time = strdup(mnttab_entry.mnt_time);
579*0Sstevel@tonic-gate if (newp->time == NULL) {
580*0Sstevel@tonic-gate /*
581*0Sstevel@tonic-gate * Out of memory
582*0Sstevel@tonic-gate */
583*0Sstevel@tonic-gate fs_free_mount_list(newp);
584*0Sstevel@tonic-gate return (NULL);
585*0Sstevel@tonic-gate }
586*0Sstevel@tonic-gate newp->next = NULL;
587*0Sstevel@tonic-gate
588*0Sstevel@tonic-gate return (newp);
589*0Sstevel@tonic-gate } /* create_mntlist_entry */
590*0Sstevel@tonic-gate
591*0Sstevel@tonic-gate static fs_mntlist_t *
create_extmntlist_entry(struct extmnttab mnttab_entry)592*0Sstevel@tonic-gate create_extmntlist_entry(struct extmnttab mnttab_entry) {
593*0Sstevel@tonic-gate
594*0Sstevel@tonic-gate fs_mntlist_t *newp;
595*0Sstevel@tonic-gate
596*0Sstevel@tonic-gate newp = (fs_mntlist_t *)calloc((size_t)1,
597*0Sstevel@tonic-gate (size_t)sizeof (fs_mntlist_t));
598*0Sstevel@tonic-gate
599*0Sstevel@tonic-gate if (newp == NULL) {
600*0Sstevel@tonic-gate /*
601*0Sstevel@tonic-gate * Out of memory
602*0Sstevel@tonic-gate */
603*0Sstevel@tonic-gate return (NULL);
604*0Sstevel@tonic-gate }
605*0Sstevel@tonic-gate
606*0Sstevel@tonic-gate newp->resource = strdup(mnttab_entry.mnt_special);
607*0Sstevel@tonic-gate if (newp->resource == NULL) {
608*0Sstevel@tonic-gate /*
609*0Sstevel@tonic-gate * Out of memory
610*0Sstevel@tonic-gate */
611*0Sstevel@tonic-gate fs_free_mount_list(newp);
612*0Sstevel@tonic-gate return (NULL);
613*0Sstevel@tonic-gate }
614*0Sstevel@tonic-gate newp->mountp = strdup(mnttab_entry.mnt_mountp);
615*0Sstevel@tonic-gate if (newp->mountp == NULL) {
616*0Sstevel@tonic-gate /*
617*0Sstevel@tonic-gate * Out of memory
618*0Sstevel@tonic-gate */
619*0Sstevel@tonic-gate fs_free_mount_list(newp);
620*0Sstevel@tonic-gate return (NULL);
621*0Sstevel@tonic-gate }
622*0Sstevel@tonic-gate newp->fstype = strdup(mnttab_entry.mnt_fstype);
623*0Sstevel@tonic-gate if (newp->fstype == NULL) {
624*0Sstevel@tonic-gate /*
625*0Sstevel@tonic-gate * Out of memory
626*0Sstevel@tonic-gate */
627*0Sstevel@tonic-gate fs_free_mount_list(newp);
628*0Sstevel@tonic-gate return (NULL);
629*0Sstevel@tonic-gate }
630*0Sstevel@tonic-gate newp->mntopts = strdup(mnttab_entry.mnt_mntopts);
631*0Sstevel@tonic-gate if (newp->mntopts == NULL) {
632*0Sstevel@tonic-gate /*
633*0Sstevel@tonic-gate * Out of memory
634*0Sstevel@tonic-gate */
635*0Sstevel@tonic-gate fs_free_mount_list(newp);
636*0Sstevel@tonic-gate return (NULL);
637*0Sstevel@tonic-gate }
638*0Sstevel@tonic-gate newp->time = strdup(mnttab_entry.mnt_time);
639*0Sstevel@tonic-gate if (newp->time == NULL) {
640*0Sstevel@tonic-gate /*
641*0Sstevel@tonic-gate * Out of memory
642*0Sstevel@tonic-gate */
643*0Sstevel@tonic-gate fs_free_mount_list(newp);
644*0Sstevel@tonic-gate return (NULL);
645*0Sstevel@tonic-gate }
646*0Sstevel@tonic-gate newp->major = mnttab_entry.mnt_major;
647*0Sstevel@tonic-gate
648*0Sstevel@tonic-gate newp->minor = mnttab_entry.mnt_minor;
649*0Sstevel@tonic-gate
650*0Sstevel@tonic-gate newp->next = NULL;
651*0Sstevel@tonic-gate
652*0Sstevel@tonic-gate return (newp);
653*0Sstevel@tonic-gate } /* create_extmntlist_entry */
654*0Sstevel@tonic-gate
655*0Sstevel@tonic-gate static struct mnttab *
create_mnttab_filter(char * resource,char * mountp,char * fstype,char * mntopts,char * time)656*0Sstevel@tonic-gate create_mnttab_filter(char *resource, char *mountp, char *fstype, char *mntopts,
657*0Sstevel@tonic-gate char *time) {
658*0Sstevel@tonic-gate
659*0Sstevel@tonic-gate struct mnttab *search_entry;
660*0Sstevel@tonic-gate
661*0Sstevel@tonic-gate search_entry = (struct mnttab *)calloc((size_t)1,
662*0Sstevel@tonic-gate (size_t)sizeof (struct mnttab));
663*0Sstevel@tonic-gate
664*0Sstevel@tonic-gate if (search_entry == NULL) {
665*0Sstevel@tonic-gate /*
666*0Sstevel@tonic-gate * Out of memory
667*0Sstevel@tonic-gate */
668*0Sstevel@tonic-gate return (NULL);
669*0Sstevel@tonic-gate }
670*0Sstevel@tonic-gate
671*0Sstevel@tonic-gate if (resource != NULL) {
672*0Sstevel@tonic-gate search_entry->mnt_special = strdup(resource);
673*0Sstevel@tonic-gate if (search_entry->mnt_special == NULL) {
674*0Sstevel@tonic-gate /*
675*0Sstevel@tonic-gate * Out of memory
676*0Sstevel@tonic-gate */
677*0Sstevel@tonic-gate free_mnttab_entry(search_entry);
678*0Sstevel@tonic-gate return (NULL);
679*0Sstevel@tonic-gate }
680*0Sstevel@tonic-gate }
681*0Sstevel@tonic-gate
682*0Sstevel@tonic-gate if (mountp != NULL) {
683*0Sstevel@tonic-gate search_entry->mnt_mountp = strdup(mountp);
684*0Sstevel@tonic-gate if (search_entry->mnt_mountp == NULL) {
685*0Sstevel@tonic-gate /*
686*0Sstevel@tonic-gate * Out of memory
687*0Sstevel@tonic-gate */
688*0Sstevel@tonic-gate free_mnttab_entry(search_entry);
689*0Sstevel@tonic-gate return (NULL);
690*0Sstevel@tonic-gate }
691*0Sstevel@tonic-gate }
692*0Sstevel@tonic-gate
693*0Sstevel@tonic-gate if (fstype != NULL) {
694*0Sstevel@tonic-gate search_entry->mnt_fstype = strdup(fstype);
695*0Sstevel@tonic-gate if (search_entry->mnt_fstype == NULL) {
696*0Sstevel@tonic-gate /*
697*0Sstevel@tonic-gate * Out of memory
698*0Sstevel@tonic-gate */
699*0Sstevel@tonic-gate free_mnttab_entry(search_entry);
700*0Sstevel@tonic-gate return (NULL);
701*0Sstevel@tonic-gate }
702*0Sstevel@tonic-gate }
703*0Sstevel@tonic-gate
704*0Sstevel@tonic-gate if (mntopts != NULL) {
705*0Sstevel@tonic-gate search_entry->mnt_mntopts = strdup(mntopts);
706*0Sstevel@tonic-gate if (search_entry->mnt_mntopts == NULL) {
707*0Sstevel@tonic-gate /*
708*0Sstevel@tonic-gate * Out of memory
709*0Sstevel@tonic-gate */
710*0Sstevel@tonic-gate free_mnttab_entry(search_entry);
711*0Sstevel@tonic-gate return (NULL);
712*0Sstevel@tonic-gate }
713*0Sstevel@tonic-gate }
714*0Sstevel@tonic-gate
715*0Sstevel@tonic-gate if (time != NULL) {
716*0Sstevel@tonic-gate search_entry->mnt_time = strdup(time);
717*0Sstevel@tonic-gate if (search_entry->mnt_time == NULL) {
718*0Sstevel@tonic-gate /*
719*0Sstevel@tonic-gate * Out of memory
720*0Sstevel@tonic-gate */
721*0Sstevel@tonic-gate free_mnttab_entry(search_entry);
722*0Sstevel@tonic-gate return (NULL);
723*0Sstevel@tonic-gate }
724*0Sstevel@tonic-gate }
725*0Sstevel@tonic-gate
726*0Sstevel@tonic-gate return (search_entry);
727*0Sstevel@tonic-gate } /* create_mnttab_filter */
728*0Sstevel@tonic-gate
729*0Sstevel@tonic-gate /*
730*0Sstevel@tonic-gate * We will go through the /etc/mnttab entries to determine the
731*0Sstevel@tonic-gate * instances of overlayed file systems. We do this with the following
732*0Sstevel@tonic-gate * assumptions:
733*0Sstevel@tonic-gate *
734*0Sstevel@tonic-gate * 1.) Entries in mnttab are ordered in the way that the most recent
735*0Sstevel@tonic-gate * mounts are placed at the bottom of /etc/mnttab. Contract to be
736*0Sstevel@tonic-gate * filed:
737*0Sstevel@tonic-gate * 2.) Mnttab entries that are returned from all mnttab library
738*0Sstevel@tonic-gate * functions such as getmntent, getextmntent, and getmntany in the order
739*0Sstevel@tonic-gate * as they are found in /etc/mnttab. Goes along with assumption #1.
740*0Sstevel@tonic-gate * 3.) All automounted NFS file systems will have an autofs entry and
741*0Sstevel@tonic-gate * a NFS entry in /etc/mnttab with the same mount point. Autofs
742*0Sstevel@tonic-gate * entries can be ignored.
743*0Sstevel@tonic-gate * 4.) The device id (dev=) uniquely identifies a mounted file system
744*0Sstevel@tonic-gate * on a host.
745*0Sstevel@tonic-gate *
746*0Sstevel@tonic-gate * Algorithm explanation:
747*0Sstevel@tonic-gate * ----------------------
748*0Sstevel@tonic-gate * For each mnt_list entry
749*0Sstevel@tonic-gate * 1.) Compare it to each /etc/mnttab entry starting at the point in mnttab
750*0Sstevel@tonic-gate * where the mnt_list entry mount is and look for matching mount points,
751*0Sstevel@tonic-gate * but ignore all "autofs" entries
752*0Sstevel@tonic-gate * If a two entries are found with the same mount point mark the mnt_list
753*0Sstevel@tonic-gate * entry as being overlayed.
754*0Sstevel@tonic-gate */
755*0Sstevel@tonic-gate static void
find_overlayed_filesystems(fs_mntlist_t * mnt_list,boolean_t filtered_list,int * errp)756*0Sstevel@tonic-gate find_overlayed_filesystems(fs_mntlist_t *mnt_list,
757*0Sstevel@tonic-gate boolean_t filtered_list, int *errp) {
758*0Sstevel@tonic-gate
759*0Sstevel@tonic-gate boolean_t exit = B_FALSE;
760*0Sstevel@tonic-gate fs_mntlist_t *mnt_list_to_compare;
761*0Sstevel@tonic-gate fs_mntlist_t *tmp;
762*0Sstevel@tonic-gate
763*0Sstevel@tonic-gate *errp = 0;
764*0Sstevel@tonic-gate if (filtered_list == B_TRUE) {
765*0Sstevel@tonic-gate /*
766*0Sstevel@tonic-gate * Get the complete mount list
767*0Sstevel@tonic-gate */
768*0Sstevel@tonic-gate mnt_list_to_compare = fs_get_mount_list(B_FALSE, errp);
769*0Sstevel@tonic-gate if (mnt_list_to_compare == NULL) {
770*0Sstevel@tonic-gate /*
771*0Sstevel@tonic-gate * If complete_mnt_list is NULL there are two
772*0Sstevel@tonic-gate * possibilites:
773*0Sstevel@tonic-gate * 1.) There are simply no entries in /etc/mnttab.
774*0Sstevel@tonic-gate * 2.) An error was encountered. errp will reflect
775*0Sstevel@tonic-gate * the error.
776*0Sstevel@tonic-gate */
777*0Sstevel@tonic-gate
778*0Sstevel@tonic-gate return;
779*0Sstevel@tonic-gate }
780*0Sstevel@tonic-gate } else {
781*0Sstevel@tonic-gate mnt_list_to_compare = mnt_list;
782*0Sstevel@tonic-gate }
783*0Sstevel@tonic-gate
784*0Sstevel@tonic-gate tmp = mnt_list_to_compare;
785*0Sstevel@tonic-gate
786*0Sstevel@tonic-gate while (mnt_list != NULL) {
787*0Sstevel@tonic-gate if (!(strcmp(mnt_list->fstype, "autofs") == 0)) {
788*0Sstevel@tonic-gate char *dev_id;
789*0Sstevel@tonic-gate
790*0Sstevel@tonic-gate dev_id = fs_parse_optlist_for_option(mnt_list->mntopts,
791*0Sstevel@tonic-gate "dev=", errp);
792*0Sstevel@tonic-gate if (dev_id == NULL) {
793*0Sstevel@tonic-gate return;
794*0Sstevel@tonic-gate }
795*0Sstevel@tonic-gate
796*0Sstevel@tonic-gate exit = B_FALSE;
797*0Sstevel@tonic-gate while (tmp != NULL && exit == B_FALSE) {
798*0Sstevel@tonic-gate if (!(strcmp(tmp->fstype, "autofs")) == 0) {
799*0Sstevel@tonic-gate char *tmp_dev_id;
800*0Sstevel@tonic-gate
801*0Sstevel@tonic-gate tmp_dev_id =
802*0Sstevel@tonic-gate fs_parse_optlist_for_option(
803*0Sstevel@tonic-gate tmp->mntopts, "dev=", errp);
804*0Sstevel@tonic-gate if (tmp_dev_id == NULL) {
805*0Sstevel@tonic-gate return;
806*0Sstevel@tonic-gate }
807*0Sstevel@tonic-gate
808*0Sstevel@tonic-gate if (strcmp(tmp_dev_id, dev_id) == 0) {
809*0Sstevel@tonic-gate /*
810*0Sstevel@tonic-gate * Start searching for an
811*0Sstevel@tonic-gate * overlay here.
812*0Sstevel@tonic-gate */
813*0Sstevel@tonic-gate mnt_list->overlayed =
814*0Sstevel@tonic-gate is_overlayed(tmp,
815*0Sstevel@tonic-gate mnt_list->mountp);
816*0Sstevel@tonic-gate exit = B_TRUE;
817*0Sstevel@tonic-gate }
818*0Sstevel@tonic-gate free(tmp_dev_id);
819*0Sstevel@tonic-gate }
820*0Sstevel@tonic-gate tmp = tmp->next;
821*0Sstevel@tonic-gate } /* while (tmp != NULL && exit == B_FALSE) */
822*0Sstevel@tonic-gate free(dev_id);
823*0Sstevel@tonic-gate } /* if (!(strcmp(mnt_list->fstype, "autofs") == 0)) */
824*0Sstevel@tonic-gate mnt_list = mnt_list->next;
825*0Sstevel@tonic-gate } /* while (mnt_list != NULL) */
826*0Sstevel@tonic-gate
827*0Sstevel@tonic-gate if (filtered_list == B_TRUE)
828*0Sstevel@tonic-gate fs_free_mount_list(mnt_list_to_compare);
829*0Sstevel@tonic-gate } /* find_overlayed_filesystems */
830*0Sstevel@tonic-gate
831*0Sstevel@tonic-gate static void
free_mnttab_entry(struct mnttab * mnttab_entry)832*0Sstevel@tonic-gate free_mnttab_entry(struct mnttab *mnttab_entry) {
833*0Sstevel@tonic-gate
834*0Sstevel@tonic-gate free(mnttab_entry->mnt_special);
835*0Sstevel@tonic-gate free(mnttab_entry->mnt_mountp);
836*0Sstevel@tonic-gate free(mnttab_entry->mnt_fstype);
837*0Sstevel@tonic-gate free(mnttab_entry->mnt_mntopts);
838*0Sstevel@tonic-gate free(mnttab_entry->mnt_time);
839*0Sstevel@tonic-gate
840*0Sstevel@tonic-gate free(mnttab_entry);
841*0Sstevel@tonic-gate
842*0Sstevel@tonic-gate } /* free_mnttab_entry */
843*0Sstevel@tonic-gate
844*0Sstevel@tonic-gate char *
is_option(char * opt_string,char * opt,int * errp)845*0Sstevel@tonic-gate is_option(char *opt_string, char *opt, int *errp) {
846*0Sstevel@tonic-gate char *equalsign = "=";
847*0Sstevel@tonic-gate char *found_equalsign;
848*0Sstevel@tonic-gate char *return_val;
849*0Sstevel@tonic-gate
850*0Sstevel@tonic-gate *errp = 0;
851*0Sstevel@tonic-gate found_equalsign = strstr(opt, equalsign);
852*0Sstevel@tonic-gate
853*0Sstevel@tonic-gate /*
854*0Sstevel@tonic-gate * If found_equalsign is NULL then we did not find an equal sign
855*0Sstevel@tonic-gate * in the option we are to be looking for.
856*0Sstevel@tonic-gate */
857*0Sstevel@tonic-gate if (found_equalsign == NULL) {
858*0Sstevel@tonic-gate if (strcmp(opt_string, opt) == 0) {
859*0Sstevel@tonic-gate /*
860*0Sstevel@tonic-gate * We have found the option so return with success.
861*0Sstevel@tonic-gate */
862*0Sstevel@tonic-gate return_val = strdup(opt);
863*0Sstevel@tonic-gate if (return_val == NULL) {
864*0Sstevel@tonic-gate *errp = errno;
865*0Sstevel@tonic-gate return (NULL);
866*0Sstevel@tonic-gate }
867*0Sstevel@tonic-gate } else {
868*0Sstevel@tonic-gate return_val = NULL;
869*0Sstevel@tonic-gate }
870*0Sstevel@tonic-gate } else {
871*0Sstevel@tonic-gate int counter = 0;
872*0Sstevel@tonic-gate char *opt_found;
873*0Sstevel@tonic-gate char *value;
874*0Sstevel@tonic-gate
875*0Sstevel@tonic-gate opt_found = strstr(opt_string, opt);
876*0Sstevel@tonic-gate
877*0Sstevel@tonic-gate if (opt_found == NULL) {
878*0Sstevel@tonic-gate return_val = NULL;
879*0Sstevel@tonic-gate } else {
880*0Sstevel@tonic-gate size_t opt_string_len;
881*0Sstevel@tonic-gate size_t opt_len;
882*0Sstevel@tonic-gate size_t value_len;
883*0Sstevel@tonic-gate
884*0Sstevel@tonic-gate opt_string_len = strlen(opt_string);
885*0Sstevel@tonic-gate opt_len = strlen(opt);
886*0Sstevel@tonic-gate
887*0Sstevel@tonic-gate value_len = opt_string_len - opt_len;
888*0Sstevel@tonic-gate
889*0Sstevel@tonic-gate value = (char *)calloc((size_t)(value_len+1),
890*0Sstevel@tonic-gate (size_t)sizeof (char));
891*0Sstevel@tonic-gate
892*0Sstevel@tonic-gate if (value == NULL) {
893*0Sstevel@tonic-gate /*
894*0Sstevel@tonic-gate * Out of memory
895*0Sstevel@tonic-gate */
896*0Sstevel@tonic-gate *errp = ENOMEM;
897*0Sstevel@tonic-gate return (NULL);
898*0Sstevel@tonic-gate
899*0Sstevel@tonic-gate }
900*0Sstevel@tonic-gate
901*0Sstevel@tonic-gate while (counter <= (value_len-1)) {
902*0Sstevel@tonic-gate value[counter] = opt_string[opt_len+counter];
903*0Sstevel@tonic-gate counter = counter + 1;
904*0Sstevel@tonic-gate }
905*0Sstevel@tonic-gate /*
906*0Sstevel@tonic-gate * Add the null terminating character.
907*0Sstevel@tonic-gate */
908*0Sstevel@tonic-gate value[counter] = '\0';
909*0Sstevel@tonic-gate return_val = value;
910*0Sstevel@tonic-gate }
911*0Sstevel@tonic-gate } /* else */
912*0Sstevel@tonic-gate
913*0Sstevel@tonic-gate return (return_val);
914*0Sstevel@tonic-gate } /* is_option */
915*0Sstevel@tonic-gate
916*0Sstevel@tonic-gate
917*0Sstevel@tonic-gate boolean_t
is_overlayed(fs_mntlist_t * mnt_list,char * mountp)918*0Sstevel@tonic-gate is_overlayed(fs_mntlist_t *mnt_list, char *mountp) {
919*0Sstevel@tonic-gate boolean_t ret_val = B_FALSE;
920*0Sstevel@tonic-gate
921*0Sstevel@tonic-gate /*
922*0Sstevel@tonic-gate * The first entry in the complete_mnt_list is the same mounted
923*0Sstevel@tonic-gate * file system as the one we are trying to determine whether it is
924*0Sstevel@tonic-gate * overlayed or not. There is no need to compare these mounts.
925*0Sstevel@tonic-gate */
926*0Sstevel@tonic-gate mnt_list = mnt_list->next;
927*0Sstevel@tonic-gate
928*0Sstevel@tonic-gate while (mnt_list != NULL && ret_val == B_FALSE) {
929*0Sstevel@tonic-gate if (!(strcmp(mnt_list->fstype, "autofs") == 0)) {
930*0Sstevel@tonic-gate if (strcmp(mnt_list->mountp, mountp) == 0) {
931*0Sstevel@tonic-gate ret_val = B_TRUE;
932*0Sstevel@tonic-gate } else {
933*0Sstevel@tonic-gate ret_val = B_FALSE;
934*0Sstevel@tonic-gate }
935*0Sstevel@tonic-gate }
936*0Sstevel@tonic-gate mnt_list = mnt_list->next;
937*0Sstevel@tonic-gate }
938*0Sstevel@tonic-gate return (ret_val);
939*0Sstevel@tonic-gate } /* is_overlayed */
940