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