cgroup----devices子系统

2023-11-13

devices子系统

    使用devices 子系统可以允许或者拒绝cgroup中的进程访问设备。devices子系统有三个控制文件:devices.allow,devices.deny,devices.list。devices.allow用于指定cgroup中的进程可以访问的设备,devices.deny用于指定cgroup中的进程不能访问的设备,devices.list用于报告cgroup中的进程访问的设备。devices.allow文件中包含若干条目,每个条目有四个字段:typemajorminor 和 accesstypemajor 和 minor 字段中使用的值对应 Linux 分配的设备。

type指定设备类型:

a - 应用所有设备,可以是字符设备,也可以是块设备

b- 指定块设备

c - 指定字符设备

majorminor指定设备的主次设备号。

access 则指定相应的权限:

r - 允许任务从指定设备中读取

w - 允许任务写入指定设备

m - 允许任务生成还不存在的设备文件

devices子系统是通过提供device whilelist 来实现的。与其他子系统一样,devices子系统也有一个内嵌了cgroup_subsystem_state的结构来管理资源。在devices子系统中,这个结构是:

struct dev_cgroup {

struct cgroup_subsys_state css;

struct list_head whitelist;

};

这个结构体除了通用的cgroup_subsystem_state之外,就只有一个链表指针,而这个链表指针指向了该cgroup中的进程可以访问的devices whilelist

下面我们来看一下devices子系统如何管理whilelist。在devices子系统中,定义了一个叫dev_whitelist_item的结构来管理可以访问的device,对应于devices.allow中的一个条目。这个结构体的定义如下:

struct dev_whitelist_item {

u32 major, minor;

short type;

short access;

struct list_head list;

struct rcu_head rcu;

};

majorminor用于指定设备的主次设备号,type用于指定设备类型,type取值可以是:#define DEV_BLOCK 1

#define DEV_CHAR  2

#define DEV_ALL   4 

对应于之前devices.allow文件中三种情况。

access用于相应的访问权限,access取值可以是:

#define ACC_MKNOD 1

#define ACC_READ  2

#define ACC_WRITE 4

也和之前devices.allow文件中的情况对应。

List字段用于将该结构体连到相应的dev_cgroupwhitelist指向的链表。

通过以上数据结构,devices子系统就能管理一个cgroup的进程可以访问的devices了。 光有数据结构还不行,还要有具体实现才行。devices子系统通过实现两个函数供内核调用来实现控制cgroup中的进程能够访问的devices。首先我们来第一个函数:

int devcgroup_inode_permission(struct inode *inode, int mask)

{

struct dev_cgroup *dev_cgroup;

struct dev_whitelist_item *wh;

 

dev_t device = inode->i_rdev;

if (!device)

return 0;

if (!S_ISBLK(inode->i_mode) && !S_ISCHR(inode->i_mode))

return 0;

 

rcu_read_lock();

 

dev_cgroup = task_devcgroup(current);

 

list_for_each_entry_rcu(wh, &dev_cgroup->whitelist, list) {

if (wh->type & DEV_ALL)

goto found;

if ((wh->type & DEV_BLOCK) && !S_ISBLK(inode->i_mode))

continue;

if ((wh->type & DEV_CHAR) && !S_ISCHR(inode->i_mode))

continue;

if (wh->major != ~0 && wh->major != imajor(inode))

continue;

if (wh->minor != ~0 && wh->minor != iminor(inode))

continue;

 

if ((mask & MAY_WRITE) && !(wh->access & ACC_WRITE))

continue;

if ((mask & MAY_READ) && !(wh->access & ACC_READ))

continue;

found:

rcu_read_unlock();

return 0;

}

 

rcu_read_unlock();

 

return -EPERM;

}

    我们来简单分析一下这个函数,首先如果该inode对应的不是devices,直接返回0,如果既不是块设备也不是字符设备,也返回0,因为devices只控制块设备和字符设备的访问,其他情况不管。接着获得当前进程的dev_cgroup,然后在dev_cgroup中whitelist指针的链表中查找,如果找到对应设备而且mask指定的权限和设备的权限一致就返回0,如果没有找到就返回错误。

    这个函数是针对inode节点存在的情况,通过对比权限来控制cgroup中的进程能够访问的devices。还有一个情况是inode不存在,在这种情况下,一个进程要访问一个设备就必须通过mknod建立相应的设备文件。为了达到对这种情况的控制,devices子系统导出了第二个函数:

int devcgroup_inode_mknod(int mode, dev_t dev)

