[CRIU] [PATCH 02/13] zdtm: check private pending signals
Andrey Vagin
avagin at openvz.org
Thu Dec 20 06:54:10 EST 2012
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
test/zdtm/live/static/Makefile | 1 +
test/zdtm/live/static/sigpending.c | 300 +++++++++++++++++++++++++------------
2 files changed, 207 insertions(+), 94 deletions(-)
diff --git a/test/zdtm/live/static/Makefile b/test/zdtm/live/static/Makefile
index a268b59..722fbd5 100644
--- a/test/zdtm/live/static/Makefile
+++ b/test/zdtm/live/static/Makefile
@@ -210,6 +210,7 @@ unlink_largefile: override CFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURC
inotify_system_nodel: override CFLAGS += -DNODEL
pthread00: override LDLIBS += -pthread
pthread01: override LDLIBS += -pthread
+sigpending: override LDLIBS += -pthread
shm: override CFLAGS += -DNEW_IPC_NS
msgque: override CFLAGS += -DNEW_IPC_NS
sem: override CFLAGS += -DNEW_IPC_NS
diff --git a/test/zdtm/live/static/sigpending.c b/test/zdtm/live/static/sigpending.c
index 35e3856..ea1e112 100644
--- a/test/zdtm/live/static/sigpending.c
+++ b/test/zdtm/live/static/sigpending.c
@@ -3,6 +3,8 @@
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
+#include <pthread.h>
+#include <string.h>
#include "zdtmtst.h"
const char *test_doc = "Check pending signals";
@@ -12,109 +14,219 @@ static pid_t child;
static int numsig;
#define TESTSIG (SIGRTMAX)
-static siginfo_t siginfo[2];
-static int siginfo_nr;
+#define THREADSIG (SIGRTMIN)
+static siginfo_t share_infos[2];
+static siginfo_t self_infos[64]; /* self */
+static siginfo_t thread_infos[3]; /* thread */
+static int share_nr;
+static int self_nr;
+static int thread_nr;
#ifndef offsetof
# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
+static pthread_mutex_t exit_lock;
+static pthread_mutex_t init_lock;
+
static void sig_handler(int signal, siginfo_t *info, void *data)
{
- uint32_t crc;
-
- test_msg("signo=%d si_code=%x\n", signal, info->si_code);
-
- switch (signal) {
- case SIGCHLD:
- if ((info->si_code & CLD_EXITED) &&
- (info->si_pid == child) &&
- (info->si_status == 5))
- numsig++;
- else {
- fail("Wrong siginfo");
- exit(1);
- }
- return;
- }
-
- if (TESTSIG == signal) {
- crc = ~0;
- if (datachk((uint8_t *) &siginfo[siginfo_nr].si_code,
- sizeof(siginfo_t) - offsetof(siginfo_t, si_code), &crc)) {
- fail("CRC mismatch\n");
- exit(1);
- }
-
- siginfo_nr++;
- numsig++;
- return;
- }
-
- err("Unexpected signal");
- exit(1);
+ uint32_t crc;
+
+ test_msg("signo=%d si_code=%x\n", signal, info->si_code);
+
+ switch (signal) {
+ case SIGCHLD:
+ if ((info->si_code & CLD_EXITED) &&
+ (info->si_pid == child) &&
+ (info->si_status == 5))
+ numsig++;
+ else {
+ fail("Wrong siginfo");
+ exit(1);
+ }
+ return;
+ }
+
+ if (TESTSIG == signal || THREADSIG == signal) {
+ siginfo_t *src;
+
+ if (signal == TESTSIG) {
+ src = &share_infos[share_nr];
+ share_nr++;
+ } else if (getpid() == syscall(SYS_gettid)) {
+ src = &self_infos[self_nr];
+ self_nr++;
+ } else {
+ src = &thread_infos[thread_nr];
+ thread_nr++;
+ }
+
+ crc = ~0;
+ if (datachk((uint8_t *) &info->_sifields,
+ sizeof(siginfo_t) - offsetof(siginfo_t, _sifields), &crc)) {
+ fail("CRC mismatch\n");
+ return;
+ }
+
+ if (memcmp(info, src, sizeof(siginfo_t))) {
+ fail("Source and received info are differ\n");
+ return;
+ }
+
+ numsig++;
+ return;
+ }
+
+ err("Unexpected signal");
+ exit(1);
}
-int main(int argc, char ** argv)
+static int thread_id;
+
+static void *thread_fn(void *args)
{
- sigset_t blockmask;
- struct sigaction act;
- uint32_t crc;
- int i;
-
- test_init(argc, argv);
-
- sigfillset(&blockmask);
- sigdelset(&blockmask, SIGTERM);
-
- if (sigprocmask(SIG_BLOCK, &blockmask, NULL) == -1) {
- err("sigprocmask");
- return -1;
- }
-
- child = fork();
- if (child == -1) {
- err("fork");
- return -1;
- } else if(child == 0) {
- return 5;
- }
-
- for (i = 0; i < 2; i++) {
- crc = ~0;
- siginfo[i].si_code = -12;
- datagen((uint8_t *) &siginfo[i].si_code,
- sizeof(siginfo_t) - offsetof(siginfo_t, si_code), &crc);
- syscall(SYS_rt_sigqueueinfo, getpid(), TESTSIG, &siginfo[i]);
- }
-
- act.sa_flags = SA_SIGINFO | SA_RESTART;
- act.sa_sigaction = sig_handler;
- sigemptyset(&act.sa_mask);
-
- if (sigaction(SIGCHLD, &act, NULL)) {
- err("sigaction() failed\n");
- return -1;
- }
-
- sigaddset(&act.sa_mask, TESTSIG);
- if (sigaction(TESTSIG, &act, NULL)) {
- err("sigaction() failed\n");
- return -1;
- }
-
- test_daemon();
-
- test_waitsig();
-
- if (sigprocmask(SIG_UNBLOCK, &blockmask, NULL) == -1) {
- err("sigprocmask");
- return -1;
- }
-
- if (numsig == 3)
- pass();
-
- return 0;
+ sigset_t blockmask;
+ struct sigaction act;
+
+ sigfillset(&blockmask);
+ sigdelset(&blockmask, SIGTERM);
+
+ if (sigprocmask(SIG_BLOCK, &blockmask, NULL) == -1) {
+ err("sigprocmask");
+ return NULL;
+ }
+
+ thread_id = syscall(SYS_gettid);
+
+ act.sa_flags = SA_SIGINFO | SA_RESTART;
+ act.sa_sigaction = sig_handler;
+ sigemptyset(&act.sa_mask);
+
+ sigaddset(&act.sa_mask, TESTSIG);
+ sigaddset(&act.sa_mask, THREADSIG);
+ if (sigaction(TESTSIG, &act, NULL)) {
+ err("sigaction() failed\n");
+ return NULL;
+ }
+
+ pthread_mutex_unlock(&init_lock);
+ pthread_mutex_lock(&exit_lock);
+
+ if (sigprocmask(SIG_UNBLOCK, &blockmask, NULL) == -1) {
+ err("sigprocmask");
+ return NULL;
+ }
+
+ return NULL;
}
+static int sent_sigs;
+
+int send_siginfo(int signo, pid_t pid, pid_t tid, int group, siginfo_t *info)
+{
+ static int si_code = -10;
+ uint32_t crc = ~0;
+
+ info->si_code = si_code;
+ si_code--;
+ info->si_signo = signo;
+ datagen((uint8_t *) &info->_sifields,
+ sizeof(siginfo_t) - offsetof(siginfo_t, _sifields), &crc);
+
+ sent_sigs++;
+
+ if (group)
+ return syscall(SYS_rt_sigqueueinfo, pid, signo, info);
+ else
+ return syscall(SYS_rt_tgsigqueueinfo, pid, tid, signo, info);
+}
+
+int main(int argc, char ** argv)
+{
+ sigset_t blockmask;
+ struct sigaction act;
+ pthread_t pthrd;
+ int i;
+
+ test_init(argc, argv);
+ pthread_mutex_init(&exit_lock, NULL);
+ pthread_mutex_lock(&exit_lock);
+ pthread_mutex_init(&init_lock, NULL);
+ pthread_mutex_lock(&init_lock);
+
+ if (pthread_create(&pthrd, NULL, thread_fn, NULL)) {
+ err("Can't create a thread");
+ return 1;
+ }
+
+ pthread_mutex_lock(&init_lock);
+
+ sigfillset(&blockmask);
+ sigdelset(&blockmask, SIGTERM);
+
+ if (sigprocmask(SIG_BLOCK, &blockmask, NULL) == -1) {
+ err("sigprocmask");
+ return -1;
+ }
+
+ child = fork();
+ if (child == -1) {
+ err("fork");
+ return -1;
+ }
+
+ if(child == 0)
+ return 5; /* SIGCHLD */
+
+ sent_sigs++;
+
+ for (i = 0; i < sizeof(share_infos) / sizeof(siginfo_t); i++) {
+ send_siginfo(TESTSIG, getpid(), -1, 1, share_infos + i);
+ }
+
+ for (i = 0; i < sizeof(self_infos) / sizeof(siginfo_t); i++) {
+ send_siginfo(THREADSIG, getpid(), getpid(), 0, self_infos + i);
+ }
+
+ for (i = 0; i < sizeof(thread_infos) / sizeof(siginfo_t); i++) {
+ send_siginfo(THREADSIG, getpid(), thread_id, 0, thread_infos + i);
+ }
+
+ act.sa_flags = SA_SIGINFO | SA_RESTART;
+ act.sa_sigaction = sig_handler;
+ sigemptyset(&act.sa_mask);
+
+ if (sigaction(SIGCHLD, &act, NULL)) {
+ err("sigaction() failed\n");
+ return -1;
+ }
+
+ sigaddset(&act.sa_mask, TESTSIG);
+ sigaddset(&act.sa_mask, THREADSIG);
+ if (sigaction(TESTSIG, &act, NULL)) {
+ err("sigaction() failed\n");
+ return -1;
+ }
+
+ if (sigaction(THREADSIG, &act, NULL)) {
+ err("sigaction() failed\n");
+ return -1;
+ }
+
+ test_daemon();
+
+ test_waitsig();
+
+ if (sigprocmask(SIG_UNBLOCK, &blockmask, NULL) == -1) {
+ err("sigprocmask");
+ return -1;
+ }
+ pthread_mutex_unlock(&exit_lock);
+ pthread_join(pthrd, NULL);
+
+ if (numsig == sent_sigs)
+ pass();
+
+ return 0;
+}
--
1.7.11.7
More information about the CRIU
mailing list