Beispiel #1
0
static sqfs_err sqfs_ll_mount(sqfs_ll_chan *ch, const char *mountpoint,
		struct fuse_args *args) {
	#ifdef HAVE_NEW_FUSE_UNMOUNT
		ch->ch = fuse_mount(mountpoint, args);
	#else
		ch->fd = fuse_mount(mountpoint, args);
		if (ch->fd == -1)
			return SQFS_ERR;
		ch->ch = fuse_kern_chan_new(ch->fd);
	#endif
	return ch->ch ? SQFS_OK : SQFS_ERR;
}
Beispiel #2
0
int
fuse_main_real(int argc, char* argv[], const struct fuse_operations* op,
	size_t opSize, void* userData)
{
printf("fuse_main_real(%d, %p, %p, %ld, %p)\n", argc, argv, op, opSize,
userData);
	// Note: We use the fuse_*() functions here to initialize and run the
	// file system, although some of them are merely dummies.

	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);

	int result = 1;

	// create the kernel channel
	struct fuse_chan* channel = fuse_mount("/dummy", &args);
	if (channel != NULL) {
		// create the FUSE handle
		struct fuse* fuseHandle = fuse_new(channel, &args, op, opSize,
			userData);
		if (fuseHandle != NULL) {
			// run the main loop
			result = fuse_loop_mt(fuseHandle);

			fuse_destroy(fuseHandle);
		}

		fuse_unmount("/dummy", channel);
	}

	fuse_opt_free_args(&args);

	return result;
}
Beispiel #3
0
// Do a mount for helper_thread()
static void helper_thread_mount(mount_t * m)
{
	Dprintf("%s(\"%s\")\n", __FUNCTION__, m->fstitch_path);

	if ((m->channel_fd = fuse_mount(m->mountpoint, &m->args)) == -1)
	{
		fprintf(stderr, "%s(): fuse_mount(\"%s\") failed. (Does the mountpoint exist?)\n", __FUNCTION__, m->mountpoint);
		return;
	}

	if (!(m->session = fuse_lowlevel_new(&m->args, ops, ops_len, m)))
	{
		fprintf(stderr, "%s(): fuse_lowlevel_new() failed\n", __FUNCTION__);
		return;
	}

	if (!(m->channel = fuse_kern_chan_new(m->channel_fd)))
	{
		fprintf(stderr, "%s(): fuse_kern_chan_new() failed\n", __FUNCTION__);
		return;
	}

	fuse_session_add_chan(m->session, m->channel);

	if (fuse_chan_bufsize(m->channel) != fuse_serve_mount_chan_bufsize())
		fprintf(stderr, "bufsizes differ!\n");

	m->mounted = 1;

	printf("Mounted \"%s\" from %s\n", m->fstitch_path, modman_name_cfs(m->cfs));
}
Beispiel #4
0
struct fuse *
fuse_setup(int argc, char **argv, const struct fuse_operations *ops,
    size_t size, char **mp, int *mt, void *data)
{
	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
	struct fuse_chan *fc;
	struct fuse *fuse;
	int fg;

	if (fuse_parse_cmdline(&args, mp, mt, &fg))
		goto err;

	fuse_daemonize(0);

	if ((fc = fuse_mount(*mp, NULL)) == NULL)
		goto err;

	if ((fuse = fuse_new(fc, NULL, ops, size, data)) == NULL) {
		free(fc);
		goto err;
	}

	return (fuse);
err:
	free(*mp);
	return (NULL);
}
Beispiel #5
0
int main(int argc, char** argv) {
  struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
  char* mountpoint;
  int multithreaded;
  int foreground;
  if (fuse_opt_parse(&args, NULL, tfs_opts, tfs_opt_proc) == -1)
    return 1;
  if (fuse_parse_cmdline(&args, &mountpoint, &multithreaded, &foreground) == -1)
    return 1;
  struct fuse_chan *ch = fuse_mount(mountpoint, &args);
  if (!ch)
    return 1;
  struct fuse *fuse = fuse_new(ch, &args, &tfs_oper, sizeof(struct fuse_operations), NULL);
  if (!fuse) {
    fuse_unmount(mountpoint, ch);
    return 1;
  }
  if (options.debug == 1 ||  foreground == 1) {
    if (fuse_daemonize(foreground) != -1)
      return 1;
  }
  if (fuse_set_signal_handlers(fuse_get_session(fuse)) == -1) {
    fuse_unmount(mountpoint, ch);
    fuse_destroy(fuse);
    return 1;
  }
  initMultiCastListener();
  if (multithreaded)
    return fuse_loop_mt(fuse);
  if (!options.debug)
    fprintf(stderr, "Running single threaded and we are not debugging, your performance may suffer.\n");
  return fuse_loop(fuse);
};
Beispiel #6
0
int main(int argc, char *argv[])
{
    struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
    char *mountpoint;
    int err = -1;
    int fd;

    if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
        (fd = fuse_mount(mountpoint, &args)) != -1) {
        struct fuse_session *se;

        se = fuse_lowlevel_new(&args, &hello_ll_oper, sizeof(hello_ll_oper),
                               NULL);
        if (se != NULL) {
            if (fuse_set_signal_handlers(se) != -1) {
                struct fuse_chan *ch = fuse_kern_chan_new(fd);
                if (ch != NULL) {
                    fuse_session_add_chan(se, ch);
                    err = fuse_session_loop(se);
                }
                fuse_remove_signal_handlers(se);
            }
            fuse_session_destroy(se);
        }
        close(fd);
    }
    fuse_unmount(mountpoint);
    fuse_opt_free_args(&args);

    return err ? 1 : 0;
}
Beispiel #7
0
/* ----------------------------------------------------- */
int main(int argc,char* argv[])
{
	signal(SIGINT, fs_sigint_handler); 
	fs_set_limit_attr();
	if (mpinit(0, 50)) return -1;

	voolefs.tc = 10;
	voolefs.tpool = threadpool_init(voolefs.tc ,10);
	voolefs.cinc  = 8;
	voolefs.phost = mpcalloc(sizeof(struct host));
	voolefs.phost->host = inet_addr("123.125.149.11");
	voolefs.phost->port = htons(4869);
	voolefs.hostc = 1; 
	voolefs.semc = 20;

	char* pmpoint = fs_create_mountpoint();
	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);	
	char *fsname =(char*)mpcalloc(256);
	sprintf(fsname,"-osubtype=%s,fsname=%s",argv[0],pmpoint);
	mpfree(pmpoint);
	int ret = fuse_opt_parse(&args, NULL,NULL,NULL /*&voolefs, voolefs_opts, fs_opt_proc*/);
	int multithreaded = 0;
	int foreground = 0;
	ret = fuse_opt_insert_arg(&args,1,fsname);
/*	if (fuse_is_lib_option("ac_attr_timeout="))
		fuse_opt_insert_arg(&args, 1, "-oauto_cache,ac_attr_timeout=0");
*/	ret = fuse_parse_cmdline(&args, &voolefs.mountpoint, &multithreaded, &foreground);
	voolefs.ch = fuse_mount(voolefs.mountpoint, &args);
