Date: Wed, 4 Mar 2009 22:03:56 +0900 (YAKT) From: Alexander Logvinov <ports@logvinov.com> To: FreeBSD-gnats-submit@FreeBSD.org Cc: Alexander Logvinov <ports@logvinov.com> Subject: ports/132309: [new port] sysutils/afuse: An automounting file system implemented in user-space using FUSE Message-ID: <200903041303.n24D3u3m040469@blg.akavia.ru> Resent-Message-ID: <200903041310.n24DA1m3090432@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 132309 >Category: ports >Synopsis: [new port] sysutils/afuse: An automounting file system implemented in user-space using FUSE >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Wed Mar 04 13:10:00 UTC 2009 >Closed-Date: >Last-Modified: >Originator: Alexander Logvinov >Release: FreeBSD 6.4-RELEASE i386 >Organization: >Environment: >Description: Afuse is an automounting file system implemented in user-space using FUSE. Afuse currently implements the most basic functionality that can be expected by an automounter; that is it manages a directory of virtual directories. If one of these virtual directories is accessed and is not already automounted, afuse will attempt to mount a filesystem onto that directory. If the mount succeeds the requested access proceeds as normal, otherwise it will fail with an error.. The advantage of using afuse over traditional automounters is that afuse is designed to run entirely in user-space by individual users. This way an automounting action can take advantage of the invoking users environment, for example allowing access to an ssh-agent for password-less sshfs mounts, or allowing access to a graphical environment to get user input to complete a mount (i.e. popping up a window asking for a password). WWW: http://afuse.sourceforge.net/ >How-To-Repeat: >Fix: # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # afuse # afuse/Makefile # afuse/distinfo # afuse/pkg-descr # afuse/files # afuse/files/patch-src_afuse.c # afuse/files/pkg-message.in # afuse/files/patch-afuse.1 # echo c - afuse mkdir -p afuse > /dev/null 2>&1 echo x - afuse/Makefile sed 's/^X//' >afuse/Makefile << '416b85b4c6a572ca95e68de5466748c7' X# New ports collection makefile for: afuse X# Date created: 03 March 2009 X# Whom: Alexander Logvinov <ports@logvinov.com> X# $FreeBSD$ X# X XPORTNAME= afuse XPORTVERSION= 0.2 XCATEGORIES= sysutils XMASTER_SITES= SF X XMAINTAINER= ports@logvinov.com XCOMMENT= An automounting file system implemented in user-space using FUSE X XLIB_DEPENDS= fuse.2:${PORTSDIR}/sysutils/fusefs-libs X XGNU_CONFIGURE= yes X XPORTDOCS= AUTHORS ChangeLog README XPLIST_FILES= bin/${PORTNAME} X XMAN1= ${PORTNAME}.1 X X.if !defined(NOPORTDOCS) XSUB_FILES= pkg-message X.endif X Xpost-install: X ${INSTALL_MAN} ${WRKSRC}/${MAN1} ${MAN1PREFIX}/man/man1 X.if !defined(NOPORTDOCS) X @${MKDIR} ${DOCSDIR} X.for i in ${PORTDOCS} X ${INSTALL_DATA} ${WRKSRC}/${i} ${DOCSDIR} X.endfor X @${CAT} ${PKGMESSAGE} X.endif X X.include <bsd.port.mk> 416b85b4c6a572ca95e68de5466748c7 echo x - afuse/distinfo sed 's/^X//' >afuse/distinfo << '8b365b92e4a45ed6ed842ef9f6182750' XMD5 (afuse-0.2.tar.gz) = 97b58a768ecb30696fb6c33dd8435b83 XSHA256 (afuse-0.2.tar.gz) = 92faa853bfeaa1446b80edbc6bb29a29f8dcf07149958be5eafc2da0679342d2 XSIZE (afuse-0.2.tar.gz) = 100568 8b365b92e4a45ed6ed842ef9f6182750 echo x - afuse/pkg-descr sed 's/^X//' >afuse/pkg-descr << '31932f0f76660a761d8e5734a9c8e643' XAfuse is an automounting file system implemented in user-space using XFUSE. Afuse currently implements the most basic functionality that can Xbe expected by an automounter; that is it manages a directory of virtual Xdirectories. If one of these virtual directories is accessed and is not Xalready automounted, afuse will attempt to mount a filesystem onto that Xdirectory. If the mount succeeds the requested access proceeds as normal, Xotherwise it will fail with an error. X XThe advantage of using afuse over traditional automounters is that afuse Xis designed to run entirely in user-space by individual users. This way an Xautomounting action can take advantage of the invoking users environment, Xfor example allowing access to an ssh-agent for password-less sshfs Xmounts, or allowing access to a graphical environment to get user input Xto complete a mount (i.e. popping up a window asking for a password). X XWWW: http://afuse.sourceforge.net/ 31932f0f76660a761d8e5734a9c8e643 echo c - afuse/files mkdir -p afuse/files > /dev/null 2>&1 echo x - afuse/files/patch-src_afuse.c sed 's/^X//' >afuse/files/patch-src_afuse.c << '559bfbccfb0f4a3953d94d5d920a5dd4' X--- src/afuse.c.orig 2009-03-03 13:17:22.000000000 +0900 X+++ src/afuse.c 2009-03-03 13:17:27.000000000 +0900 X@@ -36,7 +36,6 @@ X #include <string.h> X #include <stddef.h> X #include <unistd.h> X-#include <alloca.h> X #include <fcntl.h> X #include <dirent.h> X #include <errno.h> X@@ -280,14 +280,19 @@ X } X X X-// !!FIXME!! allow escaping of %'s X // Note: this method strips out quotes and applies them itself as should be appropriate X-char *expand_template(const char *template, const char *mount_point, const char *root_name) X+bool run_template(const char *template, const char *mount_point, const char *root_name) X { X int len = 0; X+ int nargs = 1; X int i; X- char *expanded_name; X- char *expanded_name_start; X+ char *buf; X+ char *p; X+ char **args; X+ char **arg; X+ bool quote = false; X+ pid_t pid; X+ int status; X X // calculate length X for(i = 0; template[i]; i++) X@@ -295,53 +300,100 @@ X switch(template[i + 1]) X { X case 'm': X- len += strlen(mount_point) + 2; X+ len += strlen(mount_point); X i++; X break; X case 'r': X- len += strlen(root_name) + 2; X+ len += strlen(root_name); X+ i++; X+ break; X+ case '%': X+ len++; X i++; X break; X } X- } else if(template[i] != '"') X+ } else if(template[i] == ' ' && !quote) { X+ len++; X+ nargs++; X+ } else if(template[i] == '"') X+ quote = !quote; X+ else if(template[i] == '\\' && template[i + 1]) X+ len++, i++; X+ else X len++; X X- expanded_name_start = expanded_name = my_malloc(len + 1); X+ buf = my_malloc(len + 1); X+ args = my_malloc((nargs + 1) * sizeof(*args)); X+ X+ p = buf; X+ arg = args; X+ *arg++ = p; X X for(i = 0; template[i]; i++) X if(template[i] == '%') { X- int j = 0; X switch(template[i + 1]) X { X case 'm': X- *expanded_name++ = '"'; X- while(mount_point[j]) X- *expanded_name++ = mount_point[j++]; X- *expanded_name++ = '"'; X+ strcpy(p, mount_point); X+ p += strlen(mount_point); X i++; X break; X case 'r': X- *expanded_name++ = '"'; X- while(root_name[j]) X- *expanded_name++ = root_name[j++]; X- *expanded_name++ = '"'; X+ strcpy(p, root_name); X+ p += strlen(root_name); X+ i++; X+ break; X+ case '%': X+ *p++ = '%'; X i++; X break; X } X- } else if(template[i] != '"') X- *expanded_name++ = template[i]; X- X- *expanded_name = '\0'; X- X- return expanded_name_start; X+ } else if(template[i] == ' ' && !quote) { X+ *p++ = '\0'; X+ *arg++ = p; X+ } else if(template[i] == '"') X+ quote = !quote; X+ else if(template[i] == '\\' && template[i + 1]) X+ *p++ = template[++i]; X+ else X+ *p++ = template[i]; X+ X+ *p = '\0'; X+ *arg = NULL; X+ X+ pid = fork(); X+ if(pid == -1) { X+ fprintf(stderr, "Failed to fork (%s)\n", strerror(errno)); X+ free(args); X+ free(buf); X+ return false; X+ } X+ if(pid == 0) { X+ execvp(args[0], args); X+ abort(); X+ } X+ pid = waitpid(pid, &status, 0); X+ if(pid == -1) { X+ fprintf(stderr, "Failed to waitpid (%s)\n", strerror(errno)); X+ free(args); X+ free(buf); X+ return false; X+ } X+ if(!WIFEXITED(status) || WEXITSTATUS(status) != 0) { X+ fprintf(stderr, "Failed to invoke command: %s\n", args[0]); X+ free(args); X+ free(buf); X+ return false; X+ } X+ free(args); X+ free(buf); X+ return true; X } X X mount_list_t *do_mount(const char *root_name) X { X char *mount_point; X- char *mount_command; X mount_list_t *mount; X- int sysret; X X fprintf(stderr, "Mounting: %s\n", root_name); X X@@ -351,57 +403,33 @@ X return NULL; X } X X- mount_command = expand_template(user_options.mount_command_template, X- mount_point, root_name); X- sysret = system(mount_command); X- X- fprintf(stderr, "sysret: %.8x\n", sysret); X- X- if(sysret) { X- fprintf(stderr, "Failed to invoke mount command: '%s' (%s)\n", X- mount_command, sysret != -1 ? X- "Error executing mount" : X- strerror(errno)); X- X+ if(!run_template(user_options.mount_command_template, X+ mount_point, root_name)) { X // remove the now unused directory X if( rmdir(mount_point) == -1 ) X fprintf(stderr, "Failed to remove mount point dir: %s (%s)", X mount_point, strerror(errno)); X X- free(mount_command); X free(mount_point); X return NULL; X } X X mount = add_mount(root_name, mount_point); X- X- free(mount_command); X return mount; X } X X int do_umount(mount_list_t *mount) X { X- char *unmount_command; X- int sysret; X- X fprintf(stderr, "Unmounting: %s\n", mount->root_name); X X- unmount_command = expand_template(user_options.unmount_command_template, X- mount->mount_point, mount->root_name); X- sysret = system(unmount_command); X- if(sysret) { X- fprintf(stderr, "Failed to invoke unmount command: '%s' (%s)\n", X- unmount_command, sysret != -1 ? X- "Error executing mount" : X- strerror(errno)); X- /* Still unmount anyway */ X- } X+ run_template(user_options.unmount_command_template, X+ mount->mount_point, mount->root_name); X+ /* Still unmount anyway */ X X if( rmdir(mount->mount_point) == -1 ) X fprintf(stderr, "Failed to remove mount point dir: %s (%s)", X mount->mount_point, strerror(errno)); X remove_mount(mount); X- free(unmount_command); X return 1; X } X X@@ -1504,7 +1504,8 @@ X fuse_opt_add_arg(&args, "-s"); X X // Adjust user specified timeout from seconds to microseconds as required X- user_options.auto_unmount_delay *= 1000000; X+ if(user_options.auto_unmount_delay != UINT64_MAX) X+ user_options.auto_unmount_delay *= 1000000; X X auto_unmount_ph_init(&auto_unmount_ph); X 559bfbccfb0f4a3953d94d5d920a5dd4 echo x - afuse/files/pkg-message.in sed 's/^X//' >afuse/files/pkg-message.in << '497551fe26785cd8a0dafde1a9bb61f0' X X=============================================================================== X XAdditional info about program usage can be found at X%%DOCSDIR%%/README. X X=============================================================================== 497551fe26785cd8a0dafde1a9bb61f0 echo x - afuse/files/patch-afuse.1 sed 's/^X//' >afuse/files/patch-afuse.1 << '4a6e63aec5c104138c99e3a39d306619' X--- afuse.1.orig X+++ afuse.1 X@@ -0,0 +1,95 @@ X+.TH AFUSE 1 "October 12, 2006" X+.SH NAME X+AFUSE \- automounting file system implemented in user-space using FUSE X+.SH DESCRIPTION X+usage: afuse mountpoint [options] X+.SS "general options:" X+.TP X+\fB\-o\fR opt,[opt...] X+mount options X+.TP X+\fB\-h\fR \fB\-\-help\fR X+print help X+.TP X+\fB\-V\fR \fB\-\-version\fR X+print FUSE version information X+.SS "AFUSE options:" X+.TP X+\fB\-o\fR \fB\ mount_template=CMD\fR X+template for CMD to execute to mount (*) X+.TP X+\fB\-o\fR \fB\ unmount_template=CMD\fR X+template for CMD to execute to unmount (*) (**) X+.TP X+(*) - When executed, %r and %m are expanded in templates to the root X+directory name for the new mount point, and the actual directory to X+mount onto respectively to mount onto. Both templates are REQUIRED. X+.TP X+(**)- The unmount command must perform a lazy unmount operation. E.g. the X+\-u \-z options to fusermount, or \-l for regular mount. X+.SS "FUSE options:" X+.TP X+\fB\-d\fR \fB\-o\fR debug X+enable debug output (implies \fB\-f\fR) X+.TP X+\fB\-f\fR X+foreground operation X+.TP X+\fB\-s\fR X+disable multi\-threaded operation X+.TP X+\fB\-o\fR allow_other X+allow access to other users X+.TP X+\fB\-o\fR allow_root X+allow access to root X+.TP X+\fB\-o\fR nonempty X+allow mounts over non\-empty file/dir X+.HP X+\fB\-o\fR default_permissions enable permission checking by kernel X+.TP X+\fB\-o\fR fsname=NAME X+set filesystem name X+.TP X+\fB\-o\fR large_read X+issue large read requests (2.4 only) X+.TP X+\fB\-o\fR max_read=N X+set maximum size of read requests X+.TP X+\fB\-o\fR hard_remove X+immediate removal (don't hide files) X+.TP X+\fB\-o\fR use_ino X+let filesystem set inode numbers X+.TP X+\fB\-o\fR readdir_ino X+try to fill in d_ino in readdir X+.TP X+\fB\-o\fR direct_io X+use direct I/O X+.TP X+\fB\-o\fR kernel_cache X+cache files in kernel X+.TP X+\fB\-o\fR umask=M X+set file permissions (octal) X+.TP X+\fB\-o\fR uid=N X+set file owner X+.TP X+\fB\-o\fR gid=N X+set file group X+.TP X+\fB\-o\fR entry_timeout=T X+cache timeout for names (1.0s) X+.TP X+\fB\-o\fR negative_timeout=T X+cache timeout for deleted names (0.0s) X+.TP X+\fB\-o\fR attr_timeout=T X+cache timeout for attributes (1.0s) X+.SH AUTHOR X+This manual page was written by Varun Hiremath <varunhiremath@gmail.com>, X+for the Debian project (but may be used by others). 4a6e63aec5c104138c99e3a39d306619 exit >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903041303.n24D3u3m040469>