aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2012-12-22 18:56:06 +0000
committerFelix Fietkau <nbd@openwrt.org>2012-12-22 18:56:06 +0000
commit606173432325a828bd55744857cbfd690ad9c4cf (patch)
tree933b0c1821ed2fff5e58f4d6649dff1399005e3c
parentb0c855253bee73b431ae150b4ff4aa315bca73b7 (diff)
downloadupstream-606173432325a828bd55744857cbfd690ad9c4cf.tar.gz
upstream-606173432325a828bd55744857cbfd690ad9c4cf.tar.bz2
upstream-606173432325a828bd55744857cbfd690ad9c4cf.zip
procd: add initial implementation
procd is the new OpenWrt process management daemon. It keeps track of processes started from init scripts (via ubus calls), and can suppress redundant service start/restart requests when the config/environment has not changed. SVN-Revision: 34865
-rw-r--r--package/procd/Makefile37
-rw-r--r--package/procd/files/procd.init19
-rw-r--r--package/procd/files/procd.sh171
3 files changed, 227 insertions, 0 deletions
diff --git a/package/procd/Makefile b/package/procd/Makefile
new file mode 100644
index 0000000000..0330905577
--- /dev/null
+++ b/package/procd/Makefile
@@ -0,0 +1,37 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=procd
+PKG_VERSION:=2012-12-20
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://nbd.name/luci2/procd.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=d343dd9e9a64d4ae7d225ea29169e97fa8d116a1
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+CMAKE_INSTALL:=1
+
+PKG_LICENSE:=GPLv2
+PKG_LICENSE_FILES:=
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/procd
+ SECTION:=base
+ CATEGORY:=Base system
+ DEPENDS:=+ubusd +ubus
+ TITLE:=OpenWrt system process manager
+endef
+
+define Package/procd/install
+ $(INSTALL_DIR) $(1)/sbin $(1)/lib/functions $(1)/etc/init.d
+
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/procd $(1)/sbin/
+ $(INSTALL_BIN) ./files/procd.init $(1)/etc/init.d/procd
+ $(INSTALL_DATA) ./files/procd.sh $(1)/lib/functions/
+endef
+
+$(eval $(call BuildPackage,procd))
diff --git a/package/procd/files/procd.init b/package/procd/files/procd.init
new file mode 100644
index 0000000000..3df5f48e60
--- /dev/null
+++ b/package/procd/files/procd.init
@@ -0,0 +1,19 @@
+#!/bin/sh /etc/rc.common
+
+START=11
+
+start_stop() {
+ start-stop-daemon $1 -b -m -p /var/run/procd.pid -x /sbin/procd
+}
+
+start() {
+ start_stop -S
+}
+
+reload() {
+ return
+}
+
+stop() {
+ start_stop -K
+}
diff --git a/package/procd/files/procd.sh b/package/procd/files/procd.sh
new file mode 100644
index 0000000000..e771e0c156
--- /dev/null
+++ b/package/procd/files/procd.sh
@@ -0,0 +1,171 @@
+# procd API:
+#
+# procd_open_service(name, [script]):
+# Initialize a new procd command message containing a service with one or more instances
+#
+# procd_close_service()
+# Send the command message for the service
+#
+# procd_open_instance([name]):
+# Add an instance to the service described by the previous procd_open_service call
+#
+# procd_set_param(type, [value...])
+# Available types:
+# command: command line (array).
+# env: environment variable (passed to the process)
+# data: arbitrary name/value pairs for detecting config changes (table)
+# file: configuration files (array)
+# netdev: bound network device (detects ifindex changes)
+#
+# No space separation is done for arrays/tables - use one function argument per command line argument
+#
+# procd_close_instance():
+# Complete the instance being prepared
+#
+# procd_kill(service, [instance]):
+# Kill a service instance (or all instances)
+#
+
+. $IPKG_INSTROOT/usr/share/libubox/jshn.sh
+
+_PROCD_SERVICE=
+
+_procd_call() {
+ local old_cb
+
+ json_set_namespace procd old_cb
+ "$@"
+ json_set_namespace $old_cb
+}
+
+_procd_wrapper() {
+ while [ -n "$1" ]; do
+ eval "$1() { _procd_call _$1 \"\$@\"; }"
+ shift
+ done
+}
+
+_procd_ubus_call() {
+ local cmd="$1"
+
+ ubus call service "$cmd" "$(json_dump)"
+ json_cleanup
+}
+
+_procd_open_service() {
+ local name="$1"
+ local script="$2"
+
+ _PROCD_SERVICE="$name"
+ _PROCD_INSTANCE_SEQ=0
+
+ json_init
+ json_add_string name "$name"
+ [ -n "$script" ] && json_add_string script "$script"
+ json_add_object instances
+}
+
+_procd_close_service() {
+ json_close_object
+ _procd_ubus_call set
+}
+
+_procd_add_array_data() {
+ while [ -n "$1" ]; do
+ json_add_string "" "$1"
+ shift
+ done
+}
+
+_procd_add_array() {
+ json_add_array "$1"
+ shift
+ _procd_add_array_data "$@"
+ json_close_array
+}
+
+_procd_add_table_data() {
+ while [ -n "$1" ]; do
+ local var="${1%%=*}"
+ local val="${1#*=}"
+ [[ "$1" == "$val" ]] && val=
+ json_add_string "$var" "$val"
+ shift
+ done
+}
+
+_procd_add_table() {
+ json_add_object "$1"
+ shift
+ _procd_add_table_data "$@"
+ json_close_object
+}
+
+_procd_open_instance() {
+ local name="$1"; shift
+
+ _PROCD_INSTANCE_SEQ="$(($_PROCD_INSTANCE_SEQ + 1))"
+ name="${name:-instance$_PROCD_INSTANCE_SEQ}"
+ json_add_object "$name"
+}
+
+_procd_set_param() {
+ local type="$1"; shift
+
+ case "$type" in
+ env|data)
+ _procd_add_table "$type" "$@"
+ ;;
+ command|netdev|file)
+ _procd_add_array "$type" "$@"
+ ;;
+ nice)
+ json_add_int "$type" "$1"
+ ;;
+ esac
+}
+
+_procd_append_param() {
+ local type="$1"; shift
+
+ json_select "$type"
+ case "$type" in
+ env|data)
+ _procd_add_table_data "$@"
+ ;;
+ command|netdev|file)
+ _procd_add_array_data "$@"
+ ;;
+ esac
+ json_select ..
+}
+
+_procd_close_instance() {
+ json_close_object
+}
+
+_procd_add_instance() {
+ _procd_open_instance
+ _procd_set_command "$@"
+ _procd_close_instance
+}
+
+_procd_kill() {
+ local service="$1"
+ local instance="$2"
+
+ json_init
+ [ -n "$service" ] && json_add_string service "$service"
+ [ -n "$instance" ] && json_add_string instance "$instance"
+ _procd_ubus_call delete
+}
+
+_procd_wrapper \
+ procd_open_service \
+ procd_close_service \
+ procd_add_instance \
+ procd_open_instance \
+ procd_close_instance \
+ procd_set_param \
+ procd_append_param \
+ procd_kill