]> git.proxmox.com Git - mirror_lxcfs.git/commitdiff
Implement mkdir
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Mon, 15 Dec 2014 02:21:03 +0000 (20:21 -0600)
committerSerge Hallyn <serge.hallyn@ubuntu.com>
Mon, 15 Dec 2014 02:21:03 +0000 (20:21 -0600)
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
cgmanager.c
cgmanager.h
lxcfs.c

index ce5680bceabdfa5f6cdcbc354441849c884eec52..e93ef24772f8820e973989e2d88d9e6ef601a895 100644 (file)
@@ -39,6 +39,7 @@
 #include <sys/param.h>
 #include <sys/inotify.h>
 #include <sys/mount.h>
+#include <sys/wait.h>
 #include <netinet/in.h>
 #include <net/if.h>
 #include <stdbool.h>
@@ -224,3 +225,98 @@ bool cgm_get_value(const char *controller, const char *cgroup, const char *file,
        cgm_dbus_disconnect();
        return true;
 }
+
+static int wait_for_pid(pid_t pid)
+{
+       int status, ret;
+
+again:
+       ret = waitpid(pid, &status, 0);
+       if (ret == -1) {
+               if (errno == EINTR)
+                       goto again;
+               return -1;
+       }
+       if (ret != pid)
+               goto again;
+       if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+               return -1;
+       return 0;
+}
+
+bool cgm_create(const char *controller, const char *cg, uid_t uid, gid_t gid)
+{
+       int32_t e;
+       pid_t pid = fork();
+
+       if (pid) {
+               if (wait_for_pid(pid) != 0)
+                       return false;
+               return true;
+       }
+
+       if (setgroups(0, NULL))
+               exit(1);
+       if (setresgid(gid, gid, gid))
+               exit(1);
+       if (setresuid(uid, uid, uid))
+               exit(1);
+
+       if (!cgm_dbus_connect()) {
+               exit(1);
+       }
+
+       if ( cgmanager_create_sync(NULL, cgroup_manager, controller, cg, &e) != 0) {
+               NihError *nerr;
+               nerr = nih_error_get();
+               fprintf(stderr, "call to create failed: %s", nerr->message);
+               nih_free(nerr);
+               cgm_dbus_disconnect();
+               exit(1);
+       }
+
+       cgm_dbus_disconnect();
+       exit(0);
+}
+
+#if 0
+bool cgm_chown(const char *controller, const char *cg, uid_t uid, gid_t gid)
+{
+       if (!cgm_dbus_connect()) {
+               return false;
+       }
+
+       if ( cgmanager_chown_sync(NULL, cgroup_manager, controller, cg, uid, gid) != 0) {
+               NihError *nerr;
+               nerr = nih_error_get();
+               fprintf(stderr, "call to chown failed: %s", nerr->message);
+               nih_free(nerr);
+               cgm_dbus_disconnect();
+               return false;
+       }
+
+       cgm_dbus_disconnect();
+       return true;
+}
+
+bool cgm_remove(const char *controller, const char *cg)
+{
+       int32_t r = 1, e;
+
+       if (!cgm_dbus_connect()) {
+               return false;
+       }
+
+       if ( cgmanager_remove_sync(NULL, cgroup_manager, controller, cg, r, &e) != 0) {
+               NihError *nerr;
+               nerr = nih_error_get();
+               fprintf(stderr, "call to remove failed: %s", nerr->message);
+               nih_free(nerr);
+               cgm_dbus_disconnect();
+               return false;
+       }
+
+       cgm_dbus_disconnect();
+       return true;
+}
+#endif
index a605a7cc7a35f3aa68c62bc3744cce98a2d38c2d..4fab146ba51cfa9f08bd9259a58df1ed403c70c5 100644 (file)
@@ -10,5 +10,10 @@ bool cgm_list_children(const char *controller, const char *cgroup, char ***list)
 char *cgm_get_pid_cgroup(pid_t pid, const char *controller);
 bool cgm_get_value(const char *controller, const char *cgroup, const char *file,
                char **value);
+bool cgm_create(const char *controller, const char *cg, uid_t uid, gid_t gid);
+#if 0
+bool cgm_chown(const char *controller, const char *cg, uid_t uid, gid_t gid);
+bool cgm_remove(const char *controller, const char *cg);
+#endif
 
 bool cgm_escape_cgroup(void);
diff --git a/lxcfs.c b/lxcfs.c
index 771deda7b75ffc1d0b7327f120d114945d5718e2..41c4d18fa78b13fed3ea0a06726b5bdd45529723 100644 (file)
--- a/lxcfs.c
+++ b/lxcfs.c
@@ -380,7 +380,7 @@ static int cg_getattr(const char *path, struct stat *sb)
                return 0;
        }
 
-       return -EINVAL;
+       return -ENOENT;
 }
 
 static int cg_opendir(const char *path, struct fuse_file_info *fi)
@@ -555,6 +555,44 @@ fprintf(stderr, "cg_read: returning %d: %s\n", s, buf);
        return -EINVAL;
 }
 
+int cg_mkdir(const char *path, mode_t mode)
+{
+       struct fuse_context *fc = fuse_get_context();
+       nih_local struct cgm_keys **list = NULL;
+       char *fpath = NULL, *path1;
+       nih_local char * cgdir = NULL;
+       const char *cgroup;
+       nih_local char *controller = NULL;
+
+fprintf(stderr, "XXX cg_mkdir: starting for %s\n", path);
+       if (!fc)
+               return -EIO;
+
+
+       controller = pick_controller_from_path(fc, path);
+       if (!controller)
+               return -EIO;
+
+       cgroup = find_cgroup_in_path(path);
+       if (!cgroup)
+               return -EIO;
+
+       get_cgdir_and_path(cgroup, &cgdir, &fpath);
+       if (!fpath)
+               path1 = "/";
+       else
+               path1 = cgdir;
+
+       if (!fc_may_access(fc, controller, path1, NULL, O_RDWR))
+               return -EPERM;
+
+
+       if (!cgm_create(controller, cgroup, fc->uid, fc->gid))
+               return -EINVAL;
+
+       return 0;
+}
+
 /*
  * So far I'm not actually using cg_ops and proc_ops, but listing them
  * here makes it clearer who is supporting what.  Still I prefer to 
@@ -565,7 +603,7 @@ const struct fuse_operations cg_ops = {
        .readlink = NULL,
        .getdir = NULL,
        .mknod = NULL,
-       .mkdir = NULL,
+       .mkdir = cg_mkdir,
        .unlink = NULL,
        .rmdir = NULL,
        .symlink = NULL,
@@ -737,12 +775,20 @@ static int lxcfs_fsync(const char *path, int datasync, struct fuse_file_info *fi
        return 0;
 }
 
+int lxcfs_mkdir(const char *path, mode_t mode)
+{
+       if (strncmp(path, "/cgroup", 7) == 0)
+               return cg_mkdir(path, mode);
+
+       return -EINVAL;
+}
+
 const struct fuse_operations lxcfs_ops = {
        .getattr = lxcfs_getattr,
        .readlink = NULL,
        .getdir = NULL,
        .mknod = NULL,
-       .mkdir = NULL,
+       .mkdir = lxcfs_mkdir,
        .unlink = NULL,
        .rmdir = NULL,
        .symlink = NULL,