cfuse = new CephFuse(client, fd[1]);
+ r = cfuse->init(newargc, newargv);
+ if (r != 0) {
+ cerr << "ceph-fuse[" << getpid() << "]: fuse failed to initialize" << std::endl;
+ goto out_messenger_start_failed;
+ }
+
cout << "ceph-fuse[" << getpid() << "]: starting ceph client" << std::endl;
r = messenger->start();
if (r < 0) {
goto out_shutdown;
}
- r = cfuse->init(newargc, newargv);
+ r = cfuse->start();
if (r != 0) {
- cerr << "ceph-fuse[" << getpid() << "]: fuse failed to initialize" << std::endl;
+ cerr << "ceph-fuse[" << getpid() << "]: fuse failed to start" << std::endl;
goto out_client_unmount;
}
cerr << "ceph-fuse[" << getpid() << "]: starting fuse" << std::endl;
class CephFuse::Handle {
public:
Handle(Client *c, int fd);
+ ~Handle();
int init(int argc, const char *argv[]);
+ int start();
int loop();
void finalize();
ceph::unordered_map<uint64_t,int> snap_stag_map;
ceph::unordered_map<int,uint64_t> stag_snap_map;
+ struct fuse_args args;
};
static void fuse_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
{
snap_stag_map[CEPH_NOSNAP] = 0;
stag_snap_map[0] = CEPH_NOSNAP;
+ memset(&args, 0, sizeof(args));
+}
+
+CephFuse::Handle::~Handle()
+{
+ fuse_opt_free_args(&args);
}
void CephFuse::Handle::finalize()
for (int argctr = 1; argctr < argc; argctr++)
newargv[newargc++] = argv[argctr];
- struct fuse_args args = FUSE_ARGS_INIT(newargc, (char**)newargv);
- int ret = 0;
+ derr << "init, newargv = " << newargv << " newargc=" << newargc << dendl;
+ struct fuse_args a = FUSE_ARGS_INIT(newargc, (char**)newargv);
+ args = a; // Roundabout construction b/c FUSE_ARGS_INIT is for initialization not assignment
- char *mountpoint;
if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) == -1) {
derr << "fuse_parse_cmdline failed." << dendl;
- ret = EINVAL;
- goto done;
+ fuse_opt_free_args(&args);
+ free(newargv);
+ return EINVAL;
}
+ assert(args.allocated); // Checking fuse has realloc'd args so we can free newargv
+ free(newargv);
+ return 0;
+}
+
+int CephFuse::Handle::start()
+{
ch = fuse_mount(mountpoint, &args);
if (!ch) {
derr << "fuse_mount(mountpoint=" << mountpoint << ") failed." << dendl;
- ret = EIO;
- goto done;
+ return EIO;
}
se = fuse_lowlevel_new(&args, &fuse_ll_oper, sizeof(fuse_ll_oper), this);
if (!se) {
derr << "fuse_lowlevel_new failed" << dendl;
- ret = EDOM;
- goto done;
+ return EDOM;
}
signal(SIGTERM, SIG_DFL);
signal(SIGINT, SIG_DFL);
if (fuse_set_signal_handlers(se) == -1) {
derr << "fuse_set_signal_handlers failed" << dendl;
- ret = ENOSYS;
- goto done;
+ return ENOSYS;
}
fuse_session_add_chan(se, ch);
if (client->cct->_conf->fuse_use_invalidate_cb)
client->ll_register_ino_invalidate_cb(ino_invalidate_cb, this);
-done:
- fuse_opt_free_args(&args);
- free(newargv);
- return ret;
+ return 0;
}
int CephFuse::Handle::loop()
return _handle->init(argc, argv);
}
+int CephFuse::start()
+{
+ return _handle->start();
+}
+
int CephFuse::loop()
{
return _handle->loop();
{
return _handle->finalize();
}
+
+std::string CephFuse::get_mount_point() const
+{
+ if (_handle->mountpoint) {
+ return _handle->mountpoint;
+ } else {
+ return "";
+ }
+}