Print this page
6198 Let's EOL cachefs


  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();