diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 414aec7f6aa..27b9af4bcc2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,8 +29,12 @@ jobs: ./configure --with-realtime=uspace --disable-check-runtime-deps make -O -j$((1+$(nproc))) default pycheck V=1 # Note that the package build covers html docs - ../scripts/rip-environment runtests -p - + sudo setcap cap_ipc_lock,cap_net_admin,cap_sys_rawio,cap_sys_nice+ep ../bin/rtapi_app + timeout --signal=9 3600 ../scripts/rip-environment runtests -vp || \ + ([ -e ~/linuxcnc_debug.txt ] && (echo linuxcnc_debug.txt; cat ~/linuxcnc_debug.txt); \ + [ -e ~/linuxcnc_print.txt ] && (echo linuxcnc_print.txt; cat ~/linuxcnc_print.txt); \ + false) + htmldocs: runs-on: ubuntu-16.04 steps: diff --git a/src/hal/drivers/mesa-hostmot2/hm2_eth.c b/src/hal/drivers/mesa-hostmot2/hm2_eth.c index 840cd05e5e0..fb37501a4ee 100644 --- a/src/hal/drivers/mesa-hostmot2/hm2_eth.c +++ b/src/hal/drivers/mesa-hostmot2/hm2_eth.c @@ -368,7 +368,7 @@ static bool chain_exists() { return result == EXIT_SUCCESS; } -static int iptables_state = -1; +static int iptables_state = 0; static bool use_iptables() { if(iptables_state == -1) { if(!chain_exists()) { diff --git a/src/rtapi/uspace_common.h b/src/rtapi/uspace_common.h index f2832ec9b09..50ab6037557 100644 --- a/src/rtapi/uspace_common.h +++ b/src/rtapi/uspace_common.h @@ -321,32 +321,6 @@ int rtapi_exit(int module_id) } int rtapi_is_kernelspace() { return 0; } -static int _rtapi_is_realtime = -1; -#ifdef __linux__ -static int detect_preempt_rt() { - struct utsname u; - int crit1, crit2 = 0; - FILE *fd; - - uname(&u); - crit1 = strcasestr (u.version, "PREEMPT RT") != 0; - - //"PREEMPT_RT" is used in the version string instead of "PREEMPT RT" starting with kernel version 5.4 - crit1 = crit1 || (strcasestr(u.version, "PREEMPT_RT") != 0); - - if ((fd = fopen("/sys/kernel/realtime","r")) != NULL) { - int flag; - crit2 = ((fscanf(fd, "%d", &flag) == 1) && (flag == 1)); - fclose(fd); - } - - return crit1 && crit2; -} -#else -static int detect_preempt_rt() { - return 0; -} -#endif #ifdef USPACE_RTAI static int detect_rtai() { struct utsname u; @@ -369,22 +343,9 @@ static int detect_xenomai() { return 0; } #endif -static int detect_env_override() { - char *p = getenv("LINUXCNC_FORCE_REALTIME"); - return p != NULL && atoi(p) != 0; -} - -static int detect_realtime() { - struct stat st; - if ((stat(EMC2_BIN_DIR "/rtapi_app", &st) < 0) - || st.st_uid != 0 || !(st.st_mode & S_ISUID)) - return 0; - return detect_env_override() || detect_preempt_rt() || detect_rtai() || detect_xenomai(); -} int rtapi_is_realtime() { - if(_rtapi_is_realtime == -1) _rtapi_is_realtime = detect_realtime(); - return _rtapi_is_realtime; + return 1; // now it's always realtime } /* Like clock_nanosleep, except that an optional 'estimate of now' parameter may @@ -397,7 +358,7 @@ static int rtapi_clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *pnow) { #if defined(HAVE_CLOCK_NANOSLEEP) - return clock_nanosleep(clock_id, flags, prequest, remain); + return TEMP_FAILURE_RETRY(clock_nanosleep(clock_id, flags, prequest, remain)); #else if(flags == 0) return nanosleep(prequest, remain); diff --git a/src/rtapi/uspace_rtapi_app.cc b/src/rtapi/uspace_rtapi_app.cc index 69a71e69b67..8c2922fda24 100644 --- a/src/rtapi/uspace_rtapi_app.cc +++ b/src/rtapi/uspace_rtapi_app.cc @@ -598,10 +598,8 @@ struct PosixTask : rtapi_task struct Posix : RtapiApp { - Posix(int policy = SCHED_FIFO) : RtapiApp(policy), do_thread_lock(policy != SCHED_FIFO) { + Posix(int policy = SCHED_FIFO) : RtapiApp(policy) { pthread_once(&key_once, init_key); - if(do_thread_lock) - pthread_mutex_init(&thread_lock, 0); } int task_delete(int id); int task_start(int task_id, unsigned long period_nsec); @@ -618,8 +616,6 @@ struct Posix : RtapiApp void do_outb(unsigned char value, unsigned int port); int run_threads(int fd, int (*callback)(int fd)); static void *wrapper(void *arg); - bool do_thread_lock; - pthread_mutex_t thread_lock; static pthread_once_t key_once; static pthread_key_t key; @@ -664,14 +660,21 @@ static void signal_handler(int sig, siginfo_t *si, void *uctx) } const size_t PRE_ALLOC_SIZE = 1024*1024*32; -const static struct rlimit unlimited = {RLIM_INFINITY, RLIM_INFINITY}; static void configure_memory() { - int res = setrlimit(RLIMIT_MEMLOCK, &unlimited); - if(res < 0) perror("setrlimit"); + struct rlimit limit; + int res = getrlimit(RLIMIT_MEMLOCK, &limit); + if(res < 0) + perror("getrlimit"); + else { + rtapi_print_msg(RTAPI_MSG_WARN,"RLIMIT_MEMLOCK: curr: %ju, max: %ju\n", + (uintmax_t)limit.rlim_cur, (uintmax_t)limit.rlim_max); - res = mlockall(MCL_CURRENT | MCL_FUTURE); - if(res < 0) perror("mlockall"); + if (limit.rlim_max >= 2* PRE_ALLOC_SIZE) { + res = mlockall(MCL_CURRENT | MCL_FUTURE); + if(res < 0) perror("mlockall"); + } + } #ifdef __linux__ /* Turn off malloc trimming.*/ @@ -703,40 +706,24 @@ static void configure_memory() static int harden_rt() { - if(!rtapi_is_realtime()) return -EINVAL; - - WITH_ROOT; #if defined(__linux__) && (defined(__x86_64__) || defined(__i386__)) if (iopl(3) < 0) { - rtapi_print_msg(RTAPI_MSG_ERR, + rtapi_print_msg(RTAPI_MSG_WARN, "cannot gain I/O privileges - " "forgot 'sudo make setuid'?\n"); - return -EPERM; } #endif struct sigaction sig_act = {}; #ifdef __linux__ - // enable realtime - if (setrlimit(RLIMIT_RTPRIO, &unlimited) < 0) - { - rtapi_print_msg(RTAPI_MSG_WARN, - "setrlimit(RTLIMIT_RTPRIO): %s\n", - strerror(errno)); - return -errno; - } + struct rlimit limit; - // enable core dumps - if (setrlimit(RLIMIT_CORE, &unlimited) < 0) - rtapi_print_msg(RTAPI_MSG_WARN, - "setrlimit: %s - core dumps may be truncated or non-existant\n", - strerror(errno)); - - // even when setuid root - if (prctl(PR_SET_DUMPABLE, 1) < 0) - rtapi_print_msg(RTAPI_MSG_WARN, - "prctl(PR_SET_DUMPABLE) failed: no core dumps will be created - %d - %s\n", - errno, strerror(errno)); + int res = getrlimit(RLIMIT_MEMLOCK, &limit); + if(res < 0) + perror("getrlimit"); + else + rtapi_print_msg(RTAPI_MSG_WARN,"RLIMIT_RTPRIO: curr: %ju, max: %ju\n", + (uintmax_t)limit.rlim_cur, (uintmax_t)limit.rlim_max); #endif /* __linux__ */ configure_memory(); @@ -776,11 +763,8 @@ static int harden_rt() static RtapiApp *makeApp() { - if(euid != 0 || harden_rt() < 0) - { - rtapi_print_msg(RTAPI_MSG_ERR, "Note: Using POSIX non-realtime\n"); - return new Posix(SCHED_OTHER); - } + harden_rt(); + WithRoot r; void *dll = nullptr; if(detect_xenomai()) { @@ -799,8 +783,7 @@ static RtapiApp *makeApp() return result; } } - rtapi_print_msg(RTAPI_MSG_ERR, "Note: Using POSIX realtime\n"); - return new Posix(SCHED_FIFO); + return new Posix(); } RtapiApp &App() { @@ -1041,10 +1024,6 @@ void *Posix::wrapper(void *arg) pthread_setspecific(key, arg); - Posix &papp = reinterpret_cast(App()); - if(papp.do_thread_lock) - pthread_mutex_lock(&papp.thread_lock); - struct timespec now; clock_gettime(RTAPI_CLOCK, &now); rtapi_timespec_advance(task->nextstart, now, task->period + task->pll_correction); @@ -1086,8 +1065,6 @@ int Posix::task_self() { } void Posix::wait() { - if(do_thread_lock) - pthread_mutex_unlock(&thread_lock); pthread_testcancel(); struct rtapi_task *task = reinterpret_cast(pthread_getspecific(key)); rtapi_timespec_advance(task->nextstart, task->nextstart, task->period + task->pll_correction); @@ -1103,8 +1080,6 @@ void Posix::wait() { int res = rtapi_clock_nanosleep(RTAPI_CLOCK, TIMER_ABSTIME, &task->nextstart, nullptr, &now); if(res < 0) perror("clock_nanosleep"); } - if(do_thread_lock) - pthread_mutex_lock(&thread_lock); } unsigned char Posix::do_inb(unsigned int port)