10 #include <minix/syslib.h>
17 __weak_alias(mount
, _mount
)
18 __weak_alias(umount
, _umount
)
19 __weak_alias(umount2
, _umount2
)
22 #define FSDEFAULT "mfs"
24 static char fspath
[] = "/sbin/:/usr/pkg/bin/"; /* Must include trailing '/' */
26 static int rs_down(char *label
)
29 if(strlen(_PATH_SERVICE
)+strlen(label
)+50 >= sizeof(cmd
))
31 sprintf(cmd
, _PATH_SERVICE
" down '%s'", label
);
35 char *find_rslabel(char *args_line
);
36 int mount(special
, name
, mountflags
, type
, args
)
37 char *name
, *special
, *type
, *args
;
52 if (type
== NULL
) type
= __UNCONST(FSDEFAULT
);
53 if (args
== NULL
) args
= __UNCONST("");
55 memset(path
, '\0', sizeof(path
));
57 /* Check mount flags */
58 if(mountflags
& MS_REUSE
) {
60 mountflags
&= ~MS_REUSE
; /* Temporary: turn off to not confuse VFS */
63 if(mountflags
& MS_EXISTING
) {
65 mountflags
&= ~MS_EXISTING
; /* Temporary: turn off to not confuse VFS */
68 /* Make a label for the file system process. This label must be unique and
69 * may currently not exceed 16 characters including terminating null. For
70 * requests with an associated block device, we use the last path component
71 * name of the block special file (truncated to 12 characters, which is
72 * hopefully enough). For requests with no associated block device, we use
73 * the device number and inode of the mount point, in hexadecimal form.
77 p
= strrchr(special
, '/');
78 p
= p
? p
+ 1 : special
;
79 if (strchr(p
, '\'')) {
83 sprintf(label
, "fs_%.12s", p
);
85 /* check for a rslabel option in the arguments and try to use
88 rslabel
= find_rslabel(args
);
90 snprintf(label
,16,rslabel
);
93 if (stat(name
, &statbuf
) < 0) return -1;
94 sprintf(label
, "fs_%04x%llx", statbuf
.st_dev
, statbuf
.st_ino
);
99 if (strlen(type
) < 16) {
100 sprintf(label
, "%s", type
);
107 /* Tell VFS that we are passing in a 16-byte label. */
108 mountflags
|= MS_LABEL16
;
110 /* Sanity check on user input. */
111 if(strchr(args
, '\'')) {
115 /* start the fs-server if not using existing one */
117 /* See if the given type is even remotely valid. */
120 testpath
= strtok(fspath
, ":");
123 if (strlen(testpath
) + strlen(type
) >= sizeof(path
)) {
128 strcpy(path
, testpath
);
131 if (access(path
, F_OK
) == 0) break;
133 } while ((testpath
= strtok(NULL
, ":")) != NULL
);
135 if (testpath
== NULL
) {
136 /* We were not able to find type somewhere in "fspath" */
141 if (strlen(_PATH_SERVICE
) + strlen(path
) + strlen(label
) +
142 strlen(args
) + 50 >= sizeof(cmd
)) {
147 sprintf(cmd
, _PATH_SERVICE
" %sup %s -label '%s' -args '%s %s %s%s'",
148 reuse
? "-r ": "", path
, label
, special
, name
,
149 args
[0] ? "-o " : "", args
);
151 if ((r
= system(cmd
)) != 0) {
152 fprintf(stderr
, "mount: couldn't run %s\n", cmd
);
158 /* Now perform mount(). */
159 m
.m1_i1
= special
? strlen(special
) + 1 : 0;
160 m
.m1_i2
= strlen(name
) + 1;
161 m
.m1_i3
= mountflags
;
165 r
= _syscall(VFS_PROC_NR
, MOUNT
, &m
);
167 if (r
!= OK
&& !use_existing
) {
168 /* If mount() failed, tell RS to shutdown FS process.
169 * No error check - won't do anything with this error anyway.
180 return umount2(name
, 0);
183 int umount2(name
, flags
)
192 r
= _syscall(VFS_PROC_NR
, UMOUNT
, &m
);
194 /* don't shut down the driver when exist flag is set */
195 if (!(flags
& MS_EXISTING
)) {
197 /* VFS returns the label of the unmounted file system in the reply.
198 * As of writing, the size of the m3_ca1 field is 16 bytes.
207 char *find_rslabel(args_line
)
211 * Find and return the rslabel as given as optional
212 * agument to the mount command e.g.
213 * mount -o rslabel=bla
215 * mount -o rw,rslabel=bla
216 * or as found in fstab
218 char *buf
, *input
,*saveptr
;
219 buf
= input
= saveptr
= NULL
;
221 if (args_line
== NULL
) return NULL
;
223 /* copy the input args_line we are going to modify it*/
224 input
= strndup(args_line
,20);
225 if (input
== NULL
) /* EOM */
226 return NULL
; /* it is not that bad to not find a label */
228 /* locate rslabel= in the input */
229 buf
= strstr(input
,"rslabel=");
235 /* tokenise on "," starting from rslabel (e.g null terminate )*/
236 buf
= strtok_r(buf
,",",&saveptr
);
237 /* tokenise the result again using = and take the second entry */
238 buf
= strtok_r(buf
,"=",&saveptr
);
239 buf
= strtok_r(NULL
,"=",&saveptr
);
240 /* buf is now either NULL if there was no second token or
241 * the value we are searchig for