Bernhard Schmidt wrote...

> Sure, feel free to push directly into the salsa repository and upload.

Well, although I probably could (salsa and I aren't friends yet), I'd
prefer some review and tests first.

So, patch attached.

    Christoph, old-school
diff --git a/debian/changelog b/debian/changelog
index 9a049a5..0c09722 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+nfdump (1.6.17-1.1) UNRELEASED; urgency=medium
+
+  * Non-maintainer upload.
+  * Add support for multiple instance, also eases support for
+    differing configuration. Closes: #644632, #843602
+
+ -- Christoph Biedl <debian.a...@manchmal.in-ulm.de>  Sat, 22 Sep 2018 21:21:43 +0200
+
 nfdump (1.6.17-1) unstable; urgency=medium
 
   * [2216e879] New upstream version 1.6.17
diff --git a/debian/default.conf b/debian/default.conf
new file mode 100644
index 0000000..c7c81e5
--- /dev/null
+++ b/debian/default.conf
@@ -0,0 +1,28 @@
+
+# default configuration for nfcapd
+
+# The cache directory
+#
+# In a single-instance setup, there's nothing to configure here.
+# In a multi-instance setup, you must either make sure the cache
+# directory used is created by other means - or configure it here,
+# it will be created upon start then, optionally ownership changed to
+# the given user and group (default: root:root).
+#
+#cache_directory=/var/cache/nfdump
+#user=root
+#group=root
+
+# Options for this nfcapd instance, see nfcapd(1)
+#
+# Caveats:
+# - You must define a base directory (-l or -M), this is *not* checked.
+# - When using -l for the cache directory, you must give each instance
+#   a separate directory, else all but the first instance will not
+#   start.
+# - Any cache_dir, user and group values defined above needs to be
+#   repeated here in an according option (-l/-M, -u, -g).
+#   Remember, shell expandsion will not work when using systemd.
+# - Do not use the -D and -P options, they are already set internally.
+#
+options='-l /var/cache/nfdump -p 2055'
diff --git a/debian/nfdump-generator b/debian/nfdump-generator
new file mode 100755
index 0000000..88841a3
--- /dev/null
+++ b/debian/nfdump-generator
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+set -eu
+
+SERVICEFILE="/lib/systemd/system/nfdump@.service"
+WANTDIR="$1/nfdump.service.wants"
+
+CONFIG_DIR=/etc/nfdump/
+
+if [ -d "$CONFIG_DIR" ] ; then
+    mkdir -p "$WANTDIR"
+    cd "$CONFIG_DIR"
+    for CONFIG in *.conf ; do
+        [ -f "$CONFIG" ] || continue
+        INSTANCE="$(systemd-escape "${CONFIG%%.conf}")"
+        LINK="$WANTDIR/nfdump@$INSTANCE.service"
+
+        sh -n "$CONFIG_DIR$CONFIG" 2>/dev/null || continue
+
+        cache_dir=
+        user=
+        group=
+        options=
+
+        . "$CONFIG_DIR$CONFIG"
+
+        [ "$options" ] || continue
+        if [ "$cache_dir" ] ; then
+            mkdir -p "$cache_dir"
+            if [ "$user" ] && [ "$group" ] ; then
+                chown "$user:$group" "$cache_dir"
+            elif [ "$user" ] ; then
+                chown "$user" "$cache_dir"
+            fi
+        fi
+
+        ln -s "$SERVICEFILE" "$LINK"
+    done
+fi
+
+exit 0
diff --git a/debian/nfdump.init b/debian/nfdump.init
index fb64ad5..82e6006 100644
--- a/debian/nfdump.init
+++ b/debian/nfdump.init
@@ -1,158 +1,176 @@
-#! /bin/sh
+#!/bin/sh
+
 ### BEGIN INIT INFO
-# Provides:          nfcapd
-# Required-Start:    $remote_fs $network
-# Required-Stop:     $remote_fs
+# Provides:          netflow capture daemon
+# Required-Start:    $network $remote_fs $syslog
+# Required-Stop:     $network $remote_fs $syslog
 # Default-Start:     2 3 4 5
 # Default-Stop:      0 1 6
-# Short-Description: netflow capture daemon
-# Description:       nfcapd is the netflow capture daemon of the nfdump tools.
+# Short-Description: Flow-based network traffic analyser
+# Description:       Manage all nfcapd instanaces defined in
+#                    /etc/nfdump/*.conf
 ### END INIT INFO
 
-# Author: Erik Wenzel <e...@debian.org>
-
-# Do NOT "set -e"
-
-# PATH should only include /usr/* if it runs after the mountnfs.sh script
 PATH=/sbin:/usr/sbin:/bin:/usr/bin
-DESC="netflow capture daemon"
 NAME=nfcapd
-DAEMON=/usr/bin/$NAME
-DATA_BASE_DIR="/var/cache/nfdump"
-PIDFILE=/var/run/$NAME.pid
-DAEMON_ARGS="-D -l $DATA_BASE_DIR -P $PIDFILE"
-SCRIPTNAME=/etc/init.d/nfdump
+DESC='Netflow capture daemon'
+NFCAPD='/usr/bin/nfcapd'
+PIDDIR="/var/run/$NAME/"
 
-# Exit if the package is not installed
-[ -x "$DAEMON" ] || exit 0
+[ -x "$NFCAPD" ] || exit 0
 
-# Read configuration variable file if it is present
-[ -r /etc/default/nfdump ] && . /etc/default/nfdump
+mkdir -p "$PIDDIR"
 
 # Load the VERBOSE setting and other rcS variables
 . /lib/init/vars.sh
 
-# Define LSB log_* functions.
-# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
+# Define LSB functions
 . /lib/lsb/init-functions
 
+# Start a nfcapd instance
 #
-# Function that starts the daemon/service
-#
-do_start()
-{
-	# Don't start daemon in this mode. Defined in /etc/default/nfdump
-	if [ x"$nfcapd_start" = xno ]
-	then
-		[ "$VERBOSE" != no ] && log_warning_msg "nfdump daemon not enabled in /etc/default/nfdump, not starting..."
-		return 0
-	fi
-	# Return
-	#   0 if daemon has been started
-	#   1 if daemon was already running
-	#   2 if daemon could not be started
-	start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
-		|| return 1
-	start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
-		$DAEMON_ARGS \
-		|| return 2
-	# Add code here, if necessary, that waits for the process to be ready
-	# to handle requests from services started subsequently which depend
-	# on this one.  As a last resort, sleep for some time.
+# Return
+#   0 if daemon has been started
+#   1 if daemon was already running
+#   2 if daemon could not be started
+do_start () {
+    local INSTANCE="$1"
+    local CONFIG="$2"
+
+    sh -n "$CONFIG" 2>/dev/null || return 2
+
+    cache_dir=
+    user=
+    group=
+    options=
+
+    . "$CONFIG"
+
+    [ "$options" ] || return 2
+
+    if [ "$cache_dir" ] ; then
+        mkdir -p "$cache_dir"
+        if [ "$user" ] && [ "$group" ] ; then
+            chown "$user:$group" "$cache_dir"
+        elif [ "$user" ] ; then
+            chown "$user" "$cache_dir"
+        fi
+    fi
+
+    local PIDFILE="$PIDDIR$INSTANCE.pid"
+    start-stop-daemon --start --quiet \
+        --pidfile "$PIDFILE" --exec "$NFCAPD" --test > /dev/null \
+        || return 1
+    start-stop-daemon --start --quiet \
+        --pidfile "$PIDFILE" \
+        --exec "$NFCAPD" -- \
+        -D -P "$PIDFILE" \
+        $options \
+        || return 2
+    sleep 1
+    start-stop-daemon --start --quiet \
+        --pidfile "$PIDFILE" --exec "$NFCAPD" --test > /dev/null \
+        && return 2
 }
 
+# Stop a nfcapd instance
 #
-# Function that stops the daemon/service
-#
-do_stop()
-{
-	# Return
-	#   0 if daemon has been stopped
-	#   1 if daemon was already stopped
-	#   2 if daemon could not be stopped
-	#   other if a failure occurred
-	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
-	RETVAL="$?"
-	[ "$RETVAL" = 2 ] && return 2
-	# Wait for children to finish too if this is a daemon that forks
-	# and if the daemon is only ever run from this initscript.
-	# If the above conditions are not satisfied then add some other code
-	# that waits for the process to drop all resources that could be
-	# needed by services started subsequently.  A last resort is to
-	# sleep for some time. 
-	#
-	# Disabled second call, because is kills nfsen controlled nfcapd
-	#start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
-	#[ "$?" = 2 ] && return 2
-	# Many daemons don't delete their pidfiles when they exit.
-	rm -f $PIDFILE
-	return "$RETVAL"
+# Return
+#   0 if daemon has been stopped
+#   1 if daemon was already stopped
+#   2 if daemon could not be stopped
+#   other if a failure occurred
+do_stop () {
+    local INSTANCE="$1"
+
+    local PIDFILE="$PIDDIR/$INSTANCE.pid"
+    start-stop-daemon --stop --quiet \
+        --retry=TERM/30/KILL/5 --pidfile "$PIDFILE" --name "$NAME"
+    RETVAL="$?"
+    [ "$RETVAL" = 2 ] && return 2
+    # Many daemons don't delete their pidfiles when they exit.
+    rm -f "$PIDFILE"
+    return "$RETVAL"
 }
 
-#
-# Function that sends a SIGHUP to the daemon/service
-#
-do_reload() {
-	#
-	# If the daemon can reload its configuration without
-	# restarting (for example, when it is sent a SIGHUP),
-	# then implement that here.
-	#
-	start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
-	return 0
+EXIT=0
+
+do_action () {
+    local CONFIG="$1"
+
+    INSTANCE="$(basename "${CONFIG%%.conf}")"
+
+    case "$ACTION" in
+        start)
+            [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$INSTANCE"
+            do_start "$INSTANCE" "$CONFIG"
+            case "$?" in
+                0|1)    [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+                2)
+                    [ "$VERBOSE" != no ] && log_end_msg 1
+                    EXIT=1
+                    ;;
+            esac
+            ;;
+        stop)
+            [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$INSTANCE"
+            do_stop "$INSTANCE"
+            case "$?" in
+                0|1)    [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+                2)
+                    [ "$VERBOSE" != no ] && log_end_msg 1
+                    EXIT=1
+                    ;;
+            esac
+            ;;
+        status)
+            status_of_proc -p "$PIDDIR/$INSTANCE.pid" "$NFCAPD" "nfcapd $INSTANCE instance" || EXIT=$?
+            ;;
+        restart|force-reload)
+            log_daemon_msg "Restarting $DESC" "$INSTANCE"
+            do_stop "$INSTANCE"
+            case "$?" in
+                0|1)
+                    do_start "$INSTANCE" "$CONFIG"
+                    case "$?" in
+                        0)  log_end_msg 0 ;;
+                        *)
+                            # Old process is still running or
+                            # failed to start
+                            log_end_msg 1 ;;
+                    esac
+                    ;;
+                *)
+                    # Failed to stop
+                    log_end_msg 1
+                    ;;
+                esac
+            ;;
+        *)
+            echo "Usage: /etc/init.d/nfdump {start|stop|status|restart|force-reload} [<instance> ...]" >&2
+            exit 3
+            ;;
+    esac
 }
 