//	event_reinit(voolefs.ev_base);
	if(voolefs.ch)
	{
		ret = fcntl(fuse_chan_fd(voolefs.ch), F_SETFD, FD_CLOEXEC);
		voolefs.fuse = fuse_new(voolefs.ch,&args,&oper,sizeof(struct fuse_operations),NULL);
		if (voolefs.fuse == NULL)
		{
			fs_cleanup();
			abort();
		}
		fs_daemonize(0);
		voole_net_create();
/*		if( multithreaded)
			ret = fuse_loop_mt(voolefs.fuse);
		else
*/			ret = fuse_loop(voolefs.fuse);
	}
	if( voolefs.fuse )
		fuse_remove_signal_handlers(fuse_get_session(voolefs.fuse));
	mpfree(fsname);
	if( voolefs.peventbase )
	{
		event_base_free(voolefs.peventbase);
		voolefs.peventbase = NULL;
	}
	return ret;
}
Beispiel #8
0
int main(int argc, char *argv[]){
  // Initialize an empty argument list                                                  
  struct fuse_args mountpt = FUSE_ARGS_INIT(0, NULL);
  // add program and mountpoint                                   
  fuse_opt_add_arg(&mountpt, argv[0]);
  fuse_opt_add_arg(&mountpt, argv[1]);
  //fuse_opt_add_arg(&mountpt, argv[2]);// for debug                            
  //fuse_opt_add_arg(&mountpt, argv[3]);// for debug                   

  log_file_path= argv[2];
  fs_size=atoi(argv[3])*1000000;
  num_blocks=fs_size/block_size;
  if(num_blocks < 1000){
    free_space =block_size;
  }else
  free_space=block_size*4;

  dictionary= malloc(num_blocks*sizeof(int));
  log_fp = fopen (log_file_path,"a+");
  if (log_fp == NULL) {
    printf ("Data file could not be opened\n");
    return 1;
  }
  initialize_dictionary();
  mount=time(NULL);

  struct fuse_args args = FUSE_ARGS_INIT(mountpt.argc, mountpt.argv);
  struct fuse_chan *ch;
  char *mountpoint;
  int err = -1;
  if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
      (ch = fuse_mount(mountpoint, &args)) != NULL) {
    struct fuse_session *se;
    se = fuse_lowlevel_new(&args, &lfs_ll_oper,
			   sizeof(lfs_ll_oper), NULL);
    if (se != NULL) {
      if (fuse_set_signal_handlers(se) != -1) {
	fuse_session_add_chan(se, ch);
	/* Block until ctrl+c or fusermount -u */
	err = fuse_session_loop(se);
	fuse_remove_signal_handlers(se);
	fuse_session_remove_chan(ch);
      }
      fuse_session_destroy(se);
      unmount=time(NULL);
      write_stats();
    }
    fuse_unmount(mountpoint, ch);
  }
  fuse_opt_free_args(&args);
  free(dictionary);
  fclose(log_fp);
  return err ? 1 : 0;

}
Beispiel #9
0
/* FUSE operation */
void _cachefs_fuse_new(struct cachefs *fs, GError **err)
{
    GPtrArray *argv;
    struct fuse_args args;

    /* create hash table for demand-fetching */
    fs->file_locks = g_hash_table_new(g_str_hash, g_str_equal);

    /* Construct mountpoint */
    fs->mountpoint = g_strdup("/tmp/cachefs-XXXXXX");
    if (mkdtemp(fs->mountpoint) == NULL) {
        _cachefs_write_error("[fuse] failed to create tmp directory");
        goto bad_dealloc;
    }

    /* Build FUSE command line */
    argv = g_ptr_array_new();
    g_ptr_array_add(argv, g_strdup("-odefault_permissions"));
	//g_ptr_array_add(argv, g_strdup("-oallow_root"));
	g_ptr_array_add(argv, g_strdup("-oallow_other"));
    g_ptr_array_add(argv, g_strdup_printf("-ofsname=cachefs#%d", getpid()));
    g_ptr_array_add(argv, g_strdup("-osubtype=cachefs"));
    g_ptr_array_add(argv, g_strdup("-obig_writes"));
    g_ptr_array_add(argv, g_strdup("-ointr"));
    /* Avoid kernel page cache in order to preserve semantics of read()
       and write() return values. */
    g_ptr_array_add(argv, g_strdup("-odirect_io"));
    g_ptr_array_add(argv, NULL);
    args.argv = (gchar **) g_ptr_array_free(argv, FALSE);
    args.argc = g_strv_length(args.argv);
    args.allocated = 0;

    /* Initialize FUSE */
    fs->chan = fuse_mount(fs->mountpoint, &args);
    if (fs->chan == NULL) {
        _cachefs_write_error("[fuse] failed to mount fuse");
        goto bad_rmdir;
    }
    fs->fuse = fuse_new(fs->chan, &args, &fuse_ops, sizeof(fuse_ops), fs);
    g_strfreev(args.argv);
    if (fs->fuse == NULL) {
        _cachefs_write_error("[fuse] failed to create new fuse");
        goto bad_unmount;
    }

    return;

bad_unmount:
    fuse_unmount(fs->mountpoint, fs->chan);
bad_rmdir:
    rmdir(fs->mountpoint);
bad_dealloc:
    g_free(fs->mountpoint);
    return;
}
Beispiel #10
0
static int mount_root(int argc, char ** argv)
{
	Dprintf("%s()\n", __FUNCTION__);

	if (!(root = calloc(1, sizeof(*root))))
		return -ENOMEM;

	// We can't use FUSE_ARGS_INIT() here so assert we are initing the
	// whole structure
	static_assert(sizeof(root->args) == sizeof(argc) + sizeof(argv) + sizeof(int));
	root->args.argc = argc;
	root->args.argv = argv;
	root->args.allocated = 0;

	if (!(root->fstitch_path = strdup("")))
		return -ENOMEM;

	if (!(root->parents = hash_map_create()))
		return -ENOMEM;

	root->cfs = NULL; // set later via fuse_serve_mount_set_root()

	if (fuse_parse_cmdline(&root->args, &root->mountpoint, NULL, NULL) == -1)
	{
		fprintf(stderr, "%s(): fuse_parse_cmdline() failed\n", __FUNCTION__);
		return -1;
	}

	if ((root->channel_fd = fuse_mount(root->mountpoint, &root->args)) == -1)
	{
		fprintf(stderr, "%s():%d: fuse_mount(\"%s\") failed\n", __FUNCTION__, __LINE__, root->mountpoint);
		return -1;
	}

	if (!(root->session = fuse_lowlevel_new(&root->args, ops, ops_len, root)))
	{
		fprintf(stderr, "%s(): fuse_lowlevel_new() failed\n", __FUNCTION__);
		return -1;
	}

	if (!(root->channel = fuse_kern_chan_new(root->channel_fd)))
	{
		fprintf(stderr, "%s(): fuse_kern_chan_new() failed\n", __FUNCTION__);
		return -1;
	}

	fuse_session_add_chan(root->session, root->channel);

	mounts_insert(root);

	root->mounted = 1;

	return 0;
}
Beispiel #11
0
struct fuse *fuse_setup(int argc, char *argv[],
		const struct fuse_operations *op, size_t op_size,
		char **mountpoint, int *multithreaded, void *user_data)
{
	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
	struct fuse_chan *ch=NULL;
	struct fuse *fuse;
	int foreground;
	int res;

	res = fuse_parse_cmdline(&args, mountpoint, multithreaded, &foreground);
	rDebug("res=%i", res);
	if (res == -1)
		return NULL;

	ch = fuse_mount(*mountpoint, &args);

	fuse = fuse_new(ch, &args, op, op_size, user_data);
	fuse_opt_free_args(&args);
	if (fuse == NULL || ch==NULL)
		goto err_unmount;

	res = fuse_daemonize(foreground);
	rDebug("res=%i", res);
	if (res == -1)
		goto err_unmount;

	if (fuse->conf.setsignals)
	{
		res = fuse_set_signal_handlers(fuse_get_session(fuse));
		rDebug("res=%i", res);
		if (res == -1)
			goto err_unmount;
	}

	return fuse;

err_unmount:
	fuse_unmount(*mountpoint, ch);
	if (fuse)
		fuse_destroy(fuse);
	free(*mountpoint);
	return NULL;
}
Beispiel #12
0
int cdfs_options_output_proc(void *data, const char *arg, int key, struct fuse_args *outargs)
{
	(void) arg;
	(void) data;

	switch (key) {
	case KEY_HELP:
		usage(outargs->argv[0], stdout);
		printf(
		"General options:\n"
		"    -o opt,[opt...]        mount options\n"
		"    -h   --help            print help\n"
		"    -V   --version         print version\n"
		"    -d   -o debug          enable debug output (implies -f)\n"
		"    -f                     foreground operation\n"
		"\n"
		"cdfs options:\n"
		"    -o device=DEVICE                      	device to use (like /dev/sr0)\n"
		"    -o cache-directory=DIR                     directory to store cached files\n"
		"    -o progressfifo=FILE                       fifo ro write cdrom read progress to\n"
		"    -o logging=NUMBER                          set loglevel (0=no logging)\n"
		"    -o cachebackend=none[default],sqlite       backend to store cache info\n"
		"    -o readaheadpolicy=none/piece/whole        policy for readahead\n"
		"    -o hashprogram=md5sum/sha1sum/..           program to compute hash, default md5sum\n"
		"    -o discid                                  path write the discid to, default cache-directory\n"
		"\n"
		"FUSE options:\n");
		fflush(stdout);
		dup2(1, 2);
		fuse_opt_add_arg(outargs, "--help");
		fuse_mount(NULL, outargs);
		fuse_lowlevel_new(outargs, NULL, 0, NULL);
		exit(0);
	case KEY_VERSION:
		printf("xmpfs version %s\n", PACKAGE_VERSION);
		fflush(stdout);
		dup2(1, 2);
		fuse_opt_add_arg(outargs, "--version");
		fuse_parse_cmdline(outargs, NULL, NULL, NULL);
		fuse_lowlevel_new(outargs, NULL, 0, NULL);
		exit(0);
	}
	return 1;
}
Beispiel #13
0
static void
fuseMount(CompDisplay *d)
{
   char *mountPoint;
   struct fuse_args args = FUSE_ARGS_INIT(0, NULL);

   FUSE_DISPLAY(d);

   mountPoint = strdup(fd->opt[FUSE_DISPLAY_OPTION_MOUNT_POINT].value.s);
   if (!mountPoint)
     return;

   fuse_opt_add_arg(&args, "");
   fuse_opt_add_arg(&args, "-o");
   fuse_opt_add_arg(&args, "allow_root");

   fd->channel = fuse_mount(mountPoint, &args);
   if (!fd->channel)
     {
        fuse_opt_free_args(&args);
        free(mountPoint);
        return;
     }

   fuse_opt_free_args(&args);

   fd->buffer = malloc(fuse_chan_bufsize(fd->channel));
   if (!fd->buffer)
     {
        fuse_unmount(mountPoint, fd->channel);
        free(mountPoint);
        fd->channel = NULL;
        return;
     }

   fd->mountPoint = mountPoint;

   fuse_session_add_chan(fd->session, fd->channel);

   fd->watchFdHandle = compAddWatchFd(fuse_chan_fd(fd->channel),
                                      POLLIN | POLLPRI | POLLHUP | POLLERR,
                                      fuseProcessMessages,
                                      d);
}
Beispiel #14
0
int main(int argc, char *argv[])
{
	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
	struct fuse_chan *ch;
	char *mountpoint;
	int ret = -1;
	struct lo_data lo = { .debug = 0 };

	if (fuse_opt_parse(&args, &lo, lo_opts, NULL) == -1)
		exit(1);
	lo.root.next = lo.root.prev = &lo.root;
	lo.root.fd = open("/", O_PATH);
	lo.root.nlookup = 2;
	if (lo.root.fd == -1)
		err(1, "open(\"/\", O_PATH)");

	if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
	    (ch = fuse_mount(mountpoint, &args)) != NULL) {
		struct fuse_session *se;
		se = fuse_lowlevel_new(&args, &lo_oper, sizeof(lo_oper), &lo);
		if (se != NULL) {
			if (fuse_set_signal_handlers(se) != -1) {
				fuse_session_add_chan(se, ch);
				ret = fuse_session_loop(se);
				fuse_remove_signal_handlers(se);
				fuse_session_remove_chan(ch);
			}
			fuse_session_destroy(se);
		}
		fuse_unmount(mountpoint, ch);
		free(mountpoint);
	}
	fuse_opt_free_args(&args);

	while (lo.root.next != &lo.root)
		lo_free(lo.root.next);

	return ret ? 1 : 0;
}
Beispiel #15
0
int intern_fuse_init(struct intern_fuse *inf, struct fuse_args *args, void* user_data)
{
  struct fuse_chan* fc;
  char* mountpoint;
  mountpoint = inf->mountpoint;
  fc = fuse_mount(mountpoint,args);

  if (fc == NULL) {
    return -1;
  }

  inf->fuse=fuse_new(fc, args, &(inf->fuse_op), sizeof(struct fuse_operations), user_data);

  if (inf->fuse == NULL) {
      fuse_unmount(inf->mountpoint, fc);
      return -1;
  }

  inf->fc = fc;

  return 0;
}
Beispiel #16
0
int intern_fuse_init(
  struct intern_fuse *inf,
  const char *mountpoint, 
  struct fuse_args *kernelopts,
  struct fuse_args *libopts)
{
  struct fuse_chan* fc;

  fc = fuse_mount(mountpoint, kernelopts);

  if (fc == NULL) {
    return -1;
  }

  inf->fuse=fuse_new(fc, libopts, &(inf->fuse_op), sizeof(struct fuse_operations), NULL);
  inf->fc = fc;

  if (strlen(inf->mountname) > MOUNTNAME_MAX) {
    return -1;
  }

