#include "config.h"
-#ifdef HAVE_FUSE3
-#ifndef FUSE_USE_VERSION
-#define FUSE_USE_VERSION 30
-#endif
-#else
-#ifndef FUSE_USE_VERSION
-#define FUSE_USE_VERSION 26
-#endif
-#endif
-
-#define _FILE_OFFSET_BITS 64
-
#include <alloca.h>
#include <dirent.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
-#include <fuse.h>
#include <getopt.h>
#include <libgen.h>
#include <pthread.h>
#include <sys/socket.h>
#include <linux/limits.h>
+#if HAVE_FUSE3
+#include <fuse3/fuse.h>
+#else
+#include <fuse.h>
+#endif
+
#include "bindings.h"
#include "lxcfs_fuse_compat.h"
#include "macro.h"
#else
ret = snprintf(lxcfs_lib_path, sizeof(lxcfs_lib_path), "/usr/local/lib/lxcfs/liblxcfs.so");
#endif
- if (ret < 0 || ret >= sizeof(lxcfs_lib_path))
+ if (ret < 0 || (size_t)ret >= sizeof(lxcfs_lib_path))
log_exit("Failed to create path to open liblxcfs");
dlopen_handle = dlopen(lxcfs_lib_path, RTLD_LAZY);
return __cg_write(path, buf, size, offset, fi);
}
+static int do_sys_write(const char *path, const char *buf, size_t size,
+ off_t offset, struct fuse_file_info *fi)
+{
+ char *error;
+ int (*__sys_write)(const char *path, const char *buf, size_t size,
+ off_t offset, struct fuse_file_info *fi);
+
+ dlerror();
+ __sys_write = (int (*)(const char *, const char *, size_t, off_t, struct fuse_file_info *))dlsym(dlopen_handle, "sys_write");
+ error = dlerror();
+ if (error)
+ return log_error(-1, "%s - Failed to find sys_write()", error);
+
+ return __sys_write(path, buf, size, offset, fi);
+}
+
static int do_cg_mkdir(const char *path, mode_t mode)
{
char *error;
return __sys_readdir(path, buf, filler, offset, fi);
}
+static int do_sys_readlink(const char *path, char *buf, size_t size)
+{
+ char *error;
+ int (*__sys_readlink)(const char *path, char *buf, size_t size);
+
+ dlerror();
+ __sys_readlink = (int (*)(const char *, char *, size_t))dlsym(dlopen_handle, "sys_readlink");
+ error = dlerror();
+ if (error)
+ return log_error(-1, "%s - Failed to find sys_readlink()", error);
+
+ return __sys_readlink(path, buf, size);
+}
static int do_cg_open(const char *path, struct fuse_file_info *fi)
{
return __sys_open(path, fi);
}
+static int do_sys_opendir(const char *path, struct fuse_file_info *fi)
+{
+ char *error;
+ int (*__sys_opendir)(const char *path, struct fuse_file_info *fi);
+
+ dlerror();
+ __sys_opendir = (int (*)(const char *path, struct fuse_file_info *fi))dlsym(dlopen_handle, "sys_opendir");
+ error = dlerror();
+ if (error)
+ return log_error(-1, "%s - Failed to find sys_opendir()", error);
+
+ return __sys_opendir(path, fi);
+}
+
static int do_sys_access(const char *path, int mode)
{
char *error;
if (strcmp(path, "/proc") == 0)
return 0;
- if (strncmp(path, "/sys", 4) == 0)
- return 0;
+ if (strncmp(path, "/sys", 4) == 0) {
+ up_users();
+ ret = do_sys_opendir(path, fi);
+ down_users();
+ return ret;
+ }
return -ENOENT;
}
return ret;
}
+ if (strncmp(path, "/sys", 4) == 0) {
+ up_users();
+ ret = do_sys_write(path, buf, size, offset, fi);
+ down_users();
+ return ret;
+ }
+
+ return -EINVAL;
+}
+
+int lxcfs_readlink(const char *path, char *buf, size_t size)
+{
+ int ret;
+
+ if (strncmp(path, "/sys", 4) == 0) {
+ up_users();
+ ret = do_sys_readlink(path, buf, size);
+ down_users();
+ return ret;
+ }
+
return -EINVAL;
}
if (strncmp(path, "/cgroup", 7) == 0)
return 0;
+ if (strncmp(path, "/sys", 4) == 0)
+ return 0;
+
return -EPERM;
}
return -ENOENT;
}
+#ifdef HAVE_FUSE3
+static void *lxcfs_init(struct fuse_conn_info *conn, struct fuse_config *cfg)
+#else
+static void *lxcfs_init(struct fuse_conn_info *conn)
+#endif
+{
+ char *error;
+ void *(*__lxcfs_fuse_init)(struct fuse_conn_info * conn, void * cfg);
+
+ dlerror();
+ __lxcfs_fuse_init = (void *(*)(struct fuse_conn_info * conn, void * cfg))dlsym(dlopen_handle, "lxcfs_fuse_init");
+ error = dlerror();
+ if (error)
+ return log_error(NULL, "%s - Failed to find lxcfs_fuse_init()", error);
+
+ return __lxcfs_fuse_init(conn, NULL);
+}
+
const struct fuse_operations lxcfs_ops = {
.access = lxcfs_access,
.chmod = lxcfs_chmod,
.flush = lxcfs_flush,
.fsync = lxcfs_fsync,
.getattr = lxcfs_getattr,
+ .init = lxcfs_init,
.mkdir = lxcfs_mkdir,
.open = lxcfs_open,
.opendir = lxcfs_opendir,
.rmdir = lxcfs_rmdir,
.truncate = lxcfs_truncate,
.write = lxcfs_write,
+ .readlink = lxcfs_readlink,
.create = NULL,
.destroy = NULL,
.getdir = NULL,
#endif
.getxattr = NULL,
- .init = NULL,
.link = NULL,
.listxattr = NULL,
.mknod = NULL,
- .readlink = NULL,
.rename = NULL,
.removexattr = NULL,
.setxattr = NULL,
#endif
};
-static void usage()
+static void usage(void)
{
lxcfs_info("Usage: lxcfs <directory>\n");
lxcfs_info("lxcfs is a FUSE-based proc, sys and cgroup virtualizing filesystem\n");
return log_error(-1, "Error truncating PID file '%s': %m", pidfile);
ret = snprintf(buf, sizeof(buf), "%ld\n", (long)getpid());
- if (ret < 0 || ret >= sizeof(buf))
+ if (ret < 0 || (size_t)ret >= sizeof(buf))
return log_error(-1, "Failed to convert pid to string %m");
if (write(fd, buf, ret) != ret)
opts->swap_off = false;
opts->use_pidfd = false;
opts->use_cfs = false;
+ opts->version = 1;
while ((c = getopt_long(argc, argv, "dulfhvso:p:", long_options, &idx)) != -1) {
switch (c) {
case 'u':
opts->swap_off = true;
break;
+ case 'v':
+ case 'version':
+ lxcfs_info("%s", STRINGIFY(PROJECT_VERSION));
+ exit(EXIT_SUCCESS);
default:
usage();
}
new_argv = &argv[optind];
new_argc = argc - optind;
+ if (new_argc == 0) {
+ usage();
+ }
if (new_argc != 1) {
lxcfs_error("Missing mountpoint");
goto out;
fuse_argv[fuse_argc++] = new_argv[0];
fuse_argv[fuse_argc] = NULL;
- for (int i = 0; i < fuse_argc; i++)
- printf("AAAA: %s\n", fuse_argv[i]);
-
do_reload();
if (install_signal_handler(SIGUSR1, sigusr1_reload)) {
lxcfs_error("%s - Failed to install SIGUSR1 signal handler", strerror(errno));