-case "$1" in
-  start)
-	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
-	do_start
-	case "$?" in
-		0|1) [ q"$VERBOSE" != qno ] && log_end_msg 0 ;;
-		2)   [ p"$VERBOSE" != pno ] && log_end_msg 1 ;;
-	esac
-	;;
-  stop)
-	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
-	do_stop
-	case "$?" in
-		0|1) [ "r$VERBOSE" != rno ] && log_end_msg 0 ;;
-		2) [ "s$VERBOSE" != sno ] && log_end_msg 1 ;;
-	esac
-	;;
-  #reload|force-reload)
-	#
-	# If do_reload() is not implemented then leave this commented out
-	# and leave 'force-reload' as an alias for 'restart'.
-	#
-	#log_daemon_msg "Reloading $DESC" "$NAME"
-	#do_reload
-	#log_end_msg $?
-	#;;
-  restart|force-reload)
-	#
-	# If the "reload" option is implemented then remove the
-	# 'force-reload' alias
-	#
-	log_daemon_msg "Restarting $DESC" "$NAME"
-	do_stop
-	case "$?" in
-	  0|1)
-		do_start
-		case "$?" in
-			0|1) log_end_msg 0 ;;
-			*) log_end_msg 1 ;; # Failed to start
-		esac
-		;;
-	  *)
-	  	# Failed to stop
-		log_end_msg 1
-		;;
-	esac
-	;;
-  *)
-	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
-	echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
-	exit 3
-	;;
-esac
-exit 0
+
+ACTION="$1"
+shift
+
+if [ "$1" ] ; then
+    while [ "$1" ] ; do
+        CONFIG="/etc/nfdump/$1.conf"
+        if [ -f "$CONFIG" ] ; then
+            do_action "$CONFIG"
+        fi
+        shift
+    done
+else
+    for CONFIG in /etc/nfdump/*.conf ; do
+        if [ -f "$CONFIG" ] ; then
+            do_action "$CONFIG"
+        fi
+    done
+fi
+
+exit $EXIT
diff --git a/debian/nfdump.install b/debian/nfdump.install
index df0bc5d..8348ff7 100644
--- a/debian/nfdump.install
+++ b/debian/nfdump.install
@@ -1,2 +1,4 @@
 usr/bin/nf*
 usr/share/man/man1/nf*
+debian/default.conf     etc/nfdump/
+debian/nfdump-generator lib/systemd/system-generators/
diff --git a/debian/nfdump.maintscript b/debian/nfdump.maintscript
new file mode 100644
index 0000000..9bb37a3
--- /dev/null
+++ b/debian/nfdump.maintscript
@@ -0,0 +1 @@
+rm_conffile /etc/default/nfdump 1.6.17-2~
diff --git a/debian/nfdump.service b/debian/nfdump.service
index 6d7001e..0183ccf 100644
--- a/debian/nfdump.service
+++ b/debian/nfdump.service
@@ -1,14 +1,13 @@
 [Unit]
 Description=netflow capture daemon
-After=network.target auditd.service
+Documentation=man:nfcapd(1)
+Documentation=man:softflowd(8)
 
 [Service]
-Type=simple
-ExecStart=/usr/bin/nfcapd -D -l /var/cache/nfdump -P /var/run/nfcapd.pid -p 2055
-PIDFile=/var/run/nfcapd.pid
-KillMode=process
-Restart=no
+Type=oneshot
+ExecStart=/bin/true
+ExecReload=/bin/true
+RemainAfterExit=on
 
 [Install]
 WantedBy=multi-user.target
-
diff --git a/debian/nfdump@.service b/debian/nfdump@.service
new file mode 100644
index 0000000..9cd9269
--- /dev/null
+++ b/debian/nfdump@.service
@@ -0,0 +1,16 @@
+[Unit]
+Description=netflow capture daemon, %I instance
+Documentation=man:nfcapd(1)
+After=network.target auditd.service
+PartOf=nfdump.service
+
+[Service]
+Type=forking
+EnvironmentFile=/etc/nfdump/%I.conf
+ExecStart=/usr/bin/nfcapd -D -P /run/nfcapd.%I.pid $options
+PIDFile=/run/nfcapd.%I.pid
+KillMode=process
+Restart=no
+
+[Install]
+WantedBy=multi-user.target

Attachment: signature.asc
Description: PGP signature

Reply via email to