User Tools

Site Tools


realtime:documentation:howto:applications:application_base

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
realtime:documentation:howto:applications:application_base [2017/07/15 01:49]
jithu [Memory locking] - remove duplicate
realtime:documentation:howto:applications:application_base [2023/08/29 07:45] (current)
kaiwan Add a section on leveraging the capabilities model to run the RT app as non-root (continued)
Line 14: Line 14:
 ==== Scheduling and priority ==== ==== Scheduling and priority ====
  
-The [[realtime:​documentation:​technical_basics:​sched_policy_prio|scheduling policy]] as well as the priority+The [[realtime:​documentation:​technical_basics:​sched_policy_prio:start|scheduling policy]] as well as the priority
 must be set by the application explicitly. There are two possibilities must be set by the application explicitly. There are two possibilities
 for this: for this:
Line 36: Line 36:
 See [[realtime:​documentation:​howto:​applications:​memory#​Memory Locking | here]] See [[realtime:​documentation:​howto:​applications:​memory#​Memory Locking | here]]
  
-==== Stack prefaulting ​====+==== Stack for RT thread ​====
  
-Since page faults cause non-deterministic behavior, the stack should +See [[realtime:​documentation:​howto:​applications:​memory#Stack Memory for RT threads | here]]
-be prefaulted before the real-time critical section starts. +
-In case several real-time threads are used, it should be done for each +
-thread individually. ​ In the following example, a memory ​block of a +
-certain size is allocated. ​ All of its pages are touched to get them +
-mapped into RAM ensuring that no page faults occur later.+
  
-  void *buffer;+==== Capabilities:​ running the app with RT priority as a non-root user ====
  
-  buffer = mmap(NULLMSIZEPROT_READ | PROT_WRITE,​ +Several of the Pthread APIs, like ''​mlockall()''​''​pthread_attr_setschedpolicy()''​by default and convention require root in order to successfully get their work done. ThusRT apps - which need to set an RT sched policy and priority ​-  ​are often run via ''​sudo''​. ​
-                MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +
-  memset(&​buffer,​ 0, MSIZE);+
  
-The prefaulted stack can be assigned to a thread. ​ (''&​attr''​ is a +There'far better approach to this; ''​sudo'' ​gives the process root capabilities. This interests hackers :-). 
-''​pthread_attr_t'' ​pointer; ​the pthread attribute needs to have been +Instead, you should leverage the powerful POSIX **Capabilities** model! This way, the process (and threadsget _only_ the capabilities they require and nothing more. This follows the infosec best practice, the //principle of least privilege//​.
-previously initialized):+
  
-  pthread_attr_setstack(&attrbufferPTHREAD_STACK_MIN);+Apps start out with no capabilities by default; also note that capabilities are a per-thread resource ​(essentially translating to bitmasks with the task structure,which is per-thread of course). Among the various capability bitsthe man page on ''​capabilities(7)''​ shows that **''​CAP_SYS_NICE''​** is the appropriate capability to use in this circumstancea snippet from the ''​capabilities(7)''​ man page reveals this: 
 + 
 +... 
 +**CAP_SYS_NICE** 
 +  * Lower the process nice value (nice(2), setpriority(2)) and change the nice value for arbitrary processes;​ 
 +  * **set  real-time ​ scheduling ​ policies ​ for  calling process, and set scheduling policies and priorities for arbitrary processes (sched_setscheduler(2),​ sched_setparam(2),​ sched_setattr(2));​** 
 +  * set CPU affinity for arbitrary processes (sched_setaffinity(2));​ 
 +  * set I/O scheduling class and priority for arbitrary processes (ioprio_set(2));​ 
 +  * apply migrate_pages(2) to arbitrary processes and allow processes to be migrated to arbitrary nodes; 
 +  * apply move_pages(2) to arbitrary processes;​ 
 +  * use the MPOL_MF_MOVE_ALL flag with mbind(2) and move_pages(2). ... 
 + 
 + 
 +**//Ok, great, but how exactly is this capability bit to be set on the app?// 
 +** 
 +  - One approach is to do so programatically,​ via the ''​capget()/​capset()''​ system calls. (Note that's it's generally easier to use the libcap library wrappers, ''​cap_[g|s]et_proc(3)'':​ [[https://​man7.org/​linux/​man-pages/​man3/​cap_get_proc.3.html]]. This man page even provides a small example of doing so). 
 +  - Another easy way is to leverage systemd and run your app as a service; in the service unit, specify the capability (see the man page on systemd.exec(5);​ [[https://​www.freedesktop.org/​software/​systemd/​man/​systemd.exec.html#​Capabilities]]. 
 +  - Perhaps the easiest way: via the ''​setcap(8)''​ utility (it's man page: [[https://​man7.org/​linux/​man-pages/​man8/​setcap.8.html]]). The setcap/​getcap are typically part of the libcap package. For example: 
 +    ''​sudo setcap CAP_SYS_NICE+eip <​your-app-binary-executable>''​ 
 + 
 +You could put this line in the app Makefile (or equivalent). 
 +(The ''​getcap(8)''​ utility can be used to verify that the '​dumb-capability'​ binary now has the ''​CAP_SYS_NICE''​ bit set)! 
 + 
 +And you're all set to run it as non-root now, a much more secure approach.
  
 ===== Example ===== ===== Example =====
realtime/documentation/howto/applications/application_base.1500083368.txt.gz · Last modified: 2017/07/15 01:49 by jithu