This is an old revision of the document!


rpcd (OpenWrt ubus RPC backend server)

The code is published under ISC and can be found via git at git://git.openwrt.org/project/rpcd.git or via http at http://git.openwrt.org/?p=project/rpcd.git;a=summary. It's included in OpenWrt since r37877.

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:

$ mkdir -p /usr/libexec/rpcd/
$ cat << EOF > /usr/libexec/rpcd/foo
#!/bin/sh

case "$1" in
	list)
		echo '{ "bar": { "arg1": true, "arg2": 32, "arg3": "str" }, "toto": { }, "failme": {} }'
	;;
	call)
		case "$2" in
			bar)
				# read the arguments
				read input;

				# optionally log the call
				logger -t "foo" "call" "$2" "$input"

				# return json object or an array
				echo '{ "hello": "world" }'
			;;
			toto)
				# return json object
				echo '{ "something": "somevalue" }'
			;;
                        failme)
                                # return invalid
                                echo '{asdf/3454'
                        ;;
		esac
	;;
esac
EOF
$ chmod +x /usr/libexec/rpcd/foo
$ /etc/init.d/rpcd restart

This will create new ubus functions which then can be used (after restarting rpcd):

$ ubus -v list
...
'foo' @686f0592
	"bar":{"arg1":"Boolean","arg2":"Integer","arg3":"String"}
	"toto":{}
...
$ ubus call -S foo bar '{"arg1": true }'
{{"hello":"world"}}
$ ubus -S call foo toto
{"something":"somevalue"}
# ubus -S call foo failme
# echo $?
2

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. Ie, 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.

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 '/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)

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • Last modified: 2018/10/24 20:05
  • by stokito