From patchwork Mon May 18 08:14:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 1292394 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.linux.it (client-ip=2001:1418:10:5::2; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=poK6bW0a; dkim-atps=neutral Received: from picard.linux.it (picard.linux.it [IPv6:2001:1418:10:5::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49QX0B4qcsz9sTC for ; Mon, 18 May 2020 18:16:10 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 1DD423C4F41 for ; Mon, 18 May 2020 10:16:08 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-5.smtp.seeweb.it (in-5.smtp.seeweb.it [217.194.8.5]) by picard.linux.it (Postfix) with ESMTP id EBCF83C4F45 for ; Mon, 18 May 2020 10:15:32 +0200 (CEST) Received: from mail-pg1-x541.google.com (mail-pg1-x541.google.com [IPv6:2607:f8b0:4864:20::541]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by in-5.smtp.seeweb.it (Postfix) with ESMTPS id 51E3C600E39 for ; Mon, 18 May 2020 10:15:09 +0200 (CEST) Received: by mail-pg1-x541.google.com with SMTP id s10so2213515pgm.0 for ; Mon, 18 May 2020 01:15:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=iKsSpsNJ7hk4KBlCWNnqpmrw8W5nghWd4Ii17c1bbd0=; b=poK6bW0a1FCljBjwQWke5JhVUyTqmDWD0RMduLefqB/ZXVTqe1bhrzQwVM1ycKAe8T aOlZPT1Bw9OeD362MnvDQQNaloXMaH8alHOj0V7AvHd6LsBrokQlZfgQxeWCDiAV8jpR RHdBpPAhQfsECK4aUqyc0BWhoExH019w4Pkvvm3SaajN9S8mzyCpSzK3jRiFkYZCDfI3 Fs7BbCxpEl737oEzoDCts2n7sdpSkzy2+ax0Bw1ViQ+kZ6pSNcsHt84Ktn8jL8SzsUF2 R1bcHZIATDwBhlIjCf8WvBz82Xg8jgpGADXnENMUyJPGUU1j7kwMS1a8P1M1JTO+YPic 867w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=iKsSpsNJ7hk4KBlCWNnqpmrw8W5nghWd4Ii17c1bbd0=; b=fv0CPLJtdx3ntNlw4ZtOPZo9YixIjXdbckZ31j9QR8NCYXmPcdE60v/0NClAlg2jLj 1eY9IPLQ22+HeJmEdQ4yTwnXkUCPKB8UFOiX7ypBB21+WBCSEgSvzvJl4x1tPA4/e6P7 UQq8Lb9XwvZEOOqaOAB47Dl9Yzg1Z75MWUhmiWTn/UO6sz936z1nEcGYxeVXSEU38XOI DgcQy8DdTpx9ro0/tN5sOI6fMIK1iDrxKfS6G4n8p6BWx9K11qCTk4nHkY8JPTcNCnvE b+c8kmTsny9nqs090OUfZ7qYKxNUVOAqpXdT4jnb8cPvbq8NQq1w144oHpP07UNCaTF7 c0tw== X-Gm-Message-State: AOAM5337jOLgDnAfBqRe/XoLJlcBleS1gLYANDUNOyLQXvvj0ymVNfkn 0IJiEmJVogqe+mtMylfVL4bFGVtADac= X-Google-Smtp-Source: ABdhPJwu5RtKu0ur2LDPhQNa98N18CqZeoAuLRk+LiDJeRLDt059us/XGggQK5jqQ6zjWCXOCnQCtg== X-Received: by 2002:a63:4504:: with SMTP id s4mr3769577pga.175.1589789729964; Mon, 18 May 2020 01:15:29 -0700 (PDT) Received: from localhost ([122.167.130.103]) by smtp.gmail.com with ESMTPSA id cm14sm7815087pjb.31.2020.05.18.01.15.28 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 May 2020 01:15:29 -0700 (PDT) From: Viresh Kumar To: ltp@lists.linux.it Date: Mon, 18 May 2020 13:44:56 +0530 Message-Id: X-Mailer: git-send-email 2.25.0.rc1.19.g042ed3e048af In-Reply-To: References: MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.99.2 at in-5.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.1 required=7.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,SPF_HELO_NONE,SPF_PASS autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-5.smtp.seeweb.it Subject: [LTP] [PATCH V3 04/17] syscalls/sched_rr_get_interval: Add support for time64 tests X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vincent Guittot , arnd@arndb.de, Viresh Kumar Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" This adds support for time64 tests to the existing sched_rr_get_interval() syscall tests. Signed-off-by: Viresh Kumar --- include/tst_timer.h | 16 ++ .../sched_rr_get_interval01.c | 116 ++++++-------- .../sched_rr_get_interval02.c | 122 ++++++--------- .../sched_rr_get_interval03.c | 146 ++++++++---------- 4 files changed, 173 insertions(+), 227 deletions(-) diff --git a/include/tst_timer.h b/include/tst_timer.h index f3d948d0fed7..77be32c924a1 100644 --- a/include/tst_timer.h +++ b/include/tst_timer.h @@ -12,6 +12,7 @@ #ifndef TST_TIMER #define TST_TIMER +#include #include #include #include "tst_test.h" @@ -247,6 +248,21 @@ static inline int sys_clock_nanosleep64(clockid_t clk_id, int flags, request, remain); } +static inline int libc_sched_rr_get_interval(pid_t pid, void *ts) +{ + return sched_rr_get_interval(pid, ts); +} + +static inline int sys_sched_rr_get_interval(pid_t pid, void *ts) +{ + return tst_syscall(__NR_sched_rr_get_interval, pid, ts); +} + +static inline int sys_sched_rr_get_interval64(pid_t pid, void *ts) +{ + return tst_syscall(__NR_sched_rr_get_interval_time64, pid, ts); +} + static inline int sys_timer_gettime(kernel_timer_t timerid, void *its) { return tst_syscall(__NR_timer_gettime, timerid, its); diff --git a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c index b6084f673ca7..9bad698aa6ec 100644 --- a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c +++ b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c @@ -1,20 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ -/********************************************************** * * TEST IDENTIFIER : sched_rr_get_interval01 * @@ -62,81 +48,69 @@ * -P x : Pause for x seconds between iterations. * -t : Turn on syscall timing. * - ****************************************************************/ + */ -#include #include -#include "test.h" - -static void setup(); -static void cleanup(); - -char *TCID = "sched_rr_get_interval01"; -int TST_TOTAL = 1; - -struct timespec tp; - -int main(int ac, char **av) -{ - - int lc; - - tst_parse_opts(ac, av, NULL, NULL); +#include "tst_timer.h" - setup(); +struct tst_ts tp; - for (lc = 0; TEST_LOOPING(lc); lc++) { +static struct test_variants { + int (*func)(pid_t pid, void *ts); + enum tst_ts_type type; + char *desc; +} variants[] = { + { .func = libc_sched_rr_get_interval, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"}, - tst_count = 0; +#if (__NR_sched_rr_get_interval != __LTP__NR_INVALID_SYSCALL) + { .func = sys_sched_rr_get_interval, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with old kernel spec"}, +#endif - /* - * Call sched_rr_get_interval(2) with pid=0 so that it will - * write into the timespec structure pointed to by tp, the - * round robin time quantum for the current process. - */ - TEST(sched_rr_get_interval(0, &tp)); +#if (__NR_sched_rr_get_interval_time64 != __LTP__NR_INVALID_SYSCALL) + { .func = sys_sched_rr_get_interval64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"}, +#endif +}; - if (TEST_RETURN == 0) { - tst_resm(TPASS, "sched_rr_get_interval() returned %ld", - TEST_RETURN); - } else { - tst_resm(TFAIL | TTERRNO, - "Test Failed, sched_rr_get_interval()" - "returned %ld", TEST_RETURN); - } - } - - /* cleanup and exit */ - cleanup(); - tst_exit(); - -} - -/* setup() - performs all ONE TIME setup for this test */ -void setup(void) +static void setup(void) { - tst_require_root(); + struct test_variants *tv = &variants[tst_variant]; /* * Initialize scheduling parameter structure to use with * sched_setscheduler() */ struct sched_param p = { 1 }; - tst_sig(NOFORK, DEF_HANDLER, cleanup); + tst_res(TINFO, "Testing variant: %s", tv->desc); - TEST_PAUSE; + tp.type = tv->type; /* Change scheduling policy to SCHED_RR */ - if ((sched_setscheduler(0, SCHED_RR, &p)) == -1) { - tst_brkm(TBROK, cleanup, "sched_setscheduler() failed"); - } + if ((sched_setscheduler(0, SCHED_RR, &p)) == -1) + tst_res(TFAIL | TTERRNO, "sched_setscheduler() failed"); } -/* - *cleanup() - performs all ONE TIME cleanup for this test at - * completion or premature exit. - */ -void cleanup(void) +static void run(void) { + struct test_variants *tv = &variants[tst_variant]; + + /* + * Call sched_rr_get_interval(2) with pid=0 so that it will + * write into the timespec structure pointed to by tp, the + * round robin time quantum for the current process. + */ + TEST(tv->func(0, tst_ts_get(&tp))); + if (!TST_RET) { + tst_res(TPASS, "sched_rr_get_interval() passed"); + } else { + tst_res(TFAIL | TTERRNO, "Test Failed, sched_rr_get_interval() returned %ld", + TST_RET); + } } + +static struct tst_test test = { + .test_all = run, + .test_variants = ARRAY_SIZE(variants), + .setup = setup, + .needs_root = 1, +}; diff --git a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval02.c b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval02.c index 6bf743f78c5e..8da42e97404b 100644 --- a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval02.c +++ b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval02.c @@ -1,20 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ -/********************************************************** * * TEST IDENTIFIER : sched_rr_get_interval02 * @@ -63,84 +49,72 @@ * -P x : Pause for x seconds between iterations. * -t : Turn on syscall timing. * - ****************************************************************/ + */ -#include #include -#include "test.h" - -static void setup(); -static void cleanup(); +#include "tst_timer.h" -char *TCID = "sched_rr_get_interval02"; -int TST_TOTAL = 1; +struct tst_ts tp; -struct timespec tp; +static struct test_variants { + int (*func)(pid_t pid, void *ts); + enum tst_ts_type type; + char *desc; +} variants[] = { + { .func = libc_sched_rr_get_interval, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"}, -int main(int ac, char **av) -{ - - int lc; - - tst_parse_opts(ac, av, NULL, NULL); - - setup(); +#if (__NR_sched_rr_get_interval != __LTP__NR_INVALID_SYSCALL) + { .func = sys_sched_rr_get_interval, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with old kernel spec"}, +#endif - for (lc = 0; TEST_LOOPING(lc); lc++) { +#if (__NR_sched_rr_get_interval_time64 != __LTP__NR_INVALID_SYSCALL) + { .func = sys_sched_rr_get_interval64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"}, +#endif +}; - tst_count = 0; - - tp.tv_sec = 99; - tp.tv_nsec = 99; - /* - * Call sched_rr_get_interval(2) with pid=0 sothat it will - * write into the timespec structure pointed to by tp the - * round robin time quantum for the current process. - */ - TEST(sched_rr_get_interval(0, &tp)); - - if ((TEST_RETURN == 0) && (tp.tv_sec == 0) && (tp.tv_nsec == 0)) { - tst_resm(TPASS, "Test passed"); - } else { - tst_resm(TFAIL, "Test Failed, sched_rr_get_interval()" - "returned %ld, errno = %d : %s, tp.tv_sec = %d," - " tp.tv_nsec = %ld", TEST_RETURN, TEST_ERRNO, - strerror(TEST_ERRNO), (int)tp.tv_sec, - tp.tv_nsec); - } - } - - /* cleanup and exit */ - cleanup(); - tst_exit(); - -} - -/* setup() - performs all ONE TIME setup for this test */ -void setup(void) +static void setup(void) { - tst_require_root(); + struct test_variants *tv = &variants[tst_variant]; /* * Initialize scheduling parameter structure to use with * sched_setscheduler() */ struct sched_param p = { 1 }; - tst_sig(NOFORK, DEF_HANDLER, cleanup); + tst_res(TINFO, "Testing variant: %s", tv->desc); - TEST_PAUSE; + tp.type = tv->type; /* Change scheduling policy to SCHED_FIFO */ - if ((sched_setscheduler(0, SCHED_FIFO, &p)) == -1) { - tst_brkm(TBROK, cleanup, "sched_setscheduler() failed"); - } + if ((sched_setscheduler(0, SCHED_FIFO, &p)) == -1) + tst_res(TFAIL | TTERRNO, "sched_setscheduler() failed"); } -/* - *cleanup() - performs all ONE TIME cleanup for this test at - * completion or premature exit. - */ -void cleanup(void) +static void run(void) { + struct test_variants *tv = &variants[tst_variant]; + tst_ts_set_sec(&tp, 99); + tst_ts_set_nsec(&tp, 99); + + /* + * Call sched_rr_get_interval(2) with pid=0 so that it will + * write into the timespec structure pointed to by tp the + * round robin time quantum for the current process. + */ + TEST(tv->func(0, tst_ts_get(&tp))); + + if (!TST_RET && tst_ts_valid(&tp) == -1) { + tst_res(TPASS, "sched_rr_get_interval() passed"); + } else { + tst_res(TFAIL | TTERRNO, "Test Failed, sched_rr_get_interval() returned %ld, tp.tv_sec = %lld, tp.tv_nsec = %lld", + TST_RET, tst_ts_get_sec(tp), tst_ts_get_nsec(tp)); + } } + +static struct tst_test test = { + .test_all = run, + .test_variants = ARRAY_SIZE(variants), + .setup = setup, + .needs_root = 1, +}; diff --git a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval03.c b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval03.c index 56f2fcf28269..0ccf47d2a561 100644 --- a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval03.c +++ b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval03.c @@ -1,20 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ -/********************************************************** * * TEST IDENTIFIER : sched_rr_get_interval03 * @@ -68,104 +54,100 @@ * -P x : Pause for x seconds between iterations. * -t : Turn on syscall timing. * - ****************************************************************/ + */ -#include #include -#include "test.h" - -static void setup(); -static void cleanup(); - -char *TCID = "sched_rr_get_interval03"; -struct timespec tp; +#include "tst_timer.h" static pid_t unused_pid; static pid_t inval_pid = -1; static pid_t zero_pid; +struct tst_ts tp; +static void *bad_addr; + struct test_cases_t { pid_t *pid; - struct timespec *tp; + struct tst_ts *tp; int exp_errno; } test_cases[] = { - { - &inval_pid, &tp, EINVAL}, { - &unused_pid, &tp, ESRCH}, + { &inval_pid, &tp, EINVAL}, + { &unused_pid, &tp, ESRCH}, #ifndef UCLINUX - /* Skip since uClinux does not implement memory protection */ - { - &zero_pid, (struct timespec *)-1, EFAULT} + /* Skip since uClinux does not implement memory protection */ + { &zero_pid, NULL, EFAULT} #endif }; -int TST_TOTAL = sizeof(test_cases) / sizeof(test_cases[0]); +static struct test_variants { + int (*func)(pid_t pid, void *ts); + enum tst_ts_type type; + char *desc; +} variants[] = { + { .func = libc_sched_rr_get_interval, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"}, -int main(int ac, char **av) -{ - - int lc, i; - - tst_parse_opts(ac, av, NULL, NULL); - - setup(); - - for (lc = 0; TEST_LOOPING(lc); lc++) { - - tst_count = 0; - - for (i = 0; i < TST_TOTAL; ++i) { - /* - * Call sched_rr_get_interval(2) - */ - TEST(sched_rr_get_interval(*(test_cases[i].pid), - test_cases[i].tp)); - - if ((TEST_RETURN == -1) && - (TEST_ERRNO == test_cases[i].exp_errno)) { - tst_resm(TPASS, "Test Passed"); - } else { - tst_resm(TFAIL | TTERRNO, "Test Failed," - " sched_rr_get_interval() returned %ld", - TEST_RETURN); - } - } - } - - /* cleanup and exit */ - cleanup(); - - tst_exit(); +#if (__NR_sched_rr_get_interval != __LTP__NR_INVALID_SYSCALL) + { .func = sys_sched_rr_get_interval, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with old kernel spec"}, +#endif -} +#if (__NR_sched_rr_get_interval_time64 != __LTP__NR_INVALID_SYSCALL) + { .func = sys_sched_rr_get_interval64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"}, +#endif +}; -/* setup() - performs all ONE TIME setup for this test */ -void setup(void) +static void setup(void) { - tst_require_root(); + struct test_variants *tv = &variants[tst_variant]; /* * Initialize scheduling parameter structure to use with * sched_setscheduler() */ struct sched_param p = { 1 }; - tst_sig(NOFORK, DEF_HANDLER, cleanup); + tst_res(TINFO, "Testing variant: %s", tv->desc); - TEST_PAUSE; + bad_addr = tst_get_bad_addr(NULL); + tp.type = tv->type; /* Change scheduling policy to SCHED_RR */ - if ((sched_setscheduler(0, SCHED_RR, &p)) == -1) { - tst_brkm(TBROK, cleanup, "sched_setscheduler() failed"); - } + if ((sched_setscheduler(0, SCHED_RR, &p)) == -1) + tst_res(TFAIL | TTERRNO, "sched_setscheduler() failed"); - unused_pid = tst_get_unused_pid(cleanup); + unused_pid = tst_get_unused_pid(); } -/* - *cleanup() - performs all ONE TIME cleanup for this test at - * completion or premature exit. - */ -void cleanup(void) +static void run(unsigned int i) { + struct test_variants *tv = &variants[tst_variant]; + struct test_cases_t *tc = &test_cases[i]; + struct timerspec *ts; + if (tc->exp_errno == EFAULT) + ts = bad_addr; + else + ts = tst_ts_get(tc->tp); + + /* + * Call sched_rr_get_interval(2) + */ + TEST(tv->func(*tc->pid, ts)); + + if (TST_RET != -1) { + tst_res(TFAIL, "sched_rr_get_interval() passed unexcpectedly"); + return; + } + + if (tc->exp_errno == TST_ERR) + tst_res(TPASS | TTERRNO, "sched_rr_get_interval() failed as excpected"); + else + tst_res(TFAIL | TTERRNO, "sched_rr_get_interval() failed unexcpectedly: %s", + tst_strerrno(tc->exp_errno)); } + +static struct tst_test test = { + .test = run, + .tcnt = ARRAY_SIZE(test_cases), + .test_variants = ARRAY_SIZE(variants), + .setup = setup, + .needs_root = 1, +};