fixes master
authorIan Kelling <iank@fsf.org>
Sun, 15 Feb 2026 23:48:28 +0000 (18:48 -0500)
committerIan Kelling <iank@fsf.org>
Sun, 15 Feb 2026 23:48:28 +0000 (18:48 -0500)
newns

diff --git a/newns b/newns
index 178447c66f1a60e2e2a7b48575e491fad1ddc47b..e0ab07df59c295147fa1f356031fcc51aa590373 100755 (executable)
--- a/newns
+++ b/newns
 # https://savannah.nongnu.org/projects/bash-bear-trap/
 set -e; . /usr/local/lib/bash-bear; set +e
 
 # https://savannah.nongnu.org/projects/bash-bear-trap/
 set -e; . /usr/local/lib/bash-bear; set +e
 
+# echo COMMAND then run it. Supports prefixed vars eg. x=3 cmd.
 m() {
 m() {
-  local out
-  printf "newns: %s\n" "$*"
-  if ! out=$("$@" 2>&1); then
-    echo "newns: WARNING: last command exit code: $?"
-  elif [[ ! $out ]]; then
-    echo "newns: WARNING: no output from last command"
-  fi
+  printf "+ %s\n" "$*" >&2
+  while [[ $1 == *=* ]]; do
+    declare -x "$1"
+    shift
+  done
+  "$@"
 }
 
 usage() {
 }
 
 usage() {
@@ -228,7 +228,7 @@ ip-add() {
 
 check-default-route() {
   default_route_done=false
 
 check-default-route() {
   default_route_done=false
-  default_route=$(ipnn route show default | sed -r 's,^[[:space:]]+|[[:space:]]+$,,')
+  default_route=$(ipnn route show default | sed -r 's,^[[:space:]]+|[[:space:]]+$,,g')
   if [[ $default_route == "default via $network.1 dev $v1" ]]; then
     default_route_done=true
   fi
   if [[ $default_route == "default via $network.1 dev $v1" ]]; then
     default_route_done=true
   fi
@@ -302,19 +302,28 @@ start() {
   # I've had adding the default route mysteriously fail on boot, so
   # here we check that it succeeded, do a sleep and a retry.
   while true; do
   # I've had adding the default route mysteriously fail on boot, so
   # here we check that it succeeded, do a sleep and a retry.
   while true; do
-    check-default-route
-    if $default_route_done; then
+    exists=false
+    route_show=$(ipnn route show default | sed -r 's,^[[:space:]]+|[[:space:]]+$,,g')
+    mapfile -t default_routes <<<"$route_show"
+    for d in "${default_routes[@]}"; do
+      if [[ $d == "default via $network.1 dev $v1" ]]; then
+        exists=true
+        break
+      fi
+    done
+    if $exists; then
       break
     else
       break
     else
-      $cmd
+      if ! $cmd; then
+        echo "$cmd failed. beforehand, ip route show default: '$route_show'"
+      fi
       tries=$((tries + 1))
     fi
     if (( tries >= max_tries )); then
       echo "$0: ERROR: default route added but not found, tried $max_tries. expected route: 'default via $network.1 dev $v1', found: '$default_route'"
       exit 1
     else
       tries=$((tries + 1))
     fi
     if (( tries >= max_tries )); then
       echo "$0: ERROR: default route added but not found, tried $max_tries. expected route: 'default via $network.1 dev $v1', found: '$default_route'"
       exit 1
     else
-      sleep 1
-      $cmd
+      sleep 2
     fi
   done
   if (( tries >= 2 )); then
     fi
   done
   if (( tries >= 2 )); then
@@ -341,7 +350,7 @@ stop() {
   fi
 
   # todo: do we need to umount the bind mounts within the mount namespace first?
   fi
 
   # todo: do we need to umount the bind mounts within the mount namespace first?
-  if mountpoint /run/mount-namespaces/$nn >/dev/null; then
+  if mountpoint -q /run/mount-namespaces/$nn &>/dev/null; then
     umount /run/mount-namespaces/$nn
   fi
 }
     umount /run/mount-namespaces/$nn
   fi
 }
@@ -351,8 +360,10 @@ show() {
   m dexec iptables -t nat -C POSTROUTING -s $network.0/24 -j MASQUERADE \
     -m comment --comment "systemd network namespace nat" ||:
   m dexec iptables -C FORWARD -i $v0 -j ACCEPT
   m dexec iptables -t nat -C POSTROUTING -s $network.0/24 -j MASQUERADE \
     -m comment --comment "systemd network namespace nat" ||:
   m dexec iptables -C FORWARD -i $v0 -j ACCEPT
-  m mexec mount
-  m mountpoint /run/mount-namespaces/$nn
+  if (( ${#bind_srcs[@]} )); then
+    m mexec mount
+  fi
+  m mountpoint /run/mount-namespaces/$nn ||:
 }
 
 case $action in
 }
 
 case $action in