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