  strncpy(inf->mountname, mountpoint, MOUNTNAME_MAX);
  return 0;
}
Beispiel #17
0
int main(int argc, char *argv[])
{
	char c;
	int did_explicit_auth = 0;
	char *tickets = NULL;
	struct fuse_args fa;
	fa.argc = 0;
	fa.argv = string_array_new();
	fa.allocated = 1;

	debug_config(argv[0]);

	while((c = getopt(argc, argv, "a:b:d:Dfhi:m:o:t:v")) != -1) {
		switch (c) {
		case 'd':
			debug_flags_set(optarg);
			break;
		case 'D':
			enable_small_file_optimizations = 0;
			break;
		case 'b':
			chirp_reli_blocksize_set(atoi(optarg));
			break;
		case 'i':
			tickets = xxstrdup(optarg);
			break;
		case 'm':
			fa.argc += 1;
			fa.argv = string_array_append(fa.argv, optarg);
			break;
		case 'o':
			debug_config_file(optarg);
			break;
		case 'a':
			auth_register_byname(optarg);
			did_explicit_auth = 1;
			break;
		case 't':
			chirp_fuse_timeout = string_time_parse(optarg);
			break;
		case 'f':
			run_in_foreground = 1;
			break;
		case 'v':
			cctools_version_print(stdout, argv[0]);
			return 0;
			break;
		case 'h':
		default:
			show_help(argv[0]);
			return 1;
			break;
		}
	}

	cctools_version_debug(D_DEBUG, argv[0]);

	if((argc - optind) != 1) {
		show_help(argv[0]);
		return 1;
	}

	fuse_mountpoint = argv[optind];

	if(!did_explicit_auth)
		auth_register_all();
	if(tickets) {
		auth_ticket_load(tickets);
		free(tickets);
	} else if(getenv(CHIRP_CLIENT_TICKETS)) {
		auth_ticket_load(getenv(CHIRP_CLIENT_TICKETS));
	} else {
		auth_ticket_load(NULL);
	}

	file_table = itable_create(0);

	signal(SIGHUP, exit_handler);
	signal(SIGINT, exit_handler);
	signal(SIGTERM, exit_handler);

	fuse_chan = fuse_mount(fuse_mountpoint, &fa);
	if(!fuse_chan) {
		fprintf(stderr, "chirp_fuse: couldn't access %s\n", fuse_mountpoint);
		return 1;
	}

	fuse_instance = fuse_new(fuse_chan, &fa, &chirp_fuse_operations, sizeof(chirp_fuse_operations), 0);
	if(!fuse_instance) {
		fuse_unmount(fuse_mountpoint, fuse_chan);
		fprintf(stderr, "chirp_fuse: couldn't access %s\n", fuse_mountpoint);
		return 1;
	}

	printf("chirp_fuse: mounted chirp on %s\n", fuse_mountpoint);
#ifdef CCTOOLS_OPSYS_DARWIN
	printf("chirp_fuse: to unmount: umount %s\n", fuse_mountpoint);
#else
	printf("chirp_fuse: to unmount: fusermount -u %s\n", fuse_mountpoint);
#endif

	fflush(0);

	if(!run_in_foreground)
		daemon(0, 0);

	fuse_loop(fuse_instance);

	fuse_unmount(fuse_mountpoint, fuse_chan);
	fuse_destroy(fuse_instance);

	free(fa.argv);

	return 0;
}
Beispiel #18
0
void
fuse_try_mount(FileView *view, const char program[])
{
	/* TODO: refactor this function fuse_try_mount() */

	fuse_mount_t *runner;
	char file_full_path[PATH_MAX];
	char mount_point[PATH_MAX];

	if(!path_exists(cfg.fuse_home, DEREF))
	{
		if(make_path(cfg.fuse_home, S_IRWXU) != 0)
		{
			show_error_msg("Unable to create FUSE mount home directory",
					cfg.fuse_home);
			return;
		}
	}

	get_current_full_path(view, sizeof(file_full_path), file_full_path);

	/* Check if already mounted. */
	runner = get_mount_by_source(file_full_path);

	if(runner != NULL)
	{
		strcpy(mount_point, runner->mount_point);
	}
	else
	{
		char param[PATH_MAX];
		param[0] = '\0';

		/* New file to be mounted. */
		if(starts_with(program, "FUSE_MOUNT2"))
		{
			FILE *f;
			if((f = os_fopen(file_full_path, "r")) == NULL)
			{
				show_error_msg("SSH mount failed", "Can't open file for reading");
				curr_stats.save_msg = 1;
				return;
			}

			if(fgets(param, sizeof(param), f) == NULL)
			{
				show_error_msg("SSH mount failed", "Can't read file content");
				curr_stats.save_msg = 1;
				fclose(f);
				return;
			}
			fclose(f);

			chomp(param);
			if(param[0] == '\0')
			{
				show_error_msg("SSH mount failed", "File is empty");
				curr_stats.save_msg = 1;
				return;
			}

		}
		if(fuse_mount(view, file_full_path, param, program, mount_point) != 0)
		{
			return;
		}
	}

	navigate_to(view, mount_point);
}
Beispiel #19
0
int main( int argc, char * const argv[] )
#endif
{
	libregf_error_t *error                      = NULL;
	system_character_t *mount_point             = NULL;
	system_character_t *option_codepage         = NULL;
	system_character_t *option_extended_options = NULL;
	system_character_t *source                  = NULL;
	char *program                               = "regfmount";
	system_integer_t option                     = 0;
	int result                                  = 0;
	int verbose                                 = 0;

#if defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE )
	struct fuse_operations regfmount_fuse_operations;

	struct fuse_args regfmount_fuse_arguments = FUSE_ARGS_INIT(0, NULL);
	struct fuse_chan *regfmount_fuse_channel  = NULL;
	struct fuse *regfmount_fuse_handle        = NULL;

#elif defined( HAVE_LIBDOKAN )
	DOKAN_OPERATIONS regfmount_dokan_operations;
	DOKAN_OPTIONS regfmount_dokan_options;
#endif

	libcnotify_stream_set(
	 stderr,
	 NULL );
	libcnotify_verbose_set(
	 1 );

	if( libclocale_initialize(
	     "regftools",
	     &error ) != 1 )
	{
		fprintf(
		 stderr,
		 "Unable to initialize locale values.\n" );

		goto on_error;
	}
	if( regftools_output_initialize(
	     _IONBF,
	     &error ) != 1 )
	{
		fprintf(
		 stderr,
		 "Unable to initialize output settings.\n" );

		goto on_error;
	}
	regftools_output_version_fprint(
	 stdout,
	 program );

	while( ( option = regftools_getopt(
	                   argc,
	                   argv,
	                   _SYSTEM_STRING( "c:hvVX:" ) ) ) != (system_integer_t) -1 )
	{
		switch( option )
		{
			case (system_integer_t) '?':
			default:
				fprintf(
				 stderr,
				 "Invalid argument: %" PRIs_SYSTEM "\n",
				 argv[ optind - 1 ] );

				usage_fprint(
				 stdout );

				return( EXIT_FAILURE );

			case (system_integer_t) 'c':
				option_codepage = optarg;

				break;

			case (system_integer_t) 'h':
				usage_fprint(
				 stdout );

				return( EXIT_SUCCESS );

			case (system_integer_t) 'v':
				verbose = 1;

				break;

			case (system_integer_t) 'V':
				regftools_output_copyright_fprint(
				 stdout );

				return( EXIT_SUCCESS );

			case (system_integer_t) 'X':
				option_extended_options = optarg;

				break;
		}
	}
	if( optind == argc )
	{
		fprintf(
		 stderr,
		 "Missing source file.\n" );

		usage_fprint(
		 stdout );

		return( EXIT_FAILURE );
	}
	source = argv[ optind++ ];

	if( optind == argc )
	{
		fprintf(
		 stderr,
		 "Missing mount point.\n" );

		usage_fprint(
		 stdout );

		return( EXIT_FAILURE );
	}
	mount_point = argv[ optind ];

	libcnotify_verbose_set(
	 verbose );
	libregf_notify_set_stream(
	 stderr,
	 NULL );
	libregf_notify_set_verbose(
	 verbose );

	if( mount_handle_initialize(
	     &regfmount_mount_handle,
	     &error ) != 1 )
	{
		fprintf(
		 stderr,
		 "Unable to initialize mount handle.\n" );

		goto on_error;
	}
	if( option_codepage != NULL )
	{
		result = mount_handle_set_ascii_codepage(
		          regfmount_mount_handle,
		          option_codepage,
		          &error );

		if( result == -1 )
		{
			fprintf(
			 stderr,
			 "Unable to set ASCII codepage in mount handle.\n" );

			goto on_error;
		}
		else if( result == 0 )
		{
			fprintf(
			 stderr,
			 "Unsupported ASCII codepage defaulting to: windows-1252.\n" );
		}
	}
	if( mount_handle_open(
	     regfmount_mount_handle,
	     source,
	     &error ) != 1 )
	{
		fprintf(
		 stderr,
		 "Unable to open source file\n" );

		goto on_error;
	}
#if defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE )
	if( option_extended_options != NULL )
	{
		/* This argument is required but ignored
		 */
		if( fuse_opt_add_arg(
		     &regfmount_fuse_arguments,
		     "" ) != 0 )
		{
			fprintf(
			 stderr,
			 "Unable add fuse arguments.\n" );

			goto on_error;
		}
		if( fuse_opt_add_arg(
		     &regfmount_fuse_arguments,
		     "-o" ) != 0 )
		{
			fprintf(
			 stderr,
			 "Unable add fuse arguments.\n" );

			goto on_error;
		}
		if( fuse_opt_add_arg(
		     &regfmount_fuse_arguments,
		     option_extended_options ) != 0 )
		{
			fprintf(
			 stderr,
			 "Unable add fuse arguments.\n" );

			goto on_error;
		}
	}
	if( memory_set(
	     &regfmount_fuse_operations,
	     0,
	     sizeof( struct fuse_operations ) ) == NULL )
	{
		fprintf(
		 stderr,
		 "Unable to clear fuse operations.\n" );

		goto on_error;
	}
	regfmount_fuse_operations.open       = &mount_fuse_open;
	regfmount_fuse_operations.read       = &mount_fuse_read;
	regfmount_fuse_operations.release    = &mount_fuse_release;
	regfmount_fuse_operations.opendir    = &mount_fuse_opendir;
	regfmount_fuse_operations.readdir    = &mount_fuse_readdir;
	regfmount_fuse_operations.releasedir = &mount_fuse_releasedir;
	regfmount_fuse_operations.getattr    = &mount_fuse_getattr;
	regfmount_fuse_operations.destroy    = &mount_fuse_destroy;

	regfmount_fuse_channel = fuse_mount(
	                          mount_point,
	                          &regfmount_fuse_arguments );

	if( regfmount_fuse_channel == NULL )
	{
		fprintf(
		 stderr,
		 "Unable to create fuse channel.\n" );

		goto on_error;
	}
	regfmount_fuse_handle = fuse_new(
	                         regfmount_fuse_channel,
	                         &regfmount_fuse_arguments,
	                         &regfmount_fuse_operations,
	                         sizeof( struct fuse_operations ),
	                         regfmount_mount_handle );

	if( regfmount_fuse_handle == NULL )
	{
		fprintf(
		 stderr,
		 "Unable to create fuse handle.\n" );

		goto on_error;
	}
	if( verbose == 0 )
	{
		if( fuse_daemonize(
		     0 ) != 0 )
		{
			fprintf(
			 stderr,
			 "Unable to daemonize fuse.\n" );

			goto on_error;
		}
	}
	result = fuse_loop(
	          regfmount_fuse_handle );

	if( result != 0 )
	{
		fprintf(
		 stderr,
		 "Unable to run fuse loop.\n" );

		goto on_error;
	}
	fuse_destroy(
	 regfmount_fuse_handle );

	fuse_opt_free_args(
	 &regfmount_fuse_arguments );

	return( EXIT_SUCCESS );

#elif defined( HAVE_LIBDOKAN )
	if( memory_set(
	     &regfmount_dokan_operations,
	     0,
	     sizeof( DOKAN_OPERATIONS ) ) == NULL )
	{
		fprintf(
		 stderr,
		 "Unable to clear dokan operations.\n" );

		goto on_error;
	}
	if( memory_set(
	     &regfmount_dokan_options,
	     0,
	     sizeof( DOKAN_OPTIONS ) ) == NULL )
	{
		fprintf(
		 stderr,
		 "Unable to clear dokan options.\n" );

		goto on_error;
	}
	regfmount_dokan_options.Version     = DOKAN_VERSION;
	regfmount_dokan_options.ThreadCount = 0;
	regfmount_dokan_options.MountPoint  = mount_point;

	if( verbose != 0 )
	{
		regfmount_dokan_options.Options |= DOKAN_OPTION_STDERR;
#if defined( HAVE_DEBUG_OUTPUT )
		regfmount_dokan_options.Options |= DOKAN_OPTION_DEBUG;
#endif
	}
/* This will only affect the drive properties
	regfmount_dokan_options.Options |= DOKAN_OPTION_REMOVABLE;
*/

#if ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 )
	regfmount_dokan_options.Options |= DOKAN_OPTION_KEEP_ALIVE;

	regfmount_dokan_operations.CreateFile           = &mount_dokan_CreateFile;
	regfmount_dokan_operations.OpenDirectory        = &mount_dokan_OpenDirectory;
	regfmount_dokan_operations.CreateDirectory      = NULL;
	regfmount_dokan_operations.Cleanup              = NULL;
	regfmount_dokan_operations.CloseFile            = &mount_dokan_CloseFile;
	regfmount_dokan_operations.ReadFile             = &mount_dokan_ReadFile;
	regfmount_dokan_operations.WriteFile            = NULL;
	regfmount_dokan_operations.FlushFileBuffers     = NULL;
	regfmount_dokan_operations.GetFileInformation   = &mount_dokan_GetFileInformation;
	regfmount_dokan_operations.FindFiles            = &mount_dokan_FindFiles;
	regfmount_dokan_operations.FindFilesWithPattern = NULL;
	regfmount_dokan_operations.SetFileAttributes    = NULL;
	regfmount_dokan_operations.SetFileTime          = NULL;
	regfmount_dokan_operations.DeleteFile           = NULL;
	regfmount_dokan_operations.DeleteDirectory      = NULL;
	regfmount_dokan_operations.MoveFile             = NULL;
	regfmount_dokan_operations.SetEndOfFile         = NULL;
	regfmount_dokan_operations.SetAllocationSize    = NULL;
	regfmount_dokan_operations.LockFile             = NULL;
	regfmount_dokan_operations.UnlockFile           = NULL;
	regfmount_dokan_operations.GetFileSecurity      = NULL;
	regfmount_dokan_operations.SetFileSecurity      = NULL;
	regfmount_dokan_operations.GetDiskFreeSpace     = NULL;
	regfmount_dokan_operations.GetVolumeInformation = &mount_dokan_GetVolumeInformation;
	regfmount_dokan_operations.Unmount              = &mount_dokan_Unmount;

#else
	regfmount_dokan_operations.ZwCreateFile         = &mount_dokan_ZwCreateFile;
	regfmount_dokan_operations.Cleanup              = NULL;
	regfmount_dokan_operations.CloseFile            = &mount_dokan_CloseFile;
	regfmount_dokan_operations.ReadFile             = &mount_dokan_ReadFile;
	regfmount_dokan_operations.WriteFile            = NULL;
	regfmount_dokan_operations.FlushFileBuffers     = NULL;
	regfmount_dokan_operations.GetFileInformation   = &mount_dokan_GetFileInformation;
	regfmount_dokan_operations.FindFiles            = &mount_dokan_FindFiles;
	regfmount_dokan_operations.FindFilesWithPattern = NULL;
	regfmount_dokan_operations.SetFileAttributes    = NULL;
	regfmount_dokan_operations.SetFileTime          = NULL;
	regfmount_dokan_operations.DeleteFile           = NULL;
	regfmount_dokan_operations.DeleteDirectory      = NULL;
	regfmount_dokan_operations.MoveFile             = NULL;
	regfmount_dokan_operations.SetEndOfFile         = NULL;
	regfmount_dokan_operations.SetAllocationSize    = NULL;
	regfmount_dokan_operations.LockFile             = NULL;
	regfmount_dokan_operations.UnlockFile           = NULL;
	regfmount_dokan_operations.GetFileSecurity      = NULL;
	regfmount_dokan_operations.SetFileSecurity      = NULL;
	regfmount_dokan_operations.GetDiskFreeSpace     = NULL;
	regfmount_dokan_operations.GetVolumeInformation = &mount_dokan_GetVolumeInformation;
	regfmount_dokan_operations.Unmounted            = NULL;
	regfmount_dokan_operations.FindStreams          = NULL;
	regfmount_dokan_operations.Mounted              = NULL;

#endif /* ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) */

	result = DokanMain(
	          &regfmount_dokan_options,
	          &regfmount_dokan_operations );

	switch( result )
	{
		case DOKAN_SUCCESS:
			break;

		case DOKAN_ERROR:
			fprintf(
			 stderr,
			 "Unable to run dokan main: generic error\n" );
			break;

		case DOKAN_DRIVE_LETTER_ERROR:
			fprintf(
			 stderr,
			 "Unable to run dokan main: bad drive letter\n" );
			break;

		case DOKAN_DRIVER_INSTALL_ERROR:
			fprintf(
			 stderr,
			 "Unable to run dokan main: unable to load driver\n" );
			break;

		case DOKAN_START_ERROR:
			fprintf(
			 stderr,
			 "Unable to run dokan main: driver error\n" );
			break;

		case DOKAN_MOUNT_ERROR:
			fprintf(
			 stderr,
			 "Unable to run dokan main: unable to assign drive letter\n" );
			break;

		case DOKAN_MOUNT_POINT_ERROR:
			fprintf(
			 stderr,
			 "Unable to run dokan main: mount point error\n" );
			break;

		default:
			fprintf(
			 stderr,
			 "Unable to run dokan main: unknown error: %d\n",
			 result );
			break;
	}
	return( EXIT_SUCCESS );

#else
	fprintf(
	 stderr,
	 "No sub system to mount REGF format.\n" );

	return( EXIT_FAILURE );
#endif

on_error:
	if( error != NULL )
	{
		libcnotify_print_error_backtrace(
		 error );
		libcerror_error_free(
		 &error );
	}
#if defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE )
	if( regfmount_fuse_handle != NULL )
	{
		fuse_destroy(
		 regfmount_fuse_handle );
	}
	fuse_opt_free_args(
	 &regfmount_fuse_arguments );
#endif
	if( regfmount_mount_handle != NULL )
	{
		mount_handle_free(
		 &regfmount_mount_handle,
		 NULL );
	}
	return( EXIT_FAILURE );
}
Beispiel #20
0
int main(int argc, char *argv[])
{
	int ret = -1;
	int lockfd = -1;

	gboolean foreground = FALSE;
	gboolean force_local_mode = FALSE;
	gboolean wrote_pidfile = FALSE;
	memdb_t *memdb = NULL;
	dfsm_t *dcdb = NULL;
	dfsm_t *status_fsm = NULL;

	qb_log_init("pmxcfs", LOG_DAEMON, LOG_DEBUG);
	/* remove default filter */
	qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_REMOVE, 
			  QB_LOG_FILTER_FILE, "*", LOG_DEBUG);

 	qb_log_tags_stringify_fn_set(log_tags_stringify);

	qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);

	update_qb_log_settings();

	g_set_print_handler(glib_print_handler);
	g_set_printerr_handler(glib_print_handler);
	g_log_set_default_handler(glib_log_handler, NULL);

	GOptionContext *context;

	GOptionEntry entries[] = {
		{ "debug", 'd', 0, G_OPTION_ARG_NONE, &cfs.debug, "Turn on debug messages", NULL },
		{ "foreground", 'f', 0, G_OPTION_ARG_NONE, &foreground, "Do not daemonize server", NULL },
		{ "local", 'l', 0, G_OPTION_ARG_NONE, &force_local_mode, 
		  "Force local mode (ignore cluster.conf, force quorum)", NULL },
		{ NULL },
	};

	context = g_option_context_new ("");
	g_option_context_add_main_entries (context, entries, NULL);

	GError *err = NULL;
	if (!g_option_context_parse (context, &argc, &argv, &err))
	{
		cfs_critical("option parsing failed: %s", err->message);
		g_error_free (err);
		qb_log_fini();
		exit (1);
	}
	g_option_context_free(context);

	if (optind < argc) {
		cfs_critical("too many arguments");
		qb_log_fini();
		exit(-1);
	}

	if (cfs.debug) {
		update_qb_log_settings();
	}

	struct utsname utsname;
	if (uname(&utsname) != 0) {
		cfs_critical("Unable to read local node name");
		qb_log_fini();
		exit (-1);
	}
	
	for (int i=0; i < sizeof(utsname.nodename); i++) {
		if (utsname.nodename[i] =='.') utsname.nodename[i] = 0;
	}

	cfs.nodename = g_strdup(utsname.nodename);

	if (!(cfs.ip = lookup_node_ip(cfs.nodename))) { 
		cfs_critical("Unable to get local IP address");
		qb_log_fini();
		exit(-1);
	}

	struct group *www_data = getgrnam("www-data");
	if (!www_data) {
		cfs_critical("Unable to get www-data group ID");
		qb_log_fini();
		exit (-1);
	}
	cfs.gid = www_data->gr_gid;

	g_thread_init(NULL);

	umask(027);

	mkdir(VARLIBDIR, 0755);

	if ((lockfd = open(LOCKFILE, O_RDWR|O_CREAT|O_APPEND)) == -1) {
		cfs_critical("unable to create lock '%s': %s", LOCKFILE, strerror (errno));
		goto err;
	}

	for (int i = 10; i >= 0; i--) {
		if (flock(lockfd, LOCK_EX|LOCK_NB) != 0) {
			if (!i) {
				cfs_critical("unable to aquire pmxcfs lock: %s", strerror (errno));
				goto err;
			}
			if (i == 10)
				cfs_message("unable to aquire pmxcfs lock - trying again");

			sleep(1);
		}
	}

	cfs_status_init();

	gboolean create = !g_file_test(DBFILENAME, G_FILE_TEST_EXISTS);

	if (!(memdb = memdb_open (DBFILENAME))) {
		cfs_critical("memdb_open failed - unable to open database '%s'", DBFILENAME);
		goto err;
	}

	// automatically import cluster.conf from host
	if (create && !force_local_mode) {
		char *cdata = NULL;
		gsize clen = 0;
		if (g_file_get_contents(HOST_CLUSTER_CONF_FN, &cdata, &clen, NULL)) {

			guint32 mtime = time(NULL);

			memdb_create(memdb, "/cluster.conf", 0, mtime);
			if (memdb_write(memdb, "/cluster.conf", 0, mtime, cdata, clen, 0, 1) < 0) {
				cfs_critical("memdb_write failed - unable to import cluster.conf");
				goto err;
			}
		}
	}

	// does cluster.conf exist?
	gpointer conf_data = NULL;
	int len = memdb_read(memdb, "cluster.conf", &conf_data);
	if (len >= 0) {
		if (force_local_mode) {
			cfs_message("forcing local mode (althought cluster.conf exists)");
			cfs_set_quorate(1, TRUE);
		} else {
			if (!(dcdb = dcdb_new(memdb)))
				goto err;
			dcdb_sync_cluster_conf(memdb, 1);
		}
	} else {
		cfs_debug("using local mode (cluster.conf does not exist)");
		cfs_set_quorate(1, TRUE);
	}
	if (conf_data) g_free(conf_data);

	cfs_plug_memdb_t *config = cfs_plug_memdb_new("memdb", memdb, dcdb);
	
	cfs_plug_base_t *bplug = cfs_plug_base_new("", (cfs_plug_t *)config);

	create_symlinks(bplug, cfs.nodename);

	root_plug = (cfs_plug_t *)bplug;

	system("umount -f " CFSDIR " >/dev/null 2>&1");

	char *fa[] = { "-f", "-odefault_permissions", "-oallow_other", NULL};

	struct fuse_args fuse_args = FUSE_ARGS_INIT(sizeof (fa)/sizeof(gpointer) - 1, fa); 
	
	struct fuse_chan *fuse_chan = fuse_mount(CFSDIR, &fuse_args);
	if (!fuse_chan) {
		cfs_critical("fuse_mount error: %s", strerror(errno));
		goto err;
	}

	if (!(fuse = fuse_new(fuse_chan, &fuse_args, &fuse_ops, sizeof(fuse_ops), NULL))) {
		cfs_critical("fuse_new error: %s", strerror(errno));
		goto err;
	}

	fuse_set_signal_handlers(fuse_get_session(fuse));

	if (!foreground) {
		pid_t cpid = fork();

		if (cpid == -1) {
			cfs_critical("failed to daemonize program - %s", strerror (errno));
			goto err;
		} else if (cpid) {
			write_pidfile(cpid);
			qb_log_fini();
			_exit (0);
		} else {
			int nullfd;

			chroot("/");

			if ((nullfd = open("/dev/null", O_RDWR, 0)) != -1) {
				dup2(nullfd, 0);
				dup2(nullfd, 1);
				dup2(nullfd, 2);
				if (nullfd > 2)
					close (nullfd);
			}

			// do not print to the console after this point
			qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_FALSE);

			setsid();
		}
	} else {
		write_pidfile(getpid());
	}

	wrote_pidfile = TRUE;

	cfs_loop_t *corosync_loop = cfs_loop_new(fuse);

	cfs_service_t *service_quorum = NULL;
	cfs_service_t *service_confdb = NULL;
	cfs_service_t *service_dcdb = NULL;
	cfs_service_t *service_status = NULL;

	if (dcdb) {

		service_quorum = service_quorum_new();

		cfs_loop_add_service(corosync_loop, service_quorum, QB_LOOP_HIGH);

		service_confdb = service_confdb_new();

		cfs_loop_add_service(corosync_loop, service_confdb, QB_LOOP_MED);

		service_dcdb = service_dfsm_new(dcdb);
		cfs_service_set_timer(service_dcdb, DCDB_VERIFY_TIME);

		cfs_loop_add_service(corosync_loop, service_dcdb, QB_LOOP_MED);

		status_fsm = cfs_status_dfsm_new();
		service_status = service_dfsm_new(status_fsm);

		cfs_loop_add_service(corosync_loop, service_status, QB_LOOP_LOW);

	}

	cfs_loop_start_worker(corosync_loop);

	server_start(memdb);

	ret = fuse_loop_mt(fuse);

	cfs_message("teardown filesystem");

	server_stop();

	fuse_unmount(CFSDIR, fuse_chan);

	fuse_destroy(fuse);

	cfs_debug("set stop event loop flag");

	cfs_loop_stop_worker(corosync_loop);

	cfs_loop_destroy(corosync_loop);

	cfs_debug("worker finished");

	if (service_dcdb)
		service_dfsm_destroy(service_dcdb);

	if (service_confdb)
		service_confdb_destroy(service_confdb);

	if (service_quorum)
		service_quorum_destroy(service_quorum);

	if (service_status)
		service_dfsm_destroy(service_status);

	sleep(1); /* do not restart too fast */
 ret:

	if (status_fsm) 
		dfsm_destroy(status_fsm);

	if (dcdb)
		dfsm_destroy(dcdb);

	if (memdb) 
		memdb_close(memdb);

	if (wrote_pidfile)
		unlink(CFS_PID_FN);

	cfs_message("exit proxmox configuration filesystem (%d)", ret);

	cfs_status_cleanup();

	qb_log_fini();

	exit(ret);

 err:
	goto ret;
}
Beispiel #21
0
// return value:
//   0 - discard this arg
//   1 - keep this arg for future processing
static int mfs_opt_proc_stage2(void *data, const char *arg, int key, struct fuse_args *outargs) {
	(void)data;

	switch (key) {
	case FUSE_OPT_KEY_OPT:
		return 1;
	case FUSE_OPT_KEY_NONOPT:
		return 1;
	case KEY_HOST:
		if (mfsopts.masterhost!=NULL) {
			free(mfsopts.masterhost);
		}
		mfsopts.masterhost = strdup(arg+2);
		return 0;
	case KEY_PORT:
		if (mfsopts.masterport!=NULL) {
			free(mfsopts.masterport);
		}
		mfsopts.masterport = strdup(arg+2);
		return 0;
	case KEY_BIND:
		if (mfsopts.bindhost!=NULL) {
			free(mfsopts.bindhost);
		}
		mfsopts.bindhost = strdup(arg+2);
		return 0;
	case KEY_PROXY:
		if (mfsopts.proxyhost!=NULL) {
			free(mfsopts.proxyhost);
		}
		mfsopts.proxyhost = strdup(arg+2);
		return 0;
	case KEY_PATH:
		if (mfsopts.subfolder!=NULL) {
			free(mfsopts.subfolder);
		}
		mfsopts.subfolder = strdup(arg+2);
		return 0;
	case KEY_PASSWORDASK:
		mfsopts.passwordask = 1;
		return 0;
	case KEY_META:
		mfsopts.meta = 1;
		return 0;
	case KEY_NOSTDMOUNTOPTIONS:
		mfsopts.nostdmountoptions = 1;
		return 0;
	case KEY_VERSION:
		fprintf(stderr, "MFS version %s\n",VERSSTR);
		{
			struct fuse_args helpargs = FUSE_ARGS_INIT(0, NULL);

			fuse_opt_add_arg(&helpargs,outargs->argv[0]);
			fuse_opt_add_arg(&helpargs,"--version");
			fuse_parse_cmdline(&helpargs,NULL,NULL,NULL);
			fuse_mount(NULL,&helpargs);
		}
		exit(0);
	case KEY_HELP:
		usage(outargs->argv[0]);
		{
			struct fuse_args helpargs = FUSE_ARGS_INIT(0, NULL);

			fuse_opt_add_arg(&helpargs,outargs->argv[0]);
			fuse_opt_add_arg(&helpargs,"-ho");
			fuse_parse_cmdline(&helpargs,NULL,NULL,NULL);
			fuse_mount("",&helpargs);
		}
		exit(1);
	default:
		fprintf(stderr, "internal error\n");
		abort();
	}
}
Beispiel #22
0
int main(int argc, char *argv[])
{
	if(argc <= 2) {
		QString arg = "-h";
		if(argc > 1)
			arg = argv[1];
		if(arg == QStringLiteral("-h") || arg == QStringLiteral("--help")) {
			std::cout << argv[0] << " FUSE_options --dbfs DBFS_options" << std::endl;
			std::cout << "FUSE_options" << std::endl;
			std::cout << "\tuse -h --dbfs switch to print FUSE options" << std::endl;
			std::cout << "DBFS_options" << std::endl;
			std::cout << "\t--dbfs\t" << "DBFS options separator, all options prior this will be ignored by DBFS" << std::endl;
			std::cout << "\t--host <host>\t" << "Database host" << std::endl;
			std::cout << "\t--port <port>\t" << "Database port" << std::endl;
			std::cout << "\t -u" << std::endl;
			std::cout << "\t--user <user>\t" << "Database user" << std::endl;
			std::cout << "\t -p" << std::endl;
			std::cout << "\t--password [<password>]\t" << "Database user password, use -p without password for interactive input." << std::endl;
			std::cout << "\t--database <database>\t" << "Database name" << std::endl;
			std::cout << "\t--db-schema\t" << "Database schema name" << std::endl;
			std::cout << "\t--table-name\t" << "DBFS table name, default is 'dbfs'" << std::endl;
			std::cout << "\t--create\t" << "Create DBFS tables" << std::endl;
			exit(0);
		}
	}

	int dbfs_switch_index;
	for(dbfs_switch_index = 1; dbfs_switch_index < argc; dbfs_switch_index++)
		if(argv[dbfs_switch_index] == QLatin1String("--dbfs")) {
			break;
		}

	QScopedPointer<qf::core::LogDevice> file_log_device(qf::core::FileLogDevice::install());
	file_log_device->setDomainTresholds(argc - dbfs_switch_index, argv + dbfs_switch_index);
	file_log_device->setPrettyDomain(true);

	QString o_database;
	QString o_user;
	QString o_password;
	QString o_host;
	int o_port = 0;
	QString o_db_schema;
	QString o_table_name;
	bool o_create_db = false;
	bool o_ask_passwd = false;

	for(int i=dbfs_switch_index + 1; i<argc; i++) {
		QString arg = argv[i];
		if(arg == QStringLiteral("--host")) {
			if(i<argc-1) {
				i++;
				o_host = argv[i];
			}
		}
		else if(arg == QStringLiteral("--port")) {
			if(i<argc-1) {
				i++;
				o_port = QString(argv[i]).toInt();
			}
		}
		else if(arg == QStringLiteral("-u") || arg == QStringLiteral("--user")) {
			if(i<argc-1) {
				i++;
				o_user = argv[i];
			}
		}
		else if(arg == QStringLiteral("-p") || arg == QStringLiteral("--password")) {
			if(i<argc-1) {
				QString p = argv[i+1];
				if(p.startsWith('-')) {
					o_ask_passwd = true;
				}
				else {
					o_password = p;
					i++;
				}
			}
			else {
				o_ask_passwd = true;
			}
		}
		else if(arg == QStringLiteral("--database")) {
			if(i<argc-1) {
				i++;
				o_database = argv[i];
			}
		}
		else if(arg == QStringLiteral("--db-schema")) {
			if(i<argc-1) {
				i++;
				o_db_schema = argv[i];
			}
		}
		else if(arg == QStringLiteral("--table-name")) {
			if(i<argc-1) {
				i++;
				o_table_name = argv[i];
			}
		}
		else if(arg == QStringLiteral("--create")) {
			o_create_db = true;
		}
	}

	if(o_ask_passwd) {
		char pwd[256];
		std::cout << "Please, enter your password: "******"Empty database name.";
		exit(1);
	}

	qfs::DbFsDriver *dbfs_drv = nullptr;
	qf::core::sql::Connection db_connection;
	if(dbfs_switch_index < (argc - 1)) {
		db_connection = QSqlDatabase::addDatabase("QPSQL");
		db_connection.setHostName(o_host);
		if(o_port > 0)
			db_connection.setPort(o_port);
		db_connection.setDatabaseName(o_database);
		db_connection.setUserName(o_user);
		db_connection.setPassword(o_password);
		//qfInfo() << o_host << o_port << o_user << o_database;
		bool ok = db_connection.open();
		if(!ok) {
			qfError() << db_connection.lastError().text();
			exit(1);
		}
		if(!o_db_schema.isEmpty()) {
			if(!db_connection.setCurrentSchema(o_db_schema)) {
				qfError() << "Error setting db schema to:" << o_db_schema;
				exit(1);
			}
		}
		dbfs_drv = new qfs::DbFsDriver();
		dbfs_drv->setConnectionName(db_connection.connectionName());

		if(!o_table_name.isEmpty()) {
			dbfs_drv->setTableName(o_table_name);
		}
		if(o_create_db) {
			if(!dbfs_drv->createDbFs()) {
				qfError() << "Error creating dbfs table" << dbfs_drv->tableName();
			}
			exit(1);
		}

		qfsqldbfs_setdriver(dbfs_drv);
	}

	int fuse_argc = dbfs_switch_index;

	/// FUSE variables
	struct fuse_args fuse_arguments = FUSE_ARGS_INIT(fuse_argc, argv);
	struct fuse_chan *fuse_channel = NULL;
	struct fuse *fuse_handle = NULL;
	char *mount_point = nullptr;

	if (fuse_parse_cmdline(&fuse_arguments, &mount_point, NULL, NULL) == -1) {
		qfError() << "fuse_parse_cmdline() - Error parsing fuse command line arguments!";
		exit(1);
	}

	/// Tell FUSE where the local mountpoint is
	fuse_channel = fuse_mount(mount_point, &fuse_arguments);
	if (fuse_channel == NULL){
		qfError()<<"fuse_mount() failed";
		exit(1);
	}

	// Tell FUSE about implementations of FS operations
	struct fuse_operations fuse_ops;
	memset(&fuse_ops, 0, sizeof(fuse_ops));
	fuse_ops.getattr = qfsqldbfs_getattr;
	fuse_ops.readdir = qfsqldbfs_readdir;
	fuse_ops.open = qfsqldbfs_open;
	fuse_ops.read = qfsqldbfs_read;
	fuse_ops.write = qfsqldbfs_write;
	fuse_ops.fsync = qfsqldbfs_fsync;
	fuse_ops.flush = qfsqldbfs_flush;
	fuse_ops.release = qfsqldbfs_release;
	fuse_ops.mknod = qfsqldbfs_mknod;
	fuse_ops.mkdir = qfsqldbfs_mkdir;
	fuse_ops.unlink = qfsqldbfs_unlink;
	fuse_ops.rmdir = qfsqldbfs_rmdir;
	fuse_ops.utime = qfsqldbfs_utime;
	fuse_ops.truncate = qfsqldbfs_truncate;
	fuse_ops.ftruncate = qfsqldbfs_ftruncate;
	fuse_ops.chmod = qfsqldbfs_chmod;
	fuse_ops.chown = qfsqldbfs_chown;
	fuse_ops.create = qfsqldbfs_create;
	fuse_ops.rename = qfsqldbfs_rename;

	fuse_handle = fuse_new(fuse_channel, &fuse_arguments, &fuse_ops, sizeof(fuse_ops), NULL);
	if (fuse_handle == NULL){
		qfError()<<"fuse_new() failed";
		exit(1);
	}

	if(dbfs_drv) {
#ifdef USE_QT_EVENT_LOOP
		qfInfo() << "Using Qt event loop with FUSE in separated thread";
		TheApp *app = new TheApp(argc, argv);
		s_fuseThread = new FuseThread(fuse_handle, fuse_channel, QString::fromUtf8(mount_point));
		dbfs_drv->moveToThread(s_fuseThread);
		QObject::connect(s_fuseThread, &QThread::finished, app, &TheApp::onFuseThreadFinished, Qt::QueuedConnection);
		s_fuseThread->start();

		set_signal_handlers();

		{
			/// setup SQL notify
			QSqlDatabase notify_db = QSqlDatabase::addDatabase("QPSQL", "DBFS_Notify");
			notify_db.setHostName(db_connection.hostName());
			notify_db.setPort(db_connection.port());
			notify_db.setUserName(db_connection.userName());
			notify_db.setPassword(db_connection.password());
			notify_db.setDatabaseName(db_connection.databaseName());
			bool ok = notify_db.open();
			if(!ok) {
				qfError() << "Error connect DBFS notify connection" << notify_db.lastError().text();
			}
			else {
				QSqlDriver *drv = notify_db.driver();
				//qRegisterMetaType<QSqlDriver::NotificationSource>("QSqlDriver::NotificationSource");
				QObject::connect(drv, SIGNAL(notification(QString,QSqlDriver::NotificationSource,QVariant)), dbfs_drv, SLOT(onSqlNotify(QString,QSqlDriver::NotificationSource,QVariant)), Qt::DirectConnection);
				//QObject::connect(drv, SIGNAL(notification(QString,QSqlDriver::NotificationSource,QVariant)), app, SLOT(onSqlNotify(QString,QSqlDriver::NotificationSource,QVariant)));
				drv->subscribeToNotification(qfs::DbFsDriver::CHANNEL_INVALIDATE_DBFS_DRIVER_CACHE);
				qfInfo() << drv << "subscribedToNotifications:" << drv->subscribedToNotifications().join(", ");
			}
		}

		app->exec();

		qfInfo() << "Waiting for FUSE thread to join ...";
		s_fuseThread->wait();
#else
		qfInfo() << "Using FUSE event loop";
		fuse_loop(fuse_handle);
		qfInfo() << "FUSE has quit its event loop";
#endif

		qfsqldbfs_setdriver(nullptr);
		QF_SAFE_DELETE(dbfs_drv);
#ifdef USE_QT_EVENT_LOOP
		QF_SAFE_DELETE(s_fuseThread);
		QF_SAFE_DELETE(app);
#endif
	}
	else {
		// used just to print FUSE help
		fuse_loop(fuse_handle);
	}

	qfInfo() << "bye";
	return 0;
}
/*
 * Class:     org_catacombae_jfuse_FUSE
 * Method:    mountNative26
 * Signature: (Lorg/catacombae/jfuse/FUSE26FileSystem;Ljava/lang/String;[Ljava/lang/String;Lorg/catacombae/jfuse/FUSE26Capabilities;Lorg/catacombae/jfuse/MacFUSE20Capabilities;)Z
 */
