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