syscalls/mq_notify01: prevent deadlock, cleanup
Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
diff --git a/testcases/kernel/syscalls/mq_notify/mq_notify01.c b/testcases/kernel/syscalls/mq_notify/mq_notify01.c
index 9dd073f..68fabff 100644
--- a/testcases/kernel/syscalls/mq_notify/mq_notify01.c
+++ b/testcases/kernel/syscalls/mq_notify/mq_notify01.c
@@ -16,15 +16,10 @@
* the GNU General Public License for more details.
*/
#define _XOPEN_SOURCE 600
-#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/uio.h>
-#include <getopt.h>
-#include <libgen.h>
#include <limits.h>
#include <errno.h>
-#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <mqueue.h>
@@ -32,14 +27,18 @@
#include <stdlib.h>
#include <fcntl.h>
-#include "linux_syscall_numbers.h"
#include "tst_test.h"
-static char *str_debug;
-static int opt_debug;
+#define MAX_MSGSIZE 8192
+#define MSG_SIZE 16
+#define USER_DATA 0x12345678
+#define QUEUE_NAME "/test_mqueue"
-static int notified;
-static int cmp_ok;
+static char *str_debug;
+static char smsg[MAX_MSGSIZE];
+
+static volatile sig_atomic_t notified, cmp_ok;
+static siginfo_t info;
enum test_type {
NORMAL,
@@ -52,83 +51,74 @@
struct test_case {
int notify;
int ttype;
- const char *desc; /* test description (name) */
+ const char *desc;
int ret;
int err;
};
-#define MAX_MSGSIZE 8192
-#define MSG_SIZE 16
-#define USER_DATA 0x12345678
-#define QUEUE_NAME "/test_mqueue"
-
-
#define TYPE_NAME(x) .ttype = x, .desc = #x
-
static struct test_case tcase[] = {
{
- TYPE_NAME(NORMAL),
- .notify = SIGEV_NONE,
- .ret = 0,
- .err = 0,
- },
+ TYPE_NAME(NORMAL),
+ .notify = SIGEV_NONE,
+ .ret = 0,
+ .err = 0,
+ },
{
- TYPE_NAME(NORMAL),
- .notify = SIGEV_SIGNAL,
- .ret = 0,
- .err = 0,
- },
+ TYPE_NAME(NORMAL),
+ .notify = SIGEV_SIGNAL,
+ .ret = 0,
+ .err = 0,
+ },
{
- TYPE_NAME(NORMAL),
- .notify = SIGEV_THREAD,
- .ret = 0,
- .err = 0,
- },
+ TYPE_NAME(NORMAL),
+ .notify = SIGEV_THREAD,
+ .ret = 0,
+ .err = 0,
+ },
{
- TYPE_NAME(FD_NONE),
- .notify = SIGEV_NONE,
- .ret = -1,
- .err = EBADF,
- },
+ TYPE_NAME(FD_NONE),
+ .notify = SIGEV_NONE,
+ .ret = -1,
+ .err = EBADF,
+ },
{
- TYPE_NAME(FD_NOT_EXIST),
- .notify = SIGEV_NONE,
- .ret = -1,
- .err = EBADF,
- },
+ TYPE_NAME(FD_NOT_EXIST),
+ .notify = SIGEV_NONE,
+ .ret = -1,
+ .err = EBADF,
+ },
{
- TYPE_NAME(FD_FILE),
- .notify = SIGEV_NONE,
- .ret = -1,
- .err = EBADF,
- },
+ TYPE_NAME(FD_FILE),
+ .notify = SIGEV_NONE,
+ .ret = -1,
+ .err = EBADF,
+ },
{
- TYPE_NAME(ALREADY_REGISTERED),
- .notify = SIGEV_NONE,
- .ret = -1,
- .err = EBUSY,
- },
+ TYPE_NAME(ALREADY_REGISTERED),
+ .notify = SIGEV_NONE,
+ .ret = -1,
+ .err = EBUSY,
+ },
};
static void setup(void)
{
- opt_debug = str_debug ? 1 : 0;
-}
+ int i;
-static void sigfunc(int signo, siginfo_t * info, void *data)
+ for (i = 0; i < MSG_SIZE; i++)
+ smsg[i] = i;
+}
+static void sigfunc(int signo LTP_ATTRIBUTE_UNUSED, siginfo_t *si,
+ void *data LTP_ATTRIBUTE_UNUSED)
{
- if (opt_debug) {
- tst_res(TINFO, "si_code E:%d,\tR:%d", info->si_code, SI_MESGQ);
- tst_res(TINFO, "si_signo E:%d,\tR:%d", info->si_signo, SIGUSR1);
- tst_res(TINFO, "si_value E:0x%x,\tR:0x%x",
- info->si_value.sival_int, USER_DATA);
- tst_res(TINFO, "si_pid E:%d,\tR:%d", info->si_pid, getpid());
- tst_res(TINFO, "si_uid E:%d,\tR:%d", info->si_uid, getuid());
- }
- cmp_ok = info->si_code == SI_MESGQ &&
- info->si_signo == SIGUSR1 &&
- info->si_value.sival_int == USER_DATA &&
- info->si_pid == getpid() && info->si_uid == getuid();
+ if (str_debug)
+ memcpy(&info, si, sizeof(info));
+
+ cmp_ok = si->si_code == SI_MESGQ &&
+ si->si_signo == SIGUSR1 &&
+ si->si_value.sival_int == USER_DATA &&
+ si->si_pid == getpid() && si->si_uid == getuid();
notified = 1;
}
@@ -140,13 +130,10 @@
static void do_test(unsigned int i)
{
- int sys_ret;
- int sys_errno;
- int rc, j, fd = -1;
+ int rc, fd = -1;
struct sigevent ev;
struct sigaction sigact;
struct timespec abs_timeout;
- char smsg[MAX_MSGSIZE];
struct test_case *tc = &tcase[i];
notified = cmp_ok = 1;
@@ -162,24 +149,22 @@
mq_unlink(QUEUE_NAME);
switch (tc->ttype) {
- case FD_NOT_EXIST:
- fd = INT_MAX - 1;
- /* fallthrough */
case FD_NONE:
break;
+ case FD_NOT_EXIST:
+ fd = INT_MAX - 1;
+ break;
case FD_FILE:
- TEST(fd = open("/", O_RDONLY));
- if (TEST_RETURN < 0) {
- tst_res(TFAIL, "can't open \"/\".");
+ fd = open("/", O_RDONLY);
+ if (fd < 0) {
+ tst_res(TBROK | TERRNO, "can't open \"/\".");
goto CLEANUP;
}
break;
default:
- TEST(fd =
- mq_open(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR, S_IRWXU,
- NULL));
- if (TEST_RETURN < 0) {
- tst_res(TFAIL | TTERRNO, "mq_open failed");
+ fd = mq_open(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR, S_IRWXU, NULL);
+ if (fd < 0) {
+ tst_res(TBROK | TERRNO, "mq_open failed");
goto CLEANUP;
}
}
@@ -195,7 +180,7 @@
memset(&sigact, 0, sizeof(sigact));
sigact.sa_sigaction = sigfunc;
sigact.sa_flags = SA_SIGINFO;
- TEST(rc = sigaction(SIGUSR1, &sigact, NULL));
+ rc = sigaction(SIGUSR1, &sigact, NULL);
break;
case SIGEV_THREAD:
notified = cmp_ok = 0;
@@ -206,26 +191,17 @@
}
if (tc->ttype == ALREADY_REGISTERED) {
- TEST(rc = mq_notify(fd, &ev));
- if (TEST_RETURN < 0) {
- tst_res(TFAIL | TTERRNO, "mq_notify failed");
+ rc = mq_notify(fd, &ev);
+ if (rc < 0) {
+ tst_res(TBROK | TERRNO, "mq_notify failed");
goto CLEANUP;
}
}
- /*
- * Execute system call
- */
- errno = 0;
- sys_ret = mq_notify(fd, &ev);
- sys_errno = errno;
- if (sys_ret >= 0) {
- /*
- * Prepare send message
- */
- for (j = 0; j < MSG_SIZE; j++)
- smsg[j] = j;
- TEST(rc = mq_timedsend(fd, smsg, MSG_SIZE, 0, &abs_timeout));
+ /* test */
+ TEST(mq_notify(fd, &ev));
+ if (TEST_RETURN >= 0) {
+ rc = mq_timedsend(fd, smsg, MSG_SIZE, 0, &abs_timeout);
if (rc < 0) {
tst_res(TFAIL | TTERRNO, "mq_timedsend failed");
goto CLEANUP;
@@ -233,15 +209,28 @@
while (!notified)
usleep(10000);
+
+ if (str_debug && tc->notify == SIGEV_SIGNAL) {
+ tst_res(TINFO, "si_code E:%d,\tR:%d",
+ info.si_code, SI_MESGQ);
+ tst_res(TINFO, "si_signo E:%d,\tR:%d",
+ info.si_signo, SIGUSR1);
+ tst_res(TINFO, "si_value E:0x%x,\tR:0x%x",
+ info.si_value.sival_int, USER_DATA);
+ tst_res(TINFO, "si_pid E:%d,\tR:%d",
+ info.si_pid, getpid());
+ tst_res(TINFO, "si_uid E:%d,\tR:%d",
+ info.si_uid, getuid());
+ }
}
- if ((sys_ret != 0 && sys_errno != tc->err) || !cmp_ok) {
- tst_res(TFAIL, "%s r/w check returned: %d, expected: %d,"
- " returned errno: %s (%d), expected errno: %s (%d)",
- tc->desc, sys_ret, tc->ret, tst_strerrno(sys_errno),
- sys_errno, tst_strerrno(tc->err), tc->err);
+ if ((TEST_RETURN != 0 && TEST_ERRNO != tc->err) || !cmp_ok) {
+ tst_res(TFAIL | TTERRNO, "%s r/w check returned: %ld, "
+ "expected: %d, expected errno: %s (%d)", tc->desc,
+ TEST_RETURN, tc->ret, tst_strerrno(tc->err), tc->err);
} else {
- tst_res(TPASS, "%s returned: %d", tc->desc, sys_ret);
+ tst_res(TPASS | TTERRNO, "%s returned: %ld",
+ tc->desc, TEST_RETURN);
}
CLEANUP:
@@ -261,6 +250,5 @@
.tcnt = ARRAY_SIZE(tcase),
.test = do_test,
.options = options,
- .needs_tmpdir = 1,
.setup = setup,
};