JNIEXPORT jboolean JNICALL Java_org_catacombae_jfuse_FUSE_mountNative26(
        JNIEnv *env, jclass cls, jobject fileSystem, jstring mountPoint,
        jobjectArray optionStrings, jobject fuseCapabilities,
        jobject macFuseCapabilities) {
#define _FNAME_ "Java_org_catacombae_jfuse_FUSE_mountNative26"
    CSLogTraceEnter(_FNAME_ "(%p, %p, %p, %p, %p, %p, %p)", env, cls,
            fileSystem, mountPoint, optionStrings, fuseCapabilities,
            macFuseCapabilities);

    jboolean res = JNI_FALSE;

    jFUSEContext *context = new jFUSEContext(env, fileSystem);

    if(!fillFUSE26Operations(env, fuseCapabilities, &jfuse_operations))
        CSPanicWithMessage("Could not fill FUSE 2.6 operations!");
    else
        CSLogDebug("Filled FUSE 2.6 operations.");

    if(jfuse_operations.init != NULL) {
        context->setInitEnabled(true);
    }

#if defined(__APPLE__) || defined(__DARWIN__)
#if (__FreeBSD__ >= 10)
    if(macFuseCapabilities != NULL) {
        if(!fillMacFUSE20Operations(env, macFuseCapabilities,
                &jfuse_operations))
            CSPanicWithMessage("Could not fill MacFUSE 2.0 operations!");
        else {
            CSLogDebug("Filled MacFUSE 2.0 operations.");
            if(jfuse_operations.getxtimes != NULL ||
                    jfuse_operations.setbkuptime != NULL ||
                    jfuse_operations.setcrtime != NULL ||
                    jfuse_operations.setchgtime != NULL) {
                CSLogDebug("Requesting enabling of xtimes.");
                context->setXtimesEnabled(true);
                if(jfuse_operations.init == NULL) {
                    CSLogDebug("Adding operation 'init' to fuse_operations for "
                            "support enabling of xtimes...");
                    jfuse_operations.init = jfuse_init;
                }
            }
        }
    }
    else
        CSLogDebug("No MacFUSE 2.0 operations to fill.");
#endif /*__FreeBSD__ >= 10 */
#endif /* defined(__APPLE__) || defined(__DARWIN__) */

    /* Read mountpoint. */
    jboolean isCopy;
    const char *utf8MountPoint = env->GetStringUTFChars(mountPoint, &isCopy);

    /* Read options. */
    struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
    if(fuse_opt_add_arg(&args, utf8MountPoint) != 0)
        CSPanicWithMessage("fuse_opt_add_arg failed unexpectedly.");

    jsize optionStringsLength = env->GetArrayLength(optionStrings);
    CSLogDebug("Reading option strings (length=%ld)...", (long)optionStringsLength);
    for(int i = 0; i < optionStringsLength; ++i) {
        jstring cur = (jstring)env->GetObjectArrayElement(optionStrings, i);
        const char *utfChars = env->GetStringUTFChars(cur, NULL);

        CSLogDebug("  Adding option %d: \"%s\"", i, utfChars);
        int addArgRetval = fuse_opt_add_arg(&args, utfChars);
        if(addArgRetval != 0)
            CSPanicWithMessage("fuse_opt_add_arg failed unexpectedly with "
                    "retval=%d, errno: %d (%s)", addArgRetval, errno,
                    strerror(errno));

        env->ReleaseStringUTFChars(cur, utfChars);
        env->DeleteLocalRef(cur);
    }

    if(fuse_parse_cmdline(&args, NULL, NULL, NULL) != 0)
        CSLogError("fuse_parse_cmdline didn't return 0.");
    else {
        /*
         * FUSE regular mount procedure:
         *
         * Init:
         * - fuse_mount:
         *     (char *mountpoint, struct fuse_args *args)-> (struct fuse_chan*)
         * - fuse_new:
         *     (struct fuse_chan *ch, struct fuse_args *args,
         *      struct fuse_operations *op, size_t op_size, void *user_data)
         *     ->(struct fuse*)
         * Running:
         * - fuse_loop / fuse_loop_mt:
         *     (struct fuse*)->(int)
         *   Main loop, running until file system is unmounted.
         * Cleanup:
         * - fuse_unmount:
         *     (char *mountpoint, struct fuse_chan *ch)->(void)
         * - fuse_destroy:
         *     (struct fuse* f)->(void)
         *
         *
         * FUSE lowlevel mount procedure:
         *
         * Init:
         * - fuse_mount:
         *     (char *mountpoint, struct fuse_args *args)->(struct fuse_chan*)
         * - fuse_lowlevel_new:
         *     (struct fuse_args *args, struct fuse_lowlevel_ops *op,
         *       size_t op_size, void *userdata) -> (struct fuse_session*)
         * - fuse_session_add_chan:
         *     (struct fuse_session *se, struct fuse_chan *ch)->(void)
         * Running:
         * - fuse_session_loop / fuse_session_loop_mt:
         *     (struct fuse_session *se)->(int)
         * Cleanup:
         * - fuse_session_remove_chan:
         *     (struct fuse_chan *ch)->(void)
         * - fuse_session_destroy:
         *     (struct fuse_session *se)->(void)
         * - fuse_unmount:
         *     (char *mountpoint, struct fuse_chan *ch)->(void)
         */
        fuse_chan *chan = NULL;
        fuse *fh = NULL;

        CSLogDebug("Invoking fuse_mount...");
        chan = fuse_mount(utf8MountPoint, &args);
        CSLogDebug("   done. result=%p", chan);
        if(chan != NULL) {
            CSLogDebug("Invoking fuse_new...");
            fh = fuse_new(chan, &args, &jfuse_operations,
                    sizeof (jfuse_operations), context);
            CSLogDebug("   done. result=%p", fh);
            if(fh != NULL) {
#if defined(__NetBSD__)
	        int sighandler_res = 0;
#else
                int sighandler_res =
		  fuse_set_signal_handlers(fuse_get_session(fh));
#endif /* defined(__NetBSD__) */
		if(sighandler_res == 0) {
                    CSLogDebug("Invoking fuse_loop...");
                    int fuseLoopRetval = fuse_loop(fh);
                    CSLogDebug("  done. result=%d", fuseLoopRetval);
                    if(fuseLoopRetval != 0)
                        CSLogError("fuse_loop exited with a non-zero value: %d "
                            "(errno is %d (%s)", fuseLoopRetval, errno,
                            strerror(errno));
                    else
                        res = JNI_TRUE;

#if !defined(__NetBSD__)
                    fuse_remove_signal_handlers(fuse_get_session(fh));
#endif
                }
                else
                    CSLogError("Couldn't set signal handlers!");
            }
            else
                CSLogError("fuse_new exited with an error. (errno is %d (%s))",
                    errno, strerror(errno));
        }
        else
            CSLogError("fuse_mount exited with an error. (errno is %d (%s))",
                errno, strerror(errno));

        fuse_opt_free_args(&args);

        if(chan != NULL) {
            CSLogDebug("Unmounting \"%s\"... (chan=%p)", utf8MountPoint, chan);
            fuse_unmount(utf8MountPoint, chan);
        }
        if(fh != NULL) {
            CSLogDebug("Destroying fuse filehandle %p...", fh);
            fuse_destroy(fh);
        }

        delete context;
    }

    CSLogTraceLeave(_FNAME_ "(%p, %p, %p, %p, %p, %p, %p): %d", env, cls,
            fileSystem, mountPoint, optionStrings, fuseCapabilities,
            macFuseCapabilities, res);
    return res;
#undef _FNAME_
}
Beispiel #24
0
int
guestfs_impl_mount_local (guestfs_h *g, const char *localmountpoint,
			  const struct guestfs_mount_local_argv *optargs)
{
  const char *t;
  struct fuse_args args = FUSE_ARGS_INIT (0, NULL);
  struct fuse_chan *ch;
  int fd;

  /* You can only mount each handle in one place in one thread. */
  gl_lock_lock (mount_local_lock);
  t = g->localmountpoint;
  gl_lock_unlock (mount_local_lock);
  if (t) {
    error (g, _("filesystem is already mounted in another thread"));
    return -1;
  }

  if (optargs->bitmask & GUESTFS_MOUNT_LOCAL_READONLY_BITMASK)
    g->ml_read_only = optargs->readonly;
  else
    g->ml_read_only = 0;
  if (optargs->bitmask & GUESTFS_MOUNT_LOCAL_CACHETIMEOUT_BITMASK)
    g->ml_dir_cache_timeout = optargs->cachetimeout;
  else
    g->ml_dir_cache_timeout = 60;
  if (optargs->bitmask & GUESTFS_MOUNT_LOCAL_DEBUGCALLS_BITMASK)
    g->ml_debug_calls = optargs->debugcalls;
  else
    g->ml_debug_calls = 0;

  /* Initialize the directory caches in the handle. */
  if (init_dir_caches (g) == -1)
    return -1;

  /* Create the FUSE 'args'. */
  /* XXX we don't have a program name */
  if (fuse_opt_add_arg (&args, "guestfs_mount_local") == -1) {
  arg_error:
    perrorf (g, _("fuse_opt_add_arg: %s"), localmountpoint);
    fuse_opt_free_args (&args);
    guestfs_int_free_fuse (g);
    return -1;
  }

  if (optargs->bitmask & GUESTFS_MOUNT_LOCAL_OPTIONS_BITMASK) {
    if (fuse_opt_add_arg (&args, "-o") == -1 ||
        fuse_opt_add_arg (&args, optargs->options) == -1)
      goto arg_error;
  }

  debug (g, "%s: fuse_mount %s", __func__, localmountpoint);

  /* Create the FUSE mountpoint. */
  ch = fuse_mount (localmountpoint, &args);
  if (ch == NULL) {
    perrorf (g, _("fuse_mount: %s"), localmountpoint);
    fuse_opt_free_args (&args);
    guestfs_int_free_fuse (g);
    return -1;
  }

  /* Set F_CLOEXEC on the channel.  XXX libfuse should do this. */
  fd = fuse_chan_fd (ch);
  if (fd >= 0)
    set_cloexec_flag (fd, 1);

  debug (g, "%s: fuse_new", __func__);

  /* Create the FUSE handle. */
  g->fuse = fuse_new (ch, &args,
                      &mount_local_operations, sizeof mount_local_operations,
                      g);
  if (!g->fuse) {
    perrorf (g, _("fuse_new: %s"), localmountpoint);
    fuse_unmount (localmountpoint, ch);
    fuse_opt_free_args (&args);
    guestfs_int_free_fuse (g);
    return -1;
  }

  fuse_opt_free_args (&args);

  debug (g, "%s: leaving fuse_mount_local", __func__);

  /* Set g->localmountpoint in the handle. */
  gl_lock_lock (mount_local_lock);
  g->localmountpoint = localmountpoint;
  gl_lock_unlock (mount_local_lock);

  return 0;
}
Beispiel #25
0
int mainloop(struct fuse_args *args,const char* mp,int mt,int fg) {
	struct fuse_session *se;
	struct fuse_chan *ch;
	struct rlimit rls;
	int piped[2];
	char s;
	int err;
	int i;
	md5ctx ctx;
	uint8_t md5pass[16];

	if (mfsopts.passwordask && mfsopts.password==NULL && mfsopts.md5pass==NULL) {
		mfsopts.password = getpass("MFS Password:"******"bad md5 definition (md5 should be given as 32 hex digits)\n");
				return 1;
			}
			p++;
			if (*p>='0' && *p<='9') {
				md5pass[i]+=(*p-'0');
			} else if (*p>='a' && *p<='f') {
				md5pass[i]+=(*p-'a'+10);
			} else if (*p>='A' && *p<='F') {
				md5pass[i]+=(*p-'A'+10);
			} else {
				fprintf(stderr,"bad md5 definition (md5 should be given as 32 hex digits)\n");
				return 1;
			}
			p++;
		}
		if (*p) {
			fprintf(stderr,"bad md5 definition (md5 should be given as 32 hex digits)\n");
			return 1;
		}
		memset(mfsopts.md5pass,0,strlen(mfsopts.md5pass));
	}

	if (mfsopts.delayedinit) {
		fs_init_master_connection(mfsopts.bindhost,mfsopts.masterhost,mfsopts.masterport,mfsopts.meta,mp,mfsopts.subfolder,(mfsopts.password||mfsopts.md5pass)?md5pass:NULL,mfsopts.donotrememberpassword,1);
	} else {
		if (fs_init_master_connection(mfsopts.bindhost,mfsopts.masterhost,mfsopts.masterport,mfsopts.meta,mp,mfsopts.subfolder,(mfsopts.password||mfsopts.md5pass)?md5pass:NULL,mfsopts.donotrememberpassword,0)<0) {
			return 1;
		}
	}
	memset(md5pass,0,16);

	if (fg==0) {
		openlog(STR(APPNAME), LOG_PID | LOG_NDELAY , LOG_DAEMON);
	} else {
#if defined(LOG_PERROR)
		openlog(STR(APPNAME), LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_USER);
#else
		openlog(STR(APPNAME), LOG_PID | LOG_NDELAY, LOG_USER);
#endif
	}

	i = mfsopts.nofile;
	while (1) {
		rls.rlim_cur = i;
		rls.rlim_max = i;
		if (setrlimit(RLIMIT_NOFILE,&rls)<0) {
			i /= 2;
			if (i<1000) {
				break;
			}
		} else {
			break;
		}
	}
	if (i != (int)(mfsopts.nofile)) {
		fprintf(stderr,"can't set open file limit to %d\n",mfsopts.nofile);
		if (i>=1000) {
			fprintf(stderr,"open file limit set to: %d\n",i);
		}
	}

	setpriority(PRIO_PROCESS,getpid(),mfsopts.nice);
