diff options
author | Guocai He <guocai.he.cn@windriver.com> | 2025-03-25 16:40:39 +0800 |
---|---|---|
committer | Bruce Ashfield <bruce.ashfield@gmail.com> | 2025-04-02 02:20:46 +0000 |
commit | bc324b3fe89d1b1bf6e58b0e37ff81049f7e7c98 (patch) | |
tree | 83990bec37b8e5a395dff3e95bcacef76b405b27 | |
parent | 0c191912421adff2f753e470056a9a525fbce760 (diff) | |
download | meta-virtualization-bc324b3fe89d1b1bf6e58b0e37ff81049f7e7c98.tar.gz |
criu: Adjust to glibc __rseq_size semantic change
On criu version 3.19.0:
When use "criu restore -d -D checkpoint" to restore, the error is:
1272: Error (criu/cr-restore.c:1498): 1295 killed by signal 11: Segmentation fault
The root casue is that the glibc updated and criu should adjust to glibc __rseq_size semantic change.
Signed-off-by: Guocai He <guocai.he.cn@windriver.com>
Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
-rw-r--r-- | recipes-containers/criu/criu_git.bb | 3 | ||||
-rw-r--r-- | recipes-containers/criu/files/0006-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch | 94 |
2 files changed, 96 insertions, 1 deletions
diff --git a/recipes-containers/criu/criu_git.bb b/recipes-containers/criu/criu_git.bb index 09503624..cccd3e3c 100644 --- a/recipes-containers/criu/criu_git.bb +++ b/recipes-containers/criu/criu_git.bb | |||
@@ -21,7 +21,8 @@ SRC_URI = "git://github.com/checkpoint-restore/criu.git;branch=master;protocol=h | |||
21 | file://0002-criu-Change-libraries-install-directory.patch \ | 21 | file://0002-criu-Change-libraries-install-directory.patch \ |
22 | file://0003-crit-pycriu-build-and-install-wheels.patch \ | 22 | file://0003-crit-pycriu-build-and-install-wheels.patch \ |
23 | file://0004-pycriu-attr-pycriu.version.__version__.patch \ | 23 | file://0004-pycriu-attr-pycriu.version.__version__.patch \ |
24 | file://0005-pycriu-skip-dependency-check-during-build.patch \ | 24 | file://0005-pycriu-skip-dependency-check-during-build.patch \ |
25 | file://0006-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch \ | ||
25 | " | 26 | " |
26 | 27 | ||
27 | COMPATIBLE_HOST = "(x86_64|arm|aarch64).*-linux" | 28 | COMPATIBLE_HOST = "(x86_64|arm|aarch64).*-linux" |
diff --git a/recipes-containers/criu/files/0006-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch b/recipes-containers/criu/files/0006-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch new file mode 100644 index 00000000..29715614 --- /dev/null +++ b/recipes-containers/criu/files/0006-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch | |||
@@ -0,0 +1,94 @@ | |||
1 | From 123e558a4bfa8964f9e55d0c0ecc080e6c3a38f3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Florian Weimer <fweimer@redhat.com> | ||
3 | Date: Wed, 10 Jul 2024 18:34:50 +0200 | ||
4 | Subject: [PATCH] criu: Adjust to glibc __rseq_size semantic change | ||
5 | |||
6 | In commit 2e456ccf0c34a056e3ccafac4a0c7effef14d918 ("Linux: Make | ||
7 | __rseq_size useful for feature detection (bug 31965)") glibc 2.40 | ||
8 | changed the meaning of __rseq_size slightly: it is now the size | ||
9 | of the active/feature area (20 bytes initially), and not the size | ||
10 | of the entire initially defined struct (32 bytes including padding). | ||
11 | The reason for the change is that the size including padding does not | ||
12 | allow detection of newly added features while previously unused | ||
13 | padding is consumed. | ||
14 | |||
15 | The prep_libc_rseq_info change in criu/cr-restore.c is not necessary | ||
16 | on kernels which have full ptrace support for obtaining rseq | ||
17 | information because the code is not used. On older kernels, it is | ||
18 | a correctness fix because with size 20 (the new value), rseq | ||
19 | registeration would fail. | ||
20 | |||
21 | The two other changes are required to make rseq unregistration work | ||
22 | in tests. | ||
23 | |||
24 | Upstream-Status: Backport [https://github.com/checkpoint-restore/criu/commit/ | ||
25 | 089345f77a34d1bc7ef146d650636afcd3cdda21] | ||
26 | |||
27 | Signed-off-by: Florian Weimer <fweimer@redhat.com> | ||
28 | Signed-off-by: Guocai He <guocai.he.cn@windriver.com> | ||
29 | --- | ||
30 | criu/cr-restore.c | 8 ++++++++ | ||
31 | test/zdtm/static/rseq00.c | 5 ++++- | ||
32 | test/zdtm/transition/rseq01.c | 5 ++++- | ||
33 | 3 files changed, 16 insertions(+), 2 deletions(-) | ||
34 | |||
35 | diff --git a/criu/cr-restore.c b/criu/cr-restore.c | ||
36 | index 270049721..80eb13743 100644 | ||
37 | --- a/criu/cr-restore.c | ||
38 | +++ b/criu/cr-restore.c | ||
39 | @@ -3103,7 +3103,15 @@ static void prep_libc_rseq_info(struct rst_rseq_param *rseq) | ||
40 | if (!kdat.has_ptrace_get_rseq_conf) { | ||
41 | #if defined(__GLIBC__) && defined(RSEQ_SIG) | ||
42 | rseq->rseq_abi_pointer = encode_pointer(__criu_thread_pointer() + __rseq_offset); | ||
43 | + /* | ||
44 | + * Current glibc reports the feature/active size in | ||
45 | + * __rseq_size, not the size passed to the kernel. | ||
46 | + * This could be 20, but older kernels expect 32 for | ||
47 | + * the size argument even if only 20 bytes are used. | ||
48 | + */ | ||
49 | rseq->rseq_abi_size = __rseq_size; | ||
50 | + if (rseq->rseq_abi_size < 32) | ||
51 | + rseq->rseq_abi_size = 32; | ||
52 | rseq->signature = RSEQ_SIG; | ||
53 | #else | ||
54 | rseq->rseq_abi_pointer = 0; | ||
55 | diff --git a/test/zdtm/static/rseq00.c b/test/zdtm/static/rseq00.c | ||
56 | index 471ad6a43..7add7801e 100644 | ||
57 | --- a/test/zdtm/static/rseq00.c | ||
58 | +++ b/test/zdtm/static/rseq00.c | ||
59 | @@ -46,12 +46,15 @@ static inline void *__criu_thread_pointer(void) | ||
60 | static inline void unregister_glibc_rseq(void) | ||
61 | { | ||
62 | struct rseq *rseq = (struct rseq *)((char *)__criu_thread_pointer() + __rseq_offset); | ||
63 | + unsigned int size = __rseq_size; | ||
64 | |||
65 | /* hack: mark glibc rseq structure as failed to register */ | ||
66 | rseq->cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED; | ||
67 | |||
68 | /* unregister rseq */ | ||
69 | - syscall(__NR_rseq, (void *)rseq, __rseq_size, 1, RSEQ_SIG); | ||
70 | + if (__rseq_size < 32) | ||
71 | + size = 32; | ||
72 | + syscall(__NR_rseq, (void *)rseq, size, 1, RSEQ_SIG); | ||
73 | } | ||
74 | #else | ||
75 | static inline void unregister_glibc_rseq(void) | ||
76 | diff --git a/test/zdtm/transition/rseq01.c b/test/zdtm/transition/rseq01.c | ||
77 | index 0fbcc2dca..08a7a8e1a 100644 | ||
78 | --- a/test/zdtm/transition/rseq01.c | ||
79 | +++ b/test/zdtm/transition/rseq01.c | ||
80 | @@ -33,7 +33,10 @@ static inline void *thread_pointer(void) | ||
81 | static inline void unregister_old_rseq(void) | ||
82 | { | ||
83 | /* unregister rseq */ | ||
84 | - syscall(__NR_rseq, (void *)((char *)thread_pointer() + __rseq_offset), __rseq_size, 1, RSEQ_SIG); | ||
85 | + unsigned int size = __rseq_size; | ||
86 | + if (__rseq_size < 32) | ||
87 | + size = 32; | ||
88 | + syscall(__NR_rseq, (void *)((char *)thread_pointer() + __rseq_offset), size, 1, RSEQ_SIG); | ||
89 | } | ||
90 | #else | ||
91 | static inline void unregister_old_rseq(void) | ||
92 | -- | ||
93 | 2.34.1 | ||
94 | |||