{

struct dev_cgroup *dev_cgroup;

struct dev_whitelist_item *wh;

 

if (!S_ISBLK(mode) && !S_ISCHR(mode))

return 0;

 

rcu_read_lock();

 

dev_cgroup = task_devcgroup(current);

 

list_for_each_entry_rcu(wh, &dev_cgroup->whitelist, list) {

if (wh->type & DEV_ALL)

goto found;

if ((wh->type & DEV_BLOCK) && !S_ISBLK(mode))

continue;

if ((wh->type & DEV_CHAR) && !S_ISCHR(mode))

continue;

if (wh->major != ~0 && wh->major != MAJOR(dev))

continue;

if (wh->minor != ~0 && wh->minor != MINOR(dev))

continue;

 

if (!(wh->access & ACC_MKNOD))

continue;

found:

rcu_read_unlock();

return 0;

}

 

rcu_read_unlock();

 

return -EPERM;

}

这个函数的实现跟第一个函数类似,这里就不赘述了。

下面我们再来看一下devices子系统本身的一些东西。跟其他子系统一样,devices同样实现了一个cgroup_subsys

struct cgroup_subsys devices_subsys = {

.name = "devices",

.can_attach = devcgroup_can_attach,

.create = devcgroup_create,

.destroy = devcgroup_destroy,

.populate = devcgroup_populate,

.subsys_id = devices_subsys_id,

};

devices相应的三个控制文件:

static struct cftype dev_cgroup_files[] = {

{

.name = "allow",

.write_string  = devcgroup_access_write,

.private = DEVCG_ALLOW,

},

{

.name = "deny",

.write_string = devcgroup_access_write,

.private = DEVCG_DENY,

},

{

.name = "list",

.read_seq_string = devcgroup_seq_read,

.private = DEVCG_LIST,

},

};

其中allowdeny都是通过devcgroup_access_write实现的,只是通过private字段区分,因为二者的实现逻辑有相同的地方。devcgroup_access_write最终通过调用devcgroup_update_access来实现。在devcgroup_update_access根据写入的内容构造一个dev_whitelist_item ,然后根据文件类型做不同的处理:

switch (filetype) {

case DEVCG_ALLOW:

if (!parent_has_perm(devcgroup, &wh))

return -EPERM;

return dev_whitelist_add(devcgroup, &wh);

case DEVCG_DENY:

dev_whitelist_rm(devcgroup, &wh);

break;

default:

return -EINVAL;

}

allow的话,就将item加入whitelistdeny的话,就将itemwhitelist中删去。