#ifdef MFS_USE_MEMLOCK
	if (mfsopts.memlock) {
		rls.rlim_cur = RLIM_INFINITY;
		rls.rlim_max = RLIM_INFINITY;
		if (setrlimit(RLIMIT_MEMLOCK,&rls)<0) {
			mfsopts.memlock=0;
		}
	}
#endif

	piped[0] = piped[1] = -1;
	if (fg==0) {
		if (pipe(piped)<0) {
			fprintf(stderr,"pipe error\n");
			return 1;
		}
		err = fork();
		if (err<0) {
			fprintf(stderr,"fork error\n");
			return 1;
		} else if (err>0) {
			close(piped[1]);
			err = read(piped[0],&s,1);
			if (err==0) {
				s=1;
			}
			return s;
		}
		close(piped[0]);
		s=1;
	}


#ifdef MFS_USE_MEMLOCK
	if (mfsopts.memlock) {
		if (mlockall(MCL_CURRENT|MCL_FUTURE)==0) {
			syslog(LOG_NOTICE,"process memory was successfully locked in RAM");
		}
	}
#endif

/* glibc malloc tuning */
#ifdef MFS_USE_MALLOPT
	if (mfsopts.limitarenas) {
		if (!getenv("MALLOC_ARENA_MAX")) {
			syslog(LOG_NOTICE,"setting glibc malloc arena max to 8");
			mallopt(M_ARENA_MAX, mfsopts.limitarenas);
		}
		if (!getenv("MALLOC_ARENA_TEST")) {
			syslog(LOG_NOTICE,"setting glibc malloc arena test to 1");
			mallopt(M_ARENA_TEST, 1);
		}
	} else {
		syslog(LOG_NOTICE,"setting glibc malloc arenas turned off");
	}
