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.
28 #pragma ident "%Z%%M% %I% %E% SMI"
34 #include <sys/param.h>
36 #include <sys/mntent.h>
37 #include <sys/mnttab.h>
38 #include <sys/mount.h>
39 #include <sys/utsname.h>
40 #include <sys/tiuser.h>
47 #include "automount.h"
49 static int process_opts(char *options
, int *directp
, int *sawnestp
);
50 void netbuf_free(struct netbuf
*);
63 struct utsname utsname
;
64 autofs_args
*fnip
= NULL
;
65 int mount_timeout
= AUTOFS_MOUNT_TIMEOUT
;
66 int sawnest
, len
, error
= 0;
67 char *buf
, rel_mntpnt
[MAXPATHLEN
];
70 trace_prt(1, " mount_autofs %s on %s\n",
71 me
->map_fs
->mfs_dir
, mntpnt
);
73 if (strcmp(mntpnt
, "/-") == 0) {
74 syslog(LOG_ERR
, "invalid mountpoint: /-");
79 * get relative mountpoint
81 sprintf(rel_mntpnt
, ".%s", mntpnt
+strlen(rootp
));
84 trace_prt(1, "rel_mntpnt = %s\n", rel_mntpnt
);
86 if (uname(&utsname
) < 0) {
88 syslog(LOG_ERR
, "uname %s", strerror(error
));
92 if ((fnip
= (autofs_args
*)
93 malloc(sizeof (autofs_args
))) == NULL
) {
96 (void) memset((void *) fnip
, 0, sizeof (*fnip
));
98 if ((fnip
->addr
.buf
= (char *)malloc(MAXADDRLEN
)) == NULL
)
101 (void) strcpy(fnip
->addr
.buf
, utsname
.nodename
);
102 (void) strcat(fnip
->addr
.buf
, ".autofs");
104 if ((fnip
->opts
= malloc(MAX_MNTOPT_STR
)) == NULL
)
106 strcpy(fnip
->opts
, me
->map_mntopts
);
108 if (process_opts(fnip
->opts
, &fnip
->direct
, &sawnest
) != 0)
111 fnip
->addr
.len
= strlen(fnip
->addr
.buf
);
112 fnip
->addr
.maxlen
= fnip
->addr
.len
;
115 * get absolute mountpoint
117 if ((fnip
->path
= strdup(mntpnt
)) == NULL
)
119 if ((fnip
->map
= strdup(me
->map_fs
->mfs_dir
)) == NULL
)
121 if ((fnip
->subdir
= strdup(subdir
)) == NULL
)
125 * This timeout is really ignored by autofs, it uses the
126 * parent directory's timeout since it's really the one
127 * specified/inherited from the original mount by 'automount'
129 fnip
->mount_to
= mount_timeout
; /* IGNORED */
130 fnip
->rpc_to
= AUTOFS_RPC_TIMEOUT
;
133 if (me
->map_modified
== TRUE
|| me
->map_faked
== TRUE
) {
134 if ((fnip
->key
= strdup(key
)) == NULL
)
137 /* wierd case of a direct map pointer in another map */
138 if ((fnip
->key
= strdup(fnip
->path
)) == NULL
)
146 * Fill out action list.
148 alp
->action
.action
= AUTOFS_MOUNT_RQ
;
149 if ((alp
->action
.action_list_entry_u
.mounta
.spec
=
150 strdup(me
->map_fs
->mfs_dir
)) == NULL
)
152 if ((alp
->action
.action_list_entry_u
.mounta
.dir
=
153 strdup(rel_mntpnt
)) == NULL
)
156 len
= strlen(fnip
->opts
);
158 * Get a buffer for the option string, it holds the map options plus
159 * space for "nest" if it isn't already in the option string
161 if ((buf
= (char *)malloc(MAX_MNTOPT_STR
)) == NULL
)
163 strcpy(buf
, fnip
->opts
);
165 if (len
+ strlen(",nest") + 1 > MAX_MNTOPT_STR
)
168 (void) strcat(buf
, ",");
169 (void) strcat(buf
, "nest");
171 alp
->action
.action_list_entry_u
.mounta
.optptr
= buf
;
172 alp
->action
.action_list_entry_u
.mounta
.optlen
= strlen(buf
) + 1;
173 alp
->action
.action_list_entry_u
.mounta
.flags
=
174 mntflags
| MS_DATA
| MS_OPTIONSTR
;
175 if ((alp
->action
.action_list_entry_u
.mounta
.fstype
=
176 strdup(MNTTYPE_AUTOFS
)) == NULL
)
178 alp
->action
.action_list_entry_u
.mounta
.dataptr
= (char *)fnip
;
179 alp
->action
.action_list_entry_u
.mounta
.datalen
= sizeof (*fnip
);
185 * We got an error, free the memory we allocated.
187 syslog(LOG_ERR
, "mount_autofs: memory allocation failure");
188 free_autofs_args(fnip
);
189 alp
->action
.action_list_entry_u
.mounta
.dataptr
= NULL
;
190 alp
->action
.action_list_entry_u
.mounta
.datalen
= 0;
191 free_mounta(&alp
->action
.action_list_entry_u
.mounta
);
193 return (error
? error
: ENOMEM
);
197 * Set *directp to 1 if "direct" is found, and 0 otherwise
198 * (mounts are indirect by default). If both "direct" and "indirect" are
199 * found, the last one wins.
202 process_opts(char *options
, int *directp
, int *sawnestp
)
204 char *opt
, *opts
, *lasts
;
205 char buf
[AUTOFS_MAXOPTSLEN
];
207 assert(strlen(options
)+1 < AUTOFS_MAXOPTSLEN
);
210 strcpy(buf
, options
);
215 while ((opt
= strtok_r(opts
, ",", &lasts
)) != NULL
) {
217 while (isspace(*opt
)) {
220 if (strcmp(opt
, "direct") == 0) {
222 } else if (strcmp(opt
, "indirect") == 0) {
224 } else if (strcmp(opt
, "ignore") != 0) {
225 if (strcmp(opt
, "nest") == 0) {
228 if (options
[0] != '\0') {
229 (void) strcat(options
, ",");
231 (void) strcat(options
, opt
);
238 * Free autofs_args structure
241 free_autofs_args(autofs_args
*p
)
261 * free mounta structure. Assumes that m->dataptr has
265 free_mounta(struct mounta
*m
)
277 assert(m
->dataptr
== NULL
);
278 assert(m
->datalen
== 0);
280 * no need to free 'm' since it is part of the
281 * action_list_entry structure.