1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _AUTOMOUNT_H
#define _AUTOMOUNT_H
#include <fslib.h> /* needed for mntlist_t declaration */
#include <thread.h>
#include <sys/mntent.h> /* " " MNTTYPE_* declarations */
#include <synch.h> /* needed for mutex_t declaration */
#include <sys/types.h>
#include <rpc/rpc.h>
#include <sys/fs/autofs.h>
#include <netinet/in.h> /* needed for sockaddr_in declaration */
#include <door.h>
#ifdef MALLOC_DEBUG
#include <debug_alloc.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _REENTRANT
#define fork1 vfork
#define rpc_control(a, b) 1
#endif
#define DOMOUNT_USER 1
#define DOMOUNT_KERNEL 2
/*
* Solaris autofs configuration file location
*/
#define AUTOFSADMIN "/etc/default/autofs"
#define MXHOSTNAMELEN 64
#define MAXNETNAMELEN 255
#define MAXFILENAMELEN 255
#define LINESZ 4096
#define MAXADDRLEN 128 /* max autofs address length */
#define MAXOPTSLEN 1024
#define AUTOFS_MOUNT_TIMEOUT 600 /* default min time mount will */
/* remain mounted (in seconds) */
#define AUTOFS_RPC_TIMEOUT 60 /* secs autofs will wait for */
/* automountd's reply before */
/* retransmitting */
/* stack ops */
#define ERASE 0
#define PUSH 1
#define POP 2
#define INIT 3
#define STACKSIZ 30
#define DIST_SELF 1
#define DIST_MYSUB 2
#define DIST_MYNET 3
#define DIST_OTHER 4
#define MAXIFS 32
/*
* Retry operation related definitions.
*/
#define RET_OK 0
#define RET_RETRY 32
#define RET_ERR 33
#define INITDELAY 5
#define DELAY_BACKOFF 2
#define MAXDELAY 120
#define ARGV_MAX 16
#define VFS_PATH "/usr/lib/fs"
#define DELAY(delay) { \
(void) sleep(delay); \
delay *= DELAY_BACKOFF; \
if (delay > MAXDELAY) \
delay = MAXDELAY; \
}
struct mapline {
char linebuf[LINESZ];
char lineqbuf[LINESZ];
};
/*
* Structure describing a host/filesystem/dir tuple in a NIS map entry
*/
struct mapfs {
struct mapfs *mfs_next; /* next in entry */
int mfs_ignore; /* ignore this entry */
char *mfs_host; /* host name */
char *mfs_dir; /* dir to mount */
int mfs_penalty; /* mount penalty for this host */
int mfs_distance; /* distance hint */
struct nfs_args *mfs_args; /* nfs_args */
struct netconfig *mfs_nconf;
rpcvers_t mfs_version; /* NFS version */
#define MFS_ALLOC_DIR 0x1 /* mfs_dir now points to different */
/* buffer */
#define MFS_URL 0x2 /* is NFS url listed in this tuple. */
#define MFS_FH_VIA_WEBNFS 0x4 /* got file handle during ping phase */
uint_t mfs_flags;
uint_t mfs_port; /* port# in NFS url */
};
/*
* NIS entry - lookup of name in DIR gets us this
*/
struct mapent {
char *map_fstype; /* file system type e.g. "nfs" */
char *map_mounter; /* base fs */
char *map_root; /* path to mount root */
char *map_mntpnt; /* path from mount root */
char *map_mntopts; /* mount options */
char *map_fsw; /* mount fs information */
char *map_fswq; /* quoted mountfs information */
int map_mntlevel; /* mapentry hierarchy level */
bool_t map_modified; /* flags modified mapentries */
bool_t map_faked; /* flags faked mapentries */
int map_err; /* flags any bad entries in the map */
struct mapfs *map_fs; /* list of replicas for nfs */
struct mapent *map_next;
};
/*
* Descriptor for each directory served by the automounter
*/
struct autodir {
char *dir_name; /* mount point */
char *dir_map; /* name of map for dir */
char *dir_opts; /* default mount options */
int dir_direct; /* direct mountpoint ? */
int dir_remount; /* a remount */
struct autodir *dir_next; /* next entry */
struct autodir *dir_prev; /* prev entry */
};
/*
* This structure is used to build an array of
* hostnames with associated penalties to be
* passed to the nfs_cast procedure
*/
struct host_names {
char *host;
int penalty;
};
/*
* structure used to build list of contents for a map on
* a readdir request
*/
struct dir_entry {
char *name; /* name of entry */
ino_t nodeid;
off_t offset;
struct dir_entry *next;
struct dir_entry *left; /* left element in binary tree */
struct dir_entry *right; /* right element in binary tree */
};
/*
* offset index table
*/
struct off_tbl {
off_t offset;
struct dir_entry *first;
struct off_tbl *next;
};
#ifndef NO_RDDIR_CACHE
/*
* directory cache for 'map'
*/
struct autofs_rddir_cache {
char *map;
struct off_tbl *offtp;
ulong_t bucket_size;
time_t ttl;
struct dir_entry *entp;
mutex_t lock; /* protects 'in_use' field */
int in_use; /* # threads referencing it */
rwlock_t rwlock; /* protects 'full' and 'next' */
int full; /* full == 1 when cache full */
struct autofs_rddir_cache *next;
};
#define RDDIR_CACHE_TIME 300 /* in seconds */
#endif /* NO_RDDIR_CACHE */
/*
* structure used to maintain address list for localhost
*/
struct myaddrs {
struct sockaddr_in sin;
struct myaddrs *myaddrs_next;
};
/*
* structure used to pass commands to the door servers
*/
typedef struct command {
char file[MAXPATHLEN];
char argv[ARGV_MAX][MAXOPTSLEN];
char key[MAXOPTSLEN];
int console;
} command_t;
/*
* globally visible door_server file descriptor
*/
extern int did_exec_map;
extern int did_fork_exec;
extern time_t timenow; /* set at start of processing of each RPC call */
extern char self[];
extern int verbose;
extern int trace;
extern int automountd_nobrowse;
extern struct autodir *dir_head;
extern struct autodir *dir_tail;
extern struct mntlist *current_mounts;
struct mounta; /* defined in sys/vfs.h */
extern struct myaddrs *myaddrs_head;
extern rwlock_t cache_lock;
extern rwlock_t portmap_cache_lock;
extern rwlock_t autofs_rddir_cache_lock;
extern mutex_t cleanup_lock;
extern cond_t cleanup_start_cv;
extern cond_t cleanup_done_cv;
/*
* mnttab handling routines
*/
extern void free_mapent(struct mapent *);
extern struct mntlist *getmntlist(void);
extern dev_t get_devid(struct extmnttab *);
/*
* utilities
*/
extern struct mapent *parse_entry(char *, char *, char *, struct mapline *,
char *, uint_t, bool_t);
extern int macro_expand(char *, char *, char *, int);
extern void unquote(char *, char *);
extern void unbracket(char **);
extern void trim(char *);
extern char *get_line(FILE *, char *, char *, int);
extern int getword(char *, char *, char **, char **, char, int);
extern int get_retry(char *);
extern int str_opt(struct mnttab *, char *, char **);
extern void put_automountd_env(void);
extern void dirinit(char *, char *, char *, int, char **, char ***);
extern void pr_msg(const char *, ...);
extern void trace_prt(int, char *, ...);
extern void free_autofs_args(autofs_args *);
extern void free_nfs_args(struct nfs_args *);
extern void free_mounta(struct mounta *);
extern int nopt(struct mnttab *, char *, int *);
extern int set_versrange(rpcvers_t, rpcvers_t *, rpcvers_t *);
extern enum clnt_stat pingnfs(char *, int, rpcvers_t *, rpcvers_t,
ushort_t, bool_t, char *, char *);
extern void *autofs_get_buffer(size_t);
extern int self_check(char *);
extern int do_mount1(char *, char *, char *, char *, char *, uint_t, uid_t,
action_list **, int);
extern int do_lookup1(char *, char *, char *, char *, char *, uint_t, uid_t,
autofs_action_t *, struct linka *);
extern int do_unmount1(umntrequest *);
extern int do_readdir(autofs_rddirargs *, autofs_rddirres *);
extern int nfsunmount(struct mnttab *);
extern int loopbackmount(char *, char *, char *, int);
extern int mount_nfs(struct mapent *, char *, char *, int, uid_t,
action_list **);
extern int mount_autofs(struct mapent *, char *, action_list *,
char *rootp, char *subdir, char *key);
extern int mount_generic(char *, char *, char *, char *, int);
extern enum clnt_stat nfs_cast(struct mapfs *, struct mapfs **, int);
extern bool_t hasrestrictopt(char *);
#ifndef NO_RDDIR_CACHE
/*
* readdir handling routines
*/
extern char *auto_rddir_malloc(unsigned);
extern char *auto_rddir_strdup(const char *);
extern struct dir_entry *btree_lookup(struct dir_entry *, char *);
extern void btree_enter(struct dir_entry **, struct dir_entry *);
extern int add_dir_entry(char *, struct dir_entry **, struct dir_entry **);
extern void cache_cleanup(void);
extern int autofs_rddir_cache_lookup(char *, struct autofs_rddir_cache **);
extern struct dir_entry *rddir_entry_lookup(char *, struct dir_entry *);
#endif /* NO_RDDIR_CACHE */
/*
* generic interface to specific name service functions
*/
extern void ns_setup(char **, char ***);
extern int getmapent(char *, char *, struct mapline *, char **, char ***,
bool_t *, bool_t);
extern int getmapkeys(char *, struct dir_entry **, int *, int *, char **,
char ***, uid_t);
extern int loadmaster_map(char *, char *, char **, char ***);
extern int loaddirect_map(char *, char *, char *, char **, char ***);
/*
* these name service specific functions should not be
* accessed directly, use the generic functions.
*/
extern void init_files(char **, char ***);
extern int getmapent_files(char *, char *, struct mapline *, char **, char ***,
bool_t *, bool_t);
extern int loadmaster_files(char *, char *, char **, char ***);
extern int loaddirect_files(char *, char *, char *, char **, char ***);
extern int getmapkeys_files(char *, struct dir_entry **, int *, int *,
char **, char ***);
extern int stack_op(int, char *, char **, char ***);
extern void init_nis(char **, char ***);
extern int getmapent_nis(char *, char *, struct mapline *, char **, char ***,
bool_t *, bool_t);
extern int loadmaster_nis(char *, char *, char **, char ***);
extern int loaddirect_nis(char *, char *, char *, char **, char ***);
extern int getmapkeys_nis(char *, struct dir_entry **, int *, int *,
char **, char ***);
extern void init_ldap(char **, char ***);
extern int getmapent_ldap(char *, char *, struct mapline *, char **, char ***,
bool_t *, bool_t);
extern int loadmaster_ldap(char *, char *, char **, char ***);
extern int loaddirect_ldap(char *, char *, char *, char **, char ***);
extern int getmapkeys_ldap(char *, struct dir_entry **, int *, int *,
char **, char ***);
/*
* end of name service specific functions
*/
/*
* not defined in any header file
*/
extern int __clnt_bindresvport(CLIENT *);
extern int getnetmaskbynet(const struct in_addr, struct in_addr *);
/*
* Hidden rpc functions
*/
extern int __nis_reset_state();
extern int __rpc_negotiate_uid(int);
/*
* door_server functions to handle fork activity within the automounter
*/
void automountd_do_fork_exec(void *, char *, size_t, door_desc_t *, uint_t);
void automountd_do_exec_map(void *, char *, size_t, door_desc_t *, uint_t);
#ifdef __cplusplus
}
#endif
#endif /* _AUTOMOUNT_H */
|