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
docs:techref:rpcd [2018/10/24 20:47] – [rpcd (OpenWrt ubus RPC backend server)] stokitodocs:techref:rpcd [2023/10/14 06:08] (current) – update vgaetera
Line 1: Line 1:
 ====== rpcd: OpenWrt ubus RPC daemon for backend server ====== ====== rpcd: OpenWrt ubus RPC daemon for backend server ======
 +In OpenWrt we commonly use [[docs:techref:ubus|ubus]] for all kinds of communication. It can provide info from various software as well as request various actions. Nevertheless, not every part of OpenWrt has a daemon that can register itself using ''ubus''. For an example ''uci'' and ''opkg'' are command-line tools without any background process running all the time.
  
-In OpenWrt we commonly use [[docs:techref:ubus|ubus]] for all kinds of communication. It can provide info from various software as well as request various actions. Nevertheless, not every part of OpenWrt has a daemon that can register itself using //ubus//For an example //uci// and //opkg// are command-line tools without any background process running all the time.+It would be not efficient to write a daemon for every software like this and run them independently. This is why ''rpcd'' was developed. It’s tiny daemon with support for plugins using trivial APIIt loads library ''%%.so%%'' files and calls init function of each of them.
  
-It would be not efficient to write a daemon for every software like this and run them independently. This is why //rpcd// was developed. It’s a tiny daemon with support for plugins using trivial //API//. It loads library ''%%.so%%'' files and calls init function of each of them. +The code is published under [[wp>ISC_license|ISC license]] and can be found via git at  [[https://git.openwrt.org/project/rpcd.git]].
- +
- +
-The code is published under ISC and can be found via git at [[git://git.openwrt.org/project/rpcd.git]] or via http at [[https://git.openwrt.org/?p=project/rpcd.git]].+
  
 ==== Default plugins ==== ==== Default plugins ====
 +There are few small plugins distributed with the ''rpcd'' sources. Two of them (''session'' and ''uci'') are built-in, others are optional and have to be build as separated ''%%.so%%'' libraries. Apart from that there are other projects providing their own plugins.
  
-There are few small plugins distributed with the //rpcd// sources. Two of them (//session// and //uci//) are built-in, others are optional and have to be build as separated ''%%.so%%'' libraries. Apart from that there are other projects providing their own plugins. 
 ===== plugin executables ===== ===== plugin executables =====
 +It is possible to expose shell script functionality over ubus by using ''rpcd'' plugin executables functionality. Executables stored in ''/usr/libexec/rpcd/'' directory will be run by ''rpcd''. Lets look at the following example:
  
-It is possible to expose shell script functionality over ubus by using rpcd plugin executables functionality. Executables stored in ///usr/libexec/rpcd/// directory will be runned by rpcd. Lets look at the following example: +<code bash
- +mkdir -p /usr/libexec/rpcd 
-<code> +cat << "EOF> /usr/libexec/rpcd/foo
-mkdir -p /usr/libexec/rpcd/ +
-cat << EOF > /usr/libexec/rpcd/foo+
 #!/bin/sh #!/bin/sh
  
Line 48: Line 45:
 esac esac
 EOF EOF
-chmod +x /usr/libexec/rpcd/foo +chmod +x /usr/libexec/rpcd/foo 
-$ /etc/init.d/rpcd restart+service rpcd restart
 </code> </code>
  
 This will create new ubus functions which then can be used (after restarting rpcd): This will create new ubus functions which then can be used (after restarting rpcd):
  
-<code>+<code bash>
 $ ubus -v list foo $ ubus -v list foo
 'foo' @a9482c5b 'foo' @a9482c5b
Line 60: Line 57:
  "toto":{}  "toto":{}
  "failme":{}  "failme":{}
 +
 $ ubus -S call foo bar '{"arg1": true }' $ ubus -S call foo bar '{"arg1": true }'
 {{"hello":"world"}} {{"hello":"world"}}
 +
 $ ubus -S call foo toto $ ubus -S call foo toto
 {"something":"somevalue"} {"something":"somevalue"}
 +
 $ ubus -S call foo failme $ ubus -S call foo failme
 +
 $ echo $? $ echo $?
 2 2
 </code> </code>
  
-On startup rpcd will call all executables in ///usr/libexec/rpcd/// with //argv[1]// set to "list". For a plugin, which responds with a valid list of methods and signatures, ubus method with appropriate arguments will be created. When a method provided by the plugin is about to be invoked, rpcd calls the binary with //argv[1]// set to "calland //argv[2]// set to the invoked method name. **The actual data is then sent by the ubus client via stdin.** I.e. if you're testing the script itself, you need to use ''echo '{"arg1": 42}' | yourscript call yourmethod''.  You //cannot// simply use ''yourscript call yourmethod '{"arg1": 42}''' as you might have expected.+On startup rpcd will call all executables in ''/usr/libexec/rpcd/'' with ''argv[1]'' set to "list". For a plugin, which responds with a valid list of methods and signatures, ubus method with appropriate arguments will be created. When a method provided by the plugin is about to be invoked, ''rpcd'' calls the binary with ''argv[1]'' set to ''call'' and ''argv[2]'' set to the invoked method name. 
 + 
 +**The actual data is then sent by the ''ubus'' client via ''stdin''.** I.e. if you're testing the script itself, you need to use  
 + 
 +<code bash> 
 +echo '{"arg1": 42}' | yourscript call yourmethod 
 +</code> 
 + 
 +You //cannot// simply use ''yourscript call yourmethod '{"arg1": 42}''' as you might have expected
 + 
 +The method signature is a simple object containing ''key:value'' pairs. The argument type is inferred from the value. If the value is a string (regardless of the contents) it is registered as string, if the value is a bool true or false, its registered as bool, if the value is an integer, it is registered as either int8, int16, int32 or int64 depending on the value i.e. ''"foo": 16'' will be ''INT16'', ''"foo": 64'' will be ''INT64'', ''"foo": 8'' will be ''INT8'' and everything else will be ''INT32''.
  
-The method signature is a simple object containing //key//://value// pairs. The argument type is inferred from the value. If the value is a string (regardless of the contents) it is registered as string, if the value is a bool true or false, its registered as bool, if the value is an integer, it is registered as either int8, int16, int32 or int64 depending on the value ("foo": 16 will be INT16, "foo": 64 will be INT64"foo": 8 will be INT8 and everything else will be INT32).+It is enough to issue ''service rpcd reload'' to make it pick up new plugin executablesthat way one does not lose active sessions.
  
-It is enough to issue '/etc/init.d/rpcd reload' to make it pick up new plugin executables, that way one does not lose active sessions.  (**NOTE: **At least on CC builds, reload is //not// enough, and you must //restart// to pickup new plugins and changes to existing plugins)+**NOTE:** At least on CC builds, reload is //not// enough, and you must ''restart'' to pickup new plugins and changes to existing plugins.
  
  • Last modified: 2018/10/24 20:47
  • by stokito