wip: cloning fs namespace
This commit is contained in:
parent
4277d58f26
commit
3498e9b26a
@ -8,20 +8,31 @@ CFLAGS = -std=c17
|
|||||||
|
|
||||||
INC_DIRS=-I$(UNITY_ROOT)/src
|
INC_DIRS=-I$(UNITY_ROOT)/src
|
||||||
|
|
||||||
SRC_NAMESPACES_FS_1=$(UNITY_ROOT)/src/unity.c namespaces/fs/TestUnshare.c test_runners/namespaces_fs_TestUnshare_Runner.c
|
SRC_NAMESPACES_FS_UNSHARE=$(UNITY_ROOT)/src/unity.c namespaces/fs/TestUnshare.c test_runners/namespaces_fs_TestUnshare_Runner.c
|
||||||
TARGET_NAMESPACES_FS_1=target/test_namespaces_fs
|
SRC_NAMESPACES_FS_CLONE=$(UNITY_ROOT)/src/unity.c namespaces/fs/TestClone.c test_runners/namespaces_fs_TestClone_Runner.c
|
||||||
|
|
||||||
|
TARGET_NAMESPACES_FS_UNSHARE=target/test_namespaces_fs_unshare
|
||||||
|
TARGET_NAMESPACES_FS_CLONE=target/test_namespaces_fs_clone
|
||||||
|
|
||||||
all: clean default
|
all: clean default
|
||||||
|
|
||||||
default: $(TARGET_NAMESPACES_FS_1)
|
default: $(SRC_NAMESPACES_FS_UNSHARE) $(SRC_NAMESPACES_FS_CLONE)
|
||||||
- ./$(TARGET_NAMESPACES_FS_1)
|
$(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(SYMBOLS) $(SRC_NAMESPACES_FS_UNSHARE) -o $(TARGET_NAMESPACES_FS_UNSHARE)
|
||||||
|
$(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(SYMBOLS) $(SRC_NAMESPACES_FS_CLONE) -o $(TARGET_NAMESPACES_FS_CLONE)
|
||||||
|
|
||||||
$(TARGET_NAMESPACES_FS_1): $(SRC_NAMESPACES_FS_1)
|
@echo
|
||||||
$(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(SYMBOLS) $(SRC_NAMESPACES_FS_1) -o $(TARGET_NAMESPACES_FS_1)
|
@echo Finished preparing tests, running now.
|
||||||
|
@echo
|
||||||
|
|
||||||
|
- ./$(TARGET_NAMESPACES_FS_UNSHARE)
|
||||||
|
- ./$(TARGET_NAMESPACES_FS_CLONE)
|
||||||
|
|
||||||
test_runners/namespaces_fs_TestUnshare_Runner.c: namespaces/fs/TestUnshare.c
|
test_runners/namespaces_fs_TestUnshare_Runner.c: namespaces/fs/TestUnshare.c
|
||||||
ruby $(UNITY_ROOT)/auto/generate_test_runner.rb namespaces/fs/TestUnshare.c test_runners/namespaces_fs_TestUnshare_Runner.c
|
ruby $(UNITY_ROOT)/auto/generate_test_runner.rb namespaces/fs/TestUnshare.c test_runners/namespaces_fs_TestUnshare_Runner.c
|
||||||
|
|
||||||
|
test_runners/namespaces_fs_TestClone_Runner.c: namespaces/fs/TestClone.c
|
||||||
|
ruby $(UNITY_ROOT)/auto/generate_test_runner.rb namespaces/fs/TestClone.c test_runners/namespaces_fs_TestClone_Runner.c
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(CLEANUP) $(TARGET_NAMESPACES_FS_1)
|
$(CLEANUP) $(TARGET_NAMESPACES_FS_UNSHARE) $(TARGET_NAMESPACES_FS_CLONE)
|
||||||
mkdir -p test_runners/ target/
|
mkdir -p test_runners/ target/
|
||||||
|
100
assertions/namespaces/fs/TestClone.c
Normal file
100
assertions/namespaces/fs/TestClone.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include "unity.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <linux/wait.h>
|
||||||
|
|
||||||
|
#define CHILD_STACK_SIZE (8 * 1024 * 1024)
|
||||||
|
|
||||||
|
#define FILE_DEFAULT_NS ("/tmp/file_exists_0148c163-5919-4651")
|
||||||
|
#define FILE_NEW_NS ("/tmp/file_exists_fd0fd491-9816-442d")
|
||||||
|
|
||||||
|
void createFile(const char *fname) {
|
||||||
|
int fd = open(fname, O_RDONLY | O_CREAT, 0644);
|
||||||
|
TEST_ASSERT_GREATER_THAN_MESSAGE(0, fd, "open failed");
|
||||||
|
TEST_ASSERT_EQUAL_MESSAGE(0, close(fd), "close failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteFileIfExists(const char *fname) {
|
||||||
|
if (access(fname, F_OK) == 0) {
|
||||||
|
TEST_ASSERT_EQUAL_MESSAGE(0, unlink(fname), "unlink failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUp(void) { createFile(FILE_DEFAULT_NS); }
|
||||||
|
|
||||||
|
void tearDown(void) { deleteFileIfExists(FILE_DEFAULT_NS); }
|
||||||
|
|
||||||
|
long clone3(struct clone_args *cl_args) {
|
||||||
|
return syscall(SYS_clone3, cl_args, sizeof(struct clone_args));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_cloneFs_findsFileWhenFsCloned_succeeds(void) {
|
||||||
|
// PREPARE
|
||||||
|
|
||||||
|
// ACT
|
||||||
|
pid_t forkedChildPid;
|
||||||
|
|
||||||
|
if ((forkedChildPid = fork()) == 0) {
|
||||||
|
// child process - act but do not assert
|
||||||
|
// all assertions will be on the return code
|
||||||
|
int clonedChildPidFd;
|
||||||
|
|
||||||
|
struct clone_args cl_args = {
|
||||||
|
.flags = CLONE_PIDFD | CLONE_FS,
|
||||||
|
.pidfd = (uint64_t)(&clonedChildPidFd),
|
||||||
|
.child_tid = 0,
|
||||||
|
.parent_tid = 0,
|
||||||
|
.exit_signal = 0,
|
||||||
|
.stack = 0,
|
||||||
|
.stack_size = 0,
|
||||||
|
.tls = 0,
|
||||||
|
.set_tid = 0,
|
||||||
|
.set_tid_size = 0,
|
||||||
|
.cgroup = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
long cloneResult = clone3(&cl_args);
|
||||||
|
if (cloneResult == 0) {
|
||||||
|
printf("child\n");
|
||||||
|
sleep(30);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
} else if (cloneResult == -1) {
|
||||||
|
exit(1); // clone failed
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(30);
|
||||||
|
siginfo_t status;
|
||||||
|
printf("clonedChildPidFd: %d\n", clonedChildPidFd);
|
||||||
|
if (waitid(P_PIDFD, clonedChildPidFd, &status, WEXITED) == -1) {
|
||||||
|
perror("waitid");
|
||||||
|
exit(2); // wait failed
|
||||||
|
}
|
||||||
|
|
||||||
|
// MUST exit this process and not return
|
||||||
|
// else the test runner will be duplicated
|
||||||
|
|
||||||
|
exit(status.si_status); // propogate return status
|
||||||
|
}
|
||||||
|
|
||||||
|
// ASSERT
|
||||||
|
TEST_ASSERT_GREATER_THAN_MESSAGE(0, forkedChildPid, "fork failed");
|
||||||
|
|
||||||
|
int status = 0;
|
||||||
|
TEST_ASSERT_EQUAL_MESSAGE(forkedChildPid, waitpid(forkedChildPid, &status, 0),
|
||||||
|
"wait failed");
|
||||||
|
TEST_ASSERT_EQUAL_MESSAGE(0, WEXITSTATUS(status), "return status non-zero");
|
||||||
|
}
|
Reference in New Issue
Block a user