#endif /* glibc malloc tuning */

	syslog(LOG_NOTICE,"monotonic clock function: %s",monotonic_method());
	syslog(LOG_NOTICE,"monotonic clock speed: %"PRIu32" ops / 10 mili seconds",monotonic_speed());

	conncache_init(200);
	chunkloc_cache_init();
	symlink_cache_init();
	negentry_cache_init(mfsopts.negentrycacheto);
//	dir_cache_init();
	fs_init_threads(mfsopts.ioretries);
	if (masterproxy_init(mfsopts.proxyhost)<0) {
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

//	fs_term();
//	negentry_cache_term();
//	symlink_cache_term();
//	chunkloc_cache_term();
//	return 1;

	if (mfsopts.meta==0) {
		csdb_init();
		delay_init();
		read_data_init(mfsopts.readaheadsize*1024*1024,mfsopts.readaheadleng,mfsopts.readaheadtrigger,mfsopts.ioretries);
		write_data_init(mfsopts.writecachesize*1024*1024,mfsopts.ioretries);
	}

 	ch = fuse_mount(mp, args);
	if (ch==NULL) {
		fprintf(stderr,"error in fuse_mount\n");
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				fprintf(stderr,"pipe write error\n");
			}
			close(piped[1]);
		}
		if (mfsopts.meta==0) {
			write_data_term();
			read_data_term();
			delay_term();
			csdb_term();
		}
		masterproxy_term();
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

	if (mfsopts.meta) {
		mfs_meta_init(mfsopts.debug,mfsopts.entrycacheto,mfsopts.attrcacheto);
		se = fuse_lowlevel_new(args, &mfs_meta_oper, sizeof(mfs_meta_oper), (void*)piped);
	} else {
		mfs_init(mfsopts.debug,mfsopts.keepcache,mfsopts.direntrycacheto,mfsopts.entrycacheto,mfsopts.attrcacheto,mfsopts.xattrcacheto,mfsopts.groupscacheto,mfsopts.mkdircopysgid,mfsopts.sugidclearmode,1,mfsopts.fsyncbeforeclose,mfsopts.noxattrs,mfsopts.noposixlocks,mfsopts.nobsdlocks); //mfsopts.xattraclsupport);
		se = fuse_lowlevel_new(args, &mfs_oper, sizeof(mfs_oper), (void*)piped);
	}
	if (se==NULL) {
		fuse_unmount(mp,ch);
		fprintf(stderr,"error in fuse_lowlevel_new\n");
		portable_usleep(100000);	// time for print other error messages by FUSE
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				fprintf(stderr,"pipe write error\n");
			}
			close(piped[1]);
		}
		if (mfsopts.meta==0) {
			write_data_term();
			read_data_term();
			delay_term();
			csdb_term();
		}
		masterproxy_term();
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

