4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
32 #include <sys/param.h>
34 #include <sys/mntent.h>
35 #include <sys/mnttab.h>
36 #include <sys/mount.h>
37 #include <sys/utsname.h>
38 #include <sys/tiuser.h>
45 #include "automount.h"
47 static int process_opts(char *options
, int *directp
, int *sawnestp
);
48 void netbuf_free(struct netbuf
*);
61 struct utsname utsname
;
62 autofs_args
*fnip
= NULL
;
63 int mount_timeout
= AUTOFS_MOUNT_TIMEOUT
;
64 int sawnest
, len
, error
= 0;
65 char *buf
, rel_mntpnt
[MAXPATHLEN
];
68 trace_prt(1, " mount_autofs %s on %s\n",
69 me
->map_fs
->mfs_dir
, mntpnt
);
71 if (strcmp(mntpnt
, "/-") == 0) {
72 syslog(LOG_ERR
, "invalid mountpoint: /-");
77 * get relative mountpoint
79 sprintf(rel_mntpnt
, ".%s", mntpnt
+strlen(rootp
));
82 trace_prt(1, "rel_mntpnt = %s\n", rel_mntpnt
);
84 if (uname(&utsname
) < 0) {
86 syslog(LOG_ERR
, "uname %s", strerror(error
));
90 if ((fnip
= (autofs_args
*)
91 malloc(sizeof (autofs_args
))) == NULL
) {
94 (void) memset(fnip
, 0, sizeof (*fnip
));
96 if ((fnip
->addr
.buf
= (char *)malloc(MAXADDRLEN
)) == NULL
)
99 (void) strcpy(fnip
->addr
.buf
, utsname
.nodename
);
100 (void) strcat(fnip
->addr
.buf
, ".autofs");
102 if ((fnip
->opts
= malloc(MAX_MNTOPT_STR
)) == NULL
)
104 strcpy(fnip
->opts
, me
->map_mntopts
);
106 if (process_opts(fnip
->opts
, &fnip
->direct
, &sawnest
) != 0)
109 fnip
->addr
.len
= strlen(fnip
->addr
.buf
);
110 fnip
->addr
.maxlen
= fnip
->addr
.len
;
113 * get absolute mountpoint
115 if ((fnip
->path
= strdup(mntpnt
)) == NULL
)
117 if ((fnip
->map
= strdup(me
->map_fs
->mfs_dir
)) == NULL
)
119 if ((fnip
->subdir
= strdup(subdir
)) == NULL
)
123 * This timeout is really ignored by autofs, it uses the
124 * parent directory's timeout since it's really the one
125 * specified/inherited from the original mount by 'automount'
127 fnip
->mount_to
= mount_timeout
; /* IGNORED */
128 fnip
->rpc_to
= AUTOFS_RPC_TIMEOUT
;
131 if (me
->map_modified
== TRUE
|| me
->map_faked
== TRUE
) {
132 if ((fnip
->key
= strdup(key
)) == NULL
)
135 /* wierd case of a direct map pointer in another map */
136 if ((fnip
->key
= strdup(fnip
->path
)) == NULL
)
144 * Fill out action list.
146 alp
->action
.action
= AUTOFS_MOUNT_RQ
;
147 if ((alp
->action
.action_list_entry_u
.mounta
.spec
=
148 strdup(me
->map_fs
->mfs_dir
)) == NULL
)
150 if ((alp
->action
.action_list_entry_u
.mounta
.dir
=
151 strdup(rel_mntpnt
)) == NULL
)
154 len
= strlen(fnip
->opts
);
156 * Get a buffer for the option string, it holds the map options plus
157 * space for "nest" if it isn't already in the option string
159 if ((buf
= (char *)malloc(MAX_MNTOPT_STR
)) == NULL
)
161 strcpy(buf
, fnip
->opts
);
163 if (len
+ strlen(",nest") + 1 > MAX_MNTOPT_STR
)
166 (void) strcat(buf
, ",");
167 (void) strcat(buf
, "nest");
169 alp
->action
.action_list_entry_u
.mounta
.optptr
= buf
;
170 alp
->action
.action_list_entry_u
.mounta
.optlen
= strlen(buf
) + 1;
171 alp
->action
.action_list_entry_u
.mounta
.flags
=
172 mntflags
| MS_DATA
| MS_OPTIONSTR
;
173 if ((alp
->action
.action_list_entry_u
.mounta
.fstype
=
174 strdup(MNTTYPE_AUTOFS
)) == NULL
)
176 alp
->action
.action_list_entry_u
.mounta
.dataptr
= (char *)fnip
;
177 alp
->action
.action_list_entry_u
.mounta
.datalen
= sizeof (*fnip
);
183 * We got an error, free the memory we allocated.
185 syslog(LOG_ERR
, "mount_autofs: memory allocation failure");
186 free_autofs_args(fnip
);
187 alp
->action
.action_list_entry_u
.mounta
.dataptr
= NULL
;
188 alp
->action
.action_list_entry_u
.mounta
.datalen
= 0;
189 free_mounta(&alp
->action
.action_list_entry_u
.mounta
);
191 return (error
? error
: ENOMEM
);
195 * Set *directp to 1 if "direct" is found, and 0 otherwise
196 * (mounts are indirect by default). If both "direct" and "indirect" are
197 * found, the last one wins.
200 process_opts(char *options
, int *directp
, int *sawnestp
)
202 char *opt
, *opts
, *lasts
;
203 char buf
[AUTOFS_MAXOPTSLEN
];
205 assert(strlen(options
)+1 < AUTOFS_MAXOPTSLEN
);
208 strcpy(buf
, options
);
213 while ((opt
= strtok_r(opts
, ",", &lasts
)) != NULL
) {
215 while (isspace(*opt
)) {
218 if (strcmp(opt
, "direct") == 0) {
220 } else if (strcmp(opt
, "indirect") == 0) {
222 } else if (strcmp(opt
, "ignore") != 0) {
223 if (strcmp(opt
, "nest") == 0) {
226 if (options
[0] != '\0') {
227 (void) strcat(options
, ",");
229 (void) strcat(options
, opt
);
236 * Free autofs_args structure
239 free_autofs_args(autofs_args
*p
)
253 * free mounta structure. Assumes that m->dataptr has
257 free_mounta(struct mounta
*m
)
265 assert(m
->dataptr
== NULL
);
266 assert(m
->datalen
== 0);
268 * no need to free 'm' since it is part of the
269 * action_list_entry structure.