summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKim Hagen <khagen@multi-development.com>2014-04-30 22:39:14 +0200
committerKim Hagen <khagen@multi-development.com>2014-04-30 22:39:14 +0200
commit84c14e0983b3c2b9659af2e701b606e43306ccb2 (patch)
tree74e8762091bab82922e258a47ffb7b12571a5024
parent9701d11117f532bd960672b52bc5e96dcc3e33cf (diff)
downloadvyatta-cfg-84c14e0983b3c2b9659af2e701b606e43306ccb2.tar.gz
vyatta-cfg-84c14e0983b3c2b9659af2e701b606e43306ccb2.zip
Removed dirty workaround for fuse completely.
Use Build-iso to create /etc/fuse.conf file. Use pipe(),fork(),execl() functions instead of system() function to call unionfs-fuse.
-rwxr-xr-xetc/init.d/vyatta-router8
-rw-r--r--src/common/unionfs.c83
-rw-r--r--src/cstore/unionfs/cstore-unionfs.cpp86
3 files changed, 136 insertions, 41 deletions
diff --git a/etc/init.d/vyatta-router b/etc/init.d/vyatta-router
index 116b2fd..9d11aab 100755
--- a/etc/init.d/vyatta-router
+++ b/etc/init.d/vyatta-router
@@ -50,14 +50,6 @@ if [ ! -z "$VYOS_CONFIG" ]; then
fi
fi
-# Nothing will work without unionfs-fuse
-# In squeeze fuse.conf is not world readable by default,
-# ensure it's readable and includes "user_allow_other"
-# for correct config operations.
-# XXX: Is there a better way to do that?
-echo "user_allow_other" > /etc/fuse.conf
-chmod 644 /etc/fuse.conf
-
declare -a subinit
declare -a all_subinits=(
rl-system
diff --git a/src/common/unionfs.c b/src/common/unionfs.c
index 669858a..dee7cf1 100644
--- a/src/common/unionfs.c
+++ b/src/common/unionfs.c
@@ -4,6 +4,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
+#include <sys/wait.h>
#include <syslog.h>
#include <unistd.h>
#include <glib-2.0/glib.h>
@@ -18,6 +19,10 @@ boolean g_debug;
extern vtw_path m_path;
extern vtw_path t_path;
+pid_t pid;
+int status;
+int commpipe[2];
+
/*** functions for filesystem operations ***/
/* these functions replace the system() invocations that were a major source
* of commit overhead. note that they currently duplicate the previous
@@ -63,14 +68,34 @@ static inline void
sys_umount_session(void)
{
#ifdef USE_UNIONFSFUSE
- char umountcmd[MAX_LENGTH_DIR_PATH * 2];
- const char *fusermount_call;
- const char *umountfmt;
- fusermount_call = "/usr/bin/fusermount -u ";
- umountfmt = "%s %s";
- snprintf(umountcmd, MAX_LENGTH_DIR_PATH * 4, umountfmt, fusermount_call, get_mdirp());
- if (system(umountcmd) != 0) {
- perror("umount");
+ const char *fusermount_path, *fusermount_prog;
+ const char *fusermount_umount;
+
+ fusermount_path = "/usr/bin/fusermount";
+ fusermount_prog = "fusermount";
+ fusermount_umount = "-u";
+
+ if(pipe(commpipe)){
+ fprintf(stderr,"Pipe error!\n");
+ perror("pipe");
+ }
+
+ if((pid = fork()) == -1) {
+ perror("pid");
+ }
+
+ if(pid) {
+ dup2(commpipe[1],1);
+ close(commpipe[0]);
+ setvbuf(stdout,(char*)NULL,_IONBF,0);
+ wait(&status);
+ }
+ else {
+ dup2(commpipe[0],0);
+ close(commpipe[1]);
+ if (execl(fusermount_path, fusermount_prog, fusermount_umount, get_mdirp(), NULL) != 0) {
+ perror("execl");
+ }
}
#else
if (umount(get_mdirp()) != 0) {
@@ -84,15 +109,41 @@ sys_mount_session(void)
{
#ifdef USE_UNIONFSFUSE
char mopts[MAX_LENGTH_DIR_PATH * 2];
- const char *fstype;
+ const char *fusepath, *fuseprog;
+ const char *fuseoptinit;
+ const char *fuseopt1, *fuseopt2;
const char *moptfmt;
- int local_errno;
- fstype = "/usr/bin/unionfs-fuse -o cow -o allow_other";
- moptfmt = "%s %s=RW:%s=RO %s";
- snprintf(mopts, MAX_LENGTH_DIR_PATH * 4, moptfmt,
- fstype, get_cdirp(), get_adirp(), get_mdirp());
- if (system(mopts) != 0) {
- perror("system");
+
+ fusepath = "/usr/bin/unionfs-fuse";
+ fuseprog = "unionfs-fuse";
+ fuseoptinit = "-o";
+ fuseopt1 = "cow";
+ fuseopt2 = "allow_other";
+ moptfmt = "%s=RW:%s=RO";
+
+ if(pipe(commpipe)){
+ fprintf(stderr,"Pipe error!\n");
+ perror("pipe");
+ }
+
+ if((pid = fork()) == -1) {
+ perror("pid");
+ }
+
+ if(pid) {
+ dup2(commpipe[1],1);
+ close(commpipe[0]);
+ setvbuf(stdout,(char*)NULL,_IONBF,0);
+ wait(&status);
+ }
+ else {
+ dup2(commpipe[0],0);
+ close(commpipe[1]);
+ snprintf(mopts, MAX_LENGTH_DIR_PATH * 2, moptfmt,
+ get_cdirp(), get_adirp());
+ if (execl(fusepath, fuseprog, fuseoptinit, fuseopt1, fuseoptinit, fuseopt2, mopts, get_mdirp(), NULL) != 0) {
+ perror("execl");
+ }
}
#else
char mopts[MAX_LENGTH_DIR_PATH * 2];
diff --git a/src/cstore/unionfs/cstore-unionfs.cpp b/src/cstore/unionfs/cstore-unionfs.cpp
index 39d7634..2e6f4ad 100644
--- a/src/cstore/unionfs/cstore-unionfs.cpp
+++ b/src/cstore/unionfs/cstore-unionfs.cpp
@@ -24,6 +24,7 @@
#include <errno.h>
#include <fcntl.h>
#include <sys/mount.h>
+#include <wait.h>
#include <cli_cstore.h>
#include <cstore/unionfs/cstore-unionfs.hpp>
@@ -68,6 +69,9 @@ const string UnionfsCstore::C_VAL_NAME = "node.val";
const string UnionfsCstore::C_DEF_NAME = "node.def";
const string UnionfsCstore::C_COMMIT_LOCK_FILE = "/opt/vyatta/config/.lock";
+pid_t pid;
+int status;
+int commpipe[2];
////// static
static MapT<char, string> _fs_escape_chars;
@@ -1478,21 +1482,46 @@ UnionfsCstore::do_mount(const FsPath& rwdir, const FsPath& rdir,
const FsPath& mdir)
{
#ifdef USE_UNIONFSFUSE
- string mopts = "/usr/bin/unionfs-fuse ";
- mopts += "-o cow -o allow_other ";
- mopts += rwdir.path_cstr();
+ const char *fusepath, *fuseprog;
+ const char *fuseoptinit;
+ const char *fuseopt1, *fuseopt2;
+ string mopts;
+
+ fusepath = "/usr/bin/unionfs-fuse";
+ fuseprog = "unionfs-fuse";
+ fuseoptinit = "-o";
+ fuseopt1 = "cow";
+ fuseopt2 = "allow_other";
+ mopts = rwdir.path_cstr();
mopts += "=RW:";
mopts += rdir.path_cstr();
mopts += "=RO";
- mopts += " ";
- mopts += mdir.path_cstr();
- if (system(mopts.c_str()) != 0)
- {
- output_internal("union mount failed [%s][%s][%s]\n",
- strerror(errno), mdir.path_cstr(), mopts.c_str());
+ if(pipe(commpipe)){
+ output_internal("Pipe error!\n");
return false;
}
+
+ if((pid = fork()) == -1) {
+ output_internal("*** ERROR: forking child process failed\n");
+ return false;
+ }
+
+ if(pid) {
+ dup2(commpipe[1],1);
+ close(commpipe[0]);
+ setvbuf(stdout,(char*)NULL,_IONBF,0);
+ wait(&status);
+ }
+ else {
+ dup2(commpipe[0],0);
+ close(commpipe[1]);
+ if (execl(fusepath, fuseprog, fuseoptinit, fuseopt1, fuseoptinit, fuseopt2, mopts.c_str(), mdir.path_cstr(), NULL) != 0) {
+ output_internal("union mount failed [%s][%s][%s]\n",
+ strerror(errno), mdir.path_cstr(), mopts.c_str());
+ return false;
+ }
+ }
#else
string mopts = "dirs=";
mopts += rwdir.path_cstr();
@@ -1512,15 +1541,38 @@ bool
UnionfsCstore::do_umount(const FsPath& mdir)
{
#ifdef USE_UNIONFSFUSE
- string umount_cmd = "/usr/bin/fusermount -u ";
- umount_cmd += mdir.path_cstr();
-
- if (system(umount_cmd.c_str()) != 0)
- {
- output_internal("union umount failed [%s][%s]\n",
- strerror(errno), mdir.path_cstr());
- return(false);
+ const char *fusermount_path, *fusermount_prog;
+ const char *fusermount_umount;
+
+ fusermount_path = "/usr/bin/fusermount";
+ fusermount_prog = "fusermount";
+ fusermount_umount = "-u";
+
+ if(pipe(commpipe)){
+ output_internal("Pipe error!\n");
+ return false;
+ }
+
+ if((pid = fork()) == -1) {
+ output_internal("*** ERROR: forking child process failed\n");
+ return false;
+ }
+
+ if(pid) {
+ dup2(commpipe[1],1);
+ close(commpipe[0]);
+ setvbuf(stdout,(char*)NULL,_IONBF,0);
+ wait(&status);
+ }
+ else {
+ dup2(commpipe[0],0);
+ close(commpipe[1]);
+ if (execl(fusermount_path, fusermount_prog, fusermount_umount, mdir.path_cstr(), NULL) != 0) {
+ output_internal("union mount failed [%s][%s]\n",
+ strerror(errno), mdir.path_cstr());
+ return false;
}
+ }
#else
if (umount(mdir.path_cstr()) != 0) {
output_internal("union umount failed [%s][%s]\n",