alfred: Start up alfred without valid interfaces 644/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:33:27 +0000 (21:33 +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/0004-alfred-Show-error-message-for-invalid-batadv-interfa.patch [new file with mode: 0644]
alfred/patches/0005-alfred-Allow-exactly-one-interface-for-secondary-mod.patch [new file with mode: 0644]
alfred/patches/0006-alfred-Save-global-mode-flags-in-bitfield.patch [new file with mode: 0644]
alfred/patches/0007-alfred-Allow-start-of-server-without-valid-interface.patch [new file with mode: 0644]

index ad38845ddf0077dbadcb52c039d4a1235db49b44..366f5e1a0db9f1f0a85276d4526e07e731d1e09c 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=alfred
 PKG_VERSION:=2019.2
-PKG_RELEASE:=2
+PKG_RELEASE:=3
 PKG_HASH:=b656f0e9a97a99c7531b6d49ebfd663451c16cdd275bbf7d48ff8daed3880bf2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
index b2dc9d85dd0e0855fc7e7e7979ecf47b62084dba..4468e0ee3a6b194a9d8d9463f62eb6649a5fc350 100755 (executable)
@@ -13,49 +13,6 @@ 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
-}
-
 alfred_start() {
        local args=""
        local section="$1"
@@ -65,7 +22,7 @@ alfred_start() {
        config_get_bool disabled "$section" disabled 0
        [ $disabled = 0 ] || return 1
 
-       args=""
+       args="-f"
 
        config_get interface "$section" interface
        append args "-i $interface"
@@ -76,12 +33,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
-
-       wait_for_ll_address "$interface"
-
        append alfred_args "$args"
        enable=1
 
diff --git a/alfred/patches/0004-alfred-Show-error-message-for-invalid-batadv-interfa.patch b/alfred/patches/0004-alfred-Show-error-message-for-invalid-batadv-interfa.patch
new file mode 100644 (file)
index 0000000..2112555
--- /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 18109cc76283484a67f54fbc34f88039b9602531..47e9ae28b703da23fb930756d2971161ab332bc1 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/0005-alfred-Allow-exactly-one-interface-for-secondary-mod.patch b/alfred/patches/0005-alfred-Allow-exactly-one-interface-for-secondary-mod.patch
new file mode 100644 (file)
index 0000000..0301840
--- /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 c7ee518eb9dc02c10fe1b19cea5c928915048d97..24f48fde3fdac1a8a80fae3b4f93dc2e16ddec0f 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 fcbc20be34504e271187fa9e0a120f271e622140..418b378e43144a24d4ff53544b387b1a6e7642e9 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 47e9ae28b703da23fb930756d2971161ab332bc1..95fc3bc895bf46eb775bf64d963a6eec77399dba 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_SLAVE) {
++      num_interfaces = netsocket_count_interfaces(globals);
++      if (num_interfaces > 1 && globals->opmode == OPMODE_SLAVE) {
+               fprintf(stderr, "More than one interface specified in slave mode\n");
+               return -1;
+       }
diff --git a/alfred/patches/0006-alfred-Save-global-mode-flags-in-bitfield.patch b/alfred/patches/0006-alfred-Save-global-mode-flags-in-bitfield.patch
new file mode 100644 (file)
index 0000000..52f7a9c
--- /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 24f48fde3fdac1a8a80fae3b4f93dc2e16ddec0f..f09eb497a6efe62d38891dcac2149a6473f9215a 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 f633462bcc55b1ae3369c42ccf8f030e671ab268..c7588505fb0a277de3a0c0ac08bb4365b9a9a2a1 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>
+@@ -184,8 +185,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;
+@@ -253,7 +254,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;
+@@ -269,7 +270,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/0007-alfred-Allow-start-of-server-without-valid-interface.patch b/alfred/patches/0007-alfred-Allow-start-of-server-without-valid-interface.patch
new file mode 100644 (file)
index 0000000..906e5b0
--- /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 f09eb497a6efe62d38891dcac2149a6473f9215a..5bd118cbc6052932cfad9f3eb258ceb4ce06cdc3 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 c7588505fb0a277de3a0c0ac08bb4365b9a9a2a1..2f77e1eb524f621391bf8ea7d56335e927e5197e 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},
+       };
+@@ -187,6 +188,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;
+@@ -194,7 +196,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':
+@@ -274,6 +276,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 7e31e12df0b7254e517001be5964d8c5088881e6..424633d4bdb16d25ce7b1a573cc58ab9f0dd1371 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 95fc3bc895bf46eb775bf64d963a6eec77399dba..de7ddcff2de8163457bd377c8da99ab3c66ff00e 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;
+       }