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 int fdin = 0; /* data coming out of the kernel */
34 int fdout = 0;/* data going into the kernel */
40 static void umount_autofs(void)
42 system_printf("umount %s 2> /dev/null", "/tmp/run/mountd/");
45 static int mount_autofs(void)
49 log_printf("trying to mount %s as the autofs root\n", "/tmp/run/mountd/");
50 if(is_mounted(0, "/tmp/run/mountd/"))
52 log_printf("%s is already mounted\n", "/tmp/run/mountd/");
56 mkdir("/tmp/run/mountd/", 0555);
59 log_printf("failed to get kernel pipe\n");
62 if(system_printf("/bin/mount -t autofs -o fd=%d,pgrp=%u,minproto=5,maxproto=5 \"mountd(pid%u)\" %s",
63 pipefd[1], (unsigned) getpgrp(), getpid(), "/tmp/run/mountd/") != 0)
65 log_printf("unable to mount autofs on %s\n", "/tmp/run/mountd/");
74 fdin = open("/tmp/run/mountd/", O_RDONLY);
80 stat("/tmp/run/mountd/", &st);
84 static void send_ready(unsigned int wait_queue_token)
86 if(ioctl(fdin, AUTOFS_IOC_READY, wait_queue_token) < 0)
87 log_printf("failed to report ready to kernel\n");
90 static void send_fail(unsigned int wait_queue_token)
92 if(ioctl(fdin, AUTOFS_IOC_FAIL, wait_queue_token) < 0)
93 log_printf("failed to report fail to kernel\n");
96 static int autofs_process_request(const struct autofs_v5_packet *pkt)
99 log_printf("kernel is requesting a mount -> %s\n", pkt->name);
100 chdir("/tmp/run/mountd/");
101 if (lstat(pkt->name, &st) == -1 || (S_ISDIR(st.st_mode) && st.st_dev == dev)) {
102 if(!mount_new("/tmp/run/mountd/", (char*)pkt->name))
104 send_ready(pkt->wait_queue_token);
106 send_fail(pkt->wait_queue_token);
107 log_printf("failed to mount %s\n", pkt->name);
110 send_ready(pkt->wait_queue_token);
117 static void expire_proc(void)
119 struct autofs_packet_expire pkt;
120 while(ioctl(fdin, AUTOFS_IOC_EXPIRE, &pkt) == 0)
121 mount_remove("/tmp/run/mountd/", pkt.name);
124 static int fullread(void *ptr, size_t len)
126 char *buf = (char *) ptr;
129 ssize_t r = read(fdout, buf, len);
142 static int autofs_in(union autofs_v5_packet_union *pkt)
145 struct pollfd fds[1];
148 fds[0].events = POLLIN;
152 res = poll(fds, 1, -1);
158 log_printf("failed while trying to read packet from kernel\n");
161 else if ((res > 0) && (fds[0].revents & POLLIN))
163 return fullread(pkt, sizeof(*pkt));
168 pid_t autofs_safe_fork(void)
179 static void autofs_cleanup_handler(void)
186 static void autofs_init(void)
190 struct uci_context *ctx;
191 signal_init(autofs_cleanup_handler);
192 ctx = ucix_init("mountd");
193 uci_timeout = ucix_get_option_int(ctx, "mountd", "mountd", "timeout", 60);
194 p = ucix_get_option(ctx, "mountd", "mountd", "path");
197 snprintf(uci_path, 31, "%s", p);
199 snprintf(uci_path, 31, "/tmp/mounts/");
201 mkdir("/tmp/run/", 0555);
202 mkdir("/tmp/mounts", 0555);
203 system_printf("rm -rf %s*", uci_path);
208 if(mount_autofs() < 0)
213 ioctl(fdin, AUTOFS_IOC_PROTOVER, &kproto_version);
214 if(kproto_version != 5)
216 log_printf("only kernel protocol version 5 is tested. You have %d.\n",
221 ioctl(fdin, AUTOFS_IOC_SETTIMEOUT, &uci_timeout);
222 timer_add(expire_proc, 15);
225 int autofs_loop(void)
231 union autofs_v5_packet_union pkt;
236 log_printf("Got a autofs packet\n");
237 if(pkt.hdr.type == autofs_ptype_missing_indirect)
238 autofs_process_request(&pkt.missing_indirect);
240 log_printf("unknown packet type %d\n", pkt.hdr.type);
244 log_printf("... quitting\n");