blob: 1ba0ac3c423066c9d3b5a5c6322ee698f3ea2f45 [file] [log] [blame]
William A. Kennington IIIbef990f2022-02-08 16:50:30 -08001#!/bin/bash
2# Copyright 2022 Google LLC
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
William A. Kennington III0e5de5d2023-03-24 02:41:39 -070016# shellcheck source=meta-google/recipes-google/networking/network-sh/lib.sh
17source /usr/share/network/lib.sh || exit
William A. Kennington III618c1092023-02-28 16:11:43 -080018
William A. Kennington IIIbef990f2022-02-08 16:50:30 -080019# Wait until a well known service is network available
William A. Kennington III0e5de5d2023-03-24 02:41:39 -070020echo 'Waiting for network reachability' >&2
21while true; do
22 before=$SECONDS
23 addrs="$(ip addr show gbmcbr | grep '^ *inet6' | awk '{print $2}')"
24 for addr in $addrs; do
25 # Remove the prefix length
26 ip="${addr%/*}"
27 ip_to_bytes ip_bytes "$ip" || continue
28 # Ignore ULAs and non-gBMC addresses
29 (( ip_bytes[0] & 0xfc == 0xfc || ip_bytes[8] != 0xfd )) && continue
30 # Only allow for the short, well known addresses <pfx>:fd01:: and not
31 # <pfx>:fd00:83c1:292d:feef. Otherwise, powercycle may be unavailable.
32 (( ip_bytes[9] == 0 )) && continue
33 for i in {10..15}; do
34 (( ip_bytes[i] != 0 )) && continue 2
35 done
36 echo "Trying reachability from $ip" >&2
37 for i in {0..5}; do
38 ping -I "$ip" -c 1 -W 1 2001:4860:4860::8888 >/dev/null 2>&1 && break 3
39 sleep 1
40 done
41 done
42 # Ensure we only complete the addr lookup loop every 10s
43 tosleep=$((before + 10 - SECONDS))
44 if (( tosleep > 0 )); then
Patrick Williams62ac9d52023-04-14 09:00:05 -050045 sleep "$tosleep"
William A. Kennington III0e5de5d2023-03-24 02:41:39 -070046 fi
William A. Kennington IIIbef990f2022-02-08 16:50:30 -080047done
William A. Kennington IIIe3edde42022-05-25 15:44:03 -070048
49# We need to guarantee we wait at least 5 minutes from reachable in
50# case networking just came up
William A. Kennington IIIbef990f2022-02-08 16:50:30 -080051wait_min=5
William A. Kennington IIIe3edde42022-05-25 15:44:03 -070052echo "Network is reachable, waiting $wait_min min" >&2
William A. Kennington IIIbef990f2022-02-08 16:50:30 -080053sleep $((60 * wait_min))
William A. Kennington IIIe3edde42022-05-25 15:44:03 -070054
55get_dhcp_unit_json() {
56 busctl -j call \
57 org.freedesktop.systemd1 \
58 /org/freedesktop/systemd1/unit/gbmc_2dbr_2ddhcp_2eservice \
59 org.freedesktop.DBus.Properties \
60 GetAll s org.freedesktop.systemd1.Unit
61}
62
63# Follow the process and make sure it idles for at least 5 minutes before
64# shutting down. This allows for failures and retries to happen.
65while true; do
66 json="$(get_dhcp_unit_json)" || exit
67 last_ms="$(echo "$json" | jq -r '.data[0].StateChangeTimestampMonotonic.data')"
68 if pid="$(cat /run/gbmc-br-dhcp.pid 2>/dev/null)"; then
69 # If the DHCP configuration process is running, wait for it to finish
70 echo "DHCP still running ($pid), waiting" >&2
71 while [[ -e /proc/$pid ]]; do
72 sleep 1
73 done
74 # Wait for systemd to detect the process state change
75 while true; do
76 json="$(get_dhcp_unit_json)" || exit
77 ms="$(echo "$json" | jq -r '.data[0].StateChangeTimestampMonotonic.data')"
78 (( ms != last_ms )) && break
79 sleep 1
80 done
81 fi
82
83 echo 'Checking DHCP Active State' >&2
84 json="$(get_dhcp_unit_json)" || exit
85 activestr="$(echo "$json" | jq -r '.data[0].ActiveState.data')"
86
87 # The process is already stopped, we are done
88 [[ "$activestr" == 'inactive' ]] && exit
89
90 # If the process is running, give it at least 5 minutes from when it started
91 cur_s="$(cut -d' ' -f1 /proc/uptime)"
William A. Kennington III9275d852022-08-26 14:38:02 -070092 # Remove floating point if applied since bash can't perform float arithmetic
93 cur_s="${cur_s%.*}"
William A. Kennington IIIe3edde42022-05-25 15:44:03 -070094 if [[ "$activestr" == 'active' ]]; then
95 active_ms="$(echo "$json" | jq -r '.data[0].ActiveEnterTimestampMonotonic.data')"
96 else
97 active_ms=$((cur_s*1000*1000))
98 fi
99 w=$((active_ms/1000/1000 + (wait_min*60) - cur_s))
100 [ "$w" -lt 0 ] && break
101 echo "Waiting ${w}s for DHCP process" >&2
Patrick Williams62ac9d52023-04-14 09:00:05 -0500102 sleep "$w"
William A. Kennington IIIe3edde42022-05-25 15:44:03 -0700103done
104
William A. Kennington IIIbef990f2022-02-08 16:50:30 -0800105echo "Stopping DHCP processing" >&2
106systemctl stop --no-block gbmc-br-dhcp