#include "tst_test.h" #include "lapi/sched.h" static void child_func(void) { TST_EXP_EQ_LI(getsid(0), 0); TST_EXP_EQ_LI(getpgid(0), 0); tst_res(TINFO, "setsid()"); SAFE_SETSID(); TST_EXP_EQ_LI(getsid(0), 1); TST_EXP_EQ_LI(getpgid(0), 1); } static void run(void) { const struct tst_clone_args args = { CLONE_NEWPID, SIGCHLD }; if (!SAFE_CLONE(&args)) { child_func(); return; } } static struct tst_test test = { .test_all = run, .needs_root = 1, .forks_child = 1, .needs_kconfigs = (const char *[]) { "CONFIG_PID_NS", NULL, }, };
时间: 2024-04-18 09:32:24 浏览: 126
这段代码是一个测试用例,用于测试进程命名空间(pidns)。它包含了一些头文件和相关的函数调用。
在`child_func`函数中,首先使用`tst_exp_eq_li`函数来验证`getsid`和`getpgid`函数的返回值是否符合预期。然后调用`tst_res`函数打印一条信息,然后使用`safe_setsid`函数设置新会话ID。再次调用`getsid`和`getpgid`函数来验证设置后的值。
在`run`函数中,首先定义了一个`tst_clone_args`结构体,指定了需要创建新的进程命名空间(CLONE_NEWPID)和信号处理(SIGCHLD)。然后使用`safe_clone`函数来创建子进程,在子进程中调用`child_func`函数。
最后定义了一个`tst_test`结构体,指定了测试运行的函数为`run`,需要以root权限运行,需要在内核配置中启用进程命名空间(CONFIG_PID_NS)。
这段代码的目的是测试在进程命名空间中使用`setsid`函数的功能。
相关问题
请解释这段代码:#include "uart_test.h" #include "rbfd_uart_impls.h" #include "cmsis_os.h" #include "logger.h" #include "stm32f4xx_hal.h" #include "ff.h" extern UART_HandleTypeDef huart1; #define URT1 (&RBFD_UART_GET_UART(urt1)) #define URT_TST_BUF_LEN 8192U #define U_MB(x) (x*1024u*1024u) #define TEST_DATA_LEN U_MB(768) #define TEST_LOOPS (TEST_DATA_LEN / URT_TST_BUF_LEN)
这段代码包含了一些头文件的引用,并定义了一些宏和变量。下面是代码的解释:
1. `#include` 是一个预处理指令,用于包含其他头文件。这段代码中包含了 `uart_test.h`、`rbfd_uart_impls.h`、`cmsis_os.h`、`logger.h`、`stm32f4xx_hal.h` 和 `ff.h` 这些头文件。
2. `extern UART_HandleTypeDef huart1` 是一个外部变量的声明,表示 `huart1` 是一个 UART_HandleTypeDef 类型的变量,这个变量在其他地方定义。
3. `#define` 是一个预处理指令,用于定义宏。这段代码中定义了以下几个宏:
- `URT1` 定义为 `&RBFD_UART_GET_UART(urt1)`,表示一个指向 `urt1` UART 的指针。
- `URT_TST_BUF_LEN` 定义为 `8192U`,表示一个缓冲区的长度。
- `U_MB(x)` 是一个宏函数,用于将以兆字节为单位的值转换为字节。在这里,它将 `x` 乘以 1024*1024 来得到字节的值。
- `TEST_DATA_LEN` 定义为 `U_MB(768)`,表示测试数据的长度为 768 兆字节。
- `TEST_LOOPS` 定义为 `(TEST_DATA_LEN / URT_TST_BUF_LEN)`,表示测试循环的次数,即测试数据长度除以缓冲区长度的结果。
这段代码主要是为了引用头文件,并定义了一些宏和变量,用于后续的代码使用。
#include "tst_test.h" #include "lapi/sched.h" #include "tst_safe_posix_ipc.h" #define MQNAME "/MQ1" static mqd_t mqd; static char *str_op; static void run(void) { const struct tst_clone_args clone_args = { CLONE_NEWIPC, SIGCHLD }; tst_res(TINFO, "Checking namespaces isolation from parent to child"); if (str_op && !strcmp(str_op, "clone")) { tst_res(TINFO, "Spawning isolated process"); if (!SAFE_CLONE(&clone_args)) { TST_EXP_FAIL(mq_open(MQNAME, O_RDONLY), ENOENT); return; } } else if (str_op && !strcmp(str_op, "unshare")) { tst_res(TINFO, "Spawning unshared process"); if (!SAFE_FORK()) { SAFE_UNSHARE(CLONE_NEWIPC); TST_EXP_FAIL(mq_open(MQNAME, O_RDONLY), ENOENT); return; } } else { tst_res(TINFO, "Spawning plain process"); if (!SAFE_FORK()) { TST_EXP_POSITIVE(mq_open(MQNAME, O_RDONLY)); return; } } } static void setup(void) { mqd = SAFE_MQ_OPEN(MQNAME, O_RDWR | O_CREAT | O_EXCL, 0777, NULL); } static void cleanup(void) { if (mqd != -1) { SAFE_MQ_CLOSE(mqd); SAFE_MQ_UNLINK(MQNAME); } } static struct tst_test test = { .test_all = run, .setup = setup, .cleanup = cleanup, .needs_root = 1, .forks_child = 1, .options = (struct tst_option[]) { { "m:", &str_op, "Child process isolation <clone|unshare>" }, {}, }, .needs_kconfigs = (const char *[]) { "CONFIG_USER_NS", NULL }, };
这段代码是一个测试用例,用于测试IPC命名空间的隔离性。它包含了一些头文件和相关的函数调用。
在`run`函数中,首先定义了一个`tst_clone_args`结构体,指定了需要创建新的IPC命名空间(CLONE_NEWIPC)和信号处理(SIGCHLD)。然后使用`tst_res`函数打印一条信息,说明正在检查命名空间从父进程到子进程的隔离性。
根据`str_op`的值来判断需要执行的操作。如果`str_op`不为空且等于"clone",则说明需要创建一个隔离的子进程。在子进程中使用`safe_clone`函数创建新的进程,并在新进程中调用`mq_open`函数来打开消息队列。如果打开成功,则测试失败,因为应该无法访问父进程中创建的消息队列。如果`str_op`不为空且等于"unshare",则说明需要创建一个独立的进程。在新进程中使用`safe_fork`函数创建新的进程,并使用`safe_unshare`函数来创建新的IPC命名空间。然后在新进程中调用`mq_open`函数来打开消息队列,如果打开成功,则测试失败。如果`str_op`为空或其他值,则说明需要创建一个普通的进程。在新进程中使用`safe_fork`函数创建新的进程,并调用`mq_open`函数来打开消息队列,如果打开成功,则测试通过。
在`setup`函数中,使用`safe_mq_open`函数创建一个新的消息队列。
在`cleanup`函数中,如果消息队列存在,则使用`safe_mq_close`函数关闭消息队列,并使用`safe_mq_unlink`函数删除消息队列。
最后定义了一个`tst_test`结构体,指定了测试运行的函数为`run`,初始化函数为`setup`,清理函数为`cleanup`,需要以root权限运行,需要在内核配置中启用用户命名空间(CONFIG_USER_NS),并提供了一个选项供用户选择操作类型("clone"或"unshare")。
这段代码的目的是测试IPC命名空间的隔离性,验证不同命名空间中的进程是否可以访问同一消息队列。
阅读全文