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