4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
28
29
30 #include <stdio.h>
31 #include <stdio_ext.h>
32 #include <limits.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <sys/signal.h>
37 #include <sys/mnttab.h>
38 #include <errno.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <sys/param.h>
42 #include <sys/wait.h>
43 #include <sys/vfstab.h>
62
63 extern void rpterr(), usage(), mnterror();
64
65 extern char *optarg; /* used by getopt */
66 extern int optind, opterr;
67
68 static char *myname;
69 char fs_path[] = FS_PATH;
70 char alt_path[] = ALT_PATH;
71 char mnttab[MAXPATHLEN + 1];
72 char *oarg, *farg;
73 int maxrun, nrun;
74 int no_mnttab;
75 int lofscnt; /* presence of lofs prohibits parallel */
76 /* umounting */
77 int exitcode;
78 char resolve[MAXPATHLEN];
79 static char ibuf[BUFSIZ];
80
81 /*
82 * Currently, mounting cachefs's simultaneous uncovers various problems.
83 * For the short term, we serialize cachefs activity while we fix
84 * these cachefs bugs.
85 */
86 #define CACHEFS_BUG
87 #ifdef CACHEFS_BUG
88 #include <sys/fs/cachefs_fs.h> /* for BACKMNT_NAME */
89 int cachefs_running; /* parallel cachefs not supported yet */
90 #endif
91
92 /*
93 * The basic mount struct that describes an mnttab entry.
94 * It is used both in an array and as a linked list elem.
95 */
96
97 typedef struct mountent {
98 struct mnttab ment; /* the mnttab data */
99 int mlevel; /* mount level of the mount pt */
100 pid_t pid; /* the pid of this mount process */
101 #define RDPIPE 0
102 #define WRPIPE 1
103 int sopipe[2]; /* pipe attached to child's stdout */
104 int sepipe[2]; /* pipe attached to child's stderr */
105 struct mountent *link; /* used when in linked list */
106 } mountent_t;
107
108 static mountent_t *mntll; /* head of global linked list of */
109 /* mountents */
110 int listlength; /* # of elems in this list */
111
112 /*
801 */
802 if (mp->mlevel < mpprev->mlevel || lofscnt > 0)
803 while (nrun > 0 && (dowait() != -1))
804 ;
805
806 if (lofscnt == 0) {
807 /*
808 * We can now go to parallel umounting.
809 */
810 qsort((void *)ml, cnt, sizeof (mountent_t *), mcompar);
811 mp = *ml; /* possible first entry */
812 lofscnt--; /* so we don't do this again */
813 }
814
815 while (setup_iopipe(mp) == -1 && (dowait() != -1))
816 ;
817
818 while (nrun >= maxrun && (dowait() != -1)) /* throttle */
819 ;
820
821 #ifdef CACHEFS_BUG
822 /*
823 * If this is the back file system, then let cachefs/umount
824 * unmount it.
825 */
826 if (strstr(mp->ment.mnt_mountp, BACKMNT_NAME))
827 continue;
828
829
830 if (mp->ment.mnt_fstype &&
831 (strcmp(mp->ment.mnt_fstype, "cachefs") == 0)) {
832 while (cachefs_running && (dowait() != -1))
833 ;
834 cachefs_running = 1;
835 }
836 #endif
837
838 if ((pid = fork()) == -1) {
839 perror("fork");
840 cleanup(-1);
841 /* not reached */
842 }
843 #ifdef DEBUG
844 if (dflg && pid > 0) {
845 fprintf(stderr, "parent %d: umounting %d %s\n",
846 getpid(), pid, mp->ment.mnt_mountp);
847 }
848 #endif
849 if (pid == 0) { /* child */
850 signal(SIGHUP, SIG_IGN);
851 signal(SIGQUIT, SIG_IGN);
852 signal(SIGINT, SIG_IGN);
853 setup_output(mp);
854 doexec(&mp->ment);
855 perror("exec");
856 exit(1);
857 }
927 break;
928 }
929
930 if (mp == NULL) {
931 /*
932 * This should never happen.
933 */
934 #ifdef DEBUG
935 fprintf(stderr, gettext(
936 "%s: unknown child %d\n"), myname, child);
937 #endif
938 exitcode = 1;
939 return (1);
940 }
941 doio(mp); /* Any output? */
942
943 if (mp->ment.mnt_fstype &&
944 (strcmp(mp->ment.mnt_fstype, MNTTYPE_LOFS) == 0))
945 lofscnt--;
946
947 #ifdef CACHEFS_BUG
948 if (mp->ment.mnt_fstype &&
949 (strcmp(mp->ment.mnt_fstype, "cachefs") == 0))
950 cachefs_running = 0;
951 #endif
952
953 return (ret);
954 }
955
956 static const mountent_t zmount = { 0 };
957
958 mountent_t *
959 new_mountent(struct mnttab *ment)
960 {
961 mountent_t *new;
962
963 new = (mountent_t *)malloc(sizeof (*new));
964 if (new == NULL)
965 nomem();
966
967 *new = zmount;
968 if (ment->mnt_special &&
969 (new->ment.mnt_special = strdup(ment->mnt_special)) == NULL)
970 nomem();
971 if (ment->mnt_mountp &&
972 (new->ment.mnt_mountp = strdup(ment->mnt_mountp)) == NULL)
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30
31 #include <stdio.h>
32 #include <stdio_ext.h>
33 #include <limits.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/signal.h>
38 #include <sys/mnttab.h>
39 #include <errno.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <sys/param.h>
43 #include <sys/wait.h>
44 #include <sys/vfstab.h>
63
64 extern void rpterr(), usage(), mnterror();
65
66 extern char *optarg; /* used by getopt */
67 extern int optind, opterr;
68
69 static char *myname;
70 char fs_path[] = FS_PATH;
71 char alt_path[] = ALT_PATH;
72 char mnttab[MAXPATHLEN + 1];
73 char *oarg, *farg;
74 int maxrun, nrun;
75 int no_mnttab;
76 int lofscnt; /* presence of lofs prohibits parallel */
77 /* umounting */
78 int exitcode;
79 char resolve[MAXPATHLEN];
80 static char ibuf[BUFSIZ];
81
82 /*
83 * The basic mount struct that describes an mnttab entry.
84 * It is used both in an array and as a linked list elem.
85 */
86
87 typedef struct mountent {
88 struct mnttab ment; /* the mnttab data */
89 int mlevel; /* mount level of the mount pt */
90 pid_t pid; /* the pid of this mount process */
91 #define RDPIPE 0
92 #define WRPIPE 1
93 int sopipe[2]; /* pipe attached to child's stdout */
94 int sepipe[2]; /* pipe attached to child's stderr */
95 struct mountent *link; /* used when in linked list */
96 } mountent_t;
97
98 static mountent_t *mntll; /* head of global linked list of */
99 /* mountents */
100 int listlength; /* # of elems in this list */
101
102 /*
791 */
792 if (mp->mlevel < mpprev->mlevel || lofscnt > 0)
793 while (nrun > 0 && (dowait() != -1))
794 ;
795
796 if (lofscnt == 0) {
797 /*
798 * We can now go to parallel umounting.
799 */
800 qsort((void *)ml, cnt, sizeof (mountent_t *), mcompar);
801 mp = *ml; /* possible first entry */
802 lofscnt--; /* so we don't do this again */
803 }
804
805 while (setup_iopipe(mp) == -1 && (dowait() != -1))
806 ;
807
808 while (nrun >= maxrun && (dowait() != -1)) /* throttle */
809 ;
810
811 if ((pid = fork()) == -1) {
812 perror("fork");
813 cleanup(-1);
814 /* not reached */
815 }
816 #ifdef DEBUG
817 if (dflg && pid > 0) {
818 fprintf(stderr, "parent %d: umounting %d %s\n",
819 getpid(), pid, mp->ment.mnt_mountp);
820 }
821 #endif
822 if (pid == 0) { /* child */
823 signal(SIGHUP, SIG_IGN);
824 signal(SIGQUIT, SIG_IGN);
825 signal(SIGINT, SIG_IGN);
826 setup_output(mp);
827 doexec(&mp->ment);
828 perror("exec");
829 exit(1);
830 }
900 break;
901 }
902
903 if (mp == NULL) {
904 /*
905 * This should never happen.
906 */
907 #ifdef DEBUG
908 fprintf(stderr, gettext(
909 "%s: unknown child %d\n"), myname, child);
910 #endif
911 exitcode = 1;
912 return (1);
913 }
914 doio(mp); /* Any output? */
915
916 if (mp->ment.mnt_fstype &&
917 (strcmp(mp->ment.mnt_fstype, MNTTYPE_LOFS) == 0))
918 lofscnt--;
919
920 return (ret);
921 }
922
923 static const mountent_t zmount = { 0 };
924
925 mountent_t *
926 new_mountent(struct mnttab *ment)
927 {
928 mountent_t *new;
929
930 new = (mountent_t *)malloc(sizeof (*new));
931 if (new == NULL)
932 nomem();
933
934 *new = zmount;
935 if (ment->mnt_special &&
936 (new->ment.mnt_special = strdup(ment->mnt_special)) == NULL)
937 nomem();
938 if (ment->mnt_mountp &&
939 (new->ment.mnt_mountp = strdup(ment->mnt_mountp)) == NULL)
|