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