From 144d69ee8e88c07b169eaaf825d664b857f04ebb Mon Sep 17 00:00:00 2001 From: mfalkvidd Date: Fri, 8 May 2020 23:15:01 +0200 Subject: [PATCH 1/4] Initial work for supporting multiple instances Service rename works, but we also need to handle config file, log file, log pipe, eeprom file and maybe something more. This feature was requested in https://bit.ly/3fL0fLn --- Makefile | 32 +++++++++++++++++--------------- configure | 9 +++++++-- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 5b2ef8bde..10928d1fc 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ include $(CONFIG_FILE) CPPFLAGS+=-Ofast -g -Wall -Wextra DEPFLAGS=-MT $@ -MMD -MP -GATEWAY_BIN=mysgw +GATEWAY_BIN=$(SERVICE_NAME) GATEWAY=$(BINDIR)/$(GATEWAY_BIN) GATEWAY_C_SOURCES=$(wildcard hal/architecture/Linux/drivers/core/*.c) GATEWAY_CPP_SOURCES=$(wildcard hal/architecture/Linux/drivers/core/*.cpp) examples_linux/mysgw.cpp @@ -124,31 +124,33 @@ install-gateway: install-initscripts: ifeq ($(INIT_SYSTEM), systemd) - install -m0644 initscripts/mysgw.systemd ${DESTDIR}/etc/systemd/system/mysgw.service - @sed -i -e "s|%gateway_dir%|${GATEWAY_DIR}|g" ${DESTDIR}/etc/systemd/system/mysgw.service + install -m0644 initscripts/mysgw.systemd ${DESTDIR}/etc/systemd/system/${SERVICE_NAME}.service + @sed -i -e "s|%gateway_dir%|${GATEWAY_DIR}|g" ${DESTDIR}/etc/systemd/system/${SERVICE_NAME}.service + @sed -i -e "s|%mysgw%|${SERVICE_NAME}|g" ${DESTDIR}/etc/systemd/system/${SERVICE_NAME}.service systemctl daemon-reload @echo "MySensors gateway has been installed, to add to the boot run:" - @echo " sudo systemctl enable mysgw.service" + @echo " sudo systemctl enable ${SERVICE_NAME}.service" @echo "To start the gateway run:" - @echo " sudo systemctl start mysgw.service" + @echo " sudo systemctl start ${SERVICE_NAME}.service" else ifeq ($(INIT_SYSTEM), sysvinit) - install -m0755 initscripts/mysgw.sysvinit ${DESTDIR}/etc/init.d/mysgw - @sed -i -e "s|%gateway_dir%|${GATEWAY_DIR}|g" ${DESTDIR}/etc/init.d/mysgw + install -m0755 initscripts/mysgw.sysvinit ${DESTDIR}/etc/init.d/${SERVICE_NAME} + @sed -i -e "s|%gateway_dir%|${GATEWAY_DIR}|g" ${DESTDIR}/etc/init.d/${SERVICE_NAME} + @sed -i -e "s|%mysgw%|${SERVICE_NAME}|g" ${DESTDIR}/etc/init.d/${SERVICE_NAME} @echo "MySensors gateway has been installed, to add to the boot run:" - @echo " sudo update-rc.d mysgw defaults" + @echo " sudo update-rc.d ${SERVICE_NAME} defaults" @echo "To start the gateway run:" - @echo " sudo service mysgw start" + @echo " sudo service ${SERVICE_NAME} start" endif uninstall: ifeq ($(INIT_SYSTEM), systemd) - @echo "Stopping daemon mysgw (ignore errors)" - -@systemctl stop mysgw.service + @echo "Stopping daemon ${SERVICE_NAME} (ignore errors)" + -@systemctl stop ${SERVICE_NAME}.service @echo "removing files" - rm /etc/systemd/system/mysgw.service $(GATEWAY_DIR)/$(GATEWAY_BIN) + rm /etc/systemd/system/${SERVICE_NAME}.service $(GATEWAY_DIR)/$(GATEWAY_BIN) else ifeq ($(INIT_SYSTEM), sysvinit) - @echo "Stopping daemon mysgw (ignore errors)" - -@service mysgw stop + @echo "Stopping daemon ${SERVICE_NAME} (ignore errors)" + -@service ${SERVICE_NAME} stop @echo "removing files" - rm /etc/init.d/mysgw $(GATEWAY_DIR)/$(GATEWAY_BIN) + rm /etc/init.d/${SERVICE_NAME} $(GATEWAY_DIR)/$(GATEWAY_BIN) endif diff --git a/configure b/configure index 125af49a4..fedb54b7e 100755 --- a/configure +++ b/configure @@ -4,7 +4,7 @@ # Original work: https://github.com/TMRh20/RF24/blob/master/configure function help { -cat < Installation prefix path. [/usr/local] --gateway-dir= Gateway files installation directory. [PREFIX/bin] + --service-name= Name for the binary and systemd service. [mysgw] MySensors options: --my-debug=[enable|disable] Enables or disables MySensors core debugging. [enable] @@ -297,7 +298,7 @@ signing=none signing_request_signatures=false encryption=false -params="SOC CFLAGS CXXFLAGS CPPFLAGS LDFLAGS PREFIX CC CXX ARDUINO_LIB_DIR BUILDDIR BINDIR GATEWAY_DIR INIT_SYSTEM SPI_DRIVER" +params="SOC CFLAGS CXXFLAGS CPPFLAGS LDFLAGS PREFIX CC CXX ARDUINO_LIB_DIR BUILDDIR BINDIR GATEWAY_DIR INIT_SYSTEM SPI_DRIVER SERVICE_NAME" for opt do if [ "$opt" = "-h" ] || [ "$opt" = "--help" ]; then @@ -345,6 +346,9 @@ for opt do --bin-dir=*) BINDIR="$optarg" ;; + --service-name=*) + SERVICE_NAME="$optarg" + ;; --no-clean*) NO_CLEAN="1" ;; @@ -547,6 +551,7 @@ PREFIX=${PREFIX:-/usr/local} BUILDDIR=${BUILDDIR:-build} BINDIR=${BINDIR:-bin} GATEWAY_DIR=${GATEWAY_DIR:-${PREFIX}/bin} +SERVICE_NAME=${SERVICE_NAME:-mysgw} CC=${CC:-gcc} CXX=${CXX:-g++} CXXFLAGS="$CXXFLAGS -std=c++11" From d9fb12a7504d8946ae71cd8105b3ef7337a2c4c9 Mon Sep 17 00:00:00 2001 From: mfalkvidd Date: Thu, 14 May 2020 15:27:00 +0200 Subject: [PATCH 2/4] Further work on supporting multiple instances * On stderr, the service name is printed on each line. * Print the name of the eeprom file, the log file and the log pipe on startup. Hopefully, this will help people notice when they are running multiple instances, and to distinguish between them. --- configure | 5 +++-- hal/architecture/Linux/MyHwLinuxGeneric.cpp | 2 ++ .../Linux/drivers/core/EthernetServer.cpp | 2 +- hal/architecture/Linux/drivers/core/config.c | 7 +++++-- hal/architecture/Linux/drivers/core/log.c | 16 +++++++++++++--- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/configure b/configure index fedb54b7e..f5f473afa 100755 --- a/configure +++ b/configure @@ -347,8 +347,9 @@ for opt do BINDIR="$optarg" ;; --service-name=*) - SERVICE_NAME="$optarg" - ;; + SERVICE_NAME="$optarg" + CPPFLAGS="-DMY_SERVICE_NAME=\"${optarg}\" $CPPFLAGS" + ;; --no-clean*) NO_CLEAN="1" ;; diff --git a/hal/architecture/Linux/MyHwLinuxGeneric.cpp b/hal/architecture/Linux/MyHwLinuxGeneric.cpp index 2a78e2574..3f0f1c51f 100644 --- a/hal/architecture/Linux/MyHwLinuxGeneric.cpp +++ b/hal/architecture/Linux/MyHwLinuxGeneric.cpp @@ -38,6 +38,8 @@ bool hwInit(void) exit(1); } + logInfo("Using eeprom file %s\n", conf.eeprom_file); + return true; } diff --git a/hal/architecture/Linux/drivers/core/EthernetServer.cpp b/hal/architecture/Linux/drivers/core/EthernetServer.cpp index 22309d6e7..46d00423e 100644 --- a/hal/architecture/Linux/drivers/core/EthernetServer.cpp +++ b/hal/architecture/Linux/drivers/core/EthernetServer.cpp @@ -90,7 +90,7 @@ void EthernetServer::begin(IPAddress address) } if (p == NULL) { - logError("Failed to bind!\n"); + logError("Failed to bind to port %d! Is another instance running?\n", port); freeaddrinfo(servinfo); return; } diff --git a/hal/architecture/Linux/drivers/core/config.c b/hal/architecture/Linux/drivers/core/config.c index 23c717e52..9a30c423c 100644 --- a/hal/architecture/Linux/drivers/core/config.c +++ b/hal/architecture/Linux/drivers/core/config.c @@ -25,7 +25,9 @@ #include #include #include +#include #include "log.h" +#include static int _config_create(const char *config_file); static int _config_parse_int(char *token, const char *name, int *value); @@ -36,6 +38,7 @@ int config_parse(const char *config_file) FILE *fptr; char buf[1024]; struct stat fileInfo; + logInfo("Using config file %s\n", config_file); if (stat(config_file, &fileInfo) != 0) { //File does not exist. Create it. @@ -45,7 +48,7 @@ int config_parse(const char *config_file) fptr = fopen(config_file, "rt"); if (!fptr) { - logError("Error opening config file \"%s\".\n", config_file); + logError("Error opening config file \"%s\": %s\n", config_file, strerror(errno)); return -1; } @@ -260,7 +263,7 @@ int _config_create(const char *config_file) myFile = fopen(config_file, "w"); if (!myFile) { - logError("Unable to create config file %s.\n", config_file); + logError("Unable to create config file %s: %s\n", config_file, strerror(errno)); return -1; } ret = fputs(default_conf, myFile); diff --git a/hal/architecture/Linux/drivers/core/log.c b/hal/architecture/Linux/drivers/core/log.c index 7f6c6b407..2cbe56d62 100644 --- a/hal/architecture/Linux/drivers/core/log.c +++ b/hal/architecture/Linux/drivers/core/log.c @@ -28,6 +28,13 @@ #include #include +#ifndef MY_SERVICE_NAME +#define MY_SERVICE_NAME "mysgw" +#endif + +#define STR_HELPER(x) #x //!< Helper macro, STR_HELPER() +#define STR(x) STR_HELPER(x) //!< Helper macro, STR() + static const char *_log_level_colors[] = { "\x1b[1;5;91m", "\x1b[1;91m", "\x1b[91m", "\x1b[31m", "\x1b[33m", "\x1b[34m", "\x1b[32m", "\x1b[36m" }; @@ -80,6 +87,7 @@ int logSetPipe(char *pipe_file) _log_pipe = 1; } + logInfo("Using log pipe %s\n", _log_pipe_file); return ret; } @@ -94,6 +102,7 @@ int logSetFile(char *file) return errno; } + logInfo("Using log file %s\n", file); return 0; } @@ -138,7 +147,7 @@ void vlog(int level, const char *fmt, va_list args) date[strftime(date, sizeof(date), "%b %d %H:%M:%S", lt)] = '\0'; if (_log_file_fp != NULL) { - fprintf(_log_file_fp, "%s %-5s ", date, _log_level_names[level]); + fprintf(_log_file_fp, "%s %s %-5s ", date, STR(MY_SERVICE_NAME), _log_level_names[level]); vfprintf(_log_file_fp, fmt, args); fflush(_log_file_fp); } @@ -146,10 +155,11 @@ void vlog(int level, const char *fmt, va_list args) if (!_log_quiet) { #ifdef LOG_DISABLE_COLOR (void)_log_level_colors; - fprintf(stderr, "%s %-5s ", date, _log_level_names[level]); + fprintf(stderr, "%s %s %-5s ", date, STR(MY_SERVICE_NAME) _log_level_names[level]); vfprintf(stderr, fmt, args); #else - fprintf(stderr, "%s %s%-5s\x1b[0m ", date, _log_level_colors[level], _log_level_names[level]); + fprintf(stderr, "%s %s %s%-5s\x1b[0m ", date, STR(MY_SERVICE_NAME), _log_level_colors[level], + _log_level_names[level]); vfprintf(stderr, fmt, args); #endif } From 24bb556d996da475c9dbcad46525e782d1a87aa5 Mon Sep 17 00:00:00 2001 From: mfalkvidd Date: Thu, 14 May 2020 15:51:12 +0200 Subject: [PATCH 3/4] Change MY_SERVICE_NAME to SERVICENAME --- configure | 2 +- hal/architecture/Linux/drivers/core/log.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/configure b/configure index f5f473afa..fb08bf957 100755 --- a/configure +++ b/configure @@ -348,7 +348,7 @@ for opt do ;; --service-name=*) SERVICE_NAME="$optarg" - CPPFLAGS="-DMY_SERVICE_NAME=\"${optarg}\" $CPPFLAGS" + CPPFLAGS="-DSERVICENAME=\"${optarg}\" $CPPFLAGS" ;; --no-clean*) NO_CLEAN="1" diff --git a/hal/architecture/Linux/drivers/core/log.c b/hal/architecture/Linux/drivers/core/log.c index 2cbe56d62..ed5670cae 100644 --- a/hal/architecture/Linux/drivers/core/log.c +++ b/hal/architecture/Linux/drivers/core/log.c @@ -28,8 +28,8 @@ #include #include -#ifndef MY_SERVICE_NAME -#define MY_SERVICE_NAME "mysgw" +#ifndef SERVICENAME +#define SERVICENAME "mysgw" #endif #define STR_HELPER(x) #x //!< Helper macro, STR_HELPER() @@ -147,7 +147,7 @@ void vlog(int level, const char *fmt, va_list args) date[strftime(date, sizeof(date), "%b %d %H:%M:%S", lt)] = '\0'; if (_log_file_fp != NULL) { - fprintf(_log_file_fp, "%s %s %-5s ", date, STR(MY_SERVICE_NAME), _log_level_names[level]); + fprintf(_log_file_fp, "%s %s %-5s ", date, STR(SERVICENAME), _log_level_names[level]); vfprintf(_log_file_fp, fmt, args); fflush(_log_file_fp); } @@ -155,10 +155,10 @@ void vlog(int level, const char *fmt, va_list args) if (!_log_quiet) { #ifdef LOG_DISABLE_COLOR (void)_log_level_colors; - fprintf(stderr, "%s %s %-5s ", date, STR(MY_SERVICE_NAME) _log_level_names[level]); + fprintf(stderr, "%s %s %-5s ", date, STR(SERVICENAME) _log_level_names[level]); vfprintf(stderr, fmt, args); #else - fprintf(stderr, "%s %s %s%-5s\x1b[0m ", date, STR(MY_SERVICE_NAME), _log_level_colors[level], + fprintf(stderr, "%s %s %s%-5s\x1b[0m ", date, STR(SERVICENAME), _log_level_colors[level], _log_level_names[level]); vfprintf(stderr, fmt, args); #endif From d4f4a6854ae9ae4af85b0ed0db42c5fadaccc192 Mon Sep 17 00:00:00 2001 From: mfalkvidd Date: Sat, 16 May 2020 11:09:48 +0200 Subject: [PATCH 4/4] Support replacement of the service name in start scripts --- initscripts/mysgw.systemd | 2 +- initscripts/mysgw.sysvinit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/initscripts/mysgw.systemd b/initscripts/mysgw.systemd index d983ab27f..b2d3caf18 100644 --- a/initscripts/mysgw.systemd +++ b/initscripts/mysgw.systemd @@ -3,7 +3,7 @@ Description=MySensors Gateway daemon Requires=network.target [Service] -ExecStart=%gateway_dir%/mysgw -q +ExecStart=%gateway_dir%/%mysgw% -q [Install] WantedBy=multi-user.target diff --git a/initscripts/mysgw.sysvinit b/initscripts/mysgw.sysvinit index c24fde902..7c6d43f99 100644 --- a/initscripts/mysgw.sysvinit +++ b/initscripts/mysgw.sysvinit @@ -15,7 +15,7 @@ # PATH should only include /usr/* if it runs after the mountnfs.sh script PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin DESC="MySensors Gateway" -NAME=mysgw +NAME=%mysgw% DAEMON=%gateway_dir%/$NAME DAEMON_ARGS="--daemon -q" PIDFILE=/var/run/$NAME.pid