]> git.proxmox.com Git - mirror_lxcfs.git/blobdiff - bindings.c
libtool: do not link lxcfs against liblxcfs
[mirror_lxcfs.git] / bindings.c
index 0cc926bd469e1960a0a971740ed6e209e510da84..4413a7de99eba6dc0b0888e9422c4ab005adef02 100644 (file)
@@ -1506,23 +1506,30 @@ static char *pick_controller_from_path(struct fuse_context *fc, const char *path
        const char *p1;
        char *contr, *slash;
 
-       if (strlen(path) < 9)
+       if (strlen(path) < 9) {
+               errno = EACCES;
                return NULL;
-       if (*(path+7) != '/')
+       }
+       if (*(path + 7) != '/') {
+               errno = EINVAL;
                return NULL;
-       p1 = path+8;
+       }
+       p1 = path + 8;
        contr = strdupa(p1);
-       if (!contr)
+       if (!contr) {
+               errno = ENOMEM;
                return NULL;
+       }
        slash = strstr(contr, "/");
        if (slash)
                *slash = '\0';
 
        int i;
-       for (i = 0;  i < num_hierarchies;  i++) {
+       for (i = 0; i < num_hierarchies; i++) {
                if (hierarchies[i] && strcmp(hierarchies[i], contr) == 0)
                        return hierarchies[i];
        }
+       errno = ENOENT;
        return NULL;
 }
 
@@ -1534,12 +1541,17 @@ static const char *find_cgroup_in_path(const char *path)
 {
        const char *p1;
 
-       if (strlen(path) < 9)
+       if (strlen(path) < 9) {
+               errno = EACCES;
                return NULL;
-       p1 = strstr(path+8, "/");
-       if (!p1)
+       }
+       p1 = strstr(path + 8, "/");
+       if (!p1) {
+               errno = EINVAL;
                return NULL;
-       return p1+1;
+       }
+       errno = 0;
+       return p1 + 1;
 }
 
 /*
@@ -1598,7 +1610,7 @@ int cg_getattr(const char *path, struct stat *sb)
 
        controller = pick_controller_from_path(fc, path);
        if (!controller)
-               return -EIO;
+               return -errno;
        cgroup = find_cgroup_in_path(path);
        if (!cgroup) {
                /* this is just /cgroup/controller, return it as a dir */
@@ -1698,7 +1710,7 @@ int cg_opendir(const char *path, struct fuse_file_info *fi)
                // return list of keys for the controller, and list of child cgroups
                controller = pick_controller_from_path(fc, path);
                if (!controller)
-                       return -EIO;
+                       return -errno;
 
                cgroup = find_cgroup_in_path(path);
                if (!cgroup) {
@@ -1742,6 +1754,9 @@ int cg_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset
        struct fuse_context *fc = fuse_get_context();
        char **clist = NULL;
 
+       if (filler(buf, ".", NULL, 0) != 0 || filler(buf, "..", NULL, 0) != 0)
+               return -EIO;
+
        if (d->type != LXC_TYPE_CGDIR) {
                fprintf(stderr, "Internal error: file cache info used in readdir\n");
                return -EIO;
@@ -1853,10 +1868,10 @@ int cg_open(const char *path, struct fuse_file_info *fi)
 
        controller = pick_controller_from_path(fc, path);
        if (!controller)
-               return -EIO;
+               return -errno;
        cgroup = find_cgroup_in_path(path);
        if (!cgroup)
-               return -EINVAL;
+               return -errno;
 
        get_cgdir_and_path(cgroup, &cgdir, &last);
        if (!last) {
@@ -1909,18 +1924,22 @@ out:
 
 int cg_access(const char *path, int mode)
 {
+       int ret;
        const char *cgroup;
-       char *last = NULL, *path1, *path2, * cgdir = NULL, *controller;
+       char *path1, *path2, *controller;
+       char *last = NULL, *cgdir = NULL;
        struct cgfs_files *k = NULL;
        struct fuse_context *fc = fuse_get_context();
-       int ret;
+
+       if (strcmp(path, "/cgroup") == 0)
+               return 0;
 
        if (!fc)
                return -EIO;
 
        controller = pick_controller_from_path(fc, path);
        if (!controller)
-               return -EIO;
+               return -errno;
        cgroup = find_cgroup_in_path(path);
        if (!cgroup) {
                // access("/sys/fs/cgroup/systemd", mode) - rx allowed, w not
@@ -2703,15 +2722,16 @@ int cg_chown(const char *path, uid_t uid, gid_t gid)
                return -EIO;
 
        if (strcmp(path, "/cgroup") == 0)
-               return -EINVAL;
+               return -EPERM;
 
        controller = pick_controller_from_path(fc, path);
        if (!controller)
-               return -EINVAL;
+               return errno == ENOENT ? -EPERM : -errno;
+
        cgroup = find_cgroup_in_path(path);
        if (!cgroup)
                /* this is just /cgroup/controller */
-               return -EINVAL;
+               return -EPERM;
 
        get_cgdir_and_path(cgroup, &cgdir, &last);
 
@@ -2768,15 +2788,16 @@ int cg_chmod(const char *path, mode_t mode)
                return -EIO;
 
        if (strcmp(path, "/cgroup") == 0)
-               return -EINVAL;
+               return -EPERM;
 
        controller = pick_controller_from_path(fc, path);
        if (!controller)
-               return -EINVAL;
+               return errno == ENOENT ? -EPERM : -errno;
+
        cgroup = find_cgroup_in_path(path);
        if (!cgroup)
                /* this is just /cgroup/controller */
-               return -EINVAL;
+               return -EPERM;
 
        get_cgdir_and_path(cgroup, &cgdir, &last);
 
@@ -2834,14 +2855,13 @@ int cg_mkdir(const char *path, mode_t mode)
        if (!fc)
                return -EIO;
 
-
        controller = pick_controller_from_path(fc, path);
        if (!controller)
-               return -EINVAL;
+               return errno == ENOENT ? -EPERM : -errno;
 
        cgroup = find_cgroup_in_path(path);
        if (!cgroup)
-               return -EINVAL;
+               return -errno;
 
        get_cgdir_and_path(cgroup, &cgdir, &last);
        if (!last)
@@ -2858,7 +2878,7 @@ int cg_mkdir(const char *path, mode_t mode)
                else if (last && strcmp(next, last) == 0)
                        ret = -EEXIST;
                else
-                       ret = -ENOENT;
+                       ret = -EPERM;
                goto out;
        }
 
@@ -2890,16 +2910,20 @@ int cg_rmdir(const char *path)
                return -EIO;
 
        controller = pick_controller_from_path(fc, path);
-       if (!controller)
-               return -EINVAL;
+       if (!controller) /* Someone's trying to delete "/cgroup". */
+               return -EPERM;
 
        cgroup = find_cgroup_in_path(path);
-       if (!cgroup)
-               return -EINVAL;
+       if (!cgroup) /* Someone's trying to delete a controller e.g. "/blkio". */
+               return -EPERM;
 
        get_cgdir_and_path(cgroup, &cgdir, &last);
        if (!last) {
-               ret = -EINVAL;
+               /* Someone's trying to delete a cgroup on the same level as the
+                * "/lxc" cgroup e.g. rmdir "/cgroup/blkio/lxc" or
+                * rmdir "/cgroup/blkio/init.slice".
+                */
+               ret = -EPERM;
                goto out;
        }
 
@@ -4017,12 +4041,14 @@ int proc_getattr(const char *path, struct stat *sb)
 int proc_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
                struct fuse_file_info *fi)
 {
-       if (filler(buf, "cpuinfo", NULL, 0) != 0 ||
-                               filler(buf, "meminfo", NULL, 0) != 0 ||
-                               filler(buf, "stat", NULL, 0) != 0 ||
-                               filler(buf, "uptime", NULL, 0) != 0 ||
-                               filler(buf, "diskstats", NULL, 0) != 0 ||
-                               filler(buf, "swaps", NULL, 0) != 0)
+       if (filler(buf, ".", NULL, 0) != 0 ||
+           filler(buf, "..", NULL, 0) != 0 ||
+           filler(buf, "cpuinfo", NULL, 0) != 0 ||
+           filler(buf, "meminfo", NULL, 0) != 0 ||
+           filler(buf, "stat", NULL, 0) != 0 ||
+           filler(buf, "uptime", NULL, 0) != 0 ||
+           filler(buf, "diskstats", NULL, 0) != 0 ||
+           filler(buf, "swaps", NULL, 0) != 0)
                return -EINVAL;
        return 0;
 }
@@ -4068,6 +4094,9 @@ int proc_open(const char *path, struct fuse_file_info *fi)
 
 int proc_access(const char *path, int mask)
 {
+       if (strcmp(path, "/proc") == 0 && access(path, R_OK) == 0)
+               return 0;
+
        /* these are all read-only */
        if ((mask & ~R_OK) != 0)
                return -EACCES;