//	fprintf(stderr,"check\n");
	fuse_session_add_chan(se, ch);

	if (fuse_set_signal_handlers(se)<0) {
		fprintf(stderr,"error in fuse_set_signal_handlers\n");
		fuse_session_remove_chan(ch);
		fuse_session_destroy(se);
		fuse_unmount(mp,ch);
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				fprintf(stderr,"pipe write error\n");
			}
			close(piped[1]);
		}
		if (mfsopts.meta==0) {
			write_data_term();
			read_data_term();
			delay_term();
			csdb_term();
		}
		masterproxy_term();
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

	if (mfsopts.debug==0 && fg==0) {
		setsid();
		setpgid(0,getpid());
		if ((i = open("/dev/null", O_RDWR, 0)) != -1) {
			(void)dup2(i, STDIN_FILENO);
			(void)dup2(i, STDOUT_FILENO);
			(void)dup2(i, STDERR_FILENO);
			if (i>2) close (i);
		}
	}

	if (mt) {
		err = fuse_session_loop_mt(se);
	} else {
		err = fuse_session_loop(se);
	}
	if (err) {
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				syslog(LOG_ERR,"pipe write error: %s",strerr(errno));
			}
			close(piped[1]);
		}
	}
	fuse_remove_signal_handlers(se);
	fuse_session_remove_chan(ch);
	fuse_session_destroy(se);
	fuse_unmount(mp,ch);
	if (mfsopts.meta==0) {
		write_data_term();
		read_data_term();
		delay_term();
		csdb_term();
	}
	masterproxy_term();
	fs_term();
