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 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 /* All Rights Reserved */
23
24
25 /*
26 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
28 */
29 /*
30 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
31 */
32
33 #include <stdio.h>
34 #include <stdio_ext.h>
35 #include <limits.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <stdarg.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <sys/statvfs.h>
44 #include <errno.h>
45 #include <sys/mnttab.h>
46 #include <sys/mntent.h>
47 #include <sys/mount.h>
48 #include <sys/vfstab.h>
49 #include <sys/param.h>
50 #include <sys/wait.h>
122 * and should cover the case where a long option string can be in
123 * the /etc/vfstab file.
124 */
125 char mntflags[(_POSIX_MAX_INPUT+1) * 2];
126
127 char realdir[MAXPATHLEN]; /* buffer for realpath() calls */
128 char *vfstab = VFSTAB;
129 char *mnttab = MNTTAB;
130 char *specific_opts; /* holds specific mount options */
131 char *generic_opts; /* holds generic mount options */
132 int maxrun;
133 int nrun;
134 int failcnt; /* total count of failures */
135 int lofscnt; /* presence of lofs prohibits parallel */
136 /* mounting */
137 int lofsfail; /* count of failures of lofs mounts */
138 int exitcode;
139 int aflg, cflg, fflg, Fflg, gflg, oflg, pflg, rflg, vflg, Vflg, mflg, Oflg,
140 dashflg, questflg, dflg, qflg;
141
142 /*
143 * Currently, mounting cachefs instances simultaneously uncovers various
144 * problems. For the short term, we serialize cachefs activity while we fix
145 * these cachefs bugs.
146 */
147 #define CACHEFS_BUG
148 #ifdef CACHEFS_BUG
149 int cachefs_running; /* parallel cachefs not supported yet */
150 #endif
151
152 /*
153 * Each vfsent_t describes a vfstab entry. It is used to manage and cleanup
154 * each child that performs the particular mount for the entry.
155 */
156
157 typedef struct vfsent {
158 struct vfstab v; /* the vfstab entry */
159 char *rpath; /* resolved pathname so far */
160 int mlevel; /* how deep is this mount point */
161 int order; /* vfstab serial order of this vfs */
162 int flag;
163 pid_t pid; /* the pid of this mount process */
164 int exitcode; /* process's exitcode */
165 #define RDPIPE 0
166 #define WRPIPE 1
167 int sopipe[2]; /* pipe attached to child's stdout */
168 int sepipe[2]; /* pipe attached to child's stderr */
169 struct vfsent *next; /* used when in linked list */
170 } vfsent_t;
1278 * if any.
1279 */
1280 i = isave;
1281 if (!oflg && vp->v.vfs_mntopts) {
1282 newargv[i++] = "-o";
1283 newargv[i++] = vp->v.vfs_mntopts;
1284 }
1285 newargv[i++] = vp->v.vfs_special;
1286 newargv[i++] = vp->rpath;
1287 newargv[i] = NULL;
1288
1289 /*
1290 * This should never really fail.
1291 */
1292 while (setup_iopipe(vp) == -1 && (dowait() != -1))
1293 ;
1294
1295 while (nrun >= maxrun && (dowait() != -1)) /* throttle */
1296 ;
1297
1298 #ifdef CACHEFS_BUG
1299 if (vp->v.vfs_fstype &&
1300 (strcmp(vp->v.vfs_fstype, "cachefs") == 0)) {
1301 while (cachefs_running && (dowait() != -1))
1302 ;
1303 cachefs_running = 1;
1304 }
1305 #endif
1306
1307 if ((child = fork()) == -1) {
1308 perror("fork");
1309 cleanup(-1);
1310 /* not reached */
1311 }
1312 if (child == 0) { /* child */
1313 signal(SIGHUP, SIG_IGN);
1314 signal(SIGQUIT, SIG_IGN);
1315 signal(SIGINT, SIG_IGN);
1316 setup_output(vp);
1317 doexec(vp->v.vfs_fstype, newargv);
1318 perror("exec");
1319 exit(1);
1320 }
1321
1322 /* parent */
1323 (void) close(vp->sopipe[WRPIPE]);
1324 (void) close(vp->sepipe[WRPIPE]);
1325 vp->pid = child;
1326 nrun++;
1457 }
1458
1459 if (vp == NULL) {
1460 /*
1461 * This should never happen.
1462 */
1463 fprintf(stderr, gettext(
1464 "%s: Unknown child %d\n"), myname, pid);
1465 exitcode = 1;
1466 return (ret);
1467 }
1468 doio(vp); /* Any output? */
1469
1470 if (vp->v.vfs_fstype &&
1471 (strcmp(vp->v.vfs_fstype, MNTTYPE_LOFS) == 0)) {
1472 lofscnt--;
1473 if (ret)
1474 lofsfail++;
1475 }
1476
1477 #ifdef CACHEFS_BUG
1478 if (vp->v.vfs_fstype && (strcmp(vp->v.vfs_fstype, "cachefs") == 0))
1479 cachefs_running = 0;
1480 #endif
1481
1482 vp->exitcode = ret;
1483 return (ret);
1484 }
1485
1486
1487 static vfsent_t zvmount = { 0 };
1488
1489 vfsent_t *
1490 new_vfsent(struct vfstab *vin, int order)
1491 {
1492 vfsent_t *new;
1493
1494 new = (vfsent_t *)malloc(sizeof (*new));
1495 if (new == NULL)
1496 nomem();
1497
1498 *new = zvmount;
1499 if (vin->vfs_special &&
1500 (new->v.vfs_special = strdup(vin->vfs_special)) == NULL)
1501 nomem();
|
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 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 /* All Rights Reserved */
23
24
25 /*
26 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
28 */
29 /*
30 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
31 */
32
33 #include <stdio.h>
34 #include <stdio_ext.h>
35 #include <limits.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <stdarg.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <sys/statvfs.h>
44 #include <errno.h>
45 #include <sys/mnttab.h>
46 #include <sys/mntent.h>
47 #include <sys/mount.h>
48 #include <sys/vfstab.h>
49 #include <sys/param.h>
50 #include <sys/wait.h>
122 * and should cover the case where a long option string can be in
123 * the /etc/vfstab file.
124 */
125 char mntflags[(_POSIX_MAX_INPUT+1) * 2];
126
127 char realdir[MAXPATHLEN]; /* buffer for realpath() calls */
128 char *vfstab = VFSTAB;
129 char *mnttab = MNTTAB;
130 char *specific_opts; /* holds specific mount options */
131 char *generic_opts; /* holds generic mount options */
132 int maxrun;
133 int nrun;
134 int failcnt; /* total count of failures */
135 int lofscnt; /* presence of lofs prohibits parallel */
136 /* mounting */
137 int lofsfail; /* count of failures of lofs mounts */
138 int exitcode;
139 int aflg, cflg, fflg, Fflg, gflg, oflg, pflg, rflg, vflg, Vflg, mflg, Oflg,
140 dashflg, questflg, dflg, qflg;
141
142
143 /*
144 * Each vfsent_t describes a vfstab entry. It is used to manage and cleanup
145 * each child that performs the particular mount for the entry.
146 */
147
148 typedef struct vfsent {
149 struct vfstab v; /* the vfstab entry */
150 char *rpath; /* resolved pathname so far */
151 int mlevel; /* how deep is this mount point */
152 int order; /* vfstab serial order of this vfs */
153 int flag;
154 pid_t pid; /* the pid of this mount process */
155 int exitcode; /* process's exitcode */
156 #define RDPIPE 0
157 #define WRPIPE 1
158 int sopipe[2]; /* pipe attached to child's stdout */
159 int sepipe[2]; /* pipe attached to child's stderr */
160 struct vfsent *next; /* used when in linked list */
161 } vfsent_t;
1269 * if any.
1270 */
1271 i = isave;
1272 if (!oflg && vp->v.vfs_mntopts) {
1273 newargv[i++] = "-o";
1274 newargv[i++] = vp->v.vfs_mntopts;
1275 }
1276 newargv[i++] = vp->v.vfs_special;
1277 newargv[i++] = vp->rpath;
1278 newargv[i] = NULL;
1279
1280 /*
1281 * This should never really fail.
1282 */
1283 while (setup_iopipe(vp) == -1 && (dowait() != -1))
1284 ;
1285
1286 while (nrun >= maxrun && (dowait() != -1)) /* throttle */
1287 ;
1288
1289 if ((child = fork()) == -1) {
1290 perror("fork");
1291 cleanup(-1);
1292 /* not reached */
1293 }
1294 if (child == 0) { /* child */
1295 signal(SIGHUP, SIG_IGN);
1296 signal(SIGQUIT, SIG_IGN);
1297 signal(SIGINT, SIG_IGN);
1298 setup_output(vp);
1299 doexec(vp->v.vfs_fstype, newargv);
1300 perror("exec");
1301 exit(1);
1302 }
1303
1304 /* parent */
1305 (void) close(vp->sopipe[WRPIPE]);
1306 (void) close(vp->sepipe[WRPIPE]);
1307 vp->pid = child;
1308 nrun++;
1439 }
1440
1441 if (vp == NULL) {
1442 /*
1443 * This should never happen.
1444 */
1445 fprintf(stderr, gettext(
1446 "%s: Unknown child %d\n"), myname, pid);
1447 exitcode = 1;
1448 return (ret);
1449 }
1450 doio(vp); /* Any output? */
1451
1452 if (vp->v.vfs_fstype &&
1453 (strcmp(vp->v.vfs_fstype, MNTTYPE_LOFS) == 0)) {
1454 lofscnt--;
1455 if (ret)
1456 lofsfail++;
1457 }
1458
1459 vp->exitcode = ret;
1460 return (ret);
1461 }
1462
1463
1464 static vfsent_t zvmount = { 0 };
1465
1466 vfsent_t *
1467 new_vfsent(struct vfstab *vin, int order)
1468 {
1469 vfsent_t *new;
1470
1471 new = (vfsent_t *)malloc(sizeof (*new));
1472 if (new == NULL)
1473 nomem();
1474
1475 *new = zvmount;
1476 if (vin->vfs_special &&
1477 (new->v.vfs_special = strdup(vin->vfs_special)) == NULL)
1478 nomem();
|