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
Next revision Both sides next revision
realtime:documentation:howto:applications:application_base [2017/07/15 01:37]
jithu [Example]
realtime:documentation:howto:applications:application_base [2023/08/29 07:45]
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 34: Line 34:
 ==== Memory locking ==== ==== Memory locking ====
  
-In real-time ​applications ​it is important to avoid non-deterministic +See [[realtime:​documentation:​howto:​applications:memory#Memory Locking | here]]
-behavior. ​ If the memory ​that is needed by the real-time application +
-is not locked in the RAM, this memory could be paged out.  If the +
-memory is not paged in when the application tries to access the +
-memory, a page fault occurs causing non-deterministic high latency. +
-For this reason memory should be locked in real-time applications. +
-The memory lock persists until the process owning it terminates or +
-explicitly unlocks it by calling ''​munlock()''​ or ''​munlockall()''​. +
-Be aware that page faults due to paged out memory occur in systems +
-with swap as well as in systems without swap.  In addition, the binary +
-of the executed application itself could be paged out.+
  
-The following call of ''​mlockall()''​ locks all current pages mapped +==== Stack for RT thread ====
-into the address space of the process as well as all pages that will +
-be mapped in the future.+
  
-  mlockall(MCL_CURRENT|MCL_FUTURE);​+See [[realtime:​documentation:​howto:​applications:​memory#​Stack Memory for RT threads ​here]]
  
-==== Stack prefaulting ​====+==== Capabilities:​ running the app with RT priority as a non-root user ====
  
-Since page faults cause non-deterministic behavior, ​the stack should +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''​
-be prefaulted before the real-time critical section starts. +
-In case several real-time threads are usedit should be done for each +
-thread individually In the following examplea 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;+There'​s a far better approach to this''​sudo''​ gives the process root capabilities. This interests hackers :-). 
 +Instead, you should leverage the powerful POSIX **Capabilities** model! This way, the process (and threads) get _only_ the capabilities they require and nothing more. This follows the infosec best practice, the //principle of least privilege//​.
  
-  buffer = mmap(NULL, MSIZE, PROT_READ | PROT_WRITE,​ +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:
-                MAP_PRIVATE | MAP_ANONYMOUS, -10); +
-  memset(&​buffer,​ 0, MSIZE);+
  
-The prefaulted stack can be assigned to a thread.  (''&​attr''​ is a +... 
-''​pthread_attr_t''​ pointerthe pthread attribute needs to have been +**CAP_SYS_NICE** 
-previously initialized):+  * 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(2to arbitrary processes;​ 
 +  * use the MPOL_MF_MOVE_ALL flag with mbind(2) and move_pages(2). ...
  
-  pthread_attr_setstack(&attrbufferPTHREAD_STACK_MIN);+ 
 +**//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 unitspecify 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.txt · Last modified: 2024/05/31 15:54 by alison