2 #include <linux/types.h>
17 #include <sys/ioctl.h>
18 #include <sys/types.h>
23 #include <linux/auto_fs4.h>
25 #include "include/log.h"
26 #include "include/sys.h"
27 #include "include/timer.h"
28 #include "include/mount.h"
29 #include "include/signal.h"
30 #include "include/ucix.h"
31 #include "include/autofs.h"
33 static int fdin
= 0; /* data coming out of the kernel */
34 static int fdout
= 0;/* data going into the kernel */
35 static bool term
= false;
38 static time_t uci_timeout
;
41 static void umount_autofs(void)
43 system_printf("umount %s 2> /dev/null", "/tmp/run/mountd/");
46 static int mount_autofs(void)
50 log_printf("trying to mount %s as the autofs root\n", "/tmp/run/mountd/");
51 if(is_mounted(0, "/tmp/run/mountd/"))
53 log_printf("%s is already mounted\n", "/tmp/run/mountd/");
57 mkdir("/tmp/run/mountd/", 0555);
60 log_printf("failed to get kernel pipe\n");
63 if(system_printf("/bin/mount -t autofs -o fd=%d,pgrp=%u,minproto=5,maxproto=5 \"mountd(pid%u)\" %s",
64 pipefd
[1], (unsigned) getpgrp(), getpid(), "/tmp/run/mountd/") != 0)
66 log_printf("unable to mount autofs on %s\n", "/tmp/run/mountd/");
75 fdin
= open("/tmp/run/mountd/", O_RDONLY
);
81 stat("/tmp/run/mountd/", &st
);
85 static void send_ready(unsigned int wait_queue_token
)
87 if(ioctl(fdin
, AUTOFS_IOC_READY
, wait_queue_token
) < 0)
88 log_printf("failed to report ready to kernel\n");
91 static void send_fail(unsigned int wait_queue_token
)
93 if(ioctl(fdin
, AUTOFS_IOC_FAIL
, wait_queue_token
) < 0)
94 log_printf("failed to report fail to kernel\n");
97 static int autofs_process_request(const struct autofs_v5_packet
*pkt
)
100 log_printf("kernel is requesting a mount -> %s\n", pkt
->name
);
101 chdir("/tmp/run/mountd/");
102 if (lstat(pkt
->name
, &st
) == -1 || (S_ISDIR(st
.st_mode
) && st
.st_dev
== dev
)) {
103 if(!mount_new("/tmp/run/mountd/", (char*)pkt
->name
))
105 send_ready(pkt
->wait_queue_token
);
107 send_fail(pkt
->wait_queue_token
);
108 log_printf("failed to mount %s\n", pkt
->name
);
111 send_ready(pkt
->wait_queue_token
);
118 static void expire_proc(void)
120 struct autofs_packet_expire pkt
;
121 while(ioctl(fdin
, AUTOFS_IOC_EXPIRE
, &pkt
) == 0)
122 mount_remove("/tmp/run/mountd/", pkt
.name
);
125 static int fullread(void *ptr
, size_t len
)
127 char *buf
= (char *) ptr
;
130 ssize_t r
= read(fdout
, buf
, len
);
143 static int autofs_in(union autofs_v5_packet_union
*pkt
)
146 struct pollfd fds
[1];
149 fds
[0].events
= POLLIN
;
153 res
= poll(fds
, 1, -1);
159 log_printf("failed while trying to read packet from kernel\n");
162 else if ((res
> 0) && (fds
[0].revents
& POLLIN
))
164 return fullread(pkt
, sizeof(*pkt
));
170 pid_t
autofs_safe_fork(void)
181 static void autofs_cleanup(void)
188 static void autofs_end_handler(int sig
)
193 static void autofs_init(void)
197 struct uci_context
*ctx
;
198 signal_init(autofs_end_handler
);
199 ctx
= ucix_init("mountd");
200 uci_timeout
= ucix_get_option_int(ctx
, "mountd", "mountd", "timeout", 60);
201 p
= ucix_get_option(ctx
, "mountd", "mountd", "path");
204 snprintf(uci_path
, 31, "%s", p
);
206 snprintf(uci_path
, 31, "/tmp/mounts/");
208 mkdir("/tmp/run/", 0555);
209 mkdir("/tmp/mounts", 0555);
210 system_printf("rm -rf %s*", uci_path
);
215 if(mount_autofs() < 0)
220 ioctl(fdin
, AUTOFS_IOC_PROTOVER
, &kproto_version
);
221 if(kproto_version
!= 5)
223 log_printf("only kernel protocol version 5 is tested. You have %d.\n",
228 ioctl(fdin
, AUTOFS_IOC_SETTIMEOUT
, &uci_timeout
);
229 timer_add(expire_proc
, 15);
232 int autofs_loop(void)
238 union autofs_v5_packet_union pkt
;
243 log_printf("Got a autofs packet\n");
244 if(pkt
.hdr
.type
== autofs_ptype_missing_indirect
)
245 autofs_process_request(&pkt
.missing_indirect
);
247 log_printf("unknown packet type %d\n", pkt
.hdr
.type
);
251 log_printf("... quitting\n");