mirror of
git://git.yoctoproject.org/meta-virtualization.git
synced 2025-07-19 12:50:22 +02:00
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>
This commit is contained in:
parent
cf982c9fad
commit
55209831c2
|
@ -20,8 +20,8 @@ SRC_URI = "git://github.com/checkpoint-restore/criu.git;branch=master;protocol=h
|
|||
file://0001-criu-Skip-documentation-install.patch \
|
||||
file://0002-criu-Change-libraries-install-directory.patch \
|
||||
file://0003-lib-Makefile-overwrite-install-lib-to-allow-multiarc.patch \
|
||||
file://0004-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch \
|
||||
"
|
||||
|
||||
COMPATIBLE_HOST = "(x86_64|arm|aarch64).*-linux"
|
||||
|
||||
DEPENDS += "libnl libcap protobuf-c-native protobuf-c util-linux-native libbsd libnet"
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
From 9f2eb6b9c4642fdc8aba2712d21cbe75545e4ab4 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed, 10 Jul 2024 18:34:50 +0200
|
||||
Subject: [PATCH] criu: Adjust to glibc __rseq_size semantic change
|
||||
|
||||
In commit 2e456ccf0c34a056e3ccafac4a0c7effef14d918 ("Linux: Make
|
||||
__rseq_size useful for feature detection (bug 31965)") glibc 2.40
|
||||
changed the meaning of __rseq_size slightly: it is now the size
|
||||
of the active/feature area (20 bytes initially), and not the size
|
||||
of the entire initially defined struct (32 bytes including padding).
|
||||
The reason for the change is that the size including padding does not
|
||||
allow detection of newly added features while previously unused
|
||||
padding is consumed.
|
||||
|
||||
The prep_libc_rseq_info change in criu/cr-restore.c is not necessary
|
||||
on kernels which have full ptrace support for obtaining rseq
|
||||
information because the code is not used. On older kernels, it is
|
||||
a correctness fix because with size 20 (the new value), rseq
|
||||
registeration would fail.
|
||||
|
||||
The two other changes are required to make rseq unregistration work
|
||||
in tests.
|
||||
|
||||
Upstream-Status: Backport [https://github.com/checkpoint-restore/criu/commit/
|
||||
089345f77a34d1bc7ef146d650636afcd3cdda21]
|
||||
|
||||
Signed-off-by: Florian Weimer <fweimer@redhat.com>
|
||||
Signed-off-by: Guocai He <guocai.he.cn@windriver.com>
|
||||
---
|
||||
criu/cr-restore.c | 8 ++++++++
|
||||
test/zdtm/static/rseq00.c | 7 +++++--
|
||||
test/zdtm/transition/rseq01.c | 5 ++++-
|
||||
3 files changed, 17 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
|
||||
index 9853c0585..df2010a4d 100644
|
||||
--- a/criu/cr-restore.c
|
||||
+++ b/criu/cr-restore.c
|
||||
@@ -3087,7 +3087,15 @@ static void prep_libc_rseq_info(struct rst_rseq_param *rseq)
|
||||
}
|
||||
|
||||
rseq->rseq_abi_pointer = encode_pointer(__criu_thread_pointer() + __rseq_offset);
|
||||
+ /*
|
||||
+ * Current glibc reports the feature/active size in
|
||||
+ * __rseq_size, not the size passed to the kernel.
|
||||
+ * This could be 20, but older kernels expect 32 for
|
||||
+ * the size argument even if only 20 bytes are used.
|
||||
+ */
|
||||
rseq->rseq_abi_size = __rseq_size;
|
||||
+ if (rseq->rseq_abi_size < 32)
|
||||
+ rseq->rseq_abi_size = 32;
|
||||
rseq->signature = RSEQ_SIG;
|
||||
}
|
||||
#else
|
||||
diff --git a/test/zdtm/static/rseq00.c b/test/zdtm/static/rseq00.c
|
||||
index 471ad6a43..23b2d74ab 100644
|
||||
--- a/test/zdtm/static/rseq00.c
|
||||
+++ b/test/zdtm/static/rseq00.c
|
||||
@@ -46,12 +46,15 @@ static inline void *__criu_thread_pointer(void)
|
||||
static inline void unregister_glibc_rseq(void)
|
||||
{
|
||||
struct rseq *rseq = (struct rseq *)((char *)__criu_thread_pointer() + __rseq_offset);
|
||||
+ unsigned int size = __rseq_size;
|
||||
|
||||
/* hack: mark glibc rseq structure as failed to register */
|
||||
rseq->cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED;
|
||||
|
||||
/* unregister rseq */
|
||||
- syscall(__NR_rseq, (void *)rseq, __rseq_size, 1, RSEQ_SIG);
|
||||
+ if (__rseq_size < 32)
|
||||
+ size = 32;
|
||||
+ syscall(__NR_rseq, (void *)rseq, size, 1, RSEQ_SIG);
|
||||
}
|
||||
#else
|
||||
static inline void unregister_glibc_rseq(void)
|
||||
@@ -140,4 +143,4 @@ int main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#endif /* #if defined(__x86_64__) */
|
||||
\ No newline at end of file
|
||||
+#endif /* #if defined(__x86_64__) */
|
||||
diff --git a/test/zdtm/transition/rseq01.c b/test/zdtm/transition/rseq01.c
|
||||
index b6d470785..de4355845 100644
|
||||
--- a/test/zdtm/transition/rseq01.c
|
||||
+++ b/test/zdtm/transition/rseq01.c
|
||||
@@ -33,7 +33,10 @@ static inline void *thread_pointer(void)
|
||||
static inline void unregister_old_rseq(void)
|
||||
{
|
||||
/* unregister rseq */
|
||||
- syscall(__NR_rseq, (void *)((char *)thread_pointer() + __rseq_offset), __rseq_size, 1, RSEQ_SIG);
|
||||
+ unsigned int size = __rseq_size;
|
||||
+ if (__rseq_size < 32)
|
||||
+ size = 32;
|
||||
+ syscall(__NR_rseq, (void *)((char *)thread_pointer() + __rseq_offset), size, 1, RSEQ_SIG);
|
||||
}
|
||||
#else
|
||||
static inline void unregister_old_rseq(void)
|
||||
--
|
||||
2.34.1
|
Loading…
Reference in New Issue
Block a user