作者曰:devices子系统的实现相对比较简单,通过在内核对设备访问的时候加入额外的检查来实现。而devices子系统本身只需要管理好可以访问的设备列表就行了。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cgroup----devices子系统 的相关文章

  • 如果等于特定值则替换列

    我希望替换 CSV 中的第四列 如果它等于 N A 我正在尝试将其更改为 1 我似乎无法让它发挥作用 awk F if 4 N A 4 1 test csv 您可以使用以下内容awk awk F 4 4 N A 1 4 1 OFS test
  • 如何将动态链接的应用程序转换为静态链接的应用程序?

    我有一个应用程序 例如 gedit 它是动态链接的 但我没有源代码 所以我不能按我喜欢的方式编译它 我想要做的是将其静态链接并将其移动到没有运行该应用程序所需的库的系统 那么是否可以做到以及如何做到呢 理论上是可能的 您基本上必须执行与动态
  • 为什么不使用 sshrc 中设置的 $PATH?

    我正在尝试在 OS X 服务器上通过 ssh 设置 svn 为了做到这一点 我读到我需要一个包装器来设置 umask 并 在我的例子中 设置存储库根 一种快速而肮脏的方法是重命名 usr bin svnserve并将包装器脚本放置在该位置
  • 很好的 C 库集合? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个很好的 ANSI C 库集合 用于处理向量 哈希映射 二进制树 字符串处理等 Try g
  • 将条目添加到 Linux 内核 .config 文件

    如何手动将 CONFIG XILINX FIXED DEVTREE ADDR y 行添加到 Linux 配置文件中 当我构建内核时它不断被覆盖 您可以通过以下方式构建make CONFIG XILINX FIXED DEVTREE ADDR
  • 从 alpine 容器执行“go get download”时,如何避免出现“x509:由未知机构签名的证书”?

    我正在尝试使用以下 Dockerfile 从头开始 构建 coredns FROM golang alpine SHELL bin sh ec RUN apk update apk add no cache git make ca cert
  • C++向量数组运算符计算成本高?

    我一直都知道 C 的丰富抽象会带来一定的计算开销 但我的印象是 一旦应用了正确的编译器优化 这种开销几乎可以忽略不计 我很好奇这种开销到底有多大 所以我编写了一个简单的测试来确定这一点 该测试是一个模板化函数 它接受一个容器变量 为容器中的
  • 如何在 Ubuntu 16.04 上设置 Docker + PhpStorm + xdebug

    我的问题是当我开始监听端口时 xdebug 不起作用 我认为 PhpStorm 无法与 xdebug 链接 我刚刚得到调试器面板变量不可用 看来 xdebug 没有正确设置 使用的软件及版本 Ubuntu 16 04 LTS Docker
  • 在詹金斯管道作业中将变量传递给bash脚本

    我有一个 Jenkins 管道作业 其中我使用名为 setup sh 的 bash 脚本配置我的环境 如下所示 bin bash export ARCH 1 echo architecture ARCH 在 Jenkins 管道脚本中 我使
  • 参数无效”设置键“net.core.somaxconn”

    我尝试设置Linux内核 编辑后 etc sysctl conf并执行sysctl p它显示错误 Invalid argument setting key net core somaxconn Linux 发行版 Ubuntu 12 04
  • SDL/C++ OpenGL 程序,如何阻止 SDL 捕获 SIGINT

    我在用SDL http www libsdl org 用于在 Linux 上运行的 OpenGL 应用程序 我的问题是 SDL 正在捕获 SIGINT 并忽略它 这是一个痛苦 因为我正在通过屏幕会话进行开发 并且我无法使用 CTRL C 终
  • top命令的CPU使用率计算

    我正在尝试使用 GNU coreutil top 的公式来计算 CPU 使用率的百分比 但 top 正在使用一些 half total 来计算百分比 即在百分比上添加 0 5 在top的utils c中 以下行 在 3 8 beta1 中
  • 使用 Python for Linux 模拟按键事件

    我正在编写一个脚本来自动运行特定模型 当模型失败时 它会等待用户输入 Enter 键 我可以检测到模型何时失败 但我无法使用 python 在 Linux 上 来模拟按键事件 Windows 有 SendKeys 库来执行此操作 但我想知道
  • UNIX 域 STREAM 和 DATAGRAM 套接字之间的区别?

    这个问题是NOTSTREAM 类型和 DATAGRAM 类型 INTERNET 套接字之间的区别 我知道 STREAM 套接字使用 TCP 数据报套接字使用 UDP 以及所有 TCP UDP 内容 按顺序到达的数据包 ACK NACK 等
  • 如何安装 Node 和 NPM 以便不必使用 sudo?

    我正在尝试在 Ubuntu 14 04 计算机上设置 Node js 和 NPM 但遇到了一些问题 在我的第一次尝试中 我不断得到EACCES尝试安装软件包时出错 有时甚至使用sudo 所以我彻底卸载了node和npm 现在我正在尝试找出如
  • 在Linux上如何找到当前目录的所有直接子目录?

    在Linux上如何找到当前目录的所有直接子目录 最简单的方法是通过编写来利用 shell 通配功能echo 如果你喜欢使用ls 例如要应用格式 排序选项 请使其ls d 解释 斜杠确保仅考虑目录 而不考虑文件 Option d 列出目录本身
  • 生成(非常)大的非重复整数序列而不进行预洗牌

    背景 我编写了一个简单的媒体客户端 服务器 我想生成一个不明显的时间值 随从客户端到服务器的每个命令一起发送 时间戳中将包含相当多的数据 纳秒分辨率 即使它不是真正准确 因为现代操作系统中计时器采样的限制 等 我想做的 在 Linux 上
  • 为什么运行 docker 容器后 mysql 数据所有权更改为 systemd-journal-remote

    我的mysql数据库存储在 home mysql代替 var lib mysql 该目录曾经属于mysql 但是 当我运行命令时docker compose up使用这个 yml 文件 version 3 services mariadb
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的

