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
in_mnttab(char * mountp)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
main(int argc,char * argv[])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