check_signal: system call restart is done only once
Fujitsu: POSTK_TEMP_FIX_66 Refs: #1009 Change-Id: Ic0f04ac6b7f6c6bb01b55fb389bf9befd56b1dd9
This commit is contained in:
committed by
Masamichi Takagi
parent
c25fb2aa39
commit
e4da71010c
49
test/issues/1009/C1009.patch
Normal file
49
test/issues/1009/C1009.patch
Normal file
@@ -0,0 +1,49 @@
|
||||
diff --git a/arch/x86_64/kernel/syscall.c b/arch/x86_64/kernel/syscall.c
|
||||
index 4b2742b..a3173c9 100644
|
||||
--- a/arch/x86_64/kernel/syscall.c
|
||||
+++ b/arch/x86_64/kernel/syscall.c
|
||||
@@ -1670,6 +1670,11 @@ long do_arch_prctl(unsigned long code, unsigned long address)
|
||||
break;
|
||||
case ARCH_SET_GS:
|
||||
return -ENOTSUPP;
|
||||
+ case 999: {
|
||||
+ struct thread *thread = cpu_local_var(current);
|
||||
+ thread->proc->dblsig = (int)address;
|
||||
+ return 0;
|
||||
+ }
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
diff --git a/kernel/include/process.h b/kernel/include/process.h
|
||||
index 24acf1f..dd94469 100644
|
||||
--- a/kernel/include/process.h
|
||||
+++ b/kernel/include/process.h
|
||||
@@ -580,6 +580,8 @@ struct process {
|
||||
#endif // PROFILE_ENABLE
|
||||
int nr_processes; /* For partitioned execution */
|
||||
int process_rank; /* Rank in partition */
|
||||
+
|
||||
+ int dblsig;
|
||||
};
|
||||
|
||||
/*
|
||||
diff --git a/kernel/syscall.c b/kernel/syscall.c
|
||||
index 15d4593..3d03fad 100644
|
||||
--- a/kernel/syscall.c
|
||||
+++ b/kernel/syscall.c
|
||||
@@ -9632,6 +9632,15 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||
|
||||
if (!list_empty(&thread->sigpending) ||
|
||||
!list_empty(&thread->sigcommon->sigpending)) {
|
||||
+ if (!list_empty(&thread->sigcommon->sigpending) &&
|
||||
+ thread->proc->dblsig) {
|
||||
+ kprintf("have a signal, waiting arrive more signal\n");
|
||||
+ while (list_is_singular(
|
||||
+ &thread->sigcommon->sigpending)) {
|
||||
+ schedule();
|
||||
+ }
|
||||
+ kprintf("have some signals\n");
|
||||
+ }
|
||||
check_signal(l, NULL, num);
|
||||
}
|
||||
|
||||
131
test/issues/1009/C1009.sh
Normal file
131
test/issues/1009/C1009.sh
Normal file
@@ -0,0 +1,131 @@
|
||||
#!/bin/sh
|
||||
BOOTPARAM="-c 1-7,17-23,9-15,25-31 -m 10G@0,10G@1"
|
||||
USELTP=1
|
||||
USEOSTEST=
|
||||
|
||||
################################################################################
|
||||
BINDIR=
|
||||
SBINDIR=
|
||||
OSTESTDIR=
|
||||
LTPDIR=
|
||||
LTPBIN=
|
||||
MCEXEC=
|
||||
TESTMCK=
|
||||
|
||||
if [ -f $HOME/mck_test_config ]; then
|
||||
. $HOME/mck_test_config
|
||||
elif [ -f ../../../mck_test_config.sample ]; then
|
||||
. ../../../mck_test_config.sample
|
||||
else
|
||||
BIN=
|
||||
SBIN=
|
||||
OSTEST=
|
||||
LTP=
|
||||
fi
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
if [ "x$BIN" = x ]; then
|
||||
if [ -f ../../../config.h ]; then
|
||||
str=`grep "^#define BINDIR " ../../../config.h | head -1 | sed 's/^#define BINDIR /BINDIR=/'`
|
||||
eval $str
|
||||
fi
|
||||
else
|
||||
BINDIR="$BIN"
|
||||
fi
|
||||
|
||||
if [ "x$SBIN" = x ]; then
|
||||
if [ -f ../../../Makefile ]; then
|
||||
str=`grep ^SBINDIR ../../../Makefile | head -1 | sed 's/ //g'`
|
||||
eval $str
|
||||
fi
|
||||
else
|
||||
SBINDIR="$SBIN"
|
||||
fi
|
||||
|
||||
if [ ! -x "$BINDIR/mcexec" ]; then
|
||||
echo no mckernel found $BINDIR >&2
|
||||
exit 1
|
||||
fi
|
||||
MCEXEC="$BINDIR/mcexec"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
if [ "x$USELTP" != x ]; then
|
||||
if [ "x$LTP" = x ]; then
|
||||
if [ -f "$HOME/ltp/testcases/bin/fork01" ]; then
|
||||
LTPDIR="$HOME/ltp"
|
||||
fi
|
||||
else
|
||||
LTPDIR="$LTP"
|
||||
fi
|
||||
|
||||
if [ ! -x "$LTPDIR/testcases/bin/fork01" ]; then
|
||||
echo no LTP found $LTPDIR >&2
|
||||
exit 1
|
||||
fi
|
||||
LTPBIN="$LTPDIR/testcases/bin"
|
||||
fi
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
if [ "x$USEOSTEST" != x ]; then
|
||||
if [ "x$OSTEST" = x ]; then
|
||||
if [ -f "$HOME/ostest/bin/test_mck" ]; then
|
||||
OSTESTDIR="$HOME/ostest"
|
||||
fi
|
||||
else
|
||||
OSTESTDIR="$OSTEST"
|
||||
fi
|
||||
|
||||
if [ ! -x "$OSTESTDIR"/bin/test_mck ]; then
|
||||
echo no ostest found $OSTESTDIR >&2
|
||||
exit 1
|
||||
fi
|
||||
TESTMCK="$OSTESTDIR/bin/test_mck"
|
||||
fi
|
||||
|
||||
#===============================================================================
|
||||
if [ ! -x "$SBINDIR/mcstop+release.sh" ]; then
|
||||
echo mcstop+release: not found >&2
|
||||
exit 1
|
||||
fi
|
||||
echo -n "mcstop+release.sh ... "
|
||||
sudo "$SBINDIR/mcstop+release.sh"
|
||||
echo "done"
|
||||
|
||||
if lsmod | grep mcctrl > /dev/null 2>&1; then
|
||||
echo mckernel shutdown failed >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -x "$SBINDIR/mcreboot.sh" ]; then
|
||||
echo mcreboot: not found >&2
|
||||
exit 1
|
||||
fi
|
||||
echo -n "mcreboot.sh $BOOTPARAM ... "
|
||||
sudo "$SBINDIR/mcreboot.sh" $BOOTPARAM
|
||||
echo "done"
|
||||
|
||||
if ! lsmod | grep mcctrl > /dev/null 2>&1; then
|
||||
echo mckernel boot failed >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
$MCEXEC ./C1009T01
|
||||
|
||||
if [ x$LTPDIR = x ]; then
|
||||
echo no LTP found >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for i in kill01:02 kill12:03 pause02:04 sigaction01:05 ; do
|
||||
tp=`echo $i|sed 's/:.*//'`
|
||||
id=`echo $i|sed 's/.*://'`
|
||||
$MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt
|
||||
ok=`grep TPASS $tp.txt | wc -l`
|
||||
ng=`grep TFAIL $tp.txt | wc -l`
|
||||
if [ $ng = 0 ]; then
|
||||
echo "*** C1009T$id: $tp OK ($ok)"
|
||||
else
|
||||
echo "*** C1009T$id: $tp NG (ok=$ok ng=%ng)"
|
||||
fi
|
||||
done
|
||||
24
test/issues/1009/C1009.txt
Normal file
24
test/issues/1009/C1009.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
Script started on Mon Sep 10 15:12:28 2018
|
||||
bash-4.2$ make test
|
||||
gcc -g -Wall -o C1009T01 C1009T01.c
|
||||
sh ./C1009.sh
|
||||
SIGUSR2
|
||||
SIGUSR1
|
||||
read A OK
|
||||
read B OK
|
||||
*** C1009T01: OK
|
||||
kill01 1 TPASS : received expected signal 9
|
||||
*** C1009T02: kill01 OK (1)
|
||||
kill12 1 TPASS : Test passed
|
||||
*** C1009T03: kill12 OK (1)
|
||||
pause02 1 TPASS : pause was interrupted correctly
|
||||
*** C1009T04: pause02 OK (1)
|
||||
sigaction01 1 TPASS : SA_RESETHAND did not cause SA_SIGINFO to be cleared
|
||||
sigaction01 2 TPASS : SA_RESETHAND was masked when handler executed
|
||||
sigaction01 3 TPASS : sig has been masked because sa_mask originally contained sig
|
||||
sigaction01 4 TPASS : siginfo pointer non NULL
|
||||
*** C1009T05: sigaction01 OK (4)
|
||||
bash-4.2$ exit
|
||||
exit
|
||||
|
||||
Script done on Mon Sep 10 15:12:54 2018
|
||||
107
test/issues/1009/C1009T01.c
Normal file
107
test/issues/1009/C1009T01.c
Normal file
@@ -0,0 +1,107 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <asm/prctl.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
int arch_prctl(int code, unsigned long *addr);
|
||||
|
||||
void
|
||||
sigusr(int sig)
|
||||
{
|
||||
if (sig == SIGUSR1) {
|
||||
printf("SIGUSR1\n");
|
||||
}
|
||||
else if (sig == SIGUSR2) {
|
||||
printf("SIGUSR2\n");
|
||||
}
|
||||
else {
|
||||
printf("other sig\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct sigaction act;
|
||||
pid_t pid1 = 0;
|
||||
pid_t pid2 = 0;
|
||||
pid_t parent;
|
||||
int pfd[2];
|
||||
char ch;
|
||||
int rc;
|
||||
unsigned long val;
|
||||
|
||||
memset(&act, '\0', sizeof(act));
|
||||
act.sa_handler = sigusr;
|
||||
act.sa_flags = SA_RESTART;
|
||||
sigaction(SIGUSR1, &act, NULL);
|
||||
sigaction(SIGUSR2, &act, NULL);
|
||||
|
||||
pipe(pfd);
|
||||
|
||||
parent = getpid();
|
||||
val = 1;
|
||||
if (arch_prctl(999, (unsigned long *)val) == -1) {
|
||||
fprintf(stderr, "C1009T01 WARN: no mckernel patch detected.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((pid1 = fork())) {
|
||||
pid2 = fork();
|
||||
}
|
||||
|
||||
if (!pid1 || !pid2) {
|
||||
int sig;
|
||||
|
||||
close(pfd[0]);
|
||||
if (pid1)
|
||||
sig = SIGUSR2;
|
||||
else
|
||||
sig = SIGUSR1;
|
||||
|
||||
sleep(1);
|
||||
kill(parent, sig);
|
||||
if (pid1) {
|
||||
sleep(2);
|
||||
ch = 'B';
|
||||
}
|
||||
else {
|
||||
sleep(1);
|
||||
ch = 'A';
|
||||
}
|
||||
write(pfd[1], &ch, 1);
|
||||
close(pfd[1]);
|
||||
exit(0);
|
||||
}
|
||||
rc = read(pfd[0], &ch, 1);
|
||||
if (rc != 1) {
|
||||
printf("C1009T01 NG: read error rc=%d errno=%d\n", rc, errno);
|
||||
exit(1);
|
||||
}
|
||||
if (ch != 'A') {
|
||||
printf("C1009T01 NG: read BAD DATA ch=%c\n", ch);
|
||||
exit(1);
|
||||
}
|
||||
val = 0;
|
||||
arch_prctl(999, (unsigned long *)val);
|
||||
printf("read %c OK\n", ch);
|
||||
rc = read(pfd[0], &ch, 1);
|
||||
if (rc != 1) {
|
||||
printf("C1009T01 NG: read error rc=%d errno=%d\n", rc, errno);
|
||||
exit(1);
|
||||
}
|
||||
if (ch != 'B') {
|
||||
printf("C1009T01 NG: read BAD DATA ch=%c\n", ch);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("read %c OK\n", ch);
|
||||
printf("*** C1009T01: OK\n");
|
||||
exit(0);
|
||||
}
|
||||
13
test/issues/1009/Makefile
Normal file
13
test/issues/1009/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
CC = gcc
|
||||
TARGET = C1009T01
|
||||
|
||||
all:: $(TARGET)
|
||||
|
||||
C1009T01: C1009T01.c
|
||||
$(CC) -g -Wall -o $@ $^
|
||||
|
||||
test:: all
|
||||
sh ./C1009.sh
|
||||
|
||||
clean::
|
||||
rm -f $(TARGET) *.o
|
||||
27
test/issues/1009/README
Normal file
27
test/issues/1009/README
Normal file
@@ -0,0 +1,27 @@
|
||||
【Issue#1009 動作確認】
|
||||
□ テスト内容
|
||||
1. システムコール処理中にシグナルハンドラを呼び出す複数のシグナルを
|
||||
受信し、当該システムコールを再処理するとき、当該システムコールが
|
||||
1度しか処理されないことを確認する(指摘現象)。
|
||||
尚、シグナルを同時に発行する状態を再現させるのが困難なため、本
|
||||
テストは複数シグナルを待ち合わせるパッチを適用したカーネルで行う。
|
||||
McKernel へのパッチファイルは C1009.patch である。
|
||||
C1009T01 シグナルを複数受信したとき、システムコールの再処理を1度だけ行う確認
|
||||
|
||||
2. 変更が他のシグナル処理に影響しないことをLTPを用いて確認する。
|
||||
C1009T02 kill01: kill の基本機能の確認
|
||||
C1009T03 kill12: kill, wait, signal の組み合わせ確認
|
||||
C1009T04 pause02: pause の基本機能の確認
|
||||
C1009T05 sigaction01: sigaction の基本機能の確認
|
||||
|
||||
□ 実行手順
|
||||
$ make test
|
||||
|
||||
実行できない場合は、C1009.shの以下の行を適切に書き換えた後に実行。
|
||||
BIN= mcexec が存在するパス
|
||||
SBIN= mcreboot.sh が存在するパス
|
||||
LTP= LTP が存在するパス
|
||||
|
||||
□ 実行結果
|
||||
C1009.txt 参照。
|
||||
全ての項目が OK となっていることを確認。
|
||||
Reference in New Issue
Block a user