From 606173432325a828bd55744857cbfd690ad9c4cf Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 22 Dec 2012 18:56:06 +0000 Subject: [PATCH] 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 --- package/procd/Makefile | 37 +++++++ package/procd/files/procd.init | 19 ++++ package/procd/files/procd.sh | 171 +++++++++++++++++++++++++++++++++ 3 files changed, 227 insertions(+) create mode 100644 package/procd/Makefile create mode 100644 package/procd/files/procd.init create mode 100644 package/procd/files/procd.sh 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 + +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