Skip to content

Commit 751458a

Browse files
committed
test/libcriu: check setting of RPC config file
Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
1 parent bb33248 commit 751458a

File tree

4 files changed

+226
-0
lines changed

4 files changed

+226
-0
lines changed

test/others/libcriu/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ test_pre_dump
88
test_feature_check
99
output/
1010
libcriu.so.*
11+
test_rpc_config

test/others/libcriu/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ include ../../../../criu/Makefile.versions
33
TESTS += test_sub
44
TESTS += test_self
55
TESTS += test_notify
6+
TESTS += test_rpc_config
67
TESTS += test_iters
78
TESTS += test_errno
89
TESTS += test_join_ns

test/others/libcriu/run.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ run_test() {
5555
run_test test_sub
5656
run_test test_self
5757
run_test test_notify
58+
run_test test_rpc_config
5859
if [ "$(uname -m)" = "x86_64" ]; then
5960
# Skip this on aarch64 as aarch64 has no dirty page tracking
6061
run_test test_iters
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
#include "criu.h"
2+
#include "lib.h"
3+
4+
#include <fcntl.h>
5+
#include <stdio.h>
6+
#include <errno.h>
7+
#include <stdlib.h>
8+
#include <signal.h>
9+
#include <unistd.h>
10+
#include <sys/types.h>
11+
#include <sys/stat.h>
12+
#include <sys/wait.h>
13+
#include <string.h>
14+
#include <time.h>
15+
16+
#define RANDOM_NAME_LEN 6
17+
#define PATH_BUF_SIZE 128
18+
19+
static volatile sig_atomic_t stop = 0;
20+
static char base_name[RANDOM_NAME_LEN + 1];
21+
static char log_file[PATH_BUF_SIZE];
22+
static char conf_file[PATH_BUF_SIZE];
23+
24+
static void handle_signal(int sig)
25+
{
26+
(void)sig;
27+
stop = 1;
28+
}
29+
30+
static void generate_random_base_name(void)
31+
{
32+
const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
33+
size_t charset_len;
34+
int i;
35+
36+
charset_len = sizeof(charset) - 1;
37+
38+
for (i = 0; i < RANDOM_NAME_LEN; i++) {
39+
base_name[i] = charset[rand() % charset_len];
40+
}
41+
base_name[i] = '\0';
42+
43+
snprintf(log_file, sizeof(log_file), "/tmp/criu-%s.log", base_name);
44+
snprintf(conf_file, sizeof(conf_file), "/tmp/criu-%s.conf", base_name);
45+
}
46+
47+
static int create_criu_config_file(void)
48+
{
49+
int fd;
50+
FILE *fp;
51+
52+
srand(time(NULL));
53+
generate_random_base_name();
54+
55+
fd = open(conf_file, O_CREAT | O_EXCL | O_WRONLY, 0600);
56+
if (fd < 0) {
57+
perror("Failed to create config file");
58+
return -1;
59+
}
60+
61+
fp = fdopen(fd, "w");
62+
if (!fp) {
63+
perror("fdopen failed");
64+
close(fd);
65+
unlink(conf_file);
66+
return -1;
67+
}
68+
69+
fprintf(fp, "log-file=%s\n", log_file);
70+
fflush(fp);
71+
fclose(fp);
72+
73+
return 0;
74+
}
75+
76+
static int check_log_file(void)
77+
{
78+
struct stat st;
79+
80+
if (stat(log_file, &st) < 0) {
81+
perror("Config file does not exist");
82+
return -1;
83+
}
84+
85+
if (st.st_size == 0) {
86+
fprintf(stderr, "Config file is empty\n");
87+
return -1;
88+
}
89+
90+
unlink(log_file);
91+
return 0;
92+
}
93+
94+
int main(int argc, char **argv)
95+
{
96+
int pipe_fd[2];
97+
pid_t pid;
98+
int ret;
99+
int child_ret;
100+
101+
int img_fd = open(argv[2], O_DIRECTORY);
102+
if (img_fd < 0) {
103+
perror("Failed to open images directory");
104+
goto cleanup;
105+
}
106+
107+
if (create_criu_config_file() < 0) {
108+
printf("Failed to create config file\n");
109+
return EXIT_FAILURE;
110+
}
111+
112+
if (pipe(pipe_fd) < 0) {
113+
perror("pipe");
114+
return EXIT_FAILURE;
115+
}
116+
117+
pid = fork();
118+
if (pid < 0) {
119+
perror("fork failed");
120+
return EXIT_FAILURE;
121+
}
122+
123+
if (pid == 0) {
124+
/** child process **/
125+
printf(" `- loop: initializing\n");
126+
127+
if (setsid() < 0 || signal(SIGUSR1, handle_signal) == SIG_ERR) {
128+
_exit(EXIT_FAILURE);
129+
}
130+
131+
close(STDIN_FILENO);
132+
close(STDOUT_FILENO);
133+
close(STDERR_FILENO);
134+
close(pipe_fd[0]);
135+
136+
child_ret = SUCC_ECODE;
137+
write(pipe_fd[1], &child_ret, sizeof(child_ret));
138+
close(pipe_fd[1]);
139+
140+
while (!stop) {
141+
sleep(1);
142+
}
143+
144+
_exit(SUCC_ECODE);
145+
}
146+
147+
/** parent process **/
148+
close(pipe_fd[1]);
149+
150+
ret = -1;
151+
if (read(pipe_fd[0], &ret, sizeof(ret)) != sizeof(ret) || ret != SUCC_ECODE) {
152+
printf("Error starting loop\n");
153+
goto cleanup;
154+
}
155+
156+
read(pipe_fd[0], &ret, 1);
157+
close(pipe_fd[0]);
158+
159+
printf("--- Loop process started (pid: %d) ---\n", pid);
160+
161+
printf("--- Checkpoint ---\n");
162+
criu_init_opts();
163+
criu_set_service_binary(argv[1]);
164+
criu_set_images_dir_fd(img_fd);
165+
criu_set_pid(pid);
166+
criu_set_log_level(CRIU_LOG_DEBUG);
167+
168+
/* The RPC config file should overwrite the log-file set below */
169+
printf("Setting dump RPC config file: %s\n", conf_file);
170+
criu_set_config_file(conf_file);
171+
criu_set_log_file("dump.log");
172+
173+
ret = criu_dump();
174+
if (ret < 0) {
175+
what_err_ret_mean(ret);
176+
kill(pid, SIGKILL);
177+
printf("criu dump failed\n");
178+
goto cleanup;
179+
}
180+
181+
printf(" `- Dump succeeded\n");
182+
waitpid(pid, NULL, 0);
183+
184+
if (check_log_file()) {
185+
printf("Error: log file not overwritten by RPC config file\n");
186+
goto cleanup;
187+
}
188+
189+
printf("--- Restore loop ---\n");
190+
criu_init_opts();
191+
criu_set_images_dir_fd(img_fd);
192+
criu_set_log_level(CRIU_LOG_DEBUG);
193+
194+
/* The RPC config file should overwrite the log-file set below */
195+
printf("Setting restore RPC config file: %s\n", conf_file);
196+
criu_set_config_file(conf_file);
197+
criu_set_log_file("restore.log");
198+
199+
pid = criu_restore_child();
200+
if (pid <= 0) {
201+
what_err_ret_mean(pid);
202+
ret = EXIT_FAILURE;
203+
goto cleanup;
204+
}
205+
206+
printf(" `- Restore returned pid %d\n", pid);
207+
kill(pid, SIGUSR1);
208+
209+
if (check_log_file()) {
210+
printf("Error: log file not overwritten by RPC config file\n");
211+
goto cleanup;
212+
}
213+
214+
cleanup:
215+
if (waitpid(pid, &ret, 0) < 0) {
216+
perror("waitpid failed");
217+
return EXIT_FAILURE;
218+
}
219+
220+
printf("Remove RPC config file: %s\n", conf_file);
221+
unlink(conf_file);
222+
return chk_exit(ret, SUCC_ECODE);
223+
}

0 commit comments

Comments
 (0)