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 #pragma ident "%Z%%M% %I% %E% SMI" 23*7c478bd9Sstevel@tonic-gate 24*7c478bd9Sstevel@tonic-gate /* 25*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 26*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 27*7c478bd9Sstevel@tonic-gate */ 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <stdio.h> 30*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 31*7c478bd9Sstevel@tonic-gate #include <string.h> 32*7c478bd9Sstevel@tonic-gate #include <errno.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/mount.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 35*7c478bd9Sstevel@tonic-gate #include <locale.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 37*7c478bd9Sstevel@tonic-gate #include <fslib.h> 38*7c478bd9Sstevel@tonic-gate #include <stdio.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/mnttab.h> 40*7c478bd9Sstevel@tonic-gate #include <poll.h> 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate #define MNTTYPE_TMPFS "tmpfs" 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate static int nmflg = 0; 45*7c478bd9Sstevel@tonic-gate static int qflg = 0; 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate static boolean_t 48*7c478bd9Sstevel@tonic-gate in_mnttab(char *mountp) 49*7c478bd9Sstevel@tonic-gate { 50*7c478bd9Sstevel@tonic-gate FILE *file; 51*7c478bd9Sstevel@tonic-gate int found = B_FALSE; 52*7c478bd9Sstevel@tonic-gate struct mnttab mntent; 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate if ((file = fopen("/etc/mnttab", "r")) == NULL) 55*7c478bd9Sstevel@tonic-gate return (B_FALSE); 56*7c478bd9Sstevel@tonic-gate while (getmntent(file, &mntent) == 0) { 57*7c478bd9Sstevel@tonic-gate if (mntent.mnt_mountp != NULL && 58*7c478bd9Sstevel@tonic-gate strcmp(mntent.mnt_mountp, mountp) == 0 && 59*7c478bd9Sstevel@tonic-gate mntent.mnt_fstype != NULL && 60*7c478bd9Sstevel@tonic-gate strcmp(mntent.mnt_fstype, MNTTYPE_TMPFS) == 0) { 61*7c478bd9Sstevel@tonic-gate found = B_TRUE; 62*7c478bd9Sstevel@tonic-gate break; 63*7c478bd9Sstevel@tonic-gate } 64*7c478bd9Sstevel@tonic-gate } 65*7c478bd9Sstevel@tonic-gate (void) fclose(file); 66*7c478bd9Sstevel@tonic-gate return (found); 67*7c478bd9Sstevel@tonic-gate } 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate int 70*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 71*7c478bd9Sstevel@tonic-gate { 72*7c478bd9Sstevel@tonic-gate /* mount information */ 73*7c478bd9Sstevel@tonic-gate char *special; 74*7c478bd9Sstevel@tonic-gate char *mountp; 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate int c; 77*7c478bd9Sstevel@tonic-gate char *myname; 78*7c478bd9Sstevel@tonic-gate char typename[64]; 79*7c478bd9Sstevel@tonic-gate extern int optind; 80*7c478bd9Sstevel@tonic-gate extern char *optarg; 81*7c478bd9Sstevel@tonic-gate int error = 0; 82*7c478bd9Sstevel@tonic-gate int verbose = 0; 83*7c478bd9Sstevel@tonic-gate int mflg = 0; 84*7c478bd9Sstevel@tonic-gate int optcnt = 0; 85*7c478bd9Sstevel@tonic-gate int mount_attempts = 5; 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate char optbuf[MAX_MNTOPT_STR]; 88*7c478bd9Sstevel@tonic-gate int optsize = 0; 89*7c478bd9Sstevel@tonic-gate char *saveoptbuf; 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 94*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 95*7c478bd9Sstevel@tonic-gate #endif 96*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate myname = strrchr(argv[0], '/'); 99*7c478bd9Sstevel@tonic-gate myname = myname ? myname + 1 : argv[0]; 100*7c478bd9Sstevel@tonic-gate (void) snprintf(typename, sizeof (typename), "%s_%s", 101*7c478bd9Sstevel@tonic-gate MNTTYPE_TMPFS, myname); 102*7c478bd9Sstevel@tonic-gate argv[0] = typename; 103*7c478bd9Sstevel@tonic-gate optbuf[0] = '\0'; 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "?o:VmOq")) != EOF) { 106*7c478bd9Sstevel@tonic-gate switch (c) { 107*7c478bd9Sstevel@tonic-gate case 'V': 108*7c478bd9Sstevel@tonic-gate verbose++; 109*7c478bd9Sstevel@tonic-gate break; 110*7c478bd9Sstevel@tonic-gate case '?': 111*7c478bd9Sstevel@tonic-gate error++; 112*7c478bd9Sstevel@tonic-gate break; 113*7c478bd9Sstevel@tonic-gate case 'm': 114*7c478bd9Sstevel@tonic-gate nmflg++; 115*7c478bd9Sstevel@tonic-gate break; 116*7c478bd9Sstevel@tonic-gate case 'O': 117*7c478bd9Sstevel@tonic-gate mflg |= MS_OVERLAY; 118*7c478bd9Sstevel@tonic-gate break; 119*7c478bd9Sstevel@tonic-gate case 'o': 120*7c478bd9Sstevel@tonic-gate (void) strncpy(optbuf, optarg, MAX_MNTOPT_STR); 121*7c478bd9Sstevel@tonic-gate optbuf[MAX_MNTOPT_STR - 1] = '\0'; 122*7c478bd9Sstevel@tonic-gate optsize = strlen(optbuf); 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate if (verbose) 125*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "optsize:%d optbuf:%s\n", 126*7c478bd9Sstevel@tonic-gate optsize, optbuf); 127*7c478bd9Sstevel@tonic-gate break; 128*7c478bd9Sstevel@tonic-gate case 'q': 129*7c478bd9Sstevel@tonic-gate qflg++; 130*7c478bd9Sstevel@tonic-gate break; 131*7c478bd9Sstevel@tonic-gate } 132*7c478bd9Sstevel@tonic-gate } 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate if (verbose && !error) { 135*7c478bd9Sstevel@tonic-gate char *optptr; 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s", typename); 138*7c478bd9Sstevel@tonic-gate for (optcnt = 1; optcnt < argc; optcnt++) { 139*7c478bd9Sstevel@tonic-gate optptr = argv[optcnt]; 140*7c478bd9Sstevel@tonic-gate if (optptr) 141*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, " %s", optptr); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n"); 144*7c478bd9Sstevel@tonic-gate } 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate if (argc - optind != 2 || error) { 147*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 148*7c478bd9Sstevel@tonic-gate gettext("Usage: %s [-o size] swap mount_point\n"), 149*7c478bd9Sstevel@tonic-gate typename); 150*7c478bd9Sstevel@tonic-gate exit(32); 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate special = argv[optind++]; 154*7c478bd9Sstevel@tonic-gate mountp = argv[optind++]; 155*7c478bd9Sstevel@tonic-gate mflg |= MS_OPTIONSTR; 156*7c478bd9Sstevel@tonic-gate mflg |= (nmflg ? MS_NOMNTTAB : 0); 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate if (verbose) { 159*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "mount(%s, \"%s\", %d, %s", 160*7c478bd9Sstevel@tonic-gate special, mountp, mflg, MNTTYPE_TMPFS); 161*7c478bd9Sstevel@tonic-gate if (optsize) 162*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, ", \"%s\", %d)\n", 163*7c478bd9Sstevel@tonic-gate optbuf, strlen(optbuf)); 164*7c478bd9Sstevel@tonic-gate else 165*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, ")\n"); 166*7c478bd9Sstevel@tonic-gate } 167*7c478bd9Sstevel@tonic-gate if (optsize) { 168*7c478bd9Sstevel@tonic-gate if ((saveoptbuf = strdup(optbuf)) == NULL) { 169*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: out of memory\n"), 170*7c478bd9Sstevel@tonic-gate "mount"); 171*7c478bd9Sstevel@tonic-gate exit(1); 172*7c478bd9Sstevel@tonic-gate } 173*7c478bd9Sstevel@tonic-gate } 174*7c478bd9Sstevel@tonic-gate again: if (mount(special, mountp, mflg, MNTTYPE_TMPFS, NULL, 0, 175*7c478bd9Sstevel@tonic-gate optbuf, MAX_MNTOPT_STR)) { 176*7c478bd9Sstevel@tonic-gate if (errno == EBUSY && !(mflg & MS_OVERLAY)) { 177*7c478bd9Sstevel@tonic-gate /* 178*7c478bd9Sstevel@tonic-gate * Because of bug 6176743, any attempt to mount 179*7c478bd9Sstevel@tonic-gate * tmpfs filesystem could fail for reasons 180*7c478bd9Sstevel@tonic-gate * described in that bug. We're trying to detect 181*7c478bd9Sstevel@tonic-gate * that situation here by checking that the filesystem 182*7c478bd9Sstevel@tonic-gate * we're mounting is not in /etc/mnttab yet. 183*7c478bd9Sstevel@tonic-gate * When that bug is fixed, this code can be removed. 184*7c478bd9Sstevel@tonic-gate */ 185*7c478bd9Sstevel@tonic-gate if (!in_mnttab(mountp) && mount_attempts-- > 0) { 186*7c478bd9Sstevel@tonic-gate (void) poll(NULL, 0, 50); 187*7c478bd9Sstevel@tonic-gate goto again; 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 190*7c478bd9Sstevel@tonic-gate "%s: %s is already mounted or %s is busy\n"), 191*7c478bd9Sstevel@tonic-gate myname, mountp, special); 192*7c478bd9Sstevel@tonic-gate } else { 193*7c478bd9Sstevel@tonic-gate perror("mount"); 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate exit(32); 196*7c478bd9Sstevel@tonic-gate } 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate if (optsize && !qflg) 199*7c478bd9Sstevel@tonic-gate cmp_requested_to_actual_options(saveoptbuf, optbuf, 200*7c478bd9Sstevel@tonic-gate special, mountp); 201*7c478bd9Sstevel@tonic-gate return (0); 202*7c478bd9Sstevel@tonic-gate } 203