Skip to content

Commit 350d9dc

Browse files
committed
feat: add zdtm test for posix sem c/r
fix: unused vma image definition chore: bool opt for posix-sem-migration feature Signed-off-by: Brandon Smith <[email protected]>
1 parent 2f2046e commit 350d9dc

File tree

6 files changed

+181
-8
lines changed

6 files changed

+181
-8
lines changed

criu/config.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd,
703703
BOOL_OPT("mntns-compat-mode", &opts.mntns_compat_mode),
704704
BOOL_OPT("unprivileged", &opts.unprivileged),
705705
BOOL_OPT("ghost-fiemap", &opts.ghost_fiemap),
706-
{ "posix-sem-migration", no_argument, 0, 1101 },
706+
BOOL_OPT("posix-sem-migration", &opts.posix_sem_migration),
707707
{},
708708
};
709709

criu/include/cr_options.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ struct cr_options {
246246
* explicitly request it as it comes with many limitations.
247247
*/
248248
int unprivileged;
249-
bool posix_sem_migration;
249+
int posix_sem_migration;
250250
};
251251

252252
extern struct cr_options opts;

criu/include/image.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,10 @@
9393
#define VMA_AREA_SHSTK (1 << 15)
9494

9595
#define VMA_EXT_PLUGIN (1 << 27)
96-
#define VMA_FORCE_READ (1 << 28)
97-
#define VMA_CLOSE (1 << 29)
98-
#define VMA_NO_PROT_WRITE (1 << 30)
99-
#define VMA_PREMMAPED (1U << 31)
100-
#define VMA_UNSUPP (1ULL << 32)
96+
#define VMA_CLOSE (1 << 28)
97+
#define VMA_NO_PROT_WRITE (1 << 29)
98+
#define VMA_PREMMAPED (1U << 30)
99+
#define VMA_UNSUPP (1ULL << 31)
101100

102101
#define CR_CAP_SIZE 2
103102

test/zdtm/static/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ TST_NOFILE := \
146146
ipc_namespace \
147147
selfexe00 \
148148
sem \
149+
posix_sem \
149150
maps01 \
150151
maps02 \
151152
maps04 \
@@ -189,7 +190,7 @@ TST_NOFILE := \
189190
unhashed_proc \
190191
cow00 \
191192
child_opened_proc \
192-
posix_timers \
193+
posix_timers \
193194
sigpending \
194195
sigaltstack \
195196
sk-netlink \
@@ -614,6 +615,7 @@ shm: CFLAGS += -DNEW_IPC_NS
614615
msgque: CFLAGS += -DNEW_IPC_NS
615616
sem: CFLAGS += -DNEW_IPC_NS
616617
posix_timers: LDLIBS += -lrt -pthread
618+
posix_sem: LDLIBS += -pthread
617619
remap_dead_pid_root: CFLAGS += -DREMAP_PID_ROOT
618620
sock_filter01: CFLAGS += -DSOCK_FILTER01
619621
socket-tcp6: CFLAGS += -D ZDTM_IPV6

