I want to mount cgroup controller by mount() in c language.
code like this and mount_path has already give 777 permissions and run by root(host not container, with full capabilities),but program return "mount failed: Operation not permitted",and i try to use mount command is work well, but code not
Is some error in my code?
mount("none", mount_path, "cgroup", 0, "none,name=memory")
just want same effect like mount -t cgroup -o memory cgroup /tmp
I find stackoverflow and github but could not find the answer.
Thanks
code is very simple like this
// if(mount("none", mount_path, "cgroup", 0, "none,name=memory")){
if(mount("cgroup", "/tmp/b", "cgroup", 0, "memory")){
perror("mount failed");
}
strace mount result strace -o trace.txt mount -t cgroup -o memory cgroup /tmp
execve("/usr/bin/mount", ["mount", "-t", "cgroup", "-o", "memory", "cgroup", "/tmp/a/"], 0xffffd37390c0 /* 50 vars */) = 0
brk(NULL) = 0xaaab1a331000
faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=69312, ...}) = 0
mmap(NULL, 69312, PROT_READ, MAP_PRIVATE, 3, 0) = 0xffff9d7aa000
close(3) = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libmount.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0\340\263\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=383480, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xffff9d7e7000
mmap(NULL, 447832, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xffff9d73c000
mprotect(0xffff9d797000, 65536, PROT_NONE) = 0
mmap(0xffff9d7a7000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x5b000) = 0xffff9d7a7000
close(3) = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0`\17\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1450832, ...}) = 0
mmap(NULL, 1519552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xffff9d5c9000
mprotect(0xffff9d724000, 61440, PROT_NONE) = 0
mmap(0xffff9d733000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15a000) = 0xffff9d733000
mmap(0xffff9d739000, 12224, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xffff9d739000
close(3) = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libblkid.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0\360\236\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=355240, ...}) = 0
mmap(NULL, 419600, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xffff9d562000
mprotect(0xffff9d5b3000, 65536, PROT_NONE) = 0
mmap(0xffff9d5c3000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x51000) = 0xffff9d5c3000
close(3) = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0 e\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=154872, ...}) = 0
mmap(NULL, 227800, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xffff9d52a000
mprotect(0xffff9d54f000, 61440, PROT_NONE) = 0
mmap(0xffff9d55e000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x24000) = 0xffff9d55e000
mmap(0xffff9d560000, 6616, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xffff9d560000
close(3) = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libpcre2-8.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0\0\"\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=514504, ...}) = 0
mmap(NULL, 578176, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xffff9d49c000
mprotect(0xffff9d518000, 65536, PROT_NONE) = 0
mmap(0xffff9d528000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7c000) = 0xffff9d528000
close(3) = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0P\17\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=14560, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xffff9d7e5000
mmap(NULL, 78080, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xffff9d488000
mprotect(0xffff9d48b000, 61440, PROT_NONE) = 0
mmap(0xffff9d49a000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0xffff9d49a000
close(3) = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0Ha\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=164304, ...}) = 0
mmap(NULL, 197624, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xffff9d457000
mprotect(0xffff9d473000, 61440, PROT_NONE) = 0
mmap(0xffff9d482000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b000) = 0xffff9d482000
mmap(0xffff9d484000, 13304, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xffff9d484000
close(3) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xffff9d7e3000
mprotect(0xffff9d733000, 16384, PROT_READ) = 0
mprotect(0xffff9d482000, 4096, PROT_READ) = 0
mprotect(0xffff9d49a000, 4096, PROT_READ) = 0
mprotect(0xffff9d528000, 4096, PROT_READ) = 0
mprotect(0xffff9d55e000, 4096, PROT_READ) = 0
mprotect(0xffff9d5c3000, 20480, PROT_READ) = 0
mprotect(0xffff9d7a7000, 8192, PROT_READ) = 0
mprotect(0xaaaae690a000, 4096, PROT_READ) = 0
mprotect(0xffff9d7ec000, 4096, PROT_READ) = 0
munmap(0xffff9d7aa000, 69312) = 0
set_tid_address(0xffff9d7e30e0) = 16344
set_robust_list(0xffff9d7e30f0, 24) = 0
rt_sigaction(SIGRTMIN, {sa_handler=0xffff9d45cbd0, sa_mask=[], sa_flags=SA_SIGINFO}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {sa_handler=0xffff9d45cc90, sa_mask=[], sa_flags=SA_RESTART|SA_SIGINFO}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
statfs("/sys/fs/selinux", 0xffffff7f4740) = -1 ENOENT (No such file or directory)
statfs("/selinux", 0xffffff7f4740) = -1 ENOENT (No such file or directory)
brk(NULL) = 0xaaab1a331000
brk(0xaaab1a352000) = 0xaaab1a352000
openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(3, "nodev\tsysfs\nnodev\ttmpfs\nnodev\tbd"..., 1024) = 413
read(3, "", 1024) = 0
close(3) = 0
faccessat(AT_FDCWD, "/etc/selinux/config", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3035952, ...}) = 0
mmap(NULL, 3035952, PROT_READ, MAP_PRIVATE, 3, 0) = 0xffff9d171000
close(3) = 0
getuid() = 0
geteuid() = 0
faccessat(AT_FDCWD, "/sys/fs/smackfs", F_OK) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "/tmp/a", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "/sbin/mount.cgroup", 0xffffff7f2418, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/sbin/fs.d/mount.cgroup", 0xffffff7f2418, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/sbin/fs/mount.cgroup", 0xffffff7f2418, 0) = -1 ENOENT (No such file or directory)
getuid() = 0
geteuid() = 0
getgid() = 0
getegid() = 0
prctl(PR_GET_DUMPABLE) = 1 (SUID_DUMP_USER)
newfstatat(AT_FDCWD, "/run", {st_mode=S_IFDIR|0755, st_size=1000, ...}, 0) = 0
newfstatat(AT_FDCWD, "/run/mount/utab", {st_mode=S_IFREG|0644, st_size=500, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "/run/mount/utab", {st_mode=S_IFREG|0644, st_size=500, ...}, 0) = 0
geteuid() = 0
getegid() = 0
getuid() = 0
getgid() = 0
faccessat(AT_FDCWD, "/run/mount/utab", R_OK|W_OK) = 0
mount("cgroup", "/tmp/a", "cgroup", 0, "memory") = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
Edit mount("none", mount_path, "cgroup", 0, "none,name=memory")
to mount("cgroup", "/tmp/b", "cgroup", 0, "memory")
mount() return 0,but no file in mount path
If I build an executable from the following code:
#include <stdio.h>
#include <sys/mount.h>
int main() {
if(mount("cgroup", "/tmp/b", "cgroup", 0, "memory")){
perror("mount failed");
}
}
And run it as a non-root user, I get:
$ ./mounttest
mount failed: Operation not permitted
If I run it as root
on a system that is using cgroupsv2, I see:
$ sudo ./mounttest
mount failed: Device or resource busy
We can verify whether or not a system is using cgroupsv2 by running mount -t cgroup2
. If we see a mount...
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,seclabel,nsdelegate,memory_recursiveprot)
...then we're using cgroupsv2 and we don't be able to use the -o memory
option.
On a system using cgroupsv1, it works as expected:
$ sudo ./mounttest
$ ls /tmp/b
cgroup.clone_children memory.kmem.tcp.failcnt memory.soft_limit_in_bytes
cgroup.event_control memory.kmem.tcp.limit_in_bytes memory.stat
cgroup.procs memory.kmem.tcp.max_usage_in_bytes memory.swappiness
cgroup.sane_behavior memory.kmem.tcp.usage_in_bytes memory.usage_in_bytes
init.scope memory.kmem.usage_in_bytes memory.use_hierarchy
memory.failcnt memory.limit_in_bytes notify_on_release
memory.force_empty memory.max_usage_in_bytes release_agent
memory.kmem.failcnt memory.move_charge_at_immigrate system.slice
memory.kmem.limit_in_bytes memory.numa_stat tasks
memory.kmem.max_usage_in_bytes memory.oom_control user.slice
memory.kmem.slabinfo memory.pressure_level