Merge pull request #643 from ecsv/batadv-2021.0
alfred: Fix state handling for startup and restart/reload of alfred
This commit is contained in:
commit
d63eda01ff
6 changed files with 273 additions and 49 deletions
|
@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=alfred
|
PKG_NAME:=alfred
|
||||||
PKG_VERSION:=2021.0
|
PKG_VERSION:=2021.0
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=3
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
||||||
|
|
|
@ -13,51 +13,9 @@ facters_dir="/etc/alfred"
|
||||||
enable=0
|
enable=0
|
||||||
vis_enable=0
|
vis_enable=0
|
||||||
|
|
||||||
wait_for_dir() {
|
|
||||||
local ifce="$1" dir="$2"
|
|
||||||
|
|
||||||
if ! [ -d "$dir" ] ; then
|
|
||||||
timeout=30
|
|
||||||
echo "waiting $timeout secs for $ifce interface..."
|
|
||||||
for i in $(seq $timeout); do
|
|
||||||
sleep 1
|
|
||||||
[ -d "$dir" ] && break
|
|
||||||
if [ $i = $timeout ] ; then
|
|
||||||
echo "$ifce not detected, alfred not starting."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
wait_for_ll_address() {
|
|
||||||
local iface="$1"
|
|
||||||
local timeout=30
|
|
||||||
|
|
||||||
echo "waiting $timeout secs for $iface address..."
|
|
||||||
for i in $(seq $timeout); do
|
|
||||||
# We look for
|
|
||||||
# - the link-local address (starts with fe80)
|
|
||||||
# - without tentative flag (bit 0x40 in the flags field; the first char of the fifth field is evaluated)
|
|
||||||
# - on interface $iface
|
|
||||||
if awk '
|
|
||||||
BEGIN { RET=1 }
|
|
||||||
$1 ~ /^fe80/ && $5 ~ /^[012389ab]/ && $6 == "'"$iface"'" { RET=0 }
|
|
||||||
END { exit RET }
|
|
||||||
' /proc/net/if_inet6; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "$iface address not detected, alfred not starting."
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
append_interface()
|
append_interface()
|
||||||
{
|
{
|
||||||
append "interfaces" "$1" ","
|
append "interfaces" "$1" ","
|
||||||
wait_for_ll_address "$1"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alfred_start() {
|
alfred_start() {
|
||||||
|
@ -70,7 +28,7 @@ alfred_start() {
|
||||||
config_get_bool disabled "$section" disabled 0
|
config_get_bool disabled "$section" disabled 0
|
||||||
[ $disabled = 0 ] || return 1
|
[ $disabled = 0 ] || return 1
|
||||||
|
|
||||||
args=""
|
args="-f"
|
||||||
|
|
||||||
config_list_foreach "$section" "interface" append_interface
|
config_list_foreach "$section" "interface" append_interface
|
||||||
if [ -z "$interfaces" ]; then
|
if [ -z "$interfaces" ]; then
|
||||||
|
@ -85,10 +43,6 @@ alfred_start() {
|
||||||
config_get batmanif "$section" batmanif
|
config_get batmanif "$section" batmanif
|
||||||
append args "-b $batmanif"
|
append args "-b $batmanif"
|
||||||
|
|
||||||
if [ "$batmanif" != "none" ]; then
|
|
||||||
wait_for_dir "$batmanif" "/sys/devices/virtual/net/$batmanif"
|
|
||||||
fi
|
|
||||||
|
|
||||||
append alfred_args "$args"
|
append alfred_args "$args"
|
||||||
enable=1
|
enable=1
|
||||||
|
|
||||||
|
@ -107,7 +61,7 @@ start_service() {
|
||||||
config_load "alfred"
|
config_load "alfred"
|
||||||
config_foreach alfred_start alfred
|
config_foreach alfred_start alfred
|
||||||
|
|
||||||
[ "$enable" = "0" ] && exit 0
|
[ "$enable" = "0" ] && return 0
|
||||||
|
|
||||||
procd_open_instance "alfred"
|
procd_open_instance "alfred"
|
||||||
procd_set_param command /usr/sbin/alfred
|
procd_set_param command /usr/sbin/alfred
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Mon, 15 Feb 2021 19:56:22 +0100
|
||||||
|
Subject: alfred: Show error message for invalid batadv interface
|
||||||
|
|
||||||
|
The alfred server process always stopped without any informational message
|
||||||
|
when the provided batman-adv was not "none" and was not accessible. This
|
||||||
|
made it extremely hard to debug the reason why alfred directly stopped
|
||||||
|
after launching it.
|
||||||
|
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Forwarded: https://patchwork.open-mesh.org/project/b.a.t.m.a.n./patch/20210215200126.140253-1-sven@narfation.org/
|
||||||
|
|
||||||
|
diff --git a/server.c b/server.c
|
||||||
|
index fc27246b845af75bd1f459f8bb553aef87cc24d5..efac5ad399df52f8c444711a14bcf4814e38a3bf 100644
|
||||||
|
--- a/server.c
|
||||||
|
+++ b/server.c
|
||||||
|
@@ -385,8 +385,11 @@ int alfred_server(struct globals *globals)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(globals->mesh_iface, "none") != 0 &&
|
||||||
|
- batadv_interface_check(globals->mesh_iface) < 0)
|
||||||
|
+ batadv_interface_check(globals->mesh_iface) < 0) {
|
||||||
|
+ fprintf(stderr, "Can't start server: batman-adv interface %s not found\n",
|
||||||
|
+ globals->mesh_iface);
|
||||||
|
return -1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
num_socks = netsock_open_all(globals);
|
||||||
|
if (num_socks <= 0) {
|
|
@ -0,0 +1,72 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Mon, 15 Feb 2021 20:16:15 +0100
|
||||||
|
Subject: alfred: Allow exactly one interface for secondary mode
|
||||||
|
|
||||||
|
A primary alfred daemon allows syncing over more than one interface. But
|
||||||
|
the secondary alfred daemon needs exactly one interface. But the check for
|
||||||
|
this property was insufficient because it allowed paramters like
|
||||||
|
"-i wlan0,asd" when wlan0 is valid and asd is not valid.
|
||||||
|
|
||||||
|
The better solution is to really use the number of interfaces given to
|
||||||
|
alfred instead of the number of interfaces evaluated as "valid".
|
||||||
|
|
||||||
|
Fixes: 67ae5f57eedd ("alfred: Add support for multiple interfaces per master")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Forwarded: https://patchwork.open-mesh.org/project/b.a.t.m.a.n./patch/20210215200126.140253-2-sven@narfation.org/
|
||||||
|
|
||||||
|
diff --git a/alfred.h b/alfred.h
|
||||||
|
index 1e2c05835cbfba02ebabefe55afc29f7ef8e12b1..7d6b0b35b5c8b8c3b087589880c390eb035584be 100644
|
||||||
|
--- a/alfred.h
|
||||||
|
+++ b/alfred.h
|
||||||
|
@@ -182,6 +182,7 @@ int unix_sock_req_data_finish(struct globals *globals,
|
||||||
|
int vis_update_data(struct globals *globals);
|
||||||
|
/* netsock.c */
|
||||||
|
int netsock_open_all(struct globals *globals);
|
||||||
|
+size_t netsocket_count_interfaces(struct globals *globals);
|
||||||
|
void netsock_close_all(struct globals *globals);
|
||||||
|
int netsock_set_interfaces(struct globals *globals, char *interfaces);
|
||||||
|
struct interface *netsock_first_interface(struct globals *globals);
|
||||||
|
diff --git a/netsock.c b/netsock.c
|
||||||
|
index 367b20730500a1c24448200a24149b64059f3381..84b0ec3827e491eead997f58b2b8f26c5b18b843 100644
|
||||||
|
--- a/netsock.c
|
||||||
|
+++ b/netsock.c
|
||||||
|
@@ -471,6 +471,17 @@ int netsock_open_all(struct globals *globals)
|
||||||
|
return num_socks;
|
||||||
|
}
|
||||||
|
|
||||||
|
+size_t netsocket_count_interfaces(struct globals *globals)
|
||||||
|
+{
|
||||||
|
+ struct interface *interface;
|
||||||
|
+ size_t count = 0;
|
||||||
|
+
|
||||||
|
+ list_for_each_entry(interface, &globals->interfaces, list)
|
||||||
|
+ count++;
|
||||||
|
+
|
||||||
|
+ return count;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void netsock_reopen(struct globals *globals)
|
||||||
|
{
|
||||||
|
struct interface *interface;
|
||||||
|
diff --git a/server.c b/server.c
|
||||||
|
index efac5ad399df52f8c444711a14bcf4814e38a3bf..eb2bc8aeb787e4bf028c8f9e3a523a18c6992be1 100644
|
||||||
|
--- a/server.c
|
||||||
|
+++ b/server.c
|
||||||
|
@@ -371,6 +371,7 @@ int alfred_server(struct globals *globals)
|
||||||
|
int maxsock, ret, recvs;
|
||||||
|
struct timespec last_check, now, tv;
|
||||||
|
fd_set fds, errfds;
|
||||||
|
+ size_t num_interfaces;
|
||||||
|
int num_socks;
|
||||||
|
|
||||||
|
if (create_hashes(globals))
|
||||||
|
@@ -397,7 +398,8 @@ int alfred_server(struct globals *globals)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (num_socks > 1 && globals->opmode == OPMODE_SECONDARY) {
|
||||||
|
+ num_interfaces = netsocket_count_interfaces(globals);
|
||||||
|
+ if (num_interfaces > 1 && globals->opmode == OPMODE_SECONDARY) {
|
||||||
|
fprintf(stderr, "More than one interface specified in secondary mode\n");
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Mon, 15 Feb 2021 20:34:54 +0100
|
||||||
|
Subject: alfred: Save global mode flags in bitfield
|
||||||
|
|
||||||
|
The verbose and ipv4mode entries in the globals structure is only used to
|
||||||
|
save a boolean information. So just use a bit in a bitfield to store this
|
||||||
|
information instead of a full int.
|
||||||
|
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Forwarded: https://patchwork.open-mesh.org/project/b.a.t.m.a.n./patch/20210215200126.140253-3-sven@narfation.org/
|
||||||
|
|
||||||
|
diff --git a/alfred.h b/alfred.h
|
||||||
|
index 7d6b0b35b5c8b8c3b087589880c390eb035584be..c64ff17ab9be8a16b3e1c86070b93235c226a004 100644
|
||||||
|
--- a/alfred.h
|
||||||
|
+++ b/alfred.h
|
||||||
|
@@ -115,8 +115,8 @@ struct globals {
|
||||||
|
enum clientmode clientmode;
|
||||||
|
int clientmode_arg;
|
||||||
|
int clientmode_version;
|
||||||
|
- int verbose;
|
||||||
|
- int ipv4mode;
|
||||||
|
+ uint8_t verbose:1;
|
||||||
|
+ uint8_t ipv4mode:1;
|
||||||
|
|
||||||
|
int unix_sock;
|
||||||
|
const char *unix_path;
|
||||||
|
diff --git a/main.c b/main.c
|
||||||
|
index 7b866cc4275797beb7f614dd1a19ea0099e1281b..f25b6cc11975b8523abf6c59b77a86e94684b03b 100644
|
||||||
|
--- a/main.c
|
||||||
|
+++ b/main.c
|
||||||
|
@@ -9,6 +9,7 @@
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <signal.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
@@ -181,8 +182,8 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
globals->clientmode_version = 0;
|
||||||
|
globals->mesh_iface = "bat0";
|
||||||
|
globals->unix_path = ALFRED_SOCK_PATH_DEFAULT;
|
||||||
|
- globals->verbose = 0;
|
||||||
|
- globals->ipv4mode = 0;
|
||||||
|
+ globals->verbose = false;
|
||||||
|
+ globals->ipv4mode = false;
|
||||||
|
globals->update_command = NULL;
|
||||||
|
globals->sync_period.tv_sec = ALFRED_INTERVAL;
|
||||||
|
globals->sync_period.tv_nsec = 0;
|
||||||
|
@@ -252,7 +253,7 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
globals->unix_path = optarg;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
- globals->verbose++;
|
||||||
|
+ globals->verbose = true;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
globals->update_command = optarg;
|
||||||
|
@@ -268,7 +269,7 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
printf(" ** Setting sync interval to: %.9f seconds (%ld.%09ld)\n", sync_period, globals->sync_period.tv_sec, globals->sync_period.tv_nsec);
|
||||||
|
break;
|
||||||
|
case '4':
|
||||||
|
- globals->ipv4mode = 1;
|
||||||
|
+ globals->ipv4mode = true;
|
||||||
|
inet_pton(AF_INET, optarg, &alfred_mcast.ipv4);
|
||||||
|
printf(" ** IPv4 Multicast Mode: %x\n", alfred_mcast.ipv4.s_addr);
|
||||||
|
break;
|
|
@ -0,0 +1,102 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Mon, 15 Feb 2021 20:52:17 +0100
|
||||||
|
Subject: alfred: Allow start of server without valid interface
|
||||||
|
|
||||||
|
The alfred server always needs interfaces to operate on. But these
|
||||||
|
interfaces might not exist at the moment when the daemon process is
|
||||||
|
started. This caused an error and stopped the process.
|
||||||
|
|
||||||
|
But alfred is able to deal with interfaces which disappeared at runtime but
|
||||||
|
existed at startup. To force a similar behavior for the alfred startup, the
|
||||||
|
parameter "--force" or "-f" is introduced.
|
||||||
|
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Forwarded: https://patchwork.open-mesh.org/project/b.a.t.m.a.n./patch/20210215200126.140253-4-sven@narfation.org/
|
||||||
|
|
||||||
|
diff --git a/alfred.h b/alfred.h
|
||||||
|
index c64ff17ab9be8a16b3e1c86070b93235c226a004..ac082536bd6565756835489194be9b80fe0dd653 100644
|
||||||
|
--- a/alfred.h
|
||||||
|
+++ b/alfred.h
|
||||||
|
@@ -117,6 +117,7 @@ struct globals {
|
||||||
|
int clientmode_version;
|
||||||
|
uint8_t verbose:1;
|
||||||
|
uint8_t ipv4mode:1;
|
||||||
|
+ uint8_t force:1;
|
||||||
|
|
||||||
|
int unix_sock;
|
||||||
|
const char *unix_path;
|
||||||
|
diff --git a/main.c b/main.c
|
||||||
|
index f25b6cc11975b8523abf6c59b77a86e94684b03b..e190d4274a0fe2abdb2c462a5bdefb3e199d4797 100644
|
||||||
|
--- a/main.c
|
||||||
|
+++ b/main.c
|
||||||
|
@@ -164,6 +164,7 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
{"version", no_argument, NULL, 'v'},
|
||||||
|
{"verbose", no_argument, NULL, 'd'},
|
||||||
|
{"sync-period", required_argument, NULL, 'p'},
|
||||||
|
+ {"force", no_argument, NULL, 'f'},
|
||||||
|
{NULL, 0, NULL, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -184,6 +185,7 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
globals->unix_path = ALFRED_SOCK_PATH_DEFAULT;
|
||||||
|
globals->verbose = false;
|
||||||
|
globals->ipv4mode = false;
|
||||||
|
+ globals->force = false;
|
||||||
|
globals->update_command = NULL;
|
||||||
|
globals->sync_period.tv_sec = ALFRED_INTERVAL;
|
||||||
|
globals->sync_period.tv_nsec = 0;
|
||||||
|
@@ -191,7 +193,7 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
|
||||||
|
time_random_seed();
|
||||||
|
|
||||||
|
- while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:M:I:u:dc:p:4:", long_options,
|
||||||
|
+ while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:M:I:u:dc:p:4:f", long_options,
|
||||||
|
&opt_ind)) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'r':
|
||||||
|
@@ -273,6 +275,9 @@ static struct globals *alfred_init(int argc, char *argv[])
|
||||||
|
inet_pton(AF_INET, optarg, &alfred_mcast.ipv4);
|
||||||
|
printf(" ** IPv4 Multicast Mode: %x\n", alfred_mcast.ipv4.s_addr);
|
||||||
|
break;
|
||||||
|
+ case 'f':
|
||||||
|
+ globals->force = true;
|
||||||
|
+ break;
|
||||||
|
case 'h':
|
||||||
|
default:
|
||||||
|
alfred_usage();
|
||||||
|
diff --git a/man/alfred.8 b/man/alfred.8
|
||||||
|
index 25591be9ece1f8de572be8f639576861e318005f..e965db8260086cc83bc78ad95f97bc368a6cb170 100644
|
||||||
|
--- a/man/alfred.8
|
||||||
|
+++ b/man/alfred.8
|
||||||
|
@@ -72,6 +72,9 @@ Collect data from the network and prints it on the network
|
||||||
|
\fB\-d\fP, \fB\-\-verbose\fP
|
||||||
|
Show extra information in the data output
|
||||||
|
.TP
|
||||||
|
+\fB\-d\fP, \fB\-\-force\fP
|
||||||
|
+Start server even when batman-adv or interface(s) are not yet available.
|
||||||
|
+.TP
|
||||||
|
\fB\-V\fP, \fB\-\-req\-version\fP \fIversion\fP
|
||||||
|
Specify the data version set for \fB\-s\fP
|
||||||
|
|
||||||
|
diff --git a/server.c b/server.c
|
||||||
|
index eb2bc8aeb787e4bf028c8f9e3a523a18c6992be1..b4925e7e16ba7465662a5dbf12432916fed8bd03 100644
|
||||||
|
--- a/server.c
|
||||||
|
+++ b/server.c
|
||||||
|
@@ -386,14 +386,15 @@ int alfred_server(struct globals *globals)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(globals->mesh_iface, "none") != 0 &&
|
||||||
|
- batadv_interface_check(globals->mesh_iface) < 0) {
|
||||||
|
+ batadv_interface_check(globals->mesh_iface) < 0 &&
|
||||||
|
+ !globals->force) {
|
||||||
|
fprintf(stderr, "Can't start server: batman-adv interface %s not found\n",
|
||||||
|
globals->mesh_iface);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_socks = netsock_open_all(globals);
|
||||||
|
- if (num_socks <= 0) {
|
||||||
|
+ if (num_socks <= 0 && !globals->force) {
|
||||||
|
fprintf(stderr, "Failed to open interfaces\n");
|
||||||
|
return -1;
|
||||||
|
}
|
Loading…
Reference in a new issue