Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.4
ibmrtpkgs
update_rtcheck_to_0_7_4-bnc431066.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File update_rtcheck_to_0_7_4-bnc431066.diff of Package ibmrtpkgs
diff -Napur ibmrtpkgs-2/Makefile ibmrtpkgs-2.new/Makefile --- ibmrtpkgs-2/Makefile 2008-11-03 20:48:40.634153000 +0100 +++ ibmrtpkgs-2.new/Makefile 2008-11-03 21:10:17.711927000 +0100 @@ -1,6 +1,6 @@ ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) -SUBDIRS = rtcheck-0.6-5 rt-watchdog +SUBDIRS = rtcheck rt-watchdog all: set -e ; for dir in $(SUBDIRS) ; do \ diff -Napur ibmrtpkgs-2/rtcheck/CHANGELOG ibmrtpkgs-2.new/rtcheck/CHANGELOG --- ibmrtpkgs-2/rtcheck/CHANGELOG 1970-01-01 01:00:00.000000000 +0100 +++ ibmrtpkgs-2.new/rtcheck/CHANGELOG 2008-11-03 20:52:40.855689000 +0100 @@ -0,0 +1,91 @@ +November 3rd, 2008 +Alex Tsariounov <alext@novell.com> +- Update to version 0.7-4 as shipped by IBM on bnc#431066 +- Remove version number from rtcheck directory + +0.6-5: +May 2nd, 2008 +"Vernon Mauery <vernux@us.ibm.com>" +* Added fflush() for printf's with no trailing '\n' + +0.6-4: +June 1st, 2007 +"Timothy R. Chavez" <tim.chavez@linux.vnet.ibm.com> +* Fixed print_help() to print to "stdout" rather than "stderr" + and exit with success rather than failure +* Makefile will now update /etc/rc.local to call 'rtcheck' + per-boot upon installation of 'rtcheck' +June 5th, 2007 +* Added exit(0) to -V (print version) option +* Added back check for IRQs as threads (this time using the + correct return code) for verify_preempt_rt() +* Removed 'len' variable in verify_mlock(). Using BUF_LEN + is sufficient now. +* Define __USE_UNIX98 and _XOPEN_SOURCE in Makefile via -D + rather then hardcoding it into 'rtcheck' + +0.6-3: +May 31st, 2007 +"Timothy R. Chavez" <tim.chavez@linux.vnet.ibm.com> +* Simplified file read in fetch_rtcheck_status() with fread() +* Added flags to display Version, ignore cache result and + Force execution of all tests, and display a Help message +* Fixed array "underflow" bug in verify_mlock() +* Removed duplicate sched_getparam() test in verify_sched() +* Replaced references to RHEL5-RT with RHEL-RT +* Removed references to Java in verbose message output +* Corrected spelling mistakes +* Reverted verify_preempt_rt() test with check for + /proc/loadavgrt; rtcheck now relies on /proc to make + determinations on rt capabilities - oh well +* Added Makefile, README, and CHANGELOG +* Fixed return values on do_[user|global]_tests() +* Removed superfulous whitespace + +0.6-2: +May 30th, 2007 +"Timothy R. Chavez" <tim.chavez@linux.vnet.ibm.com> +* Removed references to Java, making 'rtcheck' more generic + real-time capabilities checker +* Changed verify_sched() to test for SCHED_FIFO rather than + SCHED_RR; stronger statement +* Added check to verify_sched() to ensure real-time scheduling + policy took +* Simplified file read when getting 'boot_id' of system +* Added warning on failed write to cache file +* Fixed minor nits (e.g. using exit() in main function rather + return) +* Removed legacy cruft (e.g. unused #define's) from 0.5 and + 0.6-1 +* Removed any attempt to write result status of Global tests + to cache file if the system 'boot_id' was not successfully + retrieved. The cache _must_ be validated with a 'boot_id'. +"Vernon Mauery" <vernux@us.ibm.com> +* Fixed buffer overflows on 'boot_id''s +* Separated tests into two categories: global and user. Only + Global test results can be safely cached. User test results + may very, depending on the user executing 'rtcheck'. + +0.6-1: +May 29th, 2007 +"Timothy R. Chavez" <tim.chavez@linux.vnet.ibm.com> +* Major revision of 'rtcheck' to move away from /proc interface + and symbol maps. + - Added ability to cache result status. A cached value will + be used, if possible. If cached value a success, no tests + need to be re-run. In normal case, allows 'rtcheck' to be + run _once_ per-boot. + - Lookup symbols and make actual function calls for each symbol + to determine user and kernel support for Robust Mutexes + - Sample time measurements of nanosleep to determine presence + of HRTimers based on timer resolution. + - Determine if IRQs are threads to deduce CONFIG_PREEMPT_RT=y + on running system + +0.5: +May 7th, 2007 +"Timothy R. Chavez" <tim.chavez@linux.vnet.ibm.com> +* Added kernel symbol checker to Robust Mutex test +* Removed 'uname' check with a test to determine + CONFIG_PREEMPT_RT=y for running system using /proc/loadavgrt +* Added HRTimer discovery test using /proc/timer_list diff -Napur ibmrtpkgs-2/rtcheck/INSTALL ibmrtpkgs-2.new/rtcheck/INSTALL --- ibmrtpkgs-2/rtcheck/INSTALL 1970-01-01 01:00:00.000000000 +0100 +++ ibmrtpkgs-2.new/rtcheck/INSTALL 2008-10-28 20:40:28.100035000 +0100 @@ -0,0 +1,5 @@ +As root, + + # make && make install + +The "rtcheck" program will install to /usr/local/bin. diff -Napur ibmrtpkgs-2/rtcheck/Makefile ibmrtpkgs-2.new/rtcheck/Makefile --- ibmrtpkgs-2/rtcheck/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ ibmrtpkgs-2.new/rtcheck/Makefile 2008-10-28 20:40:28.102034000 +0100 @@ -0,0 +1,27 @@ +CC = gcc + +CFLAGS = -g -O2 -W -Wall -D_XOPEN_SOURCE=600 -D__USE_UNIX98=1 + +LIBS = -ldl -lpthread -lrt + +%.o: %.c + $(CC) -c -o $@ $< $(CFLAGS) + +.PHONEY: all clean install + +build: all + +all: rtcheck + +rtcheck: rtcheck.o + $(CC) -o $@ $< $(CFLAGS) $(LIBS) + +install: rtcheck + install -o root -g root -m 511 -s rtcheck /usr/bin + @echo -n "Updating /etc/rc.local to run 'rtcheck' on boot... " + @sed -i '/\/usr\/bin\/rtcheck/d' /etc/rc.local + @echo "/usr/bin/rtcheck" >> /etc/rc.local + @echo "done" + +clean: + rm -f *.o rtcheck diff -Napur ibmrtpkgs-2/rtcheck/README ibmrtpkgs-2.new/rtcheck/README --- ibmrtpkgs-2/rtcheck/README 1970-01-01 01:00:00.000000000 +0100 +++ ibmrtpkgs-2.new/rtcheck/README 2008-10-28 20:40:28.104035000 +0100 @@ -0,0 +1,43 @@ +The 'rtcheck' program is an application that tests the running system for +real-time capabilities and reports back a 0 if all capabilities it looks +for are identified and an error mask describing the capabilties that are +not present, otherwise. This program can be used by real-time-enabled +programs to determine if the environment they are in is suitable for +them to run [correctly]. + +The 'rtcheck' program performs the following tests: + +Memory Lock: +------------ +Verify user ability to mlock ~32K of memory. Not actually a real-time +capability, but because the JVM is the only program using 'rtcheck' +currently, it's simplest to keep it here. + +Scheduler: +---------- +Exercise the scheduler API to determine if it supports real-time; namely +setting the scheduler to SCHED_FIFO. If it takes, we know we have this +capability. We can also imply from this that SCHED_RR can also be set. + +CONFIG_PREEMPT_RT: +------------------ +Look for the precense of /proc/loadavgrt. If found, we can deduce that +the system is running with CONFIG_PREEMPT_RT=y. + +Robust Mutexes: +--------------- +Do lookups on a few symbols indicative of user space support of robust +mutexes and then do test calls of them to confirm kernel support of +robust mutexes. + +High Resolution Timers: +----------------------- +Nanosleep is timed repeatedly using gettimeofday() calls and the median +value is compared against a threshold large enough to be infeasible on a +system using hrtimers and small enough to be too fine-grained for a +system not using hrtimers. The threshold currently being used is 20us. + +Clock Resolution: +----------------- +Make sure the clock resolution is under ~200us. + diff -Napur ibmrtpkgs-2/rtcheck/rtcheck.c ibmrtpkgs-2.new/rtcheck/rtcheck.c --- ibmrtpkgs-2/rtcheck/rtcheck.c 1970-01-01 01:00:00.000000000 +0100 +++ ibmrtpkgs-2.new/rtcheck/rtcheck.c 2008-11-03 20:50:15.020672000 +0100 @@ -0,0 +1,586 @@ +/* + * rt_check.c -- Check for real-time capabilities on the running system. + * + * Returns 0 on success, and non-zero on failure. The failure will indicate + * what necessary feature was not present. + * + * 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; version 2 of the License. + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright © International Business Machines Corp., 2006-2008 + * + * Author(s): + * Theodore Ts'o + * Timothy R. Chavez <tinytim@us.ibm.com> + * Vernon Mauery <vernux@us.ibm.com> + * Darren Hart <dvhltc@us.ibm.com> + * + * Changelog: + * 09/12/2008 - Introduced printing macros to reduce code size + * 09/09/2008 - Added priority option and set SCHED_FIFO priority and + * mlockall prior to executing tests. + * 05/30/2007 - Don't cache user-dependent test results + * 05/29/2007 - Revised for RHEL5-RT inclusion (v0.6) + * 05/03/2007 - Revised for RHEL5-RT inclusion (v0.5) + * 05/08/2006 - Added verify_clockres to test whether or not clock + * resolution is within the acceptable range (<= 200us). + */ + +#include <math.h> +#include <time.h> +#include <dlfcn.h> +#include <errno.h> +#include <sched.h> +#include <signal.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <pthread.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/resource.h> + +#define VERSION "0.7-4" + +/* test error codes */ +#define FAIL_MEMLOCK 0x0001 +#define FAIL_SCHED 0x0002 +#define FAIL_ROBUST_MUTEX 0x0004 +#define FAIL_PREEMPT_RT 0x0008 +#define FAIL_HRTIMER_RES 0x0010 +#define FAIL_CLOCK_RES 0x0020 +#define FAIL_MLOCKALL 0x0040 + +/* internal error codes */ +#define FAIL_BOOT_ID_MISMATCH 0x0100 +#define FAIL_NO_CACHE 0x0200 + +#define OPT_VERBOSE 0x0001 +#define OPT_FORCE 0x0002 + +#define RT_F "/var/cache/rtcheck" +#define PROC_F "/proc/sys/kernel/random/boot_id" +#define PROC_ROOT "/proc" +#define BOOT_ID_LEN 36 + +#define US_PER_SEC 1000000 +#define NS_PER_US 1000 + +#define PRINT_RESULT(MSG, RET) \ +if (flags & OPT_VERBOSE) printf("%s: %s\n", MSG, (RET) ? "failed" : "ok") + +#define PRINTF_RESULT(FORMAT, RET, ...) \ +if (flags & OPT_VERBOSE) printf(FORMAT": %s\n", __VA_ARGS__, (RET) ? "failed" : "ok") + +#define PRINT(MSG) \ +if (flags & OPT_VERBOSE) printf(MSG) + +#define PRINTF(FORMAT, ...) \ +if (flags & OPT_VERBOSE) printf(FORMAT, __VA_ARGS__) + +static int rtcheck_priority = 95; +static int flags = 0; +static int prio_min, prio_max; + +static void print_usage(char *progname) +{ + printf("Usage: %s [-hfVv][-p rtprio]\n", progname); +} + +static void print_help(char *progname) +{ + print_usage(progname); + printf("Test system for various real-time characteristics.\n\n"); + + printf("rtcheck v%s:\n", VERSION); + printf(" -h Print help message\n"); + printf(" -f Ignore cached results, run all tests\n"); + printf(" -p prio Where prio is between %d and %d (Default %d)\n", + prio_min, prio_max, rtcheck_priority); + printf(" -v Verbose mode (implies -f\n"); + printf(" -V Version string\n"); +} + +/* Init: Lock all memory + * + * Lock all memory to avoid paging induced latencies. + */ +static uint32_t init_mlockall(void) +{ + int ret = 0; + + if (mlockall(MCL_CURRENT | MCL_FUTURE)) + ret = FAIL_MLOCKALL; + + PRINT_RESULT(" Locking all memory", ret); + if (ret) + PRINT("\tTests may reflect high paging latencies\n"); + + return ret; +} + +/* Init: Scheduler + * + * Setup rtcheck to run as a SCHED_FIFO task. + * + * Also verify user ability to run sched_setscheduler with SCHED_FIFO. It is + * implied that if we are able to set SCHED_FIFO, we are also able to set + * SCHED_RR. + */ +static uint32_t init_sched(void) +{ + int ret = 0; + struct sched_param param; + + param.sched_priority = rtcheck_priority; + if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) + ret |= FAIL_SCHED; + + PRINT_RESULT(" Setting up real-time scheduling", ret); + if (ret) + PRINT("\tTests may reflect high scheduling latencies\n"); + + return ret; +} + +/* Test: Memory lock + * + * Verify user ability to mlock ~32K of memory. + * + */ +#define BUF_LEN 32768 +static uint32_t verify_memlock(void) +{ + int ret = 0; + int page_size; + struct rlimit rlim; + static char *buf; + char *ptr; + static int mlen = 255; + char failure_msg[mlen]; + + page_size = sysconf(_SC_PAGESIZE); + + buf = (char *)malloc(BUF_LEN+page_size-1); + if (!buf) { + snprintf(failure_msg, mlen, "malloc: %s", strerror(errno)); + ret = FAIL_MEMLOCK; + } else { + /* + * Make sure the pointer is page aligned and the length is a + * multiple of a page size. Not strictly required by Linux, + * but some OS's may require this. + */ + ptr = (char *)((unsigned long)(buf + page_size - 1) & + ~(page_size - 1)); + + if (mlock(ptr, BUF_LEN) < 0) { + snprintf(failure_msg, mlen, "mlock: %s", strerror(errno)); + ret = FAIL_MEMLOCK; + } + + if (munlock(ptr, BUF_LEN) < 0) { + snprintf(failure_msg, mlen, "munlock: %s", strerror(errno)); + ret = FAIL_MEMLOCK; + } + + if (getrlimit(RLIMIT_MEMLOCK, &rlim) < 0) { + snprintf(failure_msg, mlen, "getrlimit: %s", strerror(errno)); + ret = FAIL_MEMLOCK; + } + + if (rlim.rlim_cur != RLIM_INFINITY) { + snprintf(failure_msg, mlen, "RLIMIT_MLOCK is: %u", + (unsigned int) rlim.rlim_cur); + ret = FAIL_MEMLOCK; + } + + free(buf); + } + + PRINT_RESULT(" Trying to lock memory", ret); + if (ret) + PRINTF("\t%s\n", failure_msg); + + return ret; +} + +/* Test: CONFIG_PREEMPT_RT + * + * Verify that the kernel was compiled with CONFIG_PREEMPT_RT=y. If the IRQs + * are threads and we observe interfaces such as /proc/loadavgrt, we know the + * system is running with CONFIG_PREEMPT_RT enabled. + */ +static uint32_t verify_preempt_rt(void) +{ + int rc; + int ret = 0; + struct stat stats; + + rc = system("test `ps ax | grep -E -e 'IRQ( |-)[1-9][0-9]*' | wc -l` -ne 0"); + if (WEXITSTATUS(rc) && stat("/proc/loadavgrt", &stats)) + ret = FAIL_PREEMPT_RT; + + PRINT_RESULT(" Checking for out-of-tree RT extensions", ret); + if (ret) + PRINT("\tKernel was not built with CONFIG_PREEMPT_RT=y\n"); + + return ret; +} + +/* Test: Robust mutexes + * + * Verify that the following glibc symbols exist: + * o pthread_mutex_init + * o pthread_mutexattr_getprotocol + * o pthread_mutexattr_setprotocol + * + * Verify that the following kernel symbols exist: + * o __rt_mutex_init + * o __rt_mutex_adjust_prio + * + * The existence of these symbols implies robust mutex support in both + * the kernel and userspace. + */ +struct test_sym_t { + char *sym; + uint32_t (*do_test)(void); +}; + +static inline uint32_t test_pthread_mutex_init() +{ + pthread_mutex_t mutex; + + return pthread_mutex_init(&mutex, NULL); +} + +static inline uint32_t test_pthread_mutexattr_getprotocol() +{ + int mutex_protocol; + pthread_mutexattr_t mutex_attr; + + return (pthread_mutexattr_init(&mutex_attr) || + pthread_mutexattr_getprotocol(&mutex_attr, &mutex_protocol)); +} + +static inline uint32_t test_pthread_mutexattr_setprotocol() +{ + pthread_mutexattr_t mutex_attr; + + return (pthread_mutexattr_init(&mutex_attr) || + pthread_mutexattr_setprotocol(&mutex_attr, PTHREAD_PRIO_INHERIT)); +} + +static uint32_t verify_robust_mutex(void) +{ + int ret = 0; + struct test_sym_t *next; + struct test_sym_t syms[] = { {"pthread_mutex_init", test_pthread_mutex_init}, + {"pthread_mutexattr_getprotocol", test_pthread_mutexattr_getprotocol}, + {"pthread_mutexattr_setprotocol", test_pthread_mutexattr_setprotocol}, + {0, 0}, }; + void *dl; + void *sym_addr; + static int mlen = 255; + char failure_msg[mlen]; + + for (next = syms; next->sym != NULL; next++) { + dl = dlopen(NULL, RTLD_NOW); + sym_addr = dlsym(dl, next->sym); + dlclose(dl); + if (!sym_addr) { + snprintf(failure_msg, mlen, + "Checking for %s: not found", next->sym); + ret = FAIL_ROBUST_MUTEX; + break; + } else { + if (next->do_test()) { + snprintf(failure_msg, mlen, "Testing %s: %s", + next->sym, strerror(errno)); + ret = FAIL_ROBUST_MUTEX; + break; + } + } + } + + PRINT_RESULT(" Checking for robust (PI) mutex support", ret); + if (ret) + PRINTF("\t%s\n", failure_msg); + + return ret; +} + +/* Test: High resolution timers + * + * Verify the system can use high resolution timers. + */ +#define HRTIMER_MAX_RES 100 +static uint32_t verify_timer_res(void) +{ + int ret = 0; + struct timespec before; + struct timespec after; + struct timespec sleep = {0, (HRTIMER_MAX_RES*NS_PER_US)/2}; + long delta_us; + + clock_gettime(CLOCK_MONOTONIC, &before); + if (clock_nanosleep(CLOCK_MONOTONIC, 0, &sleep, NULL)) { + fprintf(stderr, + "clock_nanosleep returned prematurely, aborting.\n"); + exit(-1); + } + clock_gettime(CLOCK_MONOTONIC, &after); + delta_us = (after.tv_sec - before.tv_sec)*US_PER_SEC + + (after.tv_nsec - before.tv_nsec)/NS_PER_US; + + ret = (delta_us <= HRTIMER_MAX_RES) ? 0 : FAIL_HRTIMER_RES; + + PRINTF_RESULT(" Testing for acceptable hrtimer resolution (<=%dus)", + ret, HRTIMER_MAX_RES); + PRINTF("\tReporting %ldus\n", delta_us); + + return ret; +} + +/* Test: Clock Resolution + * + * Verify clock_getres returns finer resolution than 200us. + */ +#define CLOCK_MAX_RES 200 +int verify_clock_res(void) +{ + int ret = 0; + struct timespec ts; + static int mlen = 255; + char detail_msg[mlen]; + + if (clock_getres(CLOCK_REALTIME, &ts) < 0) { + snprintf(detail_msg, mlen, "clock_getres: %s\n", + strerror(errno)); + ret = FAIL_CLOCK_RES; + } else { + ret = (ts.tv_sec == 0 && ts.tv_nsec / NS_PER_US <= CLOCK_MAX_RES) ? 0 : FAIL_CLOCK_RES; + if (ts.tv_nsec < NS_PER_US) + snprintf(detail_msg, mlen, "Reporting %ldns", ts.tv_nsec); + else + snprintf(detail_msg, mlen, "Reporting %ldus", (ts.tv_nsec / NS_PER_US)); + } + + PRINTF_RESULT(" Testing for acceptable clock resolution (<=%dus)", + ret, CLOCK_MAX_RES); + PRINTF("\t%s\n", detail_msg); + + return ret; +} + +static int get_boot_id(char *boot_id) +{ + int ret = 0; + FILE *proc_f; + + boot_id[0] = 0; + proc_f = fopen(PROC_F, "r"); + if (!proc_f) { + ret = errno; + } else { + fread(boot_id, sizeof(char), BOOT_ID_LEN, proc_f); + if (ferror(proc_f)) + ret = errno; + boot_id[BOOT_ID_LEN] = 0; + fclose(proc_f); + } + + PRINTF_RESULT(" Looking up boot_id (%s)", ret, + strcmp(boot_id, "") ? boot_id : "ERROR"); + if (ret) { + PRINTF("\t%s\n", strerror(ret)); + PRINT("\tSystem test results will not be cached\n"); + } + + return ret; +} + +static int fetch_rtcheck_status(char *boot_id) +{ + int ret = 0; + FILE *rt_f = NULL; + char rt_boot_id[BOOT_ID_LEN+1]; + char rtcheck_status[3]; + + rt_f = fopen(RT_F, "r"); + if (rt_f) { + // Seek passed "boot_id" key + fseek(rt_f, 8, SEEK_CUR); + + fread(rt_boot_id, sizeof(char), BOOT_ID_LEN, rt_f); + if (!ferror(rt_f)) { + rt_boot_id[BOOT_ID_LEN] = 0; + + /* Seek passed "rtcheck" key */ + fseek(rt_f, 9, SEEK_CUR); + fgets(rtcheck_status, 3, rt_f); + + fclose(rt_f); + + if (!strcmp(rt_boot_id, boot_id)) { + ret = atoi(rtcheck_status); + } else { + ret = FAIL_BOOT_ID_MISMATCH; + } + } + } else { + if (errno == ENOENT) + ret = FAIL_NO_CACHE; + /* check other error conditions? */ + } + + /* No prints here since this routine never runs with verbose on */ + + return ret; +} + +static void store_rtcheck_status(char *boot_id, uint32_t result) +{ + FILE *rt_f; + int ret = 0; + int mlen = 255; + char failure_msg[mlen]; + + rt_f = fopen(RT_F, "w"); + if (!rt_f) { + snprintf(failure_msg, mlen, "%s could not be written to: %s", + RT_F, strerror(errno)); + ret = -1; + } else { + fprintf(rt_f, "boot_id=%s\nrtcheck=%u\n", boot_id, result); + fclose(rt_f); + } + + PRINTF_RESULT(" Caching results in %s", ret, RT_F); + if (ret) + PRINTF("\t%s\n", failure_msg); +} + +static uint32_t do_system_tests(void) +{ + uint32_t ret = 0; + + ret |= verify_preempt_rt(); + ret |= verify_robust_mutex(); + ret |= verify_timer_res(); + ret |= verify_clock_res(); + + return ret; +} + +int main(int argc, char **argv) +{ + int opt; + uint32_t ret = 0; + char boot_id[BOOT_ID_LEN+1]; + struct stat stats; + int opt_prio; + int result; + + prio_min = sched_get_priority_min(SCHED_FIFO); + if (prio_min < 0) { + perror("Failed to determine minimum SCHED_FIFO priority"); + exit(-1); + } + prio_max = sched_get_priority_max(SCHED_FIFO); + if (prio_max < 0) { + perror("Failed to determine maximum SCHED_FIFO priority"); + exit(-1); + } + + while ((opt = getopt(argc, argv, "fhp:Vv")) != EOF) { + switch (opt) { + case 'f': + flags |= OPT_FORCE; + break; + case 'h': + print_help(argv[0]); + exit(0); + case 'p': + opt_prio = atoi(optarg); + if (opt_prio < prio_min || opt_prio > prio_max) { + fprintf(stderr, "Priority out of range: %d\n", + opt_prio); + print_usage(argv[0]); + exit(-1); + } + rtcheck_priority = opt_prio; + break; + case 'v': + flags |= OPT_VERBOSE; + flags |= OPT_FORCE; /* Can't display all the + output with cached values */ + break; + case 'V': + printf("rtcheck v%s:\n", VERSION); + exit(0); + default: + print_usage(argv[0]); + exit(-1); + } + } + + if (optind > argc) { + print_usage(argv[0]); + exit(-1); + } + + if (stat(PROC_ROOT, &stats)) { + fprintf(stderr, "The /proc interface must be enabled to make some " + "determinations regarding real-time capabilities of " + "this system.\n"); + exit(-1); + } + + PRINTF("RTCheck %s - Linux Real-Time Environment Checker\n", VERSION); + PRINT("---------------------------------------------------\n"); + + PRINT("RTCheck Initialization:\n"); + ret |= init_mlockall(); /* Avoid paging induced latencies */ + ret |= init_sched(); /* Run prior to latency sensitive tests */ + + PRINT("\nSystem Tests:\n"); + if (get_boot_id(boot_id) < 0 || flags & OPT_FORCE) { + result = do_system_tests(); + store_rtcheck_status(boot_id, result); + } else { + result = fetch_rtcheck_status(boot_id); + /* Re-run if the boot_id doesn't match */ + if (result == FAIL_BOOT_ID_MISMATCH || + result == FAIL_NO_CACHE) { + result = do_system_tests(); + store_rtcheck_status(boot_id, result); + } + } + ret |= result; + + PRINT("\nUser Permission Tests:\n"); + ret |= verify_memlock(); + + if (ret) { + PRINTF("\nSome tests failed, exiting with status: %d\n", ret); + } else { + PRINT("\nAll tests passed\n"); + } + + exit(ret); +} diff -Napur ibmrtpkgs-2/rtcheck/rtcheck.sh ibmrtpkgs-2.new/rtcheck/rtcheck.sh --- ibmrtpkgs-2/rtcheck/rtcheck.sh 1970-01-01 01:00:00.000000000 +0100 +++ ibmrtpkgs-2.new/rtcheck/rtcheck.sh 2008-10-28 20:40:28.106027000 +0100 @@ -0,0 +1,43 @@ +#! /bin/sh +# +# Copyright (c) 2001 SuSE GmbH Nuernberg, Germany. All rights reserved. +# +# /etc/init.d/rtcheck +# +### BEGIN INIT INFO +# Provides: rtcheck +# Required-Start: boot.localfs +# X-Should-Start: +# Required-Stop: +# Default-Start: B +# Default-Stop: +# Description: Checks for certain Real Tiem capabilities at startup +### END INIT INFO + +. /etc/rc.status + +rc_reset + +case "$1" in + start) + # + # + if [ -x /sbin/rtcheck ] ; then + /sbin/rtcheck + rc_status -v -r + fi + ;; + stop) + # skip / do nothing + ;; + status) + rc_failed 4 + rc_status -v + ;; + *) + echo "Usage: $0 {start|stop|status}" + exit 1 + ;; +esac + +rc_exit diff -Napur ibmrtpkgs-2/rtcheck-0.6-5/CHANGELOG ibmrtpkgs-2.new/rtcheck-0.6-5/CHANGELOG --- ibmrtpkgs-2/rtcheck-0.6-5/CHANGELOG 2008-11-03 20:48:40.521269000 +0100 +++ ibmrtpkgs-2.new/rtcheck-0.6-5/CHANGELOG 1970-01-01 01:00:00.000000000 +0100 @@ -1,86 +0,0 @@ -0.6-5: -May 2nd, 2008 -"Vernon Mauery <vernux@us.ibm.com>" -* Added fflush() for printf's with no trailing '\n' - -0.6-4: -June 1st, 2007 -"Timothy R. Chavez" <tim.chavez@linux.vnet.ibm.com> -* Fixed print_help() to print to "stdout" rather than "stderr" - and exit with success rather than failure -* Makefile will now update /etc/rc.local to call 'rtcheck' - per-boot upon installation of 'rtcheck' -June 5th, 2007 -* Added exit(0) to -V (print version) option -* Added back check for IRQs as threads (this time using the - correct return code) for verify_preempt_rt() -* Removed 'len' variable in verify_mlock(). Using BUF_LEN - is sufficient now. -* Define __USE_UNIX98 and _XOPEN_SOURCE in Makefile via -D - rather then hardcoding it into 'rtcheck' - -0.6-3: -May 31st, 2007 -"Timothy R. Chavez" <tim.chavez@linux.vnet.ibm.com> -* Simplified file read in fetch_rtcheck_status() with fread() -* Added flags to display Version, ignore cache result and - Force execution of all tests, and display a Help message -* Fixed array "underflow" bug in verify_mlock() -* Removed duplicate sched_getparam() test in verify_sched() -* Replaced references to RHEL5-RT with RHEL-RT -* Removed references to Java in verbose message output -* Corrected spelling mistakes -* Reverted verify_preempt_rt() test with check for - /proc/loadavgrt; rtcheck now relies on /proc to make - determinations on rt capabilities - oh well -* Added Makefile, README, and CHANGELOG -* Fixed return values on do_[user|global]_tests() -* Removed superfulous whitespace - -0.6-2: -May 30th, 2007 -"Timothy R. Chavez" <tim.chavez@linux.vnet.ibm.com> -* Removed references to Java, making 'rtcheck' more generic - real-time capabilities checker -* Changed verify_sched() to test for SCHED_FIFO rather than - SCHED_RR; stronger statement -* Added check to verify_sched() to ensure real-time scheduling - policy took -* Simplified file read when getting 'boot_id' of system -* Added warning on failed write to cache file -* Fixed minor nits (e.g. using exit() in main function rather - return) -* Removed legacy cruft (e.g. unused #define's) from 0.5 and - 0.6-1 -* Removed any attempt to write result status of Global tests - to cache file if the system 'boot_id' was not successfully - retrieved. The cache _must_ be validated with a 'boot_id'. -"Vernon Mauery" <vernux@us.ibm.com> -* Fixed buffer overflows on 'boot_id''s -* Separated tests into two categories: global and user. Only - Global test results can be safely cached. User test results - may very, depending on the user executing 'rtcheck'. - -0.6-1: -May 29th, 2007 -"Timothy R. Chavez" <tim.chavez@linux.vnet.ibm.com> -* Major revision of 'rtcheck' to move away from /proc interface - and symbol maps. - - Added ability to cache result status. A cached value will - be used, if possible. If cached value a success, no tests - need to be re-run. In normal case, allows 'rtcheck' to be - run _once_ per-boot. - - Lookup symbols and make actual function calls for each symbol - to determine user and kernel support for Robust Mutexes - - Sample time measurements of nanosleep to determine presence - of HRTimers based on timer resolution. - - Determine if IRQs are threads to deduce CONFIG_PREEMPT_RT=y - on running system - -0.5: -May 7th, 2007 -"Timothy R. Chavez" <tim.chavez@linux.vnet.ibm.com> -* Added kernel symbol checker to Robust Mutex test -* Removed 'uname' check with a test to determine - CONFIG_PREEMPT_RT=y for running system using /proc/loadavgrt -* Added HRTimer discovery test using /proc/timer_list diff -Napur ibmrtpkgs-2/rtcheck-0.6-5/INSTALL ibmrtpkgs-2.new/rtcheck-0.6-5/INSTALL --- ibmrtpkgs-2/rtcheck-0.6-5/INSTALL 2008-11-03 20:48:40.533254000 +0100 +++ ibmrtpkgs-2.new/rtcheck-0.6-5/INSTALL 1970-01-01 01:00:00.000000000 +0100 @@ -1,5 +0,0 @@ -As root, - - # make && make install - -The "rtcheck" program will install to /usr/local/bin. diff -Napur ibmrtpkgs-2/rtcheck-0.6-5/Makefile ibmrtpkgs-2.new/rtcheck-0.6-5/Makefile --- ibmrtpkgs-2/rtcheck-0.6-5/Makefile 2008-11-03 20:48:40.535252000 +0100 +++ ibmrtpkgs-2.new/rtcheck-0.6-5/Makefile 1970-01-01 01:00:00.000000000 +0100 @@ -1,27 +0,0 @@ -CC = gcc - -CFLAGS = -g -O2 -W -Wall -D_XOPEN_SOURCE=600 -D__USE_UNIX98=1 - -LIBS = -ldl -lpthread -lrt - -%.o: %.c - $(CC) -c -o $@ $< $(CFLAGS) - -.PHONEY: all clean install - -build: all - -all: rtcheck - -rtcheck: rtcheck.o - $(CC) -o $@ $< $(CFLAGS) $(LIBS) - -install: rtcheck - install -o root -g root -m 511 -s rtcheck /usr/bin - @echo -n "Updating /etc/rc.local to run 'rtcheck' on boot... " - @sed -i '/\/usr\/bin\/rtcheck/d' /etc/rc.local - @echo "/usr/bin/rtcheck" >> /etc/rc.local - @echo "done" - -clean: - rm -f *.o rtcheck diff -Napur ibmrtpkgs-2/rtcheck-0.6-5/README ibmrtpkgs-2.new/rtcheck-0.6-5/README --- ibmrtpkgs-2/rtcheck-0.6-5/README 2008-11-03 20:48:40.546239000 +0100 +++ ibmrtpkgs-2.new/rtcheck-0.6-5/README 1970-01-01 01:00:00.000000000 +0100 @@ -1,43 +0,0 @@ -The 'rtcheck' program is an application that tests the running system for -real-time capabilities and reports back a 0 if all capabilities it looks -for are identified and an error mask describing the capabilties that are -not present, otherwise. This program can be used by real-time-enabled -programs to determine if the environment they are in is suitable for -them to run [correctly]. - -The 'rtcheck' program performs the following tests: - -Memory Lock: ------------- -Verify user ability to mlock ~32K of memory. Not actually a real-time -capability, but because the JVM is the only program using 'rtcheck' -currently, it's simplest to keep it here. - -Scheduler: ----------- -Exercise the scheduler API to determine if it supports real-time; namely -setting the scheduler to SCHED_FIFO. If it takes, we know we have this -capability. We can also imply from this that SCHED_RR can also be set. - -CONFIG_PREEMPT_RT: ------------------- -Look for the precense of /proc/loadavgrt. If found, we can deduce that -the system is running with CONFIG_PREEMPT_RT=y. - -Robust Mutexes: ---------------- -Do lookups on a few symbols indicative of user space support of robust -mutexes and then do test calls of them to confirm kernel support of -robust mutexes. - -High Resolution Timers: ------------------------ -Nanosleep is timed repeatedly using gettimeofday() calls and the median -value is compared against a threshold large enough to be infeasible on a -system using hrtimers and small enough to be too fine-grained for a -system not using hrtimers. The threshold currently being used is 20us. - -Clock Resolution: ------------------ -Make sure the clock resolution is under ~200us. - diff -Napur ibmrtpkgs-2/rtcheck-0.6-5/rtcheck.c ibmrtpkgs-2.new/rtcheck-0.6-5/rtcheck.c --- ibmrtpkgs-2/rtcheck-0.6-5/rtcheck.c 2008-11-03 20:48:40.531256000 +0100 +++ ibmrtpkgs-2.new/rtcheck-0.6-5/rtcheck.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,672 +0,0 @@ -/* - * rt_check.c -- Check for real-time capabilities on the running system. - * - * Returns 0 on success, and non-zero on failure. The failure will indicate - * what necessary feature was not present. - * - * 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; version 2 of the License. - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * © Copyright IBM Corp. 2006, 2008. All rights Reserved. - * - * Author(s): - * Theodore Ts'o - * Timothy R. Chavez <tinytim@us.ibm.com> - * Vernon Mauery <vernux@us.ibm.com> - * - * Changelog: - * 05/30/2007 - Don't cache user-dependent test results - * 05/29/2007 - Revised for RHEL5-RT inclusion (v0.6) - * 05/03/2007 - Revised for RHEL5-RT inclusion (v0.5) - * 05/08/2006 - Added verify_clockres to test whether or not clock - * resolution is within the acceptable range (<= 200us). - */ - -#include <math.h> -#include <time.h> -#include <dlfcn.h> -#include <errno.h> -#include <sched.h> -#include <signal.h> -#include <stdio.h> -#include <stdarg.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <pthread.h> -#include <sys/time.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/resource.h> - -#define VERSION "0.6-4" - -#define FAIL_MEMLOCK 0x0001 -#define FAIL_SCHED 0x0002 -#define FAIL_ROBUST_MUTEX 0x0004 -#define FAIL_PREEMPT_RT 0x0008 -#define FAIL_HRTIMER_RES 0x0010 -#define FAIL_CLOCK_RES 0x0020 - -#define OPT_VERBOSE 0x0001 -#define OPT_FORCE 0x0002 - -#define FAIL_MSG "failed\n\t" - -#define RT_F "/var/cache/rtcheck" -#define PROC_F "/proc/sys/kernel/random/boot_id" -#define PROC_ROOT "/proc" -#define BOOT_ID_LEN 36 - -static void print_usage(char *progname) -{ - fprintf(stderr, "usage: %s [-hfVv]\n", progname); - exit(1); -} - -static void print_help(char *progname) -{ - printf("rtcheck v%s:\n", VERSION); - printf(" -h\tPrint help message\n"); - printf(" -f\tIgnore cached results, run all tests\n"); - printf(" -v\tVerbose mode\n"); - printf(" -V\tVersion string\n"); - printf("usage: %s [-hfVv]\n", progname); - exit(0); -} - -static uint32_t lookup_symbol(char *sym, uint32_t flags) -{ - void *dl; - - if (flags & OPT_VERBOSE) { - printf("\tchecking for %s: ", sym); - fflush(NULL); - } - - dl = dlopen(NULL, RTLD_NOW); - if (!dlsym(dl, sym)) { - if (flags & OPT_VERBOSE) { - printf("not found\n"); - } - return 1; - } - dlclose(dl); - - return 0; -} - -/* Test 1: Memory lock - * - * Verify user ability to mlock ~32K of memory. - * - */ -#define BUF_LEN 32768 -static uint32_t verify_memlock(uint32_t flags) -{ - int ret; - int page_size; - struct rlimit rlim; - static char *buf; - char *ptr; - - if (flags & OPT_VERBOSE) { - printf(" Trying to lock memory: "); - fflush(NULL); - } - - page_size = sysconf(_SC_PAGESIZE); - - buf = (char *)malloc(BUF_LEN+page_size-1); - if (!buf) { - perror("malloc"); - return FAIL_MEMLOCK; - } - - /* - * Make sure the pointer is page aligned and the length is a multiple - * of a page size. Not strictly required by Linux, but some OS's may - * require this. - */ - ptr = (char *) ((unsigned long) (buf + page_size-1) & ~(page_size-1)); - - if ((ret = mlock(ptr, BUF_LEN)) < 0) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG "mlock: %s\n", strerror(errno)); - } - free(buf); - return FAIL_MEMLOCK; - } - - if ((ret = munlock(ptr, BUF_LEN)) < 0) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG "munlock: %s\n", strerror(errno)); - } - free(buf); - return FAIL_MEMLOCK; - } - - if ((ret = getrlimit(RLIMIT_MEMLOCK, &rlim)) < 0) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG "getrlimit: %s\n", strerror(errno)); - } - free(buf); - return FAIL_MEMLOCK; - } - - if (rlim.rlim_cur != RLIM_INFINITY) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG "RLIMIT_MLOCK is %u\n", - (unsigned int) rlim.rlim_cur); - } - free(buf); - return FAIL_MEMLOCK; - } - - free(buf); - - if (flags & OPT_VERBOSE) { - printf("ok\n"); - } - - return ret; -} - -/* Test 2: Scheduler - * - * Verify user ability to run sched_setscheduler with SCHED_FIFO. It is - * implied that if we are able to set SCHED_FIFO, we are also able to set - * SCHED_RR. - */ -static uint32_t verify_sched(uint32_t flags) -{ - int ret; - int policy; - int new_policy; - struct sched_param param; - struct sched_param new_param; - - if (flags & OPT_VERBOSE) { - printf(" Trying to request real-time scheduling: "); - fflush(NULL); - } - - if ((ret = policy = sched_getscheduler(0)) < 0) { - perror("sched_getscheduler"); - return FAIL_SCHED; - } - - if ((ret = sched_getparam(0, ¶m)) < 0) { - perror("sched_getparam"); - return FAIL_SCHED; - } - - new_param = param; - new_policy = SCHED_FIFO; - new_param.sched_priority = sched_get_priority_max(new_policy); - - if ((ret = sched_setscheduler(0, new_policy, &new_param)) < 0) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG "sched_setscheduler: %s\n", - strerror(errno)); - } - return FAIL_SCHED; - } - - if ((ret = sched_getparam(0, &new_param)) < 0) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG "sched_getparam: %s\n", - strerror(errno)); - } - return FAIL_SCHED; - } - - if ((ret = sched_setscheduler(0, policy, ¶m)) < 0) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG "resetting original scheduler: %s\n", - strerror(errno)); - } - return FAIL_SCHED; - } - - if (flags & OPT_VERBOSE) { - printf("ok\n"); - } - - return ret; -} - -/* Test 3: CONFIG_PREEMPT_RT - * - * Verify that the kernel was compiled with CONFIG_PREEMPT_RT=y. If the IRQs - * are threads and we observe interfaces such as /proc/loadavgrt, we know the - * system is running with CONFIG_PREEMPT_RT enabled. - */ -static uint32_t verify_preempt_rt(uint32_t flags) -{ - int rc; - struct stat stats; - - if (flags & OPT_VERBOSE) { - printf(" Checking for out-of-tree RT extensions: "); - fflush(NULL); - } - - rc = system("test `ps ax | grep -E -e 'IRQ( |-)[1-9][0-9]*' | wc -l` -ne 0"); - if (WEXITSTATUS(rc) && stat("/proc/loadavgrt", &stats)) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG - "kernel was not built with CONFIG_PREEMPT_RT=y\n"); - } - return FAIL_PREEMPT_RT; - } - - if (flags & OPT_VERBOSE) { - printf("ok\n"); - } - - return 0; -} - -/* Test 4: Robust mutexes - * - * Verify that the following glibc symbols exist: - * o pthread_mutex_init - * o pthread_mutexattr_getprotocol - * o pthread_mutexattr_setprotocol - * - * Verify that the following kernel symbols exist: - * o __rt_mutex_init - * o __rt_mutex_adjust_prio - * - * The existence of these symbols implies robust mutex support in both - * the kernel and userspace. - */ -struct test_sym_t { - char *sym; - uint32_t (*do_test)(void); -}; - -static inline uint32_t test_pthread_mutex_init() -{ - pthread_mutex_t mutex; - - return pthread_mutex_init(&mutex, NULL); -} - -static inline uint32_t test_pthread_mutexattr_getprotocol() -{ - int mutex_protocol; - pthread_mutexattr_t mutex_attr; - - return (pthread_mutexattr_init(&mutex_attr) || - pthread_mutexattr_getprotocol(&mutex_attr, &mutex_protocol)); -} - -static inline uint32_t test_pthread_mutexattr_setprotocol() -{ - pthread_mutexattr_t mutex_attr; - - return (pthread_mutexattr_init(&mutex_attr) || - pthread_mutexattr_setprotocol(&mutex_attr, PTHREAD_PRIO_INHERIT)); -} - -static uint32_t verify_robust_mutex(uint32_t flags) -{ - struct test_sym_t *next; - struct test_sym_t syms[] = { {"pthread_mutex_init", test_pthread_mutex_init}, - {"pthread_mutexattr_getprotocol", test_pthread_mutexattr_getprotocol}, - {"pthread_mutexattr_setprotocol", test_pthread_mutexattr_setprotocol}, - {0, 0}, }; - - if (flags & OPT_VERBOSE) { - printf(" Checking for robust (PI) mutex support: "); - fflush(NULL); - } - - for (next = syms; next->sym != NULL; next++) { - if (lookup_symbol(next->sym, 0)) { - if (flags & OPT_VERBOSE) { - printf("failed\n"); - } - lookup_symbol(next->sym, flags); - return FAIL_ROBUST_MUTEX; - } else { - if (next->do_test()) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG - "\ttesting %s: %s\n", - next->sym, strerror(errno)); - } - return FAIL_ROBUST_MUTEX; - } - } - } - - if (flags & OPT_VERBOSE) { - printf("ok\n"); - } - - return 0; -} - -/* Test 5: High resolution timers - * - * Verify the system can use high resolution timers. - */ -#define HRTIMER_SAMPLE 99 -#define HRTIMER_MAX_RES 200 -static uint32_t verify_timer_res(uint32_t flags) -{ - int i; - int ret = 0; - struct timeval before; - struct timeval after; - struct timespec sleep = {0, 1}; - long period[HRTIMER_SAMPLE]; - - if (flags & OPT_VERBOSE) { - printf(" Testing for acceptable hrtimer resolution (<=%dus): ", - HRTIMER_MAX_RES); - fflush(NULL); - } - - for (i = 0; i < HRTIMER_SAMPLE; i++) { - gettimeofday(&before, NULL); - nanosleep(&sleep, NULL); - gettimeofday(&after, NULL); - period[i] = after.tv_usec - before.tv_usec; - } - - ret = (period[(int)ceil(HRTIMER_SAMPLE / 2)] <= HRTIMER_MAX_RES) ? 0 : FAIL_HRTIMER_RES; - - if (flags & OPT_VERBOSE) { - if (ret) { - printf(FAIL_MSG - "reporting %ldus\n", period[(int)ceil(HRTIMER_SAMPLE / 2)]); - } else { - printf("ok\n"); - } - } - - return ret; -} - -/* Test 6: Clock Resolution - * - * Verify clock_getres returns finer resolution than 200us. - */ -#define CLOCK_MAX_RES 200 -int verify_clock_res(uint32_t flags) -{ - int ret; - struct timespec ts; - - if (flags & OPT_VERBOSE) { - printf(" Testing for acceptable clock resolution (<=%dus): ", - CLOCK_MAX_RES); - fflush(NULL); - } - - if ((ret = clock_getres(CLOCK_REALTIME, &ts)) < 0) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG "clock_getres: %s\n", - strerror(errno)); - } - return FAIL_CLOCK_RES; - } - - ret = (ts.tv_sec == 0 && ts.tv_nsec / 1000 <= CLOCK_MAX_RES) ? 0 : FAIL_CLOCK_RES; - - if (flags & OPT_VERBOSE) { - if (ret) { - printf(FAIL_MSG - "reporting %ldus\n", (ts.tv_nsec / 1000)); - } else { - printf("ok\n"); - } - } - - return ret; -} - -static int get_boot_id(char *boot_id, uint32_t flags) -{ - int ret = 0; - FILE *proc_f; - - if (flags & OPT_VERBOSE) { - printf(" Retrieving cache validator: "); - fflush(NULL); - } - - proc_f = fopen(PROC_F, "r"); - if (!proc_f) { - ret = errno; - } else { - fread(boot_id, sizeof(char), BOOT_ID_LEN, proc_f); - if(ferror(proc_f)) { - ret = errno; - } - boot_id[BOOT_ID_LEN] = 0; - fclose(proc_f); - } - - if (flags & OPT_VERBOSE) { - if (ret) { - printf(FAIL_MSG - "'boot_id' not retrieved: %s\n", strerror(ret)); - } else { - printf("ok\n"); - } - } - - return ret; -} - -static int fetch_rtcheck_status(char *boot_id, uint32_t flags) -{ - int ret = -1; - FILE *rt_f; - char rt_boot_id[BOOT_ID_LEN+1]; - char rtcheck_status[3]; - - if (flags & OPT_VERBOSE) { - printf(" Validating cache %s: ", RT_F); - fflush(NULL); - } - - rt_f = fopen(RT_F, "r"); - if (!rt_f) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG - "cache file does not exist\n"); - } - return -1; - } - - // Seek passed "boot_id" key - fseek(rt_f, 8, SEEK_CUR); - - fread(rt_boot_id, sizeof(char), BOOT_ID_LEN, rt_f); - if (ferror(rt_f)) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG - "could not validate: %s\n", - strerror(errno)); - } - return -1; - } - rt_boot_id[BOOT_ID_LEN] = 0; - - // Seek passed "rtcheck" key - fseek(rt_f, 9, SEEK_CUR); - fgets(rtcheck_status, 3, rt_f); - - fclose(rt_f); - - if (!strcmp(rt_boot_id, boot_id)) { - ret = atoi(rtcheck_status); - } else { - if (flags & OPT_VERBOSE) - printf(FAIL_MSG - "could not validate: " - "validator key mismatch\n"); - return -1; - } - - if (flags & OPT_VERBOSE) { - printf("ok\n"); - } - - return ret; -} - -static void store_rtcheck_status(char *boot_id, uint32_t ret, uint32_t flags) -{ - FILE *rt_f; - - if (flags & OPT_VERBOSE) { - printf(" Caching results in %s: ", RT_F); - fflush(NULL); - } - - rt_f = fopen(RT_F, "w"); - if (!rt_f) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG - "%s could not be written to: %s\n", - RT_F, strerror(errno)); - } - } else { - fprintf(rt_f, "boot_id=%s\nrtcheck=%u\n", boot_id, ret); - fclose(rt_f); - if (flags & OPT_VERBOSE) - printf("ok\n"); - } -} - -static uint32_t do_global_tests(uint32_t flags) -{ - uint32_t ret = 0; - - ret |= verify_preempt_rt(flags); - ret |= verify_robust_mutex(flags); - ret |= verify_timer_res(flags); - ret |= verify_clock_res(flags); - - return ret; -} - -static uint32_t do_user_tests(uint32_t flags) -{ - uint32_t ret = 0; - - ret |= verify_memlock(flags); - ret |= verify_sched(flags); - - return ret; -} - -int main(int argc, char **argv) -{ - int opt; - uint32_t ret; - uint32_t flags = 0; - char boot_id[BOOT_ID_LEN+1]; - struct stat stats; - - while ((opt = getopt(argc, argv, "fhVv")) != EOF) { - switch (opt) { - case 'f': - flags |= OPT_FORCE; - break; - case 'h': - print_help(argv[0]); - break; - case 'v': - flags |= OPT_VERBOSE; - break; - case 'V': - printf("rtcheck v%s\n", VERSION); - exit(0); - default: - print_usage(argv[0]); - } - } - - if (optind > argc) { - print_usage(argv[0]); - } - - if (flags & OPT_VERBOSE) { - printf("RTCheck v0.6 - Linux Real-time Environment Checker\n"); - printf("--------------------------------------------------\n"); - } - - if (stat(PROC_ROOT, &stats)) { - printf("The /proc interface must be enabled to make some " - "determinations regarding real-time capabilities of " - "this system.\n"); - exit(-1); - } - - if (flags & OPT_VERBOSE) { - printf("Global tests:\n"); - } - - if (get_boot_id(boot_id, flags) < 0) { - ret = do_global_tests(flags); - } else { - if (flags & OPT_FORCE) { - ret = do_global_tests(flags); - store_rtcheck_status(boot_id, ret, flags); - } else { - ret = fetch_rtcheck_status(boot_id, flags); - if (flags & OPT_VERBOSE) { - printf(" Using cached result status: "); - } - if (ret) { - if (flags & OPT_VERBOSE) { - printf(FAIL_MSG - "result status is: %d\n " - "Re-running tests...\n", ret); - } - ret = do_global_tests(flags); - store_rtcheck_status(boot_id, ret, flags); - } else { - if (flags & OPT_VERBOSE) { - printf("ok\n"); - } - } - } - } - - if (flags & OPT_VERBOSE) { - printf("User-specific tests:\n"); - } - - ret |= do_user_tests(flags); - - if (flags & OPT_VERBOSE) { - if (ret) { - printf("Some tests failed, exiting with " - "status %d\n", ret); - } else { - printf("All tests passed\n"); - } - } - - exit(ret); -} diff -Napur ibmrtpkgs-2/rtcheck-0.6-5/rtcheck.sh ibmrtpkgs-2.new/rtcheck-0.6-5/rtcheck.sh --- ibmrtpkgs-2/rtcheck-0.6-5/rtcheck.sh 2008-11-03 20:48:40.548237000 +0100 +++ ibmrtpkgs-2.new/rtcheck-0.6-5/rtcheck.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,43 +0,0 @@ -#! /bin/sh -# -# Copyright (c) 2001 SuSE GmbH Nuernberg, Germany. All rights reserved. -# -# /etc/init.d/rtcheck -# -### BEGIN INIT INFO -# Provides: rtcheck -# Required-Start: boot.localfs -# X-Should-Start: -# Required-Stop: -# Default-Start: B -# Default-Stop: -# Description: Checks for certain Real Tiem capabilities at startup -### END INIT INFO - -. /etc/rc.status - -rc_reset - -case "$1" in - start) - # - # - if [ -x /sbin/rtcheck ] ; then - /sbin/rtcheck - rc_status -v -r - fi - ;; - stop) - # skip / do nothing - ;; - status) - rc_failed 4 - rc_status -v - ;; - *) - echo "Usage: $0 {start|stop|status}" - exit 1 - ;; -esac - -rc_exit
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor