/* Maximum number for 64 bit integer is a string with 21 digits: 2^64 - 1 = 21 */
#define LXCFS_NUMSTRLEN64 21
+/* The definitions here are well-ordered. New values should go directly
+ * above LXC_TYPE_MAX only. */
enum lxcfs_virt_t {
LXC_TYPE_CGDIR,
LXC_TYPE_CGFILE,
LXC_TYPE_SYS_DEVICES_SYSTEM_CPU_ONLINE,
#define LXC_TYPE_SYS_DEVICES_SYSTEM_CPU_ONLINE_PATH "/sys/devices/system/cpu/online"
+ LXC_TYPE_MAX,
};
+/* Macros below used to check the class from the file types above */
+#define LXCFS_TYPE_CGROUP(type) (type >= LXC_TYPE_CGDIR && type <= LXC_TYPE_CGFILE)
+#define LXCFS_TYPE_PROC(type) (type >= LXC_TYPE_PROC_MEMINFO && type <= LXC_TYPE_PROC_SLABINFO)
+#define LXCFS_TYPE_SYS(type) (type >= LXC_TYPE_SYS && type <= LXC_TYPE_SYS_DEVICES_SYSTEM_CPU_ONLINE)
+#define LXCFS_TYPE_OK(type) (type >= LXC_TYPE_CGDIR && type < LXC_TYPE_MAX)
+
struct file_info {
char *controller;
char *cgroup;
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
+#include <inttypes.h>
#include <libgen.h>
#include <pthread.h>
#include <sched.h>
unlock_mutex(&user_count_mutex);
}
+/* Returns file info type of custom type declaration carried
+ * in fuse_file_info */
+static inline enum lxcfs_virt_t file_info_type(struct fuse_file_info *fi)
+{
+ struct file_info *f;
+
+ f = INTTYPE_TO_PTR(fi->fh);
+ if (!f)
+ return -1;
+
+ if (!LXCFS_TYPE_OK(f->type))
+ return -1;
+
+ return f->type;
+}
+
static pthread_t loadavg_pid = 0;
/* Returns zero on success */
static int lxcfs_releasedir(const char *path, struct fuse_file_info *fi)
{
int ret;
+ enum lxcfs_virt_t type;
- if (strcmp(path, "/") == 0)
- return 0;
+ type = file_info_type(fi);
- if (strncmp(path, "/cgroup", 7) == 0) {
+ if (LXCFS_TYPE_CGROUP(type)) {
up_users();
ret = do_cg_releasedir(path, fi);
down_users();
return ret;
}
- if (strcmp(path, "/proc") == 0)
- return 0;
-
- if (strncmp(path, "/sys", 4) == 0) {
+ if (LXCFS_TYPE_SYS(type)) {
up_users();
ret = do_sys_releasedir(path, fi);
down_users();
return ret;
}
+ if (path) {
+ if (strcmp(path, "/") == 0)
+ return 0;
+ if (strcmp(path, "/proc") == 0)
+ return 0;
+ }
+
+ lxcfs_error("unknown file type: path=%s, type=%d, fi->fh=%" PRIu64,
+ path, type, fi->fh);
+
return -EINVAL;
}
static int lxcfs_release(const char *path, struct fuse_file_info *fi)
{
int ret;
+ enum lxcfs_virt_t type;
- if (strncmp(path, "/cgroup", 7) == 0) {
+ type = file_info_type(fi);
+
+ if (LXCFS_TYPE_CGROUP(type)) {
up_users();
ret = do_cg_release(path, fi);
down_users();
return ret;
}
- if (strncmp(path, "/proc", 5) == 0) {
+ if (LXCFS_TYPE_PROC(type)) {
up_users();
ret = do_proc_release(path, fi);
down_users();
return ret;
}
- if (strncmp(path, "/sys", 4) == 0) {
+ if (LXCFS_TYPE_SYS(type)) {
up_users();
ret = do_sys_release(path, fi);
down_users();
return ret;
}
+ lxcfs_error("unknown file type: path=%s, type=%d, fi->fh=%" PRIu64,
+ path, type, fi->fh);
+
return -EINVAL;
}