From 2412323e3fa764b00d7e54d24c31771b646b8a89 Mon Sep 17 00:00:00 2001 From: Sapan Bhatia Date: Tue, 24 Mar 2009 20:32:54 +0000 Subject: [PATCH] Adding FUSE related vsys scripts --- Makefile | 3 + fuse.h | 8 +++ fusemount.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 fuse.h create mode 100644 fusemount.c diff --git a/Makefile b/Makefile index 98afcd6..7d586f6 100644 --- a/Makefile +++ b/Makefile @@ -12,5 +12,8 @@ fdpass.o: fdpass.c fd_bmsocket: fd_bmsocket.c fdpass.o gcc fd_bmsocket.c fdpass.o -o exec/fd_bmsocket +fd_fusemount: fd_fusemount.c fdpass.o + gcc fd_fusemount.c fdpass.o -o exec/fd_fusemount + clean: rm -f exec/* diff --git a/fuse.h b/fuse.h new file mode 100644 index 0000000..2ade06c --- /dev/null +++ b/fuse.h @@ -0,0 +1,8 @@ +#define FUSE_DEV_OLD "/proc/fs/fuse/dev" +#define FUSE_DEV_NEW "/dev/fuse" + +int rrm_receive_fd(int fd); +int rrm_send_fd(int sock_fd, int fd); +int rrm_open_fuse_device(char **devp); +int rrm_fuse_mnt_umount(const char *progname, const char *mnt, int lazy); + diff --git a/fusemount.c b/fusemount.c new file mode 100644 index 0000000..eb870eb --- /dev/null +++ b/fusemount.c @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "fuse.h" + +void remove_string( char *data, char *string ) { + char *pos = strstr( data, string ); + if( pos != NULL ) { + char *comma = strchr( pos, ',' ); + if( comma == NULL ) { + char *endpos = pos - 1; + if( endpos < data ) { + endpos = data; + } + endpos[0] = '\0'; + } else { + char tmp[200]; + strcpy( tmp, comma+1 ); + strcpy( pos, tmp ); + } + } +} + +int do_mount( int control_channel ) { + char buf[1024]; + int n = read( control_channel, buf, 1024 ); + assert( n != 1024 ); + + char source[200]; + char target[200]; + char fstype[200]; + unsigned long mountflags; + char data[200]; + + int r = sscanf( buf, "%s\n%s\n%s\n%ld\n%s\n", source, target, fstype, + &mountflags, data ); + + assert( r == 5 ); // shouldn't be an assert + + int s = mount( source, target, fstype, mountflags, data ); + + // TODO: should probably make sure this is for a fuse filesystem type . . . + int fd = 0; + if( s != 0 && errno == EINVAL ) { + // replace fd with a new one + remove_string( data, "fd" ); + + char *dev; + fd = open_fuse_device(&dev); + char *end = data+strlen(data); + if( strlen(data) != 0 ) { + sprintf( end, "," ); + end = end + 1; + } + sprintf( end, "fd=%d", fd ); + + s = mount( source, target, fstype, mountflags, data ); + + } + + char outbuf[10]; + if( s < 0 ) { + sprintf( outbuf, "%08x\n", errno ); + } else { + sprintf( outbuf, "%08x\n", fd ); + } + write( control_channel, outbuf, strlen(outbuf) ); + + if( fd != 0 ) { + + // now we have to sendmsg it back + // send the fd + int r = send_fd(control_channel, fd); + + // wait for the close + if( r == 0 ) { + int x = read(control_channel, outbuf, 1 ); + assert( x <= 0 ); + } + + close(fd); + + } + +} + +int do_umount( int control_channel, int num ) { + + if( num > 30 ) { + return -1; + } + + char *argbuf = (char *) malloc(sizeof(char)*(1024*num+1)); + const char *args[num+1]; + int args_index = 0; + + // read all of the arguments + int last_o = 0; + do { + + int n = read( control_channel, argbuf, 1024*num+1 ); + assert( n < 1024*num+1 ); // no assert here + int num_left = n; + while( num_left > 0 ) { + char arg[1024]; + if( sscanf( argbuf, "%s\n", arg ) != 1 ) { + break; + } + int len = strlen(arg); + char *a = malloc( sizeof(char)*(strlen(arg)+1) ); + strcpy( a, arg ); + if( strcmp( a, "-o" ) == 0 ) { + last_o = 1; + } + args[args_index] = a; + num_left -= (len+1); + argbuf += (len+1); + args_index++; + } + + } while( args_index < num ); + + args[num] = NULL; + + // The last argument is the mountpoint, that's really all we care about + printf( "umounting %s\n", args[num-1] ); + int r = fuse_mnt_umount("reroutemount_server", args[num-1], 0 ); + + // write the status (probably not necessary) + char outbuf[10]; + if( r < 0 ) { + sprintf( outbuf, "%d\n", errno ); + } else { + sprintf( outbuf, "%d\n", 0 ); + } + write( control_channel, outbuf, strlen(outbuf) ); + +} + +int main( int argc, char **argv ) { + int control_channel; + if (argc < 3) { + printf("This script is invoked by vsys\n"); + exit(1); + } + + sscanf(argv[2],"%d",&control_channel); + + // read the length + char buf[1024]; + int n = read( control_channel, buf, 9 ); + buf[n] = '\0'; + if( n != 9 ) { + close(control_channel); + continue; + } + + int num; + if( sscanf( buf, "%08x\n", &num ) != 1 ) { + close(control_channel); + continue; + } + + if( num == 0 ) { + do_mount( control_channel ); + } else { + do_umount( control_channel, num ); + } + close(control_channel); + + } + + close(fd); + unlink(socket_name); + +} -- 2.43.0