cgroup-v1是由google工程师在内核v2.6.24合入,用来限制控制进程资源(如CPU、内存)使用的一种资源控制机制。内核4.5版本时cgroup-v2发布,虽然现在内核主线版本已发布至6.13但ubuntu-20.04的使用5.15的内核版本,系统中cgroup的v1和v2版本共存。限于篇幅本文主要介绍内核中cgroup-v1相关的内容。
cgroup中cgroupfs是Linux内核文件系统中的一个子系统,用于限制、记录和隔离进程组的资源使用。通过在cgroupfs上创建、删除和挂载cgroup,可配置和管理容器化应用程序的资源限制和优先级。cgroupfs亦可看作一种api文件系统,因为内核关于cgroup的相关操作接口通过该文件系统暴露给用户态进程使用。本篇博客以操作系统在开机时如何挂载cgroupfs文件系统为切入点,介绍cgroup的相关概念和技术原理和内核cgroup的实现。
用户空间
开机挂载
Linux系统的启动流程(基于UNIX System V4),其中主要包括:硬件初始化->操作系统加载->初始化内核->用户空间init进程->开机脚本,5个阶段,详见man 7 boot文档。基于systemd的init系统(诸如ubuntu-18+,centos-7+系统),systemd除了扮演操作系统服务管理器维护用户空间服务的角色,还在开机时刻引导系统启动必要服务,使系统进入可用状态,即systemctl get-default设置的开机目标。多用户环境用户管理器实例会通过user@.service(5)服务自动启动,此时systemd会启动一个用户实例,管理用户单元。

system-bootup流程图展示graphical.target目标所包含的基本流程,可以看出其相关的文件系统挂载工作在sysinit.target中基本已全部完成,其他与网络相关的文件系统的挂载操作在remote-fs目标中完成。
systemd-v245源码
mk-sbuild --arch=amd64 focal
apt-get source systemd
sbuild -d focal ./systemd_245.4-4ubuntu3.24.dsc
cc -Isystemd@exe -I. -I.. -Isrc/basic -I../src/basic -Isrc/boot -I../src/boot -Isrc/shared -I../src/shared -Isrc/systemd -I../src/systemd -Isrc/journal -I../src/journal -Isrc/journal-remote -I../src/journal-re mote -Isrc/nspawn -I../src/nspawn -Isrc/resolve -I../src/resolve -Isrc/timesync -I../src/timesync -I../src/time-wait-sync -Isrc/login -I../src/login -Isrc/udev -I../src/udev -Isrc/libudev -I../src/libudev -Isrc/core -I.. /src/core -Isrc/shutdown -I../src/shutdown -I../src/libsystemd/sd-bus -I../src/libsystemd/sd-device -I../src/libsystemd/sd-event -I../src/libsystemd/sd-hwdb -I../src/libsystemd/sd-id128 -I../src/libsystemd/sd-netlink -I. ./src/libsystemd/sd-network -I../src/libsystemd/sd-resolve -Isrc/libsystemd-network -I../src/libsystemd-network -I../ -I/usr/include/libmount -I/usr/include/blkid -flto -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BIT S=64 -std=gnu99 -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Werror=undef -Wlogical-op -Wmissing-include-dirs -Wold-style-definition -Wpointer-arith -Winit-self -Wfloat -equal -Wsuggest-attribute=noreturn -Werror=missing-prototypes -Werror=implicit-function-declaration -Werror=missing-declarations -Werror=return-type -Werror=incompatible-pointer-types -Werror=format=2 -Wstrict-prototype s -Wredundant-decls -Wmissing-noreturn -Wimplicit-fallthrough=5 -Wshadow -Wendif-labels -Wstrict-aliasing=2 -Wwrite-strings -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-exte rns -Wno-error=nonnull -Wno-maybe-uninitialized -ffast-math -fno-common -fdiagnostics-show-option -fno-strict-aliasing -fvisibility=hidden -fstack-protector -fstack-protector-strong --param=ssp-buffer-size=4 -ffunction-s ections -fdata-sections -Werror=shadow -include config.h -g -O2 -fdebug-prefix-map=/<<PKGBUILDDIR>>=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIE -pthread -MD -MQ 'syst emd@exe/src_core_main.c.o' -MF 'systemd@exe/src_core_main.c.o.d' -o 'systemd@exe/src_core_main.c.o' -c ../src/core/main.c
cc -o systemd 'systemd@exe/src_core_main.c.o' -flto -Wl,--as-needed -Wl,--no-undefined -pie -Wl,-z,relro -Wl,-z,now -fstack-protector -Wl,--gc-sections -g -O2 -fdebug-prefix-map=/<<PKGBUILDDIR>>=. -fstack-pro tector-strong -Wformat -Werror=format-security -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,--start-group src/core/libcore.a src/core/libcore-shared.a src/shared/libsystemd-shared-245.so -pthread -lrt /usr/lib/x86_64-linux- gnu/libseccomp.so /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libselinux.so /usr/lib/x86_64-linux-gnu/libmount.so /usr/lib/x86_64-linux-gnu/libblkid.so -lpam /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64- linux-gnu/libaudit.so /usr/lib/x86_64-linux-gnu/libkmod.so /usr/lib/x86_64-linux-gnu/libapparmor.so -Wl,--end-group '-Wl,-rpath,$ORIGIN/src/core:$ORIGIN/src/shared' -Wl,-rpath-link,/<<PKGBUILDDIR>>/build-deb/src/core -Wl ,-rpath-link,/<<PKGBUILDDIR>>/build-deb/src/shared
整个编译系统,systemd选择使用的meson构建(meson构建系统的基本用法在其他博客文章中已介绍),通过编译日志发现,systemd由src/core/main.c源码编译。调用过程如下所示:
Read more...