This test verifies sched_setaffinity(2) for all error conditions to occur correctly.
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmansk...@oracle.com> --- Changes: * added sched_setaffinity01 to runtest/syscalls * changed __LTP_SCHED_SETAFFINITY_H__ to LTP_SCHED_SETAFFINITY_H in sched_setaffinity.h * added includes to sched_setaffinity.h * made use of SAFE_SETEUID runtest/syscalls | 1 + testcases/kernel/syscalls/.gitignore | 1 + .../kernel/syscalls/sched_setaffinity/Makefile | 23 +++ .../syscalls/sched_setaffinity/sched_setaffinity.h | 60 +++++++ .../sched_setaffinity/sched_setaffinity01.c | 185 ++++++++++++++++++++ 5 files changed, 270 insertions(+), 0 deletions(-) create mode 100644 testcases/kernel/syscalls/sched_setaffinity/Makefile create mode 100644 testcases/kernel/syscalls/sched_setaffinity/sched_setaffinity.h create mode 100644 testcases/kernel/syscalls/sched_setaffinity/sched_setaffinity01.c diff --git a/runtest/syscalls b/runtest/syscalls index fb3e59f..6c8106e 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -897,6 +897,7 @@ sched_setscheduler02 sched_setscheduler02 sched_yield01 sched_yield01 +sched_setaffinity01 sched_setaffinity01 sched_getaffinity01 sched_getaffinity01 select01 select01 diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore index d5c7bac..21c6cf1 100644 --- a/testcases/kernel/syscalls/.gitignore +++ b/testcases/kernel/syscalls/.gitignore @@ -719,6 +719,7 @@ /sched_rr_get_interval/sched_rr_get_interval01 /sched_rr_get_interval/sched_rr_get_interval02 /sched_rr_get_interval/sched_rr_get_interval03 +/sched_setaffinity/sched_setaffinity01 /sched_setparam/sched_setparam01 /sched_setparam/sched_setparam02 /sched_setparam/sched_setparam03 diff --git a/testcases/kernel/syscalls/sched_setaffinity/Makefile b/testcases/kernel/syscalls/sched_setaffinity/Makefile new file mode 100644 index 0000000..2d825f1 --- /dev/null +++ b/testcases/kernel/syscalls/sched_setaffinity/Makefile @@ -0,0 +1,23 @@ +# +# Copyright (c) 2014 Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +# the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +top_srcdir ?= ../../../.. + +include $(top_srcdir)/include/mk/testcases.mk + +include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/syscalls/sched_setaffinity/sched_setaffinity.h b/testcases/kernel/syscalls/sched_setaffinity/sched_setaffinity.h new file mode 100644 index 0000000..8083894 --- /dev/null +++ b/testcases/kernel/syscalls/sched_setaffinity/sched_setaffinity.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014 Oracle and/or its affiliates. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. See the + * GNU General Public License for more details. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Some old libcs (like glibc < 2.7) do not provide interfaces for + * dynamically sized cpu sets, but provide only static cpu_set_t type + * with no more than CPU_SETSIZE cpus in it. + * + * This file is a wrapper of the dynamic interfaces using the static ones. + * + * If the number of cpus available on the system is greater than + * CPU_SETSIZE, this interface will not work. Update libc in this case :) + */ + +#define _GNU_SOURCE +#include <sched.h> + +#ifndef LTP_SCHED_SETAFFINITY_H +#define LTP_SCHED_SETAFFINITY_H + +#ifndef CPU_ALLOC +#define CPU_ALLOC(ncpus) malloc(sizeof(cpu_set_t)); \ +if (ncpus > CPU_SETSIZE) { \ + tst_brkm(TCONF, cleanup, \ + "Your libc does not support masks with %ld cpus", ncpus); \ +} +#endif + +#ifndef CPU_FREE +#define CPU_FREE(ptr) free(ptr); +#endif + +#ifndef CPU_ALLOC_SIZE +#define CPU_ALLOC_SIZE(size) sizeof(cpu_set_t); +#endif + +#ifndef CPU_ZERO_S +#define CPU_ZERO_S(size, mask) CPU_ZERO(mask); +#endif + +#ifndef CPU_SET_S +#define CPU_SET_S(cpu, size, mask) CPU_SET(cpu, mask); +#endif + +#endif /* LTP_SCHED_SETAFFINITY_H */ diff --git a/testcases/kernel/syscalls/sched_setaffinity/sched_setaffinity01.c b/testcases/kernel/syscalls/sched_setaffinity/sched_setaffinity01.c new file mode 100644 index 0000000..3b23445 --- /dev/null +++ b/testcases/kernel/syscalls/sched_setaffinity/sched_setaffinity01.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2014 Oracle and/or its affiliates. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. See the + * GNU General Public License for more details. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * This test verifies sched_setaffinity(2) for all error conditions + * to occur correctly. + * + * sched_setaffinity() returns -1 and sets the error code to: + * + * 1) EFAULT, if the supplied memory address is invalid + * 2) EINVAL, if the mask doesn't contain at least one + * permitted cpu + * 3) ESRCH, if the process whose id is pid could not + * be found + * 4) EPERM, if the calling process doesn't have appropriate + * privileges + */ + +#define _GNU_SOURCE +#include <errno.h> +#include <sched.h> +#include <signal.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> +#include "test.h" +#include "usctest.h" +#include "safe_macros.h" +#include "sched_setaffinity.h" + +char *TCID = "sched_setaffinity01"; + +static cpu_set_t *mask, *emask; +static cpu_set_t *fmask = (void *)-1; +static size_t mask_size, emask_size; +static pid_t self_pid, privileged_pid, free_pid; +static uid_t uid; +static long ncpus; + +static struct test_case_t { + pid_t *pid; + size_t *mask_size; + cpu_set_t **mask; + int exp_errno; +} test_cases[] = { + {&self_pid, &mask_size, &fmask, EFAULT}, + {&self_pid, &emask_size, &emask, EINVAL}, + {&free_pid, &mask_size, &mask, ESRCH}, + {&privileged_pid, &mask_size, &mask, EPERM}, +}; + +int TST_TOTAL = ARRAY_SIZE(test_cases); + +static void cleanup(void) +{ + if (mask != NULL) { + CPU_FREE(mask); + mask = NULL; + } + + if (emask != NULL) { + CPU_FREE(emask); + emask = NULL; + } + + SAFE_SETEUID(NULL, uid); + + if (privileged_pid != 0) { + kill(privileged_pid, SIGUSR1); + waitpid(privileged_pid, NULL, 0); + privileged_pid = 0; + } +} + +static void setup(void) +{ + /* Current mask */ + mask = CPU_ALLOC(ncpus); + if (mask == NULL) + tst_brkm(TBROK | TERRNO, cleanup, "CPU_ALLOC(%ld) failed", + ncpus); + mask_size = CPU_ALLOC_SIZE(ncpus); + if (sched_getaffinity(0, mask_size, mask) < 0) + tst_brkm(TBROK | TERRNO, cleanup, "sched_getaffinity() failed"); + + /* Mask with one more cpu than available on the system */ + emask = CPU_ALLOC(ncpus + 1); + if (emask == NULL) + tst_brkm(TBROK | TERRNO, cleanup, "CPU_ALLOC(%ld) failed", + ncpus + 1); + emask_size = CPU_ALLOC_SIZE(ncpus + 1); + CPU_ZERO_S(emask_size, emask); + CPU_SET_S(ncpus, emask_size, emask); + + privileged_pid = fork(); + if (privileged_pid == 0) { + sigset_t set; + struct timespec tv; + + sigemptyset(&set); + sigaddset(&set, SIGUSR1); + + tv.tv_sec = 30; + tv.tv_nsec = 0; + + if (sigtimedwait(&set, NULL, &tv) < 0) { + if (errno == EAGAIN) { + printf("privileged child timeouted\n"); + exit(1); + } + } + + exit(0); + } else if (privileged_pid < 0) { + tst_brkm(TBROK | TERRNO, cleanup, "fork() failed"); + } + + SAFE_SETEUID(cleanup, uid + 1); + + /* we assume that this pid will not be used again + * for some short period of time */ + free_pid = fork(); + if (free_pid == 0) + exit(0); + else if (free_pid < 0) + tst_brkm(TBROK | TERRNO, cleanup, "fork() failed"); + waitpid(free_pid, NULL, 0); +} + +int main(int argc, char *argv[]) +{ + const char *msg; + int lc; + int i; + + msg = parse_opts(argc, argv, NULL, NULL); + if (msg != NULL) + tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); + + tst_require_root(NULL); + uid = geteuid(); + ncpus = tst_ncpus_max(); + + for (lc = 0; TEST_LOOPING(lc); lc++) { + tst_count = 0; + setup(); + for (i = 0; i < TST_TOTAL; i++) { + TEST(sched_setaffinity(*(test_cases[i].pid), + *(test_cases[i].mask_size), + *(test_cases[i].mask))); + + if (TEST_RETURN != -1) + tst_resm(TFAIL, + "sched_setaffinity() unexpectedly succeded"); + + if (TEST_ERRNO == test_cases[i].exp_errno) { + tst_resm(TPASS, "expected failure with '%s'", + strerror(test_cases[i].exp_errno)); + } else { + tst_resm(TFAIL, + "call returned '%s', expected - '%s'", + strerror(TEST_ERRNO), + strerror(test_cases[i].exp_errno)); + } + } + cleanup(); + } + + tst_exit(); +} -- 1.7.1 ------------------------------------------------------------------------------ "Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE Instantly run your Selenium tests across 300+ browser/OS combos. Get unparalleled scalability from the best Selenium testing platform available. Simple to use. Nothing to install. Get started now for free." http://p.sf.net/sfu/SauceLabs _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list