//	dir_cache_term();
	negentry_cache_term();
	symlink_cache_term();
	chunkloc_cache_term();
	return err ? 1 : 0;
}
Beispiel #26
0
// run fskit with fuse
int fskit_fuse_main( struct fskit_fuse_state* state, int argc, char** argv ) {

   int rc = 0;

   // set up FUSE
   struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
   struct fuse_chan* ch = NULL;
   struct fuse* fs = NULL;
   int multithreaded = 1;
   int foreground = 0;
   char* mountpoint = NULL;

   // parse command-line...
   rc = fuse_parse_cmdline( &args, &mountpoint, &multithreaded, &foreground );
   if( rc < 0 ) {

      fskit_error("fuse_parse_cmdline rc = %d\n", rc );
      fuse_opt_free_args(&args);

      return rc;
   }

   if( mountpoint == NULL ) {

      fskit_error("%s", "No mountpoint given\n");
      fuse_opt_free_args(&args);

      return rc;
   }

   state->mountpoint = strdup( mountpoint );

   // mount
   ch = fuse_mount( mountpoint, &args );
   if( ch == NULL ) {

      rc = -errno;
      fskit_error("fuse_mount failed, errno = %d\n", rc );

      fuse_opt_free_args(&args);

      if( rc == 0 ) {
          rc = -EPERM;
      }

      return rc;
   }

   // create the filesystem
   fs = fuse_new( ch, &args, &state->ops, sizeof(state->ops), state );
   fuse_opt_free_args(&args);

   if( fs == NULL ) {

      // failed
      rc = -errno;
      fskit_error("fuse_new failed, errno = %d\n", rc );

      fuse_unmount( mountpoint, ch );

      if( rc == 0 ) {
          rc = -EPERM;
      }

      return rc;
   }

   // daemonize if running in the background
   fskit_debug("FUSE daemonize: foreground=%d\n", foreground);
   rc = fuse_daemonize( foreground );
   if( rc != 0 ) {

      // failed
      fskit_error("fuse_daemonize(%d) rc = %d\n", foreground, rc );

      fuse_unmount( mountpoint, ch );
      fuse_destroy( fs );

      return rc;
   }

   // set up FUSE signal handlers
   rc = fuse_set_signal_handlers( fuse_get_session(fs) );
   if( rc < 0 ) {

      // failed
      fskit_error("fuse_set_signal_handlers rc = %d\n", rc );

      fuse_unmount( mountpoint, ch );
      fuse_destroy( fs );
      return rc;
   }

   // if we have a post-mount callback, call it now, since FUSE is ready to receive requests
   if( state->postmount != NULL ) {

      rc = (*state->postmount)( state, state->postmount_cls );
      if( rc != 0 ) {

         fskit_error("fskit postmount callback rc = %d\n", rc );

         fuse_unmount( mountpoint, ch );
         fuse_destroy( fs );

         return rc;
      }
   }

   // run the filesystem--start processing requests
   fskit_debug("%s", "FUSE main loop entered\n");
   if( multithreaded ) {
      rc = fuse_loop_mt( fs );
   }
   else {
      rc = fuse_loop( fs );
   }

   fskit_debug("%s", "FUSE main loop finished\n");
   fuse_teardown( fs, mountpoint );

   return rc;
}
int main(int argc, char* argv[])
{
	struct fuse_args mount_args = FUSE_ARGS_INIT(0, NULL);
	struct fuse_args newfs_args = FUSE_ARGS_INIT(0, NULL);
	const char* spec = NULL;
	const char* mount_point = NULL;
	char* mount_options;
	int debug = 0;
	struct fuse_chan* fc = NULL;
	struct fuse* fh = NULL;
	int opt;

	printf("FUSE exfat %u.%u.%u\n",
			EXFAT_VERSION_MAJOR, EXFAT_VERSION_MINOR, EXFAT_VERSION_PATCH);

	mount_options = strdup(default_options);
	if (mount_options == NULL)
	{
		exfat_error("failed to allocate options string");
		return 1;
	}

	while ((opt = getopt(argc, argv, "dno:Vv")) != -1)
	{
		switch (opt)
		{
		case 'd':
			debug = 1;
			break;
		case 'n':
			break;
		case 'o':
			mount_options = add_option(mount_options, optarg, NULL);
			if (mount_options == NULL)
				return 1;
			break;
		case 'V':
			free(mount_options);
			puts("Copyright (C) 2010-2014  Andrew Nayenko");
			return 0;
		case 'v':
			break;
		default:
			free(mount_options);
			usage(argv[0]);
			break;
		}
	}
	if (argc - optind != 2)
	{
		free(mount_options);
		usage(argv[0]);
	}
	spec = argv[optind];
	mount_point = argv[optind + 1];

	if (exfat_mount(&ef, spec, mount_options) != 0)
	{
		free(mount_options);
		return 1;
	}

	if (ef.ro == -1) /* read-only fallback was used */
	{
		mount_options = add_option(mount_options, "ro", NULL);
		if (mount_options == NULL)
		{
			exfat_unmount(&ef);
			return 1;
		}
	}

	mount_options = add_fuse_options(mount_options, spec);
	if (mount_options == NULL)
	{
		exfat_unmount(&ef);
		return 1;
	}

	/* create arguments for fuse_mount() */
	if (fuse_opt_add_arg(&mount_args, "exfat") != 0 ||
		fuse_opt_add_arg(&mount_args, "-o") != 0 ||
		fuse_opt_add_arg(&mount_args, mount_options) != 0)
	{
		exfat_unmount(&ef);
		free(mount_options);
		return 1;
	}

	free(mount_options);

	/* create FUSE mount point */
	fc = fuse_mount(mount_point, &mount_args);
	fuse_opt_free_args(&mount_args);
	if (fc == NULL)
	{
		exfat_unmount(&ef);
		return 1;
	}

	/* create arguments for fuse_new() */
	if (fuse_opt_add_arg(&newfs_args, "") != 0 ||
		(debug && fuse_opt_add_arg(&newfs_args, "-d") != 0))
	{
		fuse_unmount(mount_point, fc);
		exfat_unmount(&ef);
		return 1;
	}

	/* create new FUSE file system */
	fh = fuse_new(fc, &newfs_args, &fuse_exfat_ops,
			sizeof(struct fuse_operations), NULL);
	fuse_opt_free_args(&newfs_args);
	if (fh == NULL)
	{
		fuse_unmount(mount_point, fc);
		exfat_unmount(&ef);
		return 1;
	}

	/* exit session on HUP, TERM and INT signals and ignore PIPE signal */
	if (fuse_set_signal_handlers(fuse_get_session(fh)) != 0)
	{
		fuse_unmount(mount_point, fc);
		fuse_destroy(fh);
		exfat_unmount(&ef);
		exfat_error("failed to set signal handlers");
		return 1;
	}

	/* go to background (unless "-d" option is passed) and run FUSE
	   main loop */
	if (fuse_daemonize(debug) == 0)
	{
		if (fuse_loop(fh) != 0)
			exfat_error("FUSE loop failure");
	}
	else
		exfat_error("failed to daemonize");

	fuse_remove_signal_handlers(fuse_get_session(fh));
	/* note that fuse_unmount() must be called BEFORE fuse_destroy() */
	fuse_unmount(mount_point, fc);
	fuse_destroy(fh);
	return 0;
}
Beispiel #28
0
int do_mount(char *spec, char *dir, int mflag, char *opt)
{
	// VERIFY(mflag == 0);

	vfs_t *vfs = kmem_zalloc(sizeof(vfs_t), KM_SLEEP);
	if(vfs == NULL)
		return ENOMEM;

	VFS_INIT(vfs, zfs_vfsops, 0);
	VFS_HOLD(vfs);

	struct mounta uap = {
	.spec = spec,
	.dir = dir,
	.flags = mflag | MS_SYSSPACE,
	.fstype = "zfs-fuse",
	.dataptr = "",
	.datalen = 0,
	.optptr = opt,
	.optlen = strlen(opt)
	};

	int ret;
	if ((ret = VFS_MOUNT(vfs, rootdir, &uap, kcred)) != 0) {
		kmem_free(vfs, sizeof(vfs_t));
		return ret;
	}
	/* Actually, optptr is totally ignored by VFS_MOUNT.
	 * So we are going to pass this with fuse_mount_options if possible */
    if (fuse_mount_options == NULL)
        fuse_mount_options = "";
	char real_opts[1024];
	*real_opts = 0;
	if (*fuse_mount_options)
		strcat(real_opts,fuse_mount_options); // comes with a starting ,
	if (*opt)
		sprintf(&real_opts[strlen(real_opts)],",%s",opt);

#ifdef DEBUG
	atomic_inc_32(&mounted);;

	fprintf(stderr, "mounting %s\n", dir);
#endif

	char *fuse_opts = NULL;
	int has_default_perm = 0;
	if (fuse_version() <= 27) {
	if(asprintf(&fuse_opts, FUSE_OPTIONS, spec, real_opts) == -1) {
		VERIFY(do_umount(vfs, B_FALSE) == 0);
		return ENOMEM;
	}
	} else {
	  if(asprintf(&fuse_opts, FUSE_OPTIONS ",big_writes", spec, real_opts) == -1) {
	    VERIFY(do_umount(vfs, B_FALSE) == 0);
	    return ENOMEM;
	  }
	}
	
	struct fuse_args args = FUSE_ARGS_INIT(0, NULL);

	if(fuse_opt_add_arg(&args, "") == -1 ||
	   fuse_opt_add_arg(&args, "-o") == -1 ||
	   fuse_opt_add_arg(&args, fuse_opts) == -1) {
		fuse_opt_free_args(&args);
		free(fuse_opts);
		VERIFY(do_umount(vfs, B_FALSE) == 0);
		return ENOMEM;
	}
	has_default_perm = detect_fuseoption(fuse_opts,"default_permissions");
	free(fuse_opts);

	struct fuse_chan *ch = fuse_mount(dir, &args);

	if(ch == NULL) {
		VERIFY(do_umount(vfs, B_FALSE) == 0);
		return EIO;
	}

	if (has_default_perm)
	    vfs->fuse_attribute = FUSE_VFS_HAS_DEFAULT_PERM;

	struct fuse_session *se = fuse_lowlevel_new(&args, &zfs_operations, sizeof(zfs_operations), vfs);
	fuse_opt_free_args(&args);

	if(se == NULL) {
		VERIFY(do_umount(vfs, B_FALSE) == 0); /* ZFSFUSE: FIXME?? */
		fuse_unmount(dir,ch);
		return EIO;
	}

	fuse_session_add_chan(se, ch);

	if(zfsfuse_newfs(dir, ch) != 0) {
		fuse_session_destroy(se);
		fuse_unmount(dir,ch);
		return EIO;
	}

	return 0;
}
Beispiel #29
0
int
fusefs_setup(char *mountpoint, const struct fuse_operations *op, char *opts) {
  char fuse_new_opts[1024];
  char fuse_mount_opts[1024];
  char nopts[1024];

  char *cur;
  char *ptr;

  fuse_new_opts[0] = '\0';
  fuse_mount_opts[0] = '\0';

  for (cur=opts;cur;cur = ptr) {
    ptr = strchr(cur,',');
    if (ptr) *(ptr++) = '\0';
    if (fuse_is_lib_option(cur)) {
      if (fuse_new_opts[0]) {
        strcpy(nopts,fuse_new_opts);
        snprintf(fuse_new_opts,1024,"%s,%s",nopts,cur);
      } else {
        snprintf(fuse_new_opts,1024,"%s",cur);
      }
    } else {
      if (fuse_mount_opts[0]) {
        strcpy(nopts,fuse_mount_opts);
        snprintf(fuse_mount_opts,1024,"%s,%s",nopts,cur);
      } else {
        snprintf(fuse_mount_opts,1024,"%s",cur);
      }
    }
  }

  fusefd = -1;
  if (fuse_instance != NULL) {
    return 0;
  }
  if (mounted_at != NULL) {
    return 0;
  }

  /* First, mount us */
  fusefd = fuse_mount(mountpoint, fuse_mount_opts[0] ? fuse_mount_opts : NULL);
  if (fusefd == -1) return 0;

  fuse_instance = fuse_new(fusefd, fuse_new_opts[0] ? fuse_new_opts : NULL, op, sizeof(*op));
  if (fuse_instance == NULL)
    goto err_unmount;

  /* Set signal handlers */
  if (set_one_signal_handler(SIGHUP, fusefs_ehandler) == -1 ||
      set_one_signal_handler(SIGINT, fusefs_ehandler) == -1 ||
      set_one_signal_handler(SIGTERM, fusefs_ehandler) == -1 ||
      set_one_signal_handler(SIGPIPE, SIG_IGN) == -1)
    return 0;

  atexit(fusefs_ehandler);

  /* We've initialized it! */
  mounted_at = strdup(mountpoint);
  return 1;
err_destroy:
  fuse_destroy(fuse_instance);
err_unmount:
  fuse_unmount(mountpoint);
  return 0;
}
Beispiel #30
0
int main(int argc, char **argv)
{
    extern void init_ops(fuse_lowlevel_ops *ops);
    struct options options;

    std::memset(&options, 0, sizeof(options));

    struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
    struct fuse_chan *ch;
    char *mountpoint = NULL;
    int err = -1;
    std::string mountPath;
    unsigned format = 0;

    int foreground = false;
    int multithread = false;
    
    
    Pascal::VolumeEntryPointer volume;
    
	
    init_ops(&pascal_ops);


    // scan the argument list, looking for the name of the disk image.
    if (fuse_opt_parse(&args, &options ,pascal_options, pascal_option_proc) == -1)
        exit(1);
    
    if (fDiskImage.empty())
    {
        usage();
        exit(1);
    }

    // default prodos-order disk image.
    if (options.format)
    {
        format = Device::BlockDevice::ImageType(options.format);
        if (!format)
            std::fprintf(stderr, "Warning: Unknown image type ``%s''\n", options.format);
    }

        
    try
    {        
        Device::BlockDevicePointer device;
        
        device = Device::BlockDevice::Open(fDiskImage.c_str(), File::ReadOnly, format);
        
       
        if (!device.get())
        {
            std::fprintf(stderr, "Error: Unknown or unsupported device type.\n");
            exit(1);
        }
        
        volume = Pascal::VolumeEntry::Open(device);
    }
    catch (::Exception &e)
    {
        std::fprintf(stderr, "%s\n", e.what());
        std::fprintf(stderr, "%s\n", std::strerror(e.error()));
        return -1;
    }    

    
    
    
    #ifdef __APPLE__
    {
        // Macfuse supports custom volume names (displayed in Finder)
        std::string str("-ovolname=");
        str += volume->name();
        fuse_opt_add_arg(&args, str.c_str());
    
        // 512 byte blocksize.    
        fuse_opt_add_arg(&args, "-oiosize=512");
        
    }
    #endif  

    fuse_opt_add_arg(&args, "-ofsname=PascalFS");

    if (!options.readOnly)
        fuse_opt_add_arg(&args, "-ordonly");
        
    if (options.readWrite)
    {
        std::fprintf(stderr, "Warning:  write support is not yet enabled.\n");
    }

    if (fuse_parse_cmdline(&args, &mountpoint, &multithread, &foreground) == -1)
    {
        usage();
        return -1;
    }
    
#ifdef __APPLE__
      
        if (mountpoint == NULL || *mountpoint == 0)
        {
            if (make_mount_dir(volume->name(), mountPath))
                mountpoint = (char *)mountPath.c_str();
        }
        
#endif    
    
    
    if ((ch = fuse_mount(mountpoint, &args)) != NULL)
    {
        struct fuse_session* se;

        std::printf("Mounting ``%s'' on ``%s''\n", volume->name(), mountpoint);
        
        se = fuse_lowlevel_new(&args, &pascal_ops, sizeof(pascal_ops), volume.get());

        if (se) do {

            
            err = fuse_daemonize(foreground);
            if (err < 0 ) break;
            
            err = fuse_set_signal_handlers(se);
            if (err < 0) break;
            
            fuse_session_add_chan(se, ch);
        
            if (multithread) err = fuse_session_loop_mt(se);
            else err = fuse_session_loop(se);
        
            fuse_remove_signal_handlers(se);
            fuse_session_remove_chan(ch);
        
        } while (false);
        if (se) fuse_session_destroy(se);
        fuse_unmount(mountpoint, ch);
    }



    fuse_opt_free_args(&args);


#ifdef __APPLE__
    if (!mountPath.empty()) rmdir(mountPath.c_str());
#endif


    return err ? 1 : 0;
}