随机推荐

  • Shell常用命令与工具(一)

    本章内容如下 11 1 ls 功能 列出目录内容 常用选项 a 显示所有文件 包括隐藏的 l 长格式列出信息 i 显示文件inode号 t 按修改时间排序 r 按修改时间倒序排序 示例 按修改时间排序 ls t 按修改时间倒序排序 ls r
  • CCF 202209-2 何以包邮? (01背包动态规划练习)

    一 先温习一下01背包问题 有N件物品和一个容量为V的背包 第i件物品的体积是c i 价值是w i 求解将哪些物品装入背包可使价值总和最大 条件汇总 背包限制容量 Z 此时背包容量 C 物品 1 i n 代表编号 重量 wight 1 wi
  • 日期、时间选择控件 - datetimepicker

    http www bootcss com p bootstrap datetimepicker demo htm 页面上添加控件
  • Grafana loki部署及使用及问题处理方法(超详细)

    一 下载软件 因为我是本地测试 所以用的windows版本的包 loki服务window版本的安装包下载地址 下载地址 选择 promtail windows版本的安装包下载地址 下载地址 Grafana服务的下载地址 下载地址 二 配置文
  • 能将阿里云盘挂载为webdav的webdav-aliyundriver

    虽然从内测开始就申请了阿里云盘 但是一直也没怎么用 网上一直强调的是阿里云盘的速度 但是在老苏看来天翼云也不算差 相对来说阿里云盘作为新的云盘 在功能上和百度云盘 天翼云盘这些成熟产品比还是存在很多欠缺的 直到我发现了 webdav ali
  • 【页面编号】假设页面从1开始连续编号,一共1000页。计算所有页码中的十进制数字的总个数

    题目 假设页面从1开始连续编号 一共1000页 计算所有页码中的十进制数字的总个数 这题很简单 就是求0 9出现次数的总和 public class text3 0 9为十进制数字 本题要求为统计1 1000中出现的十进制数字总数 分析 对
  • vscode安装使用教程

    一 什么是vscode Visual Studio Code 简称 VS Code VSC 是一款免费开源的现代化轻量级代码编辑器 支持几乎所有主流的开发语言的语法高亮 智能代码补全 自定义热键 括号匹配 代码片段 代码对比 Diff GI
  • 2022多益网络春招之最后一场--软件工程师笔试

    题型 选择 填空 简答 算法 凭借自己的回忆说一下题目类型 选择题 涉及到的题型主要是Java基础的题目 例如分析代码的时间复杂度 一些排序算法的时间复杂度 二叉排序树 sql语句 很简单 散列表 链表 什么数据结构具有记忆功能 连接查询
  • C++基础学习-29类模板概念,类模板定义、使用

    目录 一 概述 二 类模板的定义 三 类模板的成员函数 四 模板类名字的使用 五 非类模板参数 一 概述 用类模板来实例化一个特定的类 编译器不能为类模板推断参数类型 所以为了使用类模板 我们必须在类模板名后边用 lt gt 来提供额外的信
  • module.alias的更新

    一般通过hotplug的设备会通过module alias 中的信息来加载device对应的driver linux 1wlr lib modules 4 4 68 2 default modinfo ipmi ssif filename
  • vue3+vite+element plus+el-table中如何放置本地图片

    遇到bug 解决方案 vue组件 js代码
  • LZ77算法压缩和解压缩

    LZ77简介 Ziv和Lempel于1977年发表题为 顺序数据压缩的一个通用算法 A Universal Algorithm for Sequential Data Compression 的论文 论文中描述的算法被后人称为LZ77算法
  • 计算机的性能指标完全由cpu决定是否正确,计算机的性能指标完全由CPU决定对吗...

    电脑性能由CPU 中央处理器 主板 显卡 网卡 声卡等共同决定 如果主板 显卡不行 CPU再好也不行 这5个中 CPU 主板 显卡在决定电脑性能中占的比重大一些 推荐学习 phpstorm 1 运算速度 计算机运算速度是指每秒钟所能执行的指
  • 记录Windows10中Docker安装Mysql5.7

    DockerHub 搜索Mysql找到官方镜像 官方镜像地址 拉取mysql5 7版本镜像 拉取 docker pull mysql 5 7 查看docker 镜像 就能看到拉取的镜像 docker images 运行一个mysql容器 创
  • 电脑开机check_码住!常见电脑蓝屏代码和解决方法

    电脑蓝屏是很多人都碰到过的突发情况 引起电脑蓝屏的原因有很多 在软件方面 可能是因为个别软件或者驱动导致的 也可能是电脑中了病毒或者操作系统损坏等原因 硬件方面 可能是因为电脑散热不良 内存损坏 内存条接触不良或者电脑超频过度 硬盘坏道等问
  • anaconda换源和恢复默认源

    1 查看当前环境下的源 conda config show sources 2 换清华源 conda config add channels https mirrors tuna tsinghua edu cn anaconda pkgs
  • Android插件化主流框架和实现原理

    写在前面 这几年移动开发业界兴起的 插件化技术 的旋风 各个大厂都推出了自己的插件化框架 各种开源框架都评价自身功能优越性 令人目不暇接 随着公司业务快速发展 项目增多 开发资源却有限 如何能在有限资源内满足需求和项目的增长 同时又能快速响
  • (CentOS 7) PostgreSQL安装与配置

    一 安装相关配置软件 root www1 yum install y gcc x86 64 glibc x86 64 glibc devel x86 64 vim enhanced x86 64 gcc java apr apr devel
  • parted扩展磁盘分区(实践篇)

    系统环境 操作系统 centos7 2 前言 突然发现根下的空间不足了 没有找到可以释放的磁盘空间 所以决定要扩展一下磁盘分区 直接上操作 环境分析 发现根下的磁盘空间已经不是很充足了 看图片 显示的sda2的空间只给了280G 已经快要占
  • cgroup----devices子系统

    devices子系统 使用devices 子系统可以允许或者拒绝cgroup中的进程访问设备 devices子系统有三个控制文件 devices allow devices deny devices list devices allow用于