alfred: Start up alfred without valid interfaces 643/head
authorSven Eckelmann <sven@narfation.org>
Mon, 15 Feb 2021 20:17:53 +0000 (21:17 +0100)
committerSven Eckelmann <sven@narfation.org>
Mon, 15 Feb 2021 20:17:53 +0000 (21:17 +0100)
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 situation stopped the startup process after the init scripts
waited for a longer period of polling the system state.

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 used. The extra polling code is therefore no
longer needed in the init scripts.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
alfred/Makefile
alfred/files/alfred.init
alfred/patches/0001-alfred-Show-error-message-for-invalid-batadv-interfa.patch [new file with mode: 0644]
alfred/patches/0002-alfred-Allow-exactly-one-interface-for-secondary-mod.patch [new file with mode: 0644]
alfred/patches/0003-alfred-Save-global-mode-flags-in-bitfield.patch [new file with mode: 0644]
alfred/patches/0004-alfred-Allow-start-of-server-without-valid-interface.patch [new file with mode: 0644]

index 8ca6ecb82fe07c536eb9369742c51cd860ef582a..8ab26e1c6190c41b3dcf9ad47b15897a755f0d4a 100644 (file)
@@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=alfred
 PKG_VERSION:=2021.0
-PKG_RELEASE:=2
+PKG_RELEASE:=3
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
index e439be10f71647adb17c52743cec3f819ae31439..f191827fd0af2977a9b9cbd2fa7ce0c8ead4f9e5 100755 (executable)
@@ -13,53 +13,9 @@ facters_dir="/etc/alfred"
 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."
-                               return 1
-                       fi
-               done
-       fi
-
-       return 0
-}
-
-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 0
-               fi
-               sleep 1
-       done
-
-       echo "$iface address not detected, alfred not starting."
-       return 1
-}
-
 append_interface()
 {
        append "interfaces" "$1" ","
-       wait_for_ll_address "$1"
 }
 
 alfred_start() {
@@ -72,7 +28,7 @@ alfred_start() {
        config_get_bool disabled "$section" disabled 0
        [ $disabled = 0 ] || return 1
 
-       args=""
+       args="-f"
 
        config_list_foreach "$section" "interface" append_interface
        if [ -z "$interfaces" ]; then
@@ -87,10 +43,6 @@ alfred_start() {
        config_get batmanif "$section" batmanif
        append args "-b $batmanif"
 
-       if [ "$batmanif" != "none" ]; then
-               wait_for_dir "$batmanif" "/sys/devices/virtual/net/$batmanif" || return 1
-       fi
-
        append alfred_args "$args"
        enable=1
 
diff --git a/alfred/patches/0001-alfred-Show-error-message-for-invalid-batadv-interfa.patch b/alfred/patches/0001-alfred-Show-error-message-for-invalid-batadv-interfa.patch
new file mode 100644 (file)
index 0000000..cfab598
--- /dev/null
@@ -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) {
diff --git a/alfred/patches/0002-alfred-Allow-exactly-one-interface-for-secondary-mod.patch b/alfred/patches/0002-alfred-Allow-exactly-one-interface-for-secondary-mod.patch
new file mode 100644 (file)
index 0000000..27d3a05
--- /dev/null
@@ -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;
+       }
diff --git a/alfred/patches/0003-alfred-Save-global-mode-flags-in-bitfield.patch b/alfred/patches/0003-alfred-Save-global-mode-flags-in-bitfield.patch
new file mode 100644 (file)
index 0000000..a7da7df
--- /dev/null
@@ -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;
diff --git a/alfred/patches/0004-alfred-Allow-start-of-server-without-valid-interface.patch b/alfred/patches/0004-alfred-Allow-start-of-server-without-valid-interface.patch
new file mode 100644 (file)
index 0000000..3471dde
--- /dev/null
@@ -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;
+       }