* [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD()
@ 2020-03-27 21:39 Petr Vorel
2020-03-27 21:39 ` [LTP] [PATCH 1/6] lib: Implement .needs_cmds Petr Vorel
` (6 more replies)
0 siblings, 7 replies; 30+ messages in thread
From: Petr Vorel @ 2020-03-27 21:39 UTC (permalink / raw)
To: ltp
Hi,
I implemented .needs_cmds + SAFE_RUN_CMD().
I also checked for command in path in tst_run_cmd_fds_() as suggested by
Cyril + added possibility to TCONF when program not found. This leaded
to more verbose changes. + There is a double check (first in
.needs_cmds, then in SAFE_RUN_CMD()), maybe that's not needed.
Also this change is not used in copy_file_range02.c, because it does not
require these commands. Is it worth to reduce code it'd be good to separate
file into two, put common functions in header and tests with
fd_immutable and fd_swapfile into new test?
Petr Vorel (6):
lib: Implement .needs_cmds
Use .needs_cmds
lib/tst_run_cmd_*(): Turn int pass_exit_val into enum
lib/tst_run_cmd_*(): Search for program in $PATH
lib: Implement SAFE_RUN_CMD() macro (new API only)
Use SAFE_RUN_CMD()
doc/test-writing-guidelines.txt | 29 +++++++++++---
include/tst_cmd.h | 39 +++++++++++--------
include/tst_safe_macros.h | 20 ++++++++++
include/tst_test.h | 3 ++
lib/tst_kernel.c | 3 +-
lib/tst_mkfs.c | 3 +-
lib/tst_module.c | 3 +-
lib/tst_run_cmd.c | 28 ++++++++-----
lib/tst_test.c | 11 ++++++
testcases/kernel/input/input_helper.c | 4 +-
testcases/kernel/syscalls/acct/acct02.c | 2 +-
testcases/kernel/syscalls/add_key/add_key05.c | 24 +++++-------
.../copy_file_range/copy_file_range02.c | 2 +-
.../kernel/syscalls/quotactl/quotactl01.c | 18 +++------
.../kernel/syscalls/quotactl/quotactl06.c | 16 +++-----
.../syscalls/setpriority/setpriority01.c | 5 ++-
testcases/network/netstress/netstress.c | 2 +-
17 files changed, 134 insertions(+), 78 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 30+ messages in thread* [LTP] [PATCH 1/6] lib: Implement .needs_cmds 2020-03-27 21:39 [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() Petr Vorel @ 2020-03-27 21:39 ` Petr Vorel 2020-03-30 6:13 ` Li Wang 2020-03-27 21:39 ` [LTP] [PATCH 2/6] Use .needs_cmds Petr Vorel ` (5 subsequent siblings) 6 siblings, 1 reply; 30+ messages in thread From: Petr Vorel @ 2020-03-27 21:39 UTC (permalink / raw) To: ltp Signed-off-by: Petr Vorel <pvorel@suse.cz> --- New commit. doc/test-writing-guidelines.txt | 15 +++++++++++++++ include/tst_test.h | 3 +++ lib/tst_test.c | 11 +++++++++++ 3 files changed, 29 insertions(+) diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt index 32c9e87df..f7206f1bf 100644 --- a/doc/test-writing-guidelines.txt +++ b/doc/test-writing-guidelines.txt @@ -2023,6 +2023,21 @@ struct tst_test test = { }; ------------------------------------------------------------------------------- +2.2.35 Checking for required binaries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Required binaries can be checked with '.needs_cmds', which points to a 'NULL' +terminated array of strings such as: + +[source,c] +------------------------------------------------------------------------------- +.needs_cmds = (const char *const []) { + "useradd", + "userdel", + NULL +}, +------------------------------------------------------------------------------- + 2.3 Writing a testcase in shell ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/include/tst_test.h b/include/tst_test.h index 84b6a940f..592097084 100644 --- a/include/tst_test.h +++ b/include/tst_test.h @@ -239,6 +239,9 @@ struct tst_test { * {NULL, NULL} terminated array of tags. */ const struct tst_tag *tags; + + /* NULL terminated array of required binaries */ + const char *const *needs_cmds; }; /* diff --git a/lib/tst_test.c b/lib/tst_test.c index 220d7fdfc..dae3fa1b5 100644 --- a/lib/tst_test.c +++ b/lib/tst_test.c @@ -3,6 +3,7 @@ * Copyright (c) 2015-2016 Cyril Hrubis <chrubis@suse.cz> */ +#include <limits.h> #include <stdio.h> #include <stdarg.h> #include <unistd.h> @@ -880,6 +881,16 @@ static void do_setup(int argc, char *argv[]) if (tst_test->min_kver) check_kver(); + if (tst_test->needs_cmds) { + const char *cmd; + char path[PATH_MAX]; + int i; + + for (i = 0; (cmd = tst_test->needs_cmds[i]); ++i) + if (tst_get_path(cmd, path, sizeof(path))) + tst_brk(TCONF, "Couldn't find '%s' in $PATH", cmd); + } + if (tst_test->needs_drivers) { const char *name; int i; -- 2.25.1 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* [LTP] [PATCH 1/6] lib: Implement .needs_cmds 2020-03-27 21:39 ` [LTP] [PATCH 1/6] lib: Implement .needs_cmds Petr Vorel @ 2020-03-30 6:13 ` Li Wang 2020-03-30 7:03 ` Petr Vorel 0 siblings, 1 reply; 30+ messages in thread From: Li Wang @ 2020-03-30 6:13 UTC (permalink / raw) To: ltp On Sat, Mar 28, 2020 at 5:39 AM Petr Vorel <pvorel@suse.cz> wrote: > Signed-off-by: Petr Vorel <pvorel@suse.cz> > --- > New commit. > > doc/test-writing-guidelines.txt | 15 +++++++++++++++ > include/tst_test.h | 3 +++ > lib/tst_test.c | 11 +++++++++++ > 3 files changed, 29 insertions(+) > > diff --git a/doc/test-writing-guidelines.txt > b/doc/test-writing-guidelines.txt > index 32c9e87df..f7206f1bf 100644 > --- a/doc/test-writing-guidelines.txt > +++ b/doc/test-writing-guidelines.txt > @@ -2023,6 +2023,21 @@ struct tst_test test = { > }; > > ------------------------------------------------------------------------------- > > +2.2.35 Checking for required binaries > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > Maybe better to talk commands but not binaries, since not all of the commands are binary, there is possible python, perl or shell executable file need check too. Isn't it? -- Regards, Li Wang -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.linux.it/pipermail/ltp/attachments/20200330/eb0ca710/attachment.htm> ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 1/6] lib: Implement .needs_cmds 2020-03-30 6:13 ` Li Wang @ 2020-03-30 7:03 ` Petr Vorel 2020-03-30 11:31 ` Cyril Hrubis 0 siblings, 1 reply; 30+ messages in thread From: Petr Vorel @ 2020-03-30 7:03 UTC (permalink / raw) To: ltp Hi Li, thanks for your review. > > +2.2.35 Checking for required binaries > > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > Maybe better to talk commands but not binaries, since not all of the > commands are binary, there is possible python, perl or shell executable > file need check too. Isn't it? +1 Kind regards, Petr ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 1/6] lib: Implement .needs_cmds 2020-03-30 7:03 ` Petr Vorel @ 2020-03-30 11:31 ` Cyril Hrubis 0 siblings, 0 replies; 30+ messages in thread From: Cyril Hrubis @ 2020-03-30 11:31 UTC (permalink / raw) To: ltp Hi! > > > +2.2.35 Checking for required binaries > > > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > > Maybe better to talk commands but not binaries, since not all of the > > commands are binary, there is possible python, perl or shell executable > > file need check too. Isn't it? > +1 Acked with this change. -- Cyril Hrubis chrubis@suse.cz ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 2/6] Use .needs_cmds 2020-03-27 21:39 [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() Petr Vorel 2020-03-27 21:39 ` [LTP] [PATCH 1/6] lib: Implement .needs_cmds Petr Vorel @ 2020-03-27 21:39 ` Petr Vorel 2020-03-30 11:31 ` Cyril Hrubis 2020-03-27 21:39 ` [LTP] [PATCH 3/6] lib/tst_run_cmd_*(): Turn int pass_exit_val into enum Petr Vorel ` (4 subsequent siblings) 6 siblings, 1 reply; 30+ messages in thread From: Petr Vorel @ 2020-03-27 21:39 UTC (permalink / raw) To: ltp Change for quotactl01: require also userdel Signed-off-by: Petr Vorel <pvorel@suse.cz> --- New commit. testcases/kernel/syscalls/add_key/add_key05.c | 8 +++++--- testcases/kernel/syscalls/quotactl/quotactl01.c | 7 ++++--- testcases/kernel/syscalls/quotactl/quotactl06.c | 7 ++++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/testcases/kernel/syscalls/add_key/add_key05.c b/testcases/kernel/syscalls/add_key/add_key05.c index a39bfa0b7..7443a4970 100644 --- a/testcases/kernel/syscalls/add_key/add_key05.c +++ b/testcases/kernel/syscalls/add_key/add_key05.c @@ -43,9 +43,6 @@ static void add_user(void) user_added = 1; ltpuser = SAFE_GETPWNAM(username); break; - case 255: - tst_brk(TCONF, "useradd not found"); - break; default: tst_brk(TBROK, "useradd failed (%d)", rc); } @@ -215,6 +212,11 @@ static struct tst_test test = { {&user_buf, .size = 64}, {} }, + .needs_cmds = (const char *const []) { + "useradd", + "userdel", + NULL + }, .tags = (const struct tst_tag[]) { {"linux-git", "a08bf91ce28"}, {"linux-git", "2e356101e72"}, diff --git a/testcases/kernel/syscalls/quotactl/quotactl01.c b/testcases/kernel/syscalls/quotactl/quotactl01.c index ede61d7e4..6cc1deeb8 100644 --- a/testcases/kernel/syscalls/quotactl/quotactl01.c +++ b/testcases/kernel/syscalls/quotactl/quotactl01.c @@ -168,9 +168,6 @@ static void setup(void) switch (ret) { case 0: break; - case 255: - tst_brk(TCONF, "quotacheck binary not installed"); - break; default: tst_brk(TBROK, "quotacheck exited with %i", ret); } @@ -234,5 +231,9 @@ static struct tst_test test = { .dev_fs_type = "ext4", .mntpoint = MNTPOINT, .mnt_data = "usrquota,grpquota", + .needs_cmds = (const char *const []) { + "quotacheck", + NULL + }, .setup = setup, }; diff --git a/testcases/kernel/syscalls/quotactl/quotactl06.c b/testcases/kernel/syscalls/quotactl/quotactl06.c index a3b4517e0..758bd84cd 100644 --- a/testcases/kernel/syscalls/quotactl/quotactl06.c +++ b/testcases/kernel/syscalls/quotactl/quotactl06.c @@ -153,9 +153,6 @@ static void setup(void) switch (ret) { case 0: break; - case 255: - tst_brk(TCONF, "quotacheck binary not installed"); - break; default: tst_brk(TBROK, "quotacheck exited with %i", ret); } @@ -192,5 +189,9 @@ static struct tst_test test = { .mntpoint = MNTPOINT, .mount_device = 1, .mnt_data = "usrquota", + .needs_cmds = (const char *const []) { + "quotacheck", + NULL + }, .needs_root = 1, }; -- 2.25.1 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* [LTP] [PATCH 2/6] Use .needs_cmds 2020-03-27 21:39 ` [LTP] [PATCH 2/6] Use .needs_cmds Petr Vorel @ 2020-03-30 11:31 ` Cyril Hrubis 2020-03-30 11:48 ` Petr Vorel 0 siblings, 1 reply; 30+ messages in thread From: Cyril Hrubis @ 2020-03-30 11:31 UTC (permalink / raw) To: ltp Hi! Looks good, acked. -- Cyril Hrubis chrubis@suse.cz ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 2/6] Use .needs_cmds 2020-03-30 11:31 ` Cyril Hrubis @ 2020-03-30 11:48 ` Petr Vorel 2020-03-30 11:57 ` Li Wang 0 siblings, 1 reply; 30+ messages in thread From: Petr Vorel @ 2020-03-30 11:48 UTC (permalink / raw) To: ltp Hi, > Hi! > Looks good, acked. thanks a lot for review. Merged these two patches. Kind regards, Petr ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 2/6] Use .needs_cmds 2020-03-30 11:48 ` Petr Vorel @ 2020-03-30 11:57 ` Li Wang 2020-03-30 12:17 ` Petr Vorel 2020-03-30 12:37 ` Petr Vorel 0 siblings, 2 replies; 30+ messages in thread From: Li Wang @ 2020-03-30 11:57 UTC (permalink / raw) To: ltp On Mon, Mar 30, 2020 at 7:48 PM Petr Vorel <pvorel@suse.cz> wrote: > Hi, > > > Hi! > > Looks good, acked. > thanks a lot for review. > > Merged these two patches. > Thanks Petr, there is still a tiny place need fix. Hope you can help to correct the description in the next round patch merging. + /* NULL terminated array of required binaries */ + const char *const *needs_cmds; -- Regards, Li Wang -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.linux.it/pipermail/ltp/attachments/20200330/1489ca88/attachment.htm> ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 2/6] Use .needs_cmds 2020-03-30 11:57 ` Li Wang @ 2020-03-30 12:17 ` Petr Vorel 2020-03-30 12:37 ` Petr Vorel 1 sibling, 0 replies; 30+ messages in thread From: Petr Vorel @ 2020-03-30 12:17 UTC (permalink / raw) To: ltp Hi Li, > > > Hi! > > > Looks good, acked. > > thanks a lot for review. > > Merged these two patches. > Thanks Petr, there is still a tiny place need fix. > Hope you can help to correct the description in the next round patch > merging. Sure, thanks for catching it! > + /* NULL terminated array of required binaries */ > + const char *const *needs_cmds; Kind regards, Petr ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 2/6] Use .needs_cmds 2020-03-30 11:57 ` Li Wang 2020-03-30 12:17 ` Petr Vorel @ 2020-03-30 12:37 ` Petr Vorel 1 sibling, 0 replies; 30+ messages in thread From: Petr Vorel @ 2020-03-30 12:37 UTC (permalink / raw) To: ltp Hi Li, > Thanks Petr, there is still a tiny place need fix. > Hope you can help to correct the description in the next round patch > merging. You were right, I pushed this before. I'm sorry, fixed now. > + /* NULL terminated array of required binaries */ > + const char *const *needs_cmds; Kind regards, Petr ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 3/6] lib/tst_run_cmd_*(): Turn int pass_exit_val into enum 2020-03-27 21:39 [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() Petr Vorel 2020-03-27 21:39 ` [LTP] [PATCH 1/6] lib: Implement .needs_cmds Petr Vorel 2020-03-27 21:39 ` [LTP] [PATCH 2/6] Use .needs_cmds Petr Vorel @ 2020-03-27 21:39 ` Petr Vorel 2020-03-30 11:38 ` Cyril Hrubis 2020-03-27 21:39 ` [LTP] [PATCH 4/6] lib/tst_run_cmd_*(): Search for program in $PATH Petr Vorel ` (3 subsequent siblings) 6 siblings, 1 reply; 30+ messages in thread From: Petr Vorel @ 2020-03-27 21:39 UTC (permalink / raw) To: ltp This is a preparation for next commit. Now uses the only flag TST_RUN_CMD_PASS_EXIT_VAL. Signed-off-by: Petr Vorel <pvorel@suse.cz> --- New commit. doc/test-writing-guidelines.txt | 10 +++--- include/tst_cmd.h | 36 ++++++++++--------- lib/tst_kernel.c | 3 +- lib/tst_mkfs.c | 3 +- lib/tst_module.c | 3 +- lib/tst_run_cmd.c | 12 +++---- testcases/kernel/input/input_helper.c | 4 +-- testcases/kernel/syscalls/acct/acct02.c | 2 +- testcases/kernel/syscalls/add_key/add_key05.c | 5 +-- .../copy_file_range/copy_file_range02.c | 2 +- .../kernel/syscalls/quotactl/quotactl01.c | 2 +- .../kernel/syscalls/quotactl/quotactl06.c | 2 +- .../syscalls/setpriority/setpriority01.c | 5 +-- testcases/network/netstress/netstress.c | 2 +- 14 files changed, 50 insertions(+), 41 deletions(-) diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt index f7206f1bf..31897309d 100644 --- a/doc/test-writing-guidelines.txt +++ b/doc/test-writing-guidelines.txt @@ -1263,18 +1263,18 @@ different once the call returns and should be used only for rough estimates. int tst_run_cmd(const char *const argv[], const char *stdout_path, const char *stderr_path, - int pass_exit_val); + enum tst_run_cmd_flags flags); ------------------------------------------------------------------------------- -'tst_run_cmd' is a wrapper for 'vfork() + execvp()' which provides a way +'tst_run_cmd()' is a wrapper for 'vfork() + execvp()' which provides a way to execute an external program. 'argv[]' is a 'NULL' terminated array of strings starting with the program name which is followed by optional arguments. -A non-zero 'pass_exit_val' makes 'tst_run_cmd' return the program exit code to -the caller. A zero for 'pass_exit_val' makes 'tst_run_cmd' exit the tests -on failure. +'TST_RUN_CMD_PASS_EXIT_VAL' enum 'tst_run_cmd_flags' makes 'tst_run_cmd()' +return the program exit code to the caller, otherwise 'tst_run_cmd()' exit the +tests on failure. In case that 'execvp()' has failed and the 'pass_exit_val' flag was set, the return value is '255' if 'execvp()' failed with 'ENOENT' and '254' otherwise. diff --git a/include/tst_cmd.h b/include/tst_cmd.h index d0a3573f4..67dec32f2 100644 --- a/include/tst_cmd.h +++ b/include/tst_cmd.h @@ -5,6 +5,14 @@ #ifndef TST_CMD_H__ #define TST_CMD_H__ +enum tst_run_cmd_flags { + /* + * return the program exit code, otherwise it will call cleanup_fn() if the + * program exit code is not zero. + */ + TST_RUN_CMD_PASS_EXIT_VAL = 1, +}; + /* * vfork() + execvp() specified program. * @argv: a list of two (at least program name + NULL) or more pointers that @@ -14,68 +22,64 @@ * redirection is not needed. * @stderr_fd: file descriptor where to redirect stderr. Set -1 if * redirection is not needed. - * @pass_exit_val: if it's non-zero, this function will return the program - * exit code, otherwise it will call cleanup_fn() if the program - * exit code is not zero. + * @flags: enum tst_run_cmd_flags */ int tst_run_cmd_fds_(void (cleanup_fn)(void), const char *const argv[], int stdout_fd, int stderr_fd, - int pass_exit_val); + enum tst_run_cmd_flags flags); /* Executes tst_run_cmd_fds() and redirects its output to a file * @stdout_path: path where to redirect stdout. Set NULL if redirection is * not needed. * @stderr_path: path where to redirect stderr. Set NULL if redirection is * not needed. - * @pass_exit_val: if it's non-zero, this function will return the program - * exit code, otherwise it will call cleanup_fn() if the program - * exit code is not zero. + * @flags: enum tst_run_cmd_flags */ int tst_run_cmd_(void (cleanup_fn)(void), const char *const argv[], const char *stdout_path, const char *stderr_path, - int pass_exit_val); + enum tst_run_cmd_flags flags); #ifdef TST_TEST_H__ static inline int tst_run_cmd_fds(const char *const argv[], int stdout_fd, int stderr_fd, - int pass_exit_val) + enum tst_run_cmd_flags flags) { return tst_run_cmd_fds_(NULL, argv, - stdout_fd, stderr_fd, pass_exit_val); + stdout_fd, stderr_fd, flags); } static inline int tst_run_cmd(const char *const argv[], const char *stdout_path, const char *stderr_path, - int pass_exit_val) + enum tst_run_cmd_flags flags) { return tst_run_cmd_(NULL, argv, - stdout_path, stderr_path, pass_exit_val); + stdout_path, stderr_path, flags); } #else static inline int tst_run_cmd_fds(void (cleanup_fn)(void), const char *const argv[], int stdout_fd, int stderr_fd, - int pass_exit_val) + enum tst_run_cmd_flags flags) { return tst_run_cmd_fds_(cleanup_fn, argv, - stdout_fd, stderr_fd, pass_exit_val); + stdout_fd, stderr_fd, flags); } static inline int tst_run_cmd(void (cleanup_fn)(void), const char *const argv[], const char *stdout_path, const char *stderr_path, - int pass_exit_val) + enum tst_run_cmd_flags flags) { return tst_run_cmd_(cleanup_fn, argv, - stdout_path, stderr_path, pass_exit_val); + stdout_path, stderr_path, flags); } #endif diff --git a/lib/tst_kernel.c b/lib/tst_kernel.c index 73ab9f1b1..3ef7c21b8 100644 --- a/lib/tst_kernel.c +++ b/lib/tst_kernel.c @@ -85,7 +85,8 @@ int tst_check_driver(const char *name) { #ifndef __ANDROID__ const char * const argv[] = { "modprobe", "-n", name, NULL }; - int res = tst_run_cmd_(NULL, argv, "/dev/null", "/dev/null", 1); + int res = tst_run_cmd_(NULL, argv, "/dev/null", "/dev/null", + TST_RUN_CMD_PASS_EXIT_VAL); /* 255 - it looks like modprobe not available */ return (res == 255) ? 0 : res; diff --git a/lib/tst_mkfs.c b/lib/tst_mkfs.c index 5d208eceb..0c347e1e2 100644 --- a/lib/tst_mkfs.c +++ b/lib/tst_mkfs.c @@ -88,7 +88,8 @@ void tst_mkfs_(const char *file, const int lineno, void (cleanup_fn)(void), tst_resm(TINFO, "Formatting %s with %s opts='%s' extra opts='%s'", dev, fs_type, fs_opts_str, extra_opts_str); - ret = tst_run_cmd(cleanup_fn, argv, "/dev/null", NULL, 1); + ret = tst_run_cmd(cleanup_fn, argv, "/dev/null", NULL, + TST_RUN_CMD_PASS_EXIT_VAL); switch (ret) { case 0: diff --git a/lib/tst_module.c b/lib/tst_module.c index ed39952ee..9344b59d6 100644 --- a/lib/tst_module.c +++ b/lib/tst_module.c @@ -109,7 +109,8 @@ void tst_module_unload(void (cleanup_fn)(void), const char *mod_name) rc = 1; for (i = 0; i < 50; i++) { - rc = tst_run_cmd(NULL, argv, "/dev/null", "/dev/null", 1); + rc = tst_run_cmd(NULL, argv, "/dev/null", "/dev/null", + TST_RUN_CMD_PASS_EXIT_VAL); if (!rc) break; diff --git a/lib/tst_run_cmd.c b/lib/tst_run_cmd.c index 8e4bf6ba3..3536ec494 100644 --- a/lib/tst_run_cmd.c +++ b/lib/tst_run_cmd.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. + * Copyright (c) 2020 Petr Vorel <pvorel@suse.cz> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -16,7 +17,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Author: Alexey Kodanev <alexey.kodanev@oracle.com> - * */ #include <errno.h> @@ -27,6 +27,7 @@ #include <unistd.h> #include <signal.h> #include "test.h" +#include "tst_cmd.h" #define OPEN_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) #define OPEN_FLAGS (O_WRONLY | O_APPEND | O_CREAT) @@ -35,7 +36,7 @@ int tst_run_cmd_fds_(void (cleanup_fn)(void), const char *const argv[], int stdout_fd, int stderr_fd, - int pass_exit_val) + enum tst_run_cmd_flags flags) { int rc; @@ -97,7 +98,7 @@ int tst_run_cmd_fds_(void (cleanup_fn)(void), rc = WEXITSTATUS(ret); - if ((!pass_exit_val) && rc) { + if (!(flags & TST_RUN_CMD_PASS_EXIT_VAL) && rc) { tst_brkm(TBROK, cleanup_fn, "'%s' exited with a non-zero code %d at %s:%d", argv[0], rc, __FILE__, __LINE__); @@ -111,7 +112,7 @@ int tst_run_cmd_(void (cleanup_fn)(void), const char *const argv[], const char *stdout_path, const char *stderr_path, - int pass_exit_val) + enum tst_run_cmd_flags flags) { int stdout_fd = -1; int stderr_fd = -1; @@ -137,8 +138,7 @@ int tst_run_cmd_(void (cleanup_fn)(void), stderr_path, __FILE__, __LINE__); } - rc = tst_run_cmd_fds(cleanup_fn, argv, stdout_fd, stderr_fd, - pass_exit_val); + rc = tst_run_cmd_fds(cleanup_fn, argv, stdout_fd, stderr_fd, flags); if ((stdout_fd != -1) && (close(stdout_fd) == -1)) tst_resm(TWARN | TERRNO, diff --git a/testcases/kernel/input/input_helper.c b/testcases/kernel/input/input_helper.c index f6ae9c9b6..41c042aaf 100644 --- a/testcases/kernel/input/input_helper.c +++ b/testcases/kernel/input/input_helper.c @@ -92,7 +92,7 @@ static int try_load_uinput(void) tst_resm(TINFO, "Trying to load uinput kernel module"); - ret = tst_run_cmd(NULL, argv, NULL, NULL, 1); + ret = tst_run_cmd(NULL, argv, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL); if (ret) { tst_resm(TINFO, "Failed to load the uinput module"); return 0; @@ -108,7 +108,7 @@ static void unload_uinput(void) tst_resm(TINFO, "Unloading uinput kernel module"); - ret = tst_run_cmd(NULL, argv, NULL, NULL, 1); + ret = tst_run_cmd(NULL, argv, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL); if (ret) tst_resm(TWARN, "Failed to unload uinput module"); } diff --git a/testcases/kernel/syscalls/acct/acct02.c b/testcases/kernel/syscalls/acct/acct02.c index 2f1290fa2..801c7908d 100644 --- a/testcases/kernel/syscalls/acct/acct02.c +++ b/testcases/kernel/syscalls/acct/acct02.c @@ -67,7 +67,7 @@ static void run_command(void) { const char *const cmd[] = {COMMAND, NULL}; - rc = tst_run_cmd(cmd, NULL, NULL, 1) << 8; + rc = tst_run_cmd(cmd, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL) << 8; } static int verify_acct(void *acc, int elap_time) diff --git a/testcases/kernel/syscalls/add_key/add_key05.c b/testcases/kernel/syscalls/add_key/add_key05.c index 7443a4970..3da3be9ee 100644 --- a/testcases/kernel/syscalls/add_key/add_key05.c +++ b/testcases/kernel/syscalls/add_key/add_key05.c @@ -38,7 +38,8 @@ static void add_user(void) const char *const cmd_useradd[] = {"useradd", username, NULL}; int rc; - switch ((rc = tst_run_cmd(cmd_useradd, NULL, NULL, 1))) { + switch ((rc = tst_run_cmd(cmd_useradd, NULL, NULL, + TST_RUN_CMD_PASS_EXIT_VAL))) { case 0: user_added = 1; ltpuser = SAFE_GETPWNAM(username); @@ -56,7 +57,7 @@ static void clean_user(void) const char *const cmd_userdel[] = {"userdel", "-r", username, NULL}; - if (tst_run_cmd(cmd_userdel, NULL, NULL, 1)) + if (tst_run_cmd(cmd_userdel, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL)) tst_res(TWARN | TERRNO, "'userdel -r %s' failed", username); else user_added = 0; diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c index c09766fe6..f47479f16 100644 --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c @@ -87,7 +87,7 @@ static int run_command(char *command, char *option, char *file) const char *const cmd[] = {command, option, file, NULL}; int ret; - ret = tst_run_cmd(cmd, NULL, NULL, 1); + ret = tst_run_cmd(cmd, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL); switch (ret) { case 0: return 0; diff --git a/testcases/kernel/syscalls/quotactl/quotactl01.c b/testcases/kernel/syscalls/quotactl/quotactl01.c index 6cc1deeb8..e4c2a8939 100644 --- a/testcases/kernel/syscalls/quotactl/quotactl01.c +++ b/testcases/kernel/syscalls/quotactl/quotactl01.c @@ -164,7 +164,7 @@ static void setup(void) const char *const cmd[] = {"quotacheck", "-ugF", "vfsv0", MNTPOINT, NULL}; int ret; - ret = tst_run_cmd(cmd, NULL, NULL, 1); + ret = tst_run_cmd(cmd, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL); switch (ret) { case 0: break; diff --git a/testcases/kernel/syscalls/quotactl/quotactl06.c b/testcases/kernel/syscalls/quotactl/quotactl06.c index 758bd84cd..5d70f340f 100644 --- a/testcases/kernel/syscalls/quotactl/quotactl06.c +++ b/testcases/kernel/syscalls/quotactl/quotactl06.c @@ -149,7 +149,7 @@ static void setup(void) int ret; unsigned int i; - ret = tst_run_cmd(cmd, NULL, NULL, 1); + ret = tst_run_cmd(cmd, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL); switch (ret) { case 0: break; diff --git a/testcases/kernel/syscalls/setpriority/setpriority01.c b/testcases/kernel/syscalls/setpriority/setpriority01.c index ffd7499c4..0c6689fd5 100644 --- a/testcases/kernel/syscalls/setpriority/setpriority01.c +++ b/testcases/kernel/syscalls/setpriority/setpriority01.c @@ -112,7 +112,8 @@ static void setup(void) struct passwd *ltpuser; int rc; - switch ((rc = tst_run_cmd(cmd_useradd, NULL, NULL, 1))) { + switch ((rc = tst_run_cmd(cmd_useradd, NULL, NULL, + TST_RUN_CMD_PASS_EXIT_VAL))) { case 0: user_added = 1; ltpuser = SAFE_GETPWNAM(username); @@ -133,7 +134,7 @@ static void cleanup(void) const char *const cmd_userdel[] = {"userdel", "-r", username, NULL}; - if (tst_run_cmd(cmd_userdel, NULL, NULL, 1)) + if (tst_run_cmd(cmd_userdel, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL)) tst_res(TWARN | TERRNO, "'userdel -r %s' failed", username); } diff --git a/testcases/network/netstress/netstress.c b/testcases/network/netstress/netstress.c index 76d2fdb04..8d85ad085 100644 --- a/testcases/network/netstress/netstress.c +++ b/testcases/network/netstress/netstress.c @@ -967,7 +967,7 @@ static void setup(void) /* dccp* modules can be blacklisted, load them manually */ const char * const argv[] = {"modprobe", "dccp_ipv6", NULL}; - if (tst_run_cmd(argv, NULL, NULL, 1)) + if (tst_run_cmd(argv, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL)) tst_brk(TCONF, "Failed to load dccp_ipv6 module"); tst_res(TINFO, "DCCP %s", (client_mode) ? "client" : "server"); -- 2.25.1 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* [LTP] [PATCH 3/6] lib/tst_run_cmd_*(): Turn int pass_exit_val into enum 2020-03-27 21:39 ` [LTP] [PATCH 3/6] lib/tst_run_cmd_*(): Turn int pass_exit_val into enum Petr Vorel @ 2020-03-30 11:38 ` Cyril Hrubis 2020-03-30 11:40 ` Petr Vorel 0 siblings, 1 reply; 30+ messages in thread From: Cyril Hrubis @ 2020-03-30 11:38 UTC (permalink / raw) To: ltp Hi! > This is a preparation for next commit. > Now uses the only flag TST_RUN_CMD_PASS_EXIT_VAL. That is quite long name, I wonder if we can shorten it. Maybe we can rename the whole tst_run_cmd() just to tst_cmd() and change this flag to TST_CMD_PASS_RETVAL. Other that this the patchset looks good. > Signed-off-by: Petr Vorel <pvorel@suse.cz> > --- > New commit. > > doc/test-writing-guidelines.txt | 10 +++--- > include/tst_cmd.h | 36 ++++++++++--------- > lib/tst_kernel.c | 3 +- > lib/tst_mkfs.c | 3 +- > lib/tst_module.c | 3 +- > lib/tst_run_cmd.c | 12 +++---- > testcases/kernel/input/input_helper.c | 4 +-- > testcases/kernel/syscalls/acct/acct02.c | 2 +- > testcases/kernel/syscalls/add_key/add_key05.c | 5 +-- > .../copy_file_range/copy_file_range02.c | 2 +- > .../kernel/syscalls/quotactl/quotactl01.c | 2 +- > .../kernel/syscalls/quotactl/quotactl06.c | 2 +- > .../syscalls/setpriority/setpriority01.c | 5 +-- > testcases/network/netstress/netstress.c | 2 +- > 14 files changed, 50 insertions(+), 41 deletions(-) > > diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt > index f7206f1bf..31897309d 100644 > --- a/doc/test-writing-guidelines.txt > +++ b/doc/test-writing-guidelines.txt > @@ -1263,18 +1263,18 @@ different once the call returns and should be used only for rough estimates. > int tst_run_cmd(const char *const argv[], > const char *stdout_path, > const char *stderr_path, > - int pass_exit_val); > + enum tst_run_cmd_flags flags); > ------------------------------------------------------------------------------- > > -'tst_run_cmd' is a wrapper for 'vfork() + execvp()' which provides a way > +'tst_run_cmd()' is a wrapper for 'vfork() + execvp()' which provides a way > to execute an external program. > > 'argv[]' is a 'NULL' terminated array of strings starting with the program name > which is followed by optional arguments. > > -A non-zero 'pass_exit_val' makes 'tst_run_cmd' return the program exit code to > -the caller. A zero for 'pass_exit_val' makes 'tst_run_cmd' exit the tests > -on failure. > +'TST_RUN_CMD_PASS_EXIT_VAL' enum 'tst_run_cmd_flags' makes 'tst_run_cmd()' > +return the program exit code to the caller, otherwise 'tst_run_cmd()' exit the > +tests on failure. > > In case that 'execvp()' has failed and the 'pass_exit_val' flag was set, the > return value is '255' if 'execvp()' failed with 'ENOENT' and '254' otherwise. > diff --git a/include/tst_cmd.h b/include/tst_cmd.h > index d0a3573f4..67dec32f2 100644 > --- a/include/tst_cmd.h > +++ b/include/tst_cmd.h > @@ -5,6 +5,14 @@ > #ifndef TST_CMD_H__ > #define TST_CMD_H__ > > +enum tst_run_cmd_flags { > + /* > + * return the program exit code, otherwise it will call cleanup_fn() if the > + * program exit code is not zero. > + */ > + TST_RUN_CMD_PASS_EXIT_VAL = 1, > +}; > + > /* > * vfork() + execvp() specified program. > * @argv: a list of two (at least program name + NULL) or more pointers that > @@ -14,68 +22,64 @@ > * redirection is not needed. > * @stderr_fd: file descriptor where to redirect stderr. Set -1 if > * redirection is not needed. > - * @pass_exit_val: if it's non-zero, this function will return the program > - * exit code, otherwise it will call cleanup_fn() if the program > - * exit code is not zero. > + * @flags: enum tst_run_cmd_flags > */ > int tst_run_cmd_fds_(void (cleanup_fn)(void), > const char *const argv[], > int stdout_fd, > int stderr_fd, > - int pass_exit_val); > + enum tst_run_cmd_flags flags); > > /* Executes tst_run_cmd_fds() and redirects its output to a file > * @stdout_path: path where to redirect stdout. Set NULL if redirection is > * not needed. > * @stderr_path: path where to redirect stderr. Set NULL if redirection is > * not needed. > - * @pass_exit_val: if it's non-zero, this function will return the program > - * exit code, otherwise it will call cleanup_fn() if the program > - * exit code is not zero. > + * @flags: enum tst_run_cmd_flags > */ > int tst_run_cmd_(void (cleanup_fn)(void), > const char *const argv[], > const char *stdout_path, > const char *stderr_path, > - int pass_exit_val); > + enum tst_run_cmd_flags flags); > > #ifdef TST_TEST_H__ > static inline int tst_run_cmd_fds(const char *const argv[], > int stdout_fd, > int stderr_fd, > - int pass_exit_val) > + enum tst_run_cmd_flags flags) > { > return tst_run_cmd_fds_(NULL, argv, > - stdout_fd, stderr_fd, pass_exit_val); > + stdout_fd, stderr_fd, flags); > } > > static inline int tst_run_cmd(const char *const argv[], > const char *stdout_path, > const char *stderr_path, > - int pass_exit_val) > + enum tst_run_cmd_flags flags) > { > return tst_run_cmd_(NULL, argv, > - stdout_path, stderr_path, pass_exit_val); > + stdout_path, stderr_path, flags); > } > #else > static inline int tst_run_cmd_fds(void (cleanup_fn)(void), > const char *const argv[], > int stdout_fd, > int stderr_fd, > - int pass_exit_val) > + enum tst_run_cmd_flags flags) > { > return tst_run_cmd_fds_(cleanup_fn, argv, > - stdout_fd, stderr_fd, pass_exit_val); > + stdout_fd, stderr_fd, flags); > } > > static inline int tst_run_cmd(void (cleanup_fn)(void), > const char *const argv[], > const char *stdout_path, > const char *stderr_path, > - int pass_exit_val) > + enum tst_run_cmd_flags flags) > { > return tst_run_cmd_(cleanup_fn, argv, > - stdout_path, stderr_path, pass_exit_val); > + stdout_path, stderr_path, flags); > } > #endif > > diff --git a/lib/tst_kernel.c b/lib/tst_kernel.c > index 73ab9f1b1..3ef7c21b8 100644 > --- a/lib/tst_kernel.c > +++ b/lib/tst_kernel.c > @@ -85,7 +85,8 @@ int tst_check_driver(const char *name) > { > #ifndef __ANDROID__ > const char * const argv[] = { "modprobe", "-n", name, NULL }; > - int res = tst_run_cmd_(NULL, argv, "/dev/null", "/dev/null", 1); > + int res = tst_run_cmd_(NULL, argv, "/dev/null", "/dev/null", > + TST_RUN_CMD_PASS_EXIT_VAL); > > /* 255 - it looks like modprobe not available */ > return (res == 255) ? 0 : res; > diff --git a/lib/tst_mkfs.c b/lib/tst_mkfs.c > index 5d208eceb..0c347e1e2 100644 > --- a/lib/tst_mkfs.c > +++ b/lib/tst_mkfs.c > @@ -88,7 +88,8 @@ void tst_mkfs_(const char *file, const int lineno, void (cleanup_fn)(void), > > tst_resm(TINFO, "Formatting %s with %s opts='%s' extra opts='%s'", > dev, fs_type, fs_opts_str, extra_opts_str); > - ret = tst_run_cmd(cleanup_fn, argv, "/dev/null", NULL, 1); > + ret = tst_run_cmd(cleanup_fn, argv, "/dev/null", NULL, > + TST_RUN_CMD_PASS_EXIT_VAL); > > switch (ret) { > case 0: > diff --git a/lib/tst_module.c b/lib/tst_module.c > index ed39952ee..9344b59d6 100644 > --- a/lib/tst_module.c > +++ b/lib/tst_module.c > @@ -109,7 +109,8 @@ void tst_module_unload(void (cleanup_fn)(void), const char *mod_name) > > rc = 1; > for (i = 0; i < 50; i++) { > - rc = tst_run_cmd(NULL, argv, "/dev/null", "/dev/null", 1); > + rc = tst_run_cmd(NULL, argv, "/dev/null", "/dev/null", > + TST_RUN_CMD_PASS_EXIT_VAL); > if (!rc) > break; > > diff --git a/lib/tst_run_cmd.c b/lib/tst_run_cmd.c > index 8e4bf6ba3..3536ec494 100644 > --- a/lib/tst_run_cmd.c > +++ b/lib/tst_run_cmd.c > @@ -1,5 +1,6 @@ > /* > * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. > + * Copyright (c) 2020 Petr Vorel <pvorel@suse.cz> > * > * This program is free software; you can redistribute it and/or > * modify it under the terms of the GNU General Public License as > @@ -16,7 +17,6 @@ > * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > * > * Author: Alexey Kodanev <alexey.kodanev@oracle.com> > - * > */ > > #include <errno.h> > @@ -27,6 +27,7 @@ > #include <unistd.h> > #include <signal.h> > #include "test.h" > +#include "tst_cmd.h" > > #define OPEN_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) > #define OPEN_FLAGS (O_WRONLY | O_APPEND | O_CREAT) > @@ -35,7 +36,7 @@ int tst_run_cmd_fds_(void (cleanup_fn)(void), > const char *const argv[], > int stdout_fd, > int stderr_fd, > - int pass_exit_val) > + enum tst_run_cmd_flags flags) > { > int rc; > > @@ -97,7 +98,7 @@ int tst_run_cmd_fds_(void (cleanup_fn)(void), > > rc = WEXITSTATUS(ret); > > - if ((!pass_exit_val) && rc) { > + if (!(flags & TST_RUN_CMD_PASS_EXIT_VAL) && rc) { > tst_brkm(TBROK, cleanup_fn, > "'%s' exited with a non-zero code %d at %s:%d", > argv[0], rc, __FILE__, __LINE__); > @@ -111,7 +112,7 @@ int tst_run_cmd_(void (cleanup_fn)(void), > const char *const argv[], > const char *stdout_path, > const char *stderr_path, > - int pass_exit_val) > + enum tst_run_cmd_flags flags) > { > int stdout_fd = -1; > int stderr_fd = -1; > @@ -137,8 +138,7 @@ int tst_run_cmd_(void (cleanup_fn)(void), > stderr_path, __FILE__, __LINE__); > } > > - rc = tst_run_cmd_fds(cleanup_fn, argv, stdout_fd, stderr_fd, > - pass_exit_val); > + rc = tst_run_cmd_fds(cleanup_fn, argv, stdout_fd, stderr_fd, flags); > > if ((stdout_fd != -1) && (close(stdout_fd) == -1)) > tst_resm(TWARN | TERRNO, > diff --git a/testcases/kernel/input/input_helper.c b/testcases/kernel/input/input_helper.c > index f6ae9c9b6..41c042aaf 100644 > --- a/testcases/kernel/input/input_helper.c > +++ b/testcases/kernel/input/input_helper.c > @@ -92,7 +92,7 @@ static int try_load_uinput(void) > > tst_resm(TINFO, "Trying to load uinput kernel module"); > > - ret = tst_run_cmd(NULL, argv, NULL, NULL, 1); > + ret = tst_run_cmd(NULL, argv, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL); > if (ret) { > tst_resm(TINFO, "Failed to load the uinput module"); > return 0; > @@ -108,7 +108,7 @@ static void unload_uinput(void) > > tst_resm(TINFO, "Unloading uinput kernel module"); > > - ret = tst_run_cmd(NULL, argv, NULL, NULL, 1); > + ret = tst_run_cmd(NULL, argv, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL); > if (ret) > tst_resm(TWARN, "Failed to unload uinput module"); > } > diff --git a/testcases/kernel/syscalls/acct/acct02.c b/testcases/kernel/syscalls/acct/acct02.c > index 2f1290fa2..801c7908d 100644 > --- a/testcases/kernel/syscalls/acct/acct02.c > +++ b/testcases/kernel/syscalls/acct/acct02.c > @@ -67,7 +67,7 @@ static void run_command(void) > { > const char *const cmd[] = {COMMAND, NULL}; > > - rc = tst_run_cmd(cmd, NULL, NULL, 1) << 8; > + rc = tst_run_cmd(cmd, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL) << 8; > } > > static int verify_acct(void *acc, int elap_time) > diff --git a/testcases/kernel/syscalls/add_key/add_key05.c b/testcases/kernel/syscalls/add_key/add_key05.c > index 7443a4970..3da3be9ee 100644 > --- a/testcases/kernel/syscalls/add_key/add_key05.c > +++ b/testcases/kernel/syscalls/add_key/add_key05.c > @@ -38,7 +38,8 @@ static void add_user(void) > const char *const cmd_useradd[] = {"useradd", username, NULL}; > int rc; > > - switch ((rc = tst_run_cmd(cmd_useradd, NULL, NULL, 1))) { > + switch ((rc = tst_run_cmd(cmd_useradd, NULL, NULL, > + TST_RUN_CMD_PASS_EXIT_VAL))) { > case 0: > user_added = 1; > ltpuser = SAFE_GETPWNAM(username); > @@ -56,7 +57,7 @@ static void clean_user(void) > > const char *const cmd_userdel[] = {"userdel", "-r", username, NULL}; > > - if (tst_run_cmd(cmd_userdel, NULL, NULL, 1)) > + if (tst_run_cmd(cmd_userdel, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL)) > tst_res(TWARN | TERRNO, "'userdel -r %s' failed", username); > else > user_added = 0; > diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c > index c09766fe6..f47479f16 100644 > --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c > +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c > @@ -87,7 +87,7 @@ static int run_command(char *command, char *option, char *file) > const char *const cmd[] = {command, option, file, NULL}; > int ret; > > - ret = tst_run_cmd(cmd, NULL, NULL, 1); > + ret = tst_run_cmd(cmd, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL); > switch (ret) { > case 0: > return 0; > diff --git a/testcases/kernel/syscalls/quotactl/quotactl01.c b/testcases/kernel/syscalls/quotactl/quotactl01.c > index 6cc1deeb8..e4c2a8939 100644 > --- a/testcases/kernel/syscalls/quotactl/quotactl01.c > +++ b/testcases/kernel/syscalls/quotactl/quotactl01.c > @@ -164,7 +164,7 @@ static void setup(void) > const char *const cmd[] = {"quotacheck", "-ugF", "vfsv0", MNTPOINT, NULL}; > int ret; > > - ret = tst_run_cmd(cmd, NULL, NULL, 1); > + ret = tst_run_cmd(cmd, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL); > switch (ret) { > case 0: > break; > diff --git a/testcases/kernel/syscalls/quotactl/quotactl06.c b/testcases/kernel/syscalls/quotactl/quotactl06.c > index 758bd84cd..5d70f340f 100644 > --- a/testcases/kernel/syscalls/quotactl/quotactl06.c > +++ b/testcases/kernel/syscalls/quotactl/quotactl06.c > @@ -149,7 +149,7 @@ static void setup(void) > int ret; > unsigned int i; > > - ret = tst_run_cmd(cmd, NULL, NULL, 1); > + ret = tst_run_cmd(cmd, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL); > switch (ret) { > case 0: > break; > diff --git a/testcases/kernel/syscalls/setpriority/setpriority01.c b/testcases/kernel/syscalls/setpriority/setpriority01.c > index ffd7499c4..0c6689fd5 100644 > --- a/testcases/kernel/syscalls/setpriority/setpriority01.c > +++ b/testcases/kernel/syscalls/setpriority/setpriority01.c > @@ -112,7 +112,8 @@ static void setup(void) > struct passwd *ltpuser; > int rc; > > - switch ((rc = tst_run_cmd(cmd_useradd, NULL, NULL, 1))) { > + switch ((rc = tst_run_cmd(cmd_useradd, NULL, NULL, > + TST_RUN_CMD_PASS_EXIT_VAL))) { > case 0: > user_added = 1; > ltpuser = SAFE_GETPWNAM(username); > @@ -133,7 +134,7 @@ static void cleanup(void) > > const char *const cmd_userdel[] = {"userdel", "-r", username, NULL}; > > - if (tst_run_cmd(cmd_userdel, NULL, NULL, 1)) > + if (tst_run_cmd(cmd_userdel, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL)) > tst_res(TWARN | TERRNO, "'userdel -r %s' failed", username); > } > > diff --git a/testcases/network/netstress/netstress.c b/testcases/network/netstress/netstress.c > index 76d2fdb04..8d85ad085 100644 > --- a/testcases/network/netstress/netstress.c > +++ b/testcases/network/netstress/netstress.c > @@ -967,7 +967,7 @@ static void setup(void) > /* dccp* modules can be blacklisted, load them manually */ > const char * const argv[] = {"modprobe", "dccp_ipv6", NULL}; > > - if (tst_run_cmd(argv, NULL, NULL, 1)) > + if (tst_run_cmd(argv, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL)) > tst_brk(TCONF, "Failed to load dccp_ipv6 module"); > > tst_res(TINFO, "DCCP %s", (client_mode) ? "client" : "server"); > -- > 2.25.1 > -- Cyril Hrubis chrubis@suse.cz ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 3/6] lib/tst_run_cmd_*(): Turn int pass_exit_val into enum 2020-03-30 11:38 ` Cyril Hrubis @ 2020-03-30 11:40 ` Petr Vorel 0 siblings, 0 replies; 30+ messages in thread From: Petr Vorel @ 2020-03-30 11:40 UTC (permalink / raw) To: ltp Hi, > > This is a preparation for next commit. > > Now uses the only flag TST_RUN_CMD_PASS_EXIT_VAL. > That is quite long name, I wonder if we can shorten it. > Maybe we can rename the whole tst_run_cmd() just to tst_cmd() and change > this flag to TST_CMD_PASS_RETVAL. This looks good to me, I'll change it. > Other that this the patchset looks good. And push whole patchset with your, Li's and Xiao Reviewed-by: tag. Kind regards, Petr ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 4/6] lib/tst_run_cmd_*(): Search for program in $PATH 2020-03-27 21:39 [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() Petr Vorel ` (2 preceding siblings ...) 2020-03-27 21:39 ` [LTP] [PATCH 3/6] lib/tst_run_cmd_*(): Turn int pass_exit_val into enum Petr Vorel @ 2020-03-27 21:39 ` Petr Vorel 2020-03-30 11:40 ` Cyril Hrubis 2020-03-27 21:39 ` [LTP] [PATCH 5/6] lib: Implement SAFE_RUN_CMD() macro (new API only) Petr Vorel ` (2 subsequent siblings) 6 siblings, 1 reply; 30+ messages in thread From: Petr Vorel @ 2020-03-27 21:39 UTC (permalink / raw) To: ltp before calling execvp(). This is slightly safer than checking errno ENOENT. TST_RUN_CMD_CHECK_CMD flag cause TBROK when program not found. Suggested-by: Cyril Hrubis <chrubis@suse.cz> Signed-off-by: Petr Vorel <pvorel@suse.cz> --- New commit. doc/test-writing-guidelines.txt | 3 ++- include/tst_cmd.h | 3 +++ lib/tst_run_cmd.c | 16 ++++++++++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt index 31897309d..51eba6e39 100644 --- a/doc/test-writing-guidelines.txt +++ b/doc/test-writing-guidelines.txt @@ -1274,7 +1274,8 @@ which is followed by optional arguments. 'TST_RUN_CMD_PASS_EXIT_VAL' enum 'tst_run_cmd_flags' makes 'tst_run_cmd()' return the program exit code to the caller, otherwise 'tst_run_cmd()' exit the -tests on failure. +tests on failure. 'TST_RUN_CMD_CHECK_CMD' check for program in '$PATH' and exit +with 'TCONF' if not found. In case that 'execvp()' has failed and the 'pass_exit_val' flag was set, the return value is '255' if 'execvp()' failed with 'ENOENT' and '254' otherwise. diff --git a/include/tst_cmd.h b/include/tst_cmd.h index 67dec32f2..cab25462e 100644 --- a/include/tst_cmd.h +++ b/include/tst_cmd.h @@ -11,6 +11,9 @@ enum tst_run_cmd_flags { * program exit code is not zero. */ TST_RUN_CMD_PASS_EXIT_VAL = 1, + + /* exit with TCONF if program is not in path */ + TST_RUN_CMD_CHECK_CMD = 2, }; /* diff --git a/lib/tst_run_cmd.c b/lib/tst_run_cmd.c index 3536ec494..0494c6083 100644 --- a/lib/tst_run_cmd.c +++ b/lib/tst_run_cmd.c @@ -56,6 +56,17 @@ int tst_run_cmd_fds_(void (cleanup_fn)(void), */ void *old_handler = signal(SIGCHLD, SIG_DFL); + const char *cmd; + char path[PATH_MAX]; + + if (tst_get_path(argv[0], path, sizeof(path))) { + if (flags & TST_RUN_CMD_CHECK_CMD) + tst_brkm(TCONF, "Couldn't find '%s' in $PATH at %s:%d", argv[0], + __FILE__, __LINE__); + else + _exit(255); + } + pid_t pid = vfork(); if (pid == -1) { tst_brkm(TBROK | TERRNO, cleanup_fn, "vfork failed at %s:%d", @@ -74,10 +85,7 @@ int tst_run_cmd_fds_(void (cleanup_fn)(void), dup2(stderr_fd, STDERR_FILENO); } - if (execvp(argv[0], (char *const *)argv)) { - if (errno == ENOENT) - _exit(255); - } + execvp(argv[0], (char *const *)argv); _exit(254); } -- 2.25.1 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* [LTP] [PATCH 4/6] lib/tst_run_cmd_*(): Search for program in $PATH 2020-03-27 21:39 ` [LTP] [PATCH 4/6] lib/tst_run_cmd_*(): Search for program in $PATH Petr Vorel @ 2020-03-30 11:40 ` Cyril Hrubis 2020-03-30 11:52 ` Petr Vorel 0 siblings, 1 reply; 30+ messages in thread From: Cyril Hrubis @ 2020-03-30 11:40 UTC (permalink / raw) To: ltp Hi! > + /* exit with TCONF if program is not in path */ > + TST_RUN_CMD_CHECK_CMD = 2, Shouldn't be this rather called TST_CMD_TCONF_ON_MISSING? > }; > > /* > diff --git a/lib/tst_run_cmd.c b/lib/tst_run_cmd.c > index 3536ec494..0494c6083 100644 > --- a/lib/tst_run_cmd.c > +++ b/lib/tst_run_cmd.c > @@ -56,6 +56,17 @@ int tst_run_cmd_fds_(void (cleanup_fn)(void), > */ > void *old_handler = signal(SIGCHLD, SIG_DFL); > > + const char *cmd; > + char path[PATH_MAX]; > + > + if (tst_get_path(argv[0], path, sizeof(path))) { > + if (flags & TST_RUN_CMD_CHECK_CMD) > + tst_brkm(TCONF, "Couldn't find '%s' in $PATH at %s:%d", argv[0], > + __FILE__, __LINE__); > + else > + _exit(255); > + } > + > pid_t pid = vfork(); > if (pid == -1) { > tst_brkm(TBROK | TERRNO, cleanup_fn, "vfork failed at %s:%d", > @@ -74,10 +85,7 @@ int tst_run_cmd_fds_(void (cleanup_fn)(void), > dup2(stderr_fd, STDERR_FILENO); > } > > - if (execvp(argv[0], (char *const *)argv)) { > - if (errno == ENOENT) > - _exit(255); > - } > + execvp(argv[0], (char *const *)argv); > _exit(254); > } > > -- > 2.25.1 > -- Cyril Hrubis chrubis@suse.cz ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 4/6] lib/tst_run_cmd_*(): Search for program in $PATH 2020-03-30 11:40 ` Cyril Hrubis @ 2020-03-30 11:52 ` Petr Vorel 2020-03-30 11:53 ` Cyril Hrubis 0 siblings, 1 reply; 30+ messages in thread From: Petr Vorel @ 2020-03-30 11:52 UTC (permalink / raw) To: ltp Hi, > > + /* exit with TCONF if program is not in path */ > > + TST_RUN_CMD_CHECK_CMD = 2, > Shouldn't be this rather called TST_CMD_TCONF_ON_MISSING? +1. If these two comments (with renaming to tst_cmd() + flags) are the only your concern, I'll rename it and just push without sending to ML. When we're in renaming, I guess I should rename SAFE_RUN_CMD() into SAFE_CMD(), ok? Kind regards, Petr ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 4/6] lib/tst_run_cmd_*(): Search for program in $PATH 2020-03-30 11:52 ` Petr Vorel @ 2020-03-30 11:53 ` Cyril Hrubis 0 siblings, 0 replies; 30+ messages in thread From: Cyril Hrubis @ 2020-03-30 11:53 UTC (permalink / raw) To: ltp Hi! > > > + /* exit with TCONF if program is not in path */ > > > + TST_RUN_CMD_CHECK_CMD = 2, > > > Shouldn't be this rather called TST_CMD_TCONF_ON_MISSING? > +1. > > If these two comments (with renaming to tst_cmd() + flags) are the only your > concern, I'll rename it and just push without sending to ML. Yes, minus the comments on the function and constant names the code lookgs good. > When we're in renaming, I guess I should rename SAFE_RUN_CMD() into SAFE_CMD(), Indeed. -- Cyril Hrubis chrubis@suse.cz ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 5/6] lib: Implement SAFE_RUN_CMD() macro (new API only) 2020-03-27 21:39 [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() Petr Vorel ` (3 preceding siblings ...) 2020-03-27 21:39 ` [LTP] [PATCH 4/6] lib/tst_run_cmd_*(): Search for program in $PATH Petr Vorel @ 2020-03-27 21:39 ` Petr Vorel 2020-03-30 6:35 ` Li Wang 2020-03-27 21:39 ` [LTP] [PATCH 6/6] Use SAFE_RUN_CMD() Petr Vorel 2020-03-28 2:41 ` [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() Xiao Yang 6 siblings, 1 reply; 30+ messages in thread From: Petr Vorel @ 2020-03-27 21:39 UTC (permalink / raw) To: ltp Reviewed-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com> Reviewed-by: Li Wang <liwang@redhat.com> Signed-off-by: Petr Vorel <pvorel@suse.cz> --- Renamed: s/SAFE_RUNCMD()/SAFE_RUN_CMD()/ doc/test-writing-guidelines.txt | 3 +++ include/tst_safe_macros.h | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt index 51eba6e39..4b195a002 100644 --- a/doc/test-writing-guidelines.txt +++ b/doc/test-writing-guidelines.txt @@ -1283,6 +1283,9 @@ return value is '255' if 'execvp()' failed with 'ENOENT' and '254' otherwise. 'stdout_path' and 'stderr_path' determine where to redirect the program stdout and stderr I/O streams. +The 'SAFE_RUN_CMD()' macro can be used automatic handling non zero exits (exits +with 'TBROK') or 'ENOENT' (exits with 'TCONF'). + .Example [source,c] ------------------------------------------------------------------------------- diff --git a/include/tst_safe_macros.h b/include/tst_safe_macros.h index d95d26219..af45bc51d 100644 --- a/include/tst_safe_macros.h +++ b/include/tst_safe_macros.h @@ -21,6 +21,7 @@ #include <grp.h> #include "safe_macros_fn.h" +#include "tst_cmd.h" #define SAFE_BASENAME(path) \ safe_basename(__FILE__, __LINE__, NULL, (path)) @@ -534,4 +535,23 @@ int safe_personality(const char *filename, unsigned int lineno, void safe_unshare(const char *file, const int lineno, int flags); #define SAFE_UNSHARE(flags) safe_unshare(__FILE__, __LINE__, (flags)) +static inline void safe_run_cmd(const char *file, const int lineno, + const char *const argv[], + const char *stdout_path, + const char *stderr_path) +{ + int rval; + + switch ((rval = tst_run_cmd(argv, stdout_path, stderr_path, + TST_RUN_CMD_PASS_EXIT_VAL | + TST_RUN_CMD_CHECK_CMD))) { + case 0: + break; + default: + tst_brk(TBROK, "%s:%d: %s failed (%d)", file, lineno, argv[0], rval); + } +} +#define SAFE_RUN_CMD(argv, stdout_path, stderr_path) \ + safe_run_cmd(__FILE__, __LINE__, (argv), (stdout_path), (stderr_path)) + #endif /* SAFE_MACROS_H__ */ -- 2.25.1 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* [LTP] [PATCH 5/6] lib: Implement SAFE_RUN_CMD() macro (new API only) 2020-03-27 21:39 ` [LTP] [PATCH 5/6] lib: Implement SAFE_RUN_CMD() macro (new API only) Petr Vorel @ 2020-03-30 6:35 ` Li Wang 2020-03-30 8:44 ` Petr Vorel 0 siblings, 1 reply; 30+ messages in thread From: Li Wang @ 2020-03-30 6:35 UTC (permalink / raw) To: ltp Hi Petr, Thanks for your work on this. > > +static inline void safe_run_cmd(const char *file, const int lineno, > + const char > *const argv[], > Be cautious of the code indent here, otherwise patchset looks good. > + const char *stdout_path, > + const char *stderr_path) > +{ > -- Regards, Li Wang -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.linux.it/pipermail/ltp/attachments/20200330/0fcdfb80/attachment.htm> ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 5/6] lib: Implement SAFE_RUN_CMD() macro (new API only) 2020-03-30 6:35 ` Li Wang @ 2020-03-30 8:44 ` Petr Vorel 0 siblings, 0 replies; 30+ messages in thread From: Petr Vorel @ 2020-03-30 8:44 UTC (permalink / raw) To: ltp Hi Li, > Thanks for your work on this. > > +static inline void safe_run_cmd(const char *file, const int lineno, Old code. 'static inline' shouldn't be here. > > + const char > > *const argv[], > Be cautious of the code indent here, otherwise patchset looks good. Thanks! > > + const char *stdout_path, > > + const char *stderr_path) > > +{ Kind regards, Petr ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 6/6] Use SAFE_RUN_CMD() 2020-03-27 21:39 [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() Petr Vorel ` (4 preceding siblings ...) 2020-03-27 21:39 ` [LTP] [PATCH 5/6] lib: Implement SAFE_RUN_CMD() macro (new API only) Petr Vorel @ 2020-03-27 21:39 ` Petr Vorel 2020-03-28 2:41 ` [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() Xiao Yang 6 siblings, 0 replies; 30+ messages in thread From: Petr Vorel @ 2020-03-27 21:39 UTC (permalink / raw) To: ltp Reviewed-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com> Reviewed-by: Li Wang <liwang@redhat.com> Signed-off-by: Petr Vorel <pvorel@suse.cz> --- Renamed: s/SAFE_RUNCMD()/SAFE_RUN_CMD()/ testcases/kernel/syscalls/add_key/add_key05.c | 15 ++++----------- testcases/kernel/syscalls/quotactl/quotactl01.c | 11 ++--------- testcases/kernel/syscalls/quotactl/quotactl06.c | 9 +-------- 3 files changed, 7 insertions(+), 28 deletions(-) diff --git a/testcases/kernel/syscalls/add_key/add_key05.c b/testcases/kernel/syscalls/add_key/add_key05.c index 3da3be9ee..fd0fb0a50 100644 --- a/testcases/kernel/syscalls/add_key/add_key05.c +++ b/testcases/kernel/syscalls/add_key/add_key05.c @@ -36,17 +36,10 @@ static void add_user(void) return; const char *const cmd_useradd[] = {"useradd", username, NULL}; - int rc; - - switch ((rc = tst_run_cmd(cmd_useradd, NULL, NULL, - TST_RUN_CMD_PASS_EXIT_VAL))) { - case 0: - user_added = 1; - ltpuser = SAFE_GETPWNAM(username); - break; - default: - tst_brk(TBROK, "useradd failed (%d)", rc); - } + + SAFE_RUN_CMD(cmd_useradd, NULL, NULL); + user_added = 1; + ltpuser = SAFE_GETPWNAM(username); sprintf(fmt, "%5u: %%*5d %%*d/%%*d %%d/%%d %%d/%%d", ltpuser->pw_uid); } diff --git a/testcases/kernel/syscalls/quotactl/quotactl01.c b/testcases/kernel/syscalls/quotactl/quotactl01.c index e4c2a8939..a40852f34 100644 --- a/testcases/kernel/syscalls/quotactl/quotactl01.c +++ b/testcases/kernel/syscalls/quotactl/quotactl01.c @@ -162,15 +162,8 @@ static struct tcase { static void setup(void) { const char *const cmd[] = {"quotacheck", "-ugF", "vfsv0", MNTPOINT, NULL}; - int ret; - - ret = tst_run_cmd(cmd, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL); - switch (ret) { - case 0: - break; - default: - tst_brk(TBROK, "quotacheck exited with %i", ret); - } + + SAFE_RUN_CMD(cmd, NULL, NULL); test_id = geteuid(); if (access(USRPATH, F_OK) == -1) diff --git a/testcases/kernel/syscalls/quotactl/quotactl06.c b/testcases/kernel/syscalls/quotactl/quotactl06.c index 5d70f340f..e990d6976 100644 --- a/testcases/kernel/syscalls/quotactl/quotactl06.c +++ b/testcases/kernel/syscalls/quotactl/quotactl06.c @@ -146,16 +146,9 @@ static void verify_quotactl(unsigned int n) static void setup(void) { const char *const cmd[] = {"quotacheck", "-uF", "vfsv0", MNTPOINT, NULL}; - int ret; unsigned int i; - ret = tst_run_cmd(cmd, NULL, NULL, TST_RUN_CMD_PASS_EXIT_VAL); - switch (ret) { - case 0: - break; - default: - tst_brk(TBROK, "quotacheck exited with %i", ret); - } + SAFE_RUN_CMD(cmd, NULL, NULL); if (access(USRPATH, F_OK) == -1) tst_brk(TFAIL | TERRNO, "user quotafile didn't exist"); -- 2.25.1 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() 2020-03-27 21:39 [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() Petr Vorel ` (5 preceding siblings ...) 2020-03-27 21:39 ` [LTP] [PATCH 6/6] Use SAFE_RUN_CMD() Petr Vorel @ 2020-03-28 2:41 ` Xiao Yang 2020-03-28 3:42 ` Petr Vorel 6 siblings, 1 reply; 30+ messages in thread From: Xiao Yang @ 2020-03-28 2:41 UTC (permalink / raw) To: ltp On 3/28/20 5:39 AM, Petr Vorel wrote: > + There is a double check (first in > .needs_cmds, then in SAFE_RUN_CMD()), maybe that's not needed. Hi Petr, Why do you need the duplicate .needs_cmds flag?(it introduces the double check as you said) Usually, all tests run commands by tst_run_cmd()/SAFE_RUN_CMD() and they can report TCONF by passing TST_RUN_CMD_CHECK_CMD so it is fair to be a part of tst_run_cmd()/SAFE_RUN_CMD(). Thanks, Xiao Yang ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() 2020-03-28 2:41 ` [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() Xiao Yang @ 2020-03-28 3:42 ` Petr Vorel 2020-03-29 5:29 ` Xiao Yang 2020-03-30 4:24 ` Li Wang 0 siblings, 2 replies; 30+ messages in thread From: Petr Vorel @ 2020-03-28 3:42 UTC (permalink / raw) To: ltp Hi Xiao, > On 3/28/20 5:39 AM, Petr Vorel wrote: > > + There is a double check (first in > > .needs_cmds, then in SAFE_RUN_CMD()), maybe that's not needed. > Hi Petr, > Why do you need the duplicate .needs_cmds flag?(it introduces the double > check as you said) > Usually, all tests run commands by tst_run_cmd()/SAFE_RUN_CMD() and they can > report TCONF > by passing TST_RUN_CMD_CHECK_CMD so it is fair to be a part of > tst_run_cmd()/SAFE_RUN_CMD(). Thanks for your review. I guess Cyril will prefer .needs_cmds, as it can be parsed - metadata project: https://people.kernel.org/metan/towards-parallel-kernel-test-runs https://github.com/metan-ucw/ltp/tree/master/docparse I put it there because some command might be run just under some condition (not always), thus not suitable for .needs_cmds, but still nice to have reliable check. But maybe I'm wrong. Kind regards, Petr ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() 2020-03-28 3:42 ` Petr Vorel @ 2020-03-29 5:29 ` Xiao Yang 2020-03-30 4:39 ` Li Wang 2020-03-30 4:24 ` Li Wang 1 sibling, 1 reply; 30+ messages in thread From: Xiao Yang @ 2020-03-29 5:29 UTC (permalink / raw) To: ltp On 2020/3/28 11:42, Petr Vorel wrote: > Hi Xiao, > >> On 3/28/20 5:39 AM, Petr Vorel wrote: >>> + There is a double check (first in >>> .needs_cmds, then in SAFE_RUN_CMD()), maybe that's not needed. > >> Hi Petr, > >> Why do you need the duplicate .needs_cmds flag?(it introduces the double >> check as you said) > >> Usually, all tests run commands by tst_run_cmd()/SAFE_RUN_CMD() and they can >> report TCONF > >> by passing TST_RUN_CMD_CHECK_CMD so it is fair to be a part of >> tst_run_cmd()/SAFE_RUN_CMD(). > > Thanks for your review. > I guess Cyril will prefer .needs_cmds, as it can be parsed - metadata project: > https://people.kernel.org/metan/towards-parallel-kernel-test-runs > https://github.com/metan-ucw/ltp/tree/master/docparse Hi Petr? Thank you for sharing these info. Does Cyril want to get metadata from struct tst_test directly? How about the rough design? 1) .needs_cmds only saves the required commands.(doesn't do any check) 2) pass the corresponding member of .needs_cmds to tst_run_cmd()/SAFE_RUN_CMD()(do check in these functions). For example: ---------------------------------------------- # grep tst_needs_cmds include/tst_cmd.h extern const char *const *tst_needs_cmds; # grep -B1 tst_needs_cmds lib/tst_test.c const char *const *tst_needs_cmds; -- if (tst_test->needs_cmds) tst_needs_cmds = tst_test->needs_cmds; # grep -A2 'needs_cmds' testcases/kernel/syscalls/add_key/add_key05.c const char *const cmd_useradd[] = {tst_needs_cmds[0], username, NULL}; int rc; -- const char *const cmd_userdel[] = {tst_needs_cmds[1], "-r", username, NULL}; if (tst_run_cmd(cmd_userdel, NULL, NULL, 1)) -- .needs_cmds = (const char *const []) { "useradd", "userdel", ---------------------------------------------- btw: is it possible for .needs_cmds to save the required commands with options? Thanks, Xiao Yang > > I put it there because some command might be run just under some condition (not > always), thus not suitable for .needs_cmds, but still nice to have reliable > check. But maybe I'm wrong. > > Kind regards, > Petr > ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() 2020-03-29 5:29 ` Xiao Yang @ 2020-03-30 4:39 ` Li Wang 2020-03-30 5:20 ` Xiao Yang 0 siblings, 1 reply; 30+ messages in thread From: Li Wang @ 2020-03-30 4:39 UTC (permalink / raw) To: ltp Hi Xiao, On Sun, Mar 29, 2020 at 1:36 PM Xiao Yang <yangx.jy@cn.fujitsu.com> wrote: > On 2020/3/28 11:42, Petr Vorel wrote: > > Hi Xiao, > > > >> On 3/28/20 5:39 AM, Petr Vorel wrote: > >>> + There is a double check (first in > >>> .needs_cmds, then in SAFE_RUN_CMD()), maybe that's not needed. > > > >> Hi Petr, > > > >> Why do you need the duplicate .needs_cmds flag?(it introduces the double > >> check as you said) > > > >> Usually, all tests run commands by tst_run_cmd()/SAFE_RUN_CMD() and > they can > >> report TCONF > > > >> by passing TST_RUN_CMD_CHECK_CMD so it is fair to be a part of > >> tst_run_cmd()/SAFE_RUN_CMD(). > > > > Thanks for your review. > > I guess Cyril will prefer .needs_cmds, as it can be parsed - metadata > project: > > https://people.kernel.org/metan/towards-parallel-kernel-test-runs > > https://github.com/metan-ucw/ltp/tree/master/docparse > Hi Petr? > > Thank you for sharing these info. > Does Cyril want to get metadata from struct tst_test directly? > > How about the rough design? > 1) .needs_cmds only saves the required commands.(doesn't do any check) > 2) pass the corresponding member of .needs_cmds to > tst_run_cmd()/SAFE_RUN_CMD()(do check in these functions). > For example: > ---------------------------------------------- > # grep tst_needs_cmds include/tst_cmd.h > extern const char *const *tst_needs_cmds; > > # grep -B1 tst_needs_cmds lib/tst_test.c > > const char *const *tst_needs_cmds; > -- > if (tst_test->needs_cmds) > tst_needs_cmds = tst_test->needs_cmds; > > # grep -A2 'needs_cmds' testcases/kernel/syscalls/add_key/add_key05.c > const char *const cmd_useradd[] = {tst_needs_cmds[0], username, NULL}; > int rc; > I don't see any advantage of involving this struct in a test case, and it also makes things more complicated. IMO, the '.needs_cmds' should do check and guarantee all the cmds exist. That's a hard requirement for the test. If a situation that the commands are only part of the requirement(soft), we could avoid using '.needs_cmds' in the test and just calling tst_run_cmd() without passing TST_RUN_CMD_CHECK_CMD flag. This satisfies most situations we have, it is safe enough and choosable for people. Or maybe I'm wrong here too:). -- Regards, Li Wang -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.linux.it/pipermail/ltp/attachments/20200330/e959385c/attachment-0001.htm> ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() 2020-03-30 4:39 ` Li Wang @ 2020-03-30 5:20 ` Xiao Yang 2020-03-30 7:12 ` Petr Vorel 0 siblings, 1 reply; 30+ messages in thread From: Xiao Yang @ 2020-03-30 5:20 UTC (permalink / raw) To: ltp On 2020/3/30 12:39, Li Wang wrote: > Hi Xiao, > > On Sun, Mar 29, 2020 at 1:36 PM Xiao Yang <yangx.jy@cn.fujitsu.com > <mailto:yangx.jy@cn.fujitsu.com>> wrote: > > On 2020/3/28 11:42, Petr Vorel wrote: > > Hi Xiao, > > > >> On 3/28/20 5:39 AM, Petr Vorel wrote: > >>> + There is a double check (first in > >>> .needs_cmds, then in SAFE_RUN_CMD()), maybe that's not needed. > > > >> Hi Petr, > > > >> Why do you need the duplicate .needs_cmds flag?(it introduces > the double > >> check as you said) > > > >> Usually, all tests run commands by tst_run_cmd()/SAFE_RUN_CMD() > and they can > >> report TCONF > > > >> by passing TST_RUN_CMD_CHECK_CMD so it is fair to be a part of > >> tst_run_cmd()/SAFE_RUN_CMD(). > > > > Thanks for your review. > > I guess Cyril will prefer .needs_cmds, as it can be parsed - > metadata project: > > https://people.kernel.org/metan/towards-parallel-kernel-test-runs > > https://github.com/metan-ucw/ltp/tree/master/docparse > Hi Petr? > > Thank you for sharing these info. > Does Cyril want to get metadata from struct tst_test directly? > > How about the rough design? > 1) .needs_cmds only saves the required commands.(doesn't do any check) > 2) pass the corresponding member of .needs_cmds to > tst_run_cmd()/SAFE_RUN_CMD()(do check in these functions). > For example: > ---------------------------------------------- > # grep tst_needs_cmds include/tst_cmd.h > extern const char *const *tst_needs_cmds; > > # grep -B1 tst_needs_cmds lib/tst_test.c > > const char *const *tst_needs_cmds; > -- > if (tst_test->needs_cmds) > tst_needs_cmds = tst_test->needs_cmds; > > # grep -A2 'needs_cmds' testcases/kernel/syscalls/add_key/add_key05.c > const char *const cmd_useradd[] = {tst_needs_cmds[0], username, NULL}; > int rc; > > > I don't see any advantage of involving this struct in a test case, and > it also makes things more complicated. Hi Li, In fact, I perfer to remove .need_cmd and use tst_run_cmd with/without TST_RUN_CMD_CHECK_CMD directly. But I am not sure if it is necessary to keep .need_cmd for metadata project. I think we can generate json about resouce by reading struct tst_test or other ways. Thanks, Xiao Yang > > IMO, the '.needs_cmds' should do check and guarantee all the cmds exist. > That's a hard requirement for the test. If a situation that the commands > are only part of the requirement(soft), we could avoid using > '.needs_cmds' in the test and just calling tst_run_cmd() without passing > TST_RUN_CMD_CHECK_CMD flag. This satisfies most situations we have, it > is safe enough and choosable for people. > > Or maybe I'm wrong here too:). > > -- > Regards, > Li Wang ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() 2020-03-30 5:20 ` Xiao Yang @ 2020-03-30 7:12 ` Petr Vorel 2020-03-30 7:43 ` Xiao Yang 0 siblings, 1 reply; 30+ messages in thread From: Petr Vorel @ 2020-03-30 7:12 UTC (permalink / raw) To: ltp Hi Xiao, > > # grep -A2 'needs_cmds' testcases/kernel/syscalls/add_key/add_key05.c > > const char *const cmd_useradd[] = {tst_needs_cmds[0], username, NULL}; > > int rc; > > I don't see any advantage of involving this struct in a test case, and > > it also makes things more complicated. > Hi Li, > In fact, I perfer to remove .need_cmd and use tst_run_cmd with/without > TST_RUN_CMD_CHECK_CMD directly. > But I am not sure if it is necessary to keep .need_cmd for metadata project. > I think we can generate json about resouce by reading struct tst_test or > other ways. not sure if you mean removing .needs_cmds entirely or just for copy_file_range02.c. or some other test. I rewritten the original patchset because Cyril suggested .needs_cmds implementation: "Actually I would like to avoid exposing the function to the tests and force people to use the .needs_cmds instead in order to have a proper metadata." [1] IMHO parsing struct members is easier to get metadata than searching for various functions to be used, so I understand Cyril's intention. Cyril explains this on his blog posts (I've noticed [2], but it's also in [3]: "this arrangement also helps to export the test metadata into a machine parsable format"). Kind regards, Petr > Thanks, > Xiao Yang > > IMO, the '.needs_cmds' should do check and guarantee all the cmds exist. > > That's a hard requirement for the test. If a situation that the commands > > are only part of the requirement(soft), we could avoid using > > '.needs_cmds' in the test and just calling tst_run_cmd() without passing > > TST_RUN_CMD_CHECK_CMD flag. This satisfies most situations we have, it > > is safe enough and choosable for people. > > Or maybe I'm wrong here too:). > > -- > > Regards, > > Li Wang Kind regards, Petr [1] https://lists.linux.it/pipermail/ltp/2020-March/016233.html [2] https://people.kernel.org/metan/towards-parallel-kernel-test-runs [3] https://people.kernel.org/metan/the-ltp-test-driver-model ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() 2020-03-30 7:12 ` Petr Vorel @ 2020-03-30 7:43 ` Xiao Yang 0 siblings, 0 replies; 30+ messages in thread From: Xiao Yang @ 2020-03-30 7:43 UTC (permalink / raw) To: ltp On 2020/3/30 15:12, Petr Vorel wrote: > Hi Xiao, > >>> # grep -A2 'needs_cmds' testcases/kernel/syscalls/add_key/add_key05.c >>> const char *const cmd_useradd[] = {tst_needs_cmds[0], username, NULL}; >>> int rc; > >>> I don't see any advantage of involving this struct in a test case, and >>> it also makes things more complicated. >> Hi Li, > >> In fact, I perfer to remove .need_cmd and use tst_run_cmd with/without >> TST_RUN_CMD_CHECK_CMD directly. >> But I am not sure if it is necessary to keep .need_cmd for metadata project. >> I think we can generate json about resouce by reading struct tst_test or >> other ways. > > not sure if you mean removing .needs_cmds entirely or just for > copy_file_range02.c. or some other test. I rewritten the original patchset > because Cyril suggested .needs_cmds implementation: > > "Actually I would like to avoid exposing the function to the tests and > force people to use the .needs_cmds instead in order to have a proper > metadata." [1] > > Hi Petr, Thanks a lot for your explanation. I want to remove .needs_cmds entirely before but it may be helpful to get metadata about command. Thanks, Xiao Yang > IMHO parsing struct members is easier to get metadata than searching for > various functions to be used, so I understand Cyril's intention. Cyril explains > this on his blog posts (I've noticed [2], but it's also in [3]: "this > arrangement also helps to export the test metadata into a machine parsable > format"). > > Kind regards, > Petr > >> Thanks, >> Xiao Yang > > >>> IMO, the '.needs_cmds' should do check and guarantee all the cmds exist. >>> That's a hard requirement for the test. If a situation that the commands >>> are only part of the requirement(soft), we could avoid using >>> '.needs_cmds' in the test and just calling tst_run_cmd() without passing >>> TST_RUN_CMD_CHECK_CMD flag. This satisfies most situations we have, it >>> is safe enough and choosable for people. > >>> Or maybe I'm wrong here too:). > >>> -- >>> Regards, >>> Li Wang > > > Kind regards, > Petr > > [1] https://lists.linux.it/pipermail/ltp/2020-March/016233.html > [2] https://people.kernel.org/metan/towards-parallel-kernel-test-runs > [3] https://people.kernel.org/metan/the-ltp-test-driver-model > > > . > ^ permalink raw reply [flat|nested] 30+ messages in thread
* [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() 2020-03-28 3:42 ` Petr Vorel 2020-03-29 5:29 ` Xiao Yang @ 2020-03-30 4:24 ` Li Wang 1 sibling, 0 replies; 30+ messages in thread From: Li Wang @ 2020-03-30 4:24 UTC (permalink / raw) To: ltp On Sat, Mar 28, 2020 at 11:43 AM Petr Vorel <pvorel@suse.cz> wrote: > Hi Xiao, > > > On 3/28/20 5:39 AM, Petr Vorel wrote: > > > + There is a double check (first in > > > .needs_cmds, then in SAFE_RUN_CMD()), maybe that's not needed. > > > Hi Petr, > > > Why do you need the duplicate .needs_cmds flag?(it introduces the double > > check as you said) > > > Usually, all tests run commands by tst_run_cmd()/SAFE_RUN_CMD() and they > can > > report TCONF > > > by passing TST_RUN_CMD_CHECK_CMD so it is fair to be a part of > > tst_run_cmd()/SAFE_RUN_CMD(). > > Thanks for your review. > I guess Cyril will prefer .needs_cmds, as it can be parsed - metadata > project: > https://people.kernel.org/metan/towards-parallel-kernel-test-runs > https://github.com/metan-ucw/ltp/tree/master/docparse > > I put it there because some command might be run just under some condition > (not > always), thus not suitable for .needs_cmds, but still nice to have reliable > check. But maybe I'm wrong. > +1 you're right, I believe that is safer and choosable for the test. -- Regards, Li Wang -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.linux.it/pipermail/ltp/attachments/20200330/e2d2298a/attachment.htm> ^ permalink raw reply [flat|nested] 30+ messages in thread
end of thread, other threads:[~2020-03-30 12:37 UTC | newest] Thread overview: 30+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-03-27 21:39 [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() Petr Vorel 2020-03-27 21:39 ` [LTP] [PATCH 1/6] lib: Implement .needs_cmds Petr Vorel 2020-03-30 6:13 ` Li Wang 2020-03-30 7:03 ` Petr Vorel 2020-03-30 11:31 ` Cyril Hrubis 2020-03-27 21:39 ` [LTP] [PATCH 2/6] Use .needs_cmds Petr Vorel 2020-03-30 11:31 ` Cyril Hrubis 2020-03-30 11:48 ` Petr Vorel 2020-03-30 11:57 ` Li Wang 2020-03-30 12:17 ` Petr Vorel 2020-03-30 12:37 ` Petr Vorel 2020-03-27 21:39 ` [LTP] [PATCH 3/6] lib/tst_run_cmd_*(): Turn int pass_exit_val into enum Petr Vorel 2020-03-30 11:38 ` Cyril Hrubis 2020-03-30 11:40 ` Petr Vorel 2020-03-27 21:39 ` [LTP] [PATCH 4/6] lib/tst_run_cmd_*(): Search for program in $PATH Petr Vorel 2020-03-30 11:40 ` Cyril Hrubis 2020-03-30 11:52 ` Petr Vorel 2020-03-30 11:53 ` Cyril Hrubis 2020-03-27 21:39 ` [LTP] [PATCH 5/6] lib: Implement SAFE_RUN_CMD() macro (new API only) Petr Vorel 2020-03-30 6:35 ` Li Wang 2020-03-30 8:44 ` Petr Vorel 2020-03-27 21:39 ` [LTP] [PATCH 6/6] Use SAFE_RUN_CMD() Petr Vorel 2020-03-28 2:41 ` [LTP] [PATCH 0/6] C API: .needs_cmds and SAFE_RUN_CMD() Xiao Yang 2020-03-28 3:42 ` Petr Vorel 2020-03-29 5:29 ` Xiao Yang 2020-03-30 4:39 ` Li Wang 2020-03-30 5:20 ` Xiao Yang 2020-03-30 7:12 ` Petr Vorel 2020-03-30 7:43 ` Xiao Yang 2020-03-30 4:24 ` Li Wang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox