diff options
| author | Guocai He <guocai.he.cn@windriver.com> | 2025-03-21 11:54:32 +0800 |
|---|---|---|
| committer | Bruce Ashfield <bruce.ashfield@gmail.com> | 2025-03-24 18:44:22 +0000 |
| commit | 55209831c2d4bdc2fe57e82b8ea878e1da0d20d1 (patch) | |
| tree | 926646141b6e69bd588ba0821cf41a152157fe85 | |
| parent | cf982c9fad8fe654058d80f53c558fa6f23a5193 (diff) | |
| download | meta-virtualization-55209831c2d4bdc2fe57e82b8ea878e1da0d20d1.tar.gz | |
criu: Adjust to glibc __rseq_size semantic change
On criu version 3.17:
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 | 2 | ||||
| -rw-r--r-- | recipes-containers/criu/files/0004-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch | 100 |
2 files changed, 101 insertions, 1 deletions
diff --git a/recipes-containers/criu/criu_git.bb b/recipes-containers/criu/criu_git.bb index 46401f9a..cff2d9d6 100644 --- a/recipes-containers/criu/criu_git.bb +++ b/recipes-containers/criu/criu_git.bb | |||
| @@ -20,8 +20,8 @@ SRC_URI = "git://github.com/checkpoint-restore/criu.git;branch=master;protocol=h | |||
| 20 | file://0001-criu-Skip-documentation-install.patch \ | 20 | file://0001-criu-Skip-documentation-install.patch \ |
| 21 | file://0002-criu-Change-libraries-install-directory.patch \ | 21 | file://0002-criu-Change-libraries-install-directory.patch \ |
| 22 | file://0003-lib-Makefile-overwrite-install-lib-to-allow-multiarc.patch \ | 22 | file://0003-lib-Makefile-overwrite-install-lib-to-allow-multiarc.patch \ |
| 23 | file://0004-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch \ | ||
| 23 | " | 24 | " |
| 24 | |||
| 25 | COMPATIBLE_HOST = "(x86_64|arm|aarch64).*-linux" | 25 | COMPATIBLE_HOST = "(x86_64|arm|aarch64).*-linux" |
| 26 | 26 | ||
| 27 | DEPENDS += "libnl libcap protobuf-c-native protobuf-c util-linux-native libbsd libnet" | 27 | DEPENDS += "libnl libcap protobuf-c-native protobuf-c util-linux-native libbsd libnet" |
diff --git a/recipes-containers/criu/files/0004-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch b/recipes-containers/criu/files/0004-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch new file mode 100644 index 00000000..b6f642f8 --- /dev/null +++ b/recipes-containers/criu/files/0004-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | From 9f2eb6b9c4642fdc8aba2712d21cbe75545e4ab4 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 | 7 +++++-- | ||
| 32 | test/zdtm/transition/rseq01.c | 5 ++++- | ||
| 33 | 3 files changed, 17 insertions(+), 3 deletions(-) | ||
| 34 | |||
| 35 | diff --git a/criu/cr-restore.c b/criu/cr-restore.c | ||
| 36 | index 9853c0585..df2010a4d 100644 | ||
| 37 | --- a/criu/cr-restore.c | ||
| 38 | +++ b/criu/cr-restore.c | ||
| 39 | @@ -3087,7 +3087,15 @@ static void prep_libc_rseq_info(struct rst_rseq_param *rseq) | ||
| 40 | } | ||
| 41 | |||
| 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 | } | ||
| 54 | #else | ||
| 55 | diff --git a/test/zdtm/static/rseq00.c b/test/zdtm/static/rseq00.c | ||
| 56 | index 471ad6a43..23b2d74ab 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 | @@ -140,4 +143,4 @@ int main(int argc, char *argv[]) | ||
| 77 | return 0; | ||
| 78 | } | ||
| 79 | |||
| 80 | -#endif /* #if defined(__x86_64__) */ | ||
| 81 | \ No newline at end of file | ||
| 82 | +#endif /* #if defined(__x86_64__) */ | ||
| 83 | diff --git a/test/zdtm/transition/rseq01.c b/test/zdtm/transition/rseq01.c | ||
| 84 | index b6d470785..de4355845 100644 | ||
| 85 | --- a/test/zdtm/transition/rseq01.c | ||
| 86 | +++ b/test/zdtm/transition/rseq01.c | ||
| 87 | @@ -33,7 +33,10 @@ static inline void *thread_pointer(void) | ||
| 88 | static inline void unregister_old_rseq(void) | ||
| 89 | { | ||
| 90 | /* unregister rseq */ | ||
| 91 | - syscall(__NR_rseq, (void *)((char *)thread_pointer() + __rseq_offset), __rseq_size, 1, RSEQ_SIG); | ||
| 92 | + unsigned int size = __rseq_size; | ||
| 93 | + if (__rseq_size < 32) | ||
| 94 | + size = 32; | ||
| 95 | + syscall(__NR_rseq, (void *)((char *)thread_pointer() + __rseq_offset), size, 1, RSEQ_SIG); | ||
| 96 | } | ||
| 97 | #else | ||
| 98 | static inline void unregister_old_rseq(void) | ||
| 99 | -- | ||
| 100 | 2.34.1 | ||