test/zdtm/static/posix_sem.c

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <unistd.h>
4+
#include <fcntl.h>
5+
#include <semaphore.h>
6+
#include <errno.h>
7+
#include <string.h>
8+
#include <sys/wait.h>
9+
#include <time.h>
10+
#include <sys/stat.h>
11+
12+
#include "zdtmtst.h"
13+
14+
const char *test_doc = "Test POSIX semaphore migration with --posix-sem-migration";
15+
const char *test_author = "CRIU community";
16+
17+
static sem_t *test_sem;
18+
static char sem_name[64];
19+
static int initial_value = 3;
20+
21+
static int setup_posix_semaphore(void)
22+
{
23+
struct stat st;
24+
25+
/* Host mode is needed for /dev/shm access */
26+
if (stat("/dev/shm", &st) < 0) {
27+
pr_perror("stat /dev/shm");
28+
test_msg("ERROR: /dev/shm is not accessible\n");
29+
return -1;
30+
}
31+
32+
if (!S_ISDIR(st.st_mode)) {
33+
test_msg("ERROR: /dev/shm is not a directory\n");
34+
return -1;
35+
}
36+
37+
test_msg("/dev/shm is accessible (mode: %o)\n", st.st_mode);
38+
39+
snprintf(sem_name, sizeof(sem_name), "/test_posix_sem_%d", getpid());
40+
41+
test_msg("Attempting to create semaphore: %s\n", sem_name);
42+
43+
/* Create the semaphore with initial value */
44+
test_sem = sem_open(sem_name, O_CREAT | O_EXCL, 0644, initial_value);
45+
if (test_sem == SEM_FAILED) {
46+
if (errno == EEXIST) {
47+
test_msg("Semaphore already exists, trying to open existing one\n");
48+
test_sem = sem_open(sem_name, 0);
49+
if (test_sem == SEM_FAILED) {
50+
pr_perror("sem_open (existing semaphore)");
51+
return -1;
52+
}
53+
} else {
54+
pr_perror("sem_open (create)");
55+
test_msg("Failed to create semaphore %s (errno=%d: %s)\n",
56+
sem_name, errno, strerror(errno));
57+
return -1;
58+
}
59+
}
60+
61+
test_msg("Created POSIX semaphore %s with initial value %d\n", sem_name, initial_value);
62+
return 0;
63+
}
64+
65+
/* lol this is fun it works ig */
66+
static int test_semaphore_operations(void)
67+
{
68+
int sem_value;
69+
70+
if (sem_getvalue(test_sem, &sem_value) < 0) {
71+
pr_perror("sem_getvalue");
72+
return -1;
73+
}
74+
75+
test_msg("Semaphore value before operations: %d\n", sem_value);
76+
77+
if (sem_wait(test_sem) < 0) {
78+
pr_perror("sem_wait");
79+
return -1;
80+
}
81+
82+
if (sem_getvalue(test_sem, &sem_value) < 0) {
83+
pr_perror("sem_getvalue after wait");
84+
return -1;
85+
}
86+
87+
test_msg("Semaphore value after wait: %d\n", sem_value);
88+
89+
if (sem_post(test_sem) < 0) {
90+
pr_perror("sem_post");
91+
return -1;
92+
}
93+
94+
if (sem_getvalue(test_sem, &sem_value) < 0) {
95+
pr_perror("sem_getvalue after post");
96+
return -1;
97+
}
98+
99+
test_msg("Semaphore value after post: %d\n", sem_value);
100+
101+
return 0;
102+
}
103+
104+
static int verify_semaphore_state(int expected_value)
105+
{
106+
int sem_value;
107+
108+
if (sem_getvalue(test_sem, &sem_value) < 0) {
109+
pr_perror("sem_getvalue in verify");
110+
return -1;
111+
}
112+
113+
if (sem_value != expected_value) {
114+
fail("Semaphore value mismatch: expected %d, got %d", expected_value, sem_value);
115+
return -1;
116+
}
117+
118+
test_msg("Semaphore value verified: %d\n", sem_value);
119+
return 0;
120+
}
121+
122+
static void cleanup_semaphore(void)
123+
{
124+
if (test_sem != SEM_FAILED) {
125+
sem_close(test_sem);
126+
sem_unlink(sem_name);
127+
test_msg("Cleaned up semaphore %s\n", sem_name);
128+
}
129+
}
130+
131+
int main(int argc, char **argv)
132+
{
133+
int expected_final_value;
134+
135+
test_init(argc, argv);
136+
137+
/* Setup POSIX semaphore */
138+
if (setup_posix_semaphore() < 0) {
139+
return 1;
140+
}
141+
142+
/* Perform some operations to change semaphore state */
143+
if (test_semaphore_operations() < 0) {
144+
cleanup_semaphore();
145+
return 1;
146+
}
147+
148+
/* Record expected value which should be same as initial after wait+post */
149+
expected_final_value = initial_value;
150+
151+
/* Enter daemon mode */
152+
test_daemon();
153+
/* Checkpoint and restore */
154+
test_waitsig();
155+
156+
/* Verify semaphore state after restore */
157+
if (verify_semaphore_state(expected_final_value) < 0) {
158+
cleanup_semaphore();
159+
return 1;
160+
}
161+
162+
if (test_semaphore_operations() < 0) {
163+
cleanup_semaphore();
164+
return 1;
165+
}
166+
167+
cleanup_semaphore();
168+
169+
pass();
170+
return 0;
171+
}

test/zdtm/static/posix_sem.desc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{'flavor': 'h', 'opts': '--posix-sem-migration'}

0 commit comments

Comments
 (0)