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: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: 2023/08/29 07:45 by kaiwan