-
-
Notifications
You must be signed in to change notification settings - Fork 55
feat/lower squashfs size #211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2881477
deff430
f274f19
a087c0d
51f092e
6275988
eeb2377
a8032e0
b9eec55
2251e84
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -74,6 +74,9 @@ if ! "$SCRIPT_DIR/kexec" --load "$SCRIPT_DIR/bzImage" \ | |
| exit 1 | ||
| fi | ||
|
|
||
| sync; echo 3 > /proc/sys/vm/drop_caches | ||
| echo "current available memory: $(free -h | awk '/^Mem/ {print $7}')" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't the linux kernel do this automatically anyway if it needs memory. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could very well imagine that yes, although I didn't verify and don't intent to stake that claim either. The main reason I put this here is for reporting so that (especially during tests) we can see how much effective free memory was available prior to switching the kernel. Not sure if it is utterly useful otherwise. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok. But you are already printing the available memory, which will automatically substract any memory claimed by page cache or dirty pages. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we could even print a warning if we are below X MB available memory. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yeah, I had that idea, too, today: outright refuse to proceed because it's potentially not recoverable, if you have no IPMI access. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Iirc, I did some A/B testing and saw a small ~30MB difference, but yeah, I agree that it shouldn't be necessary. I did notice, however, on a slightly tangential note, that at the RAM-limit, |
||
|
|
||
| # Disconnect our background kexec from the terminal | ||
| echo "machine will boot into nixos in 6s..." | ||
| if test -e /dev/kmsg; then | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| { config, lib, modulesPath, pkgs, ... }: | ||
| let | ||
| restore-network = pkgs.writers.writePython3 "restore-network" { flakeIgnore = [ "E501" ]; } | ||
| ./restore_routes.py; | ||
|
|
||
| restore-network = pkgs.writers.writeBash "restore-network" ./restore_routes.sh; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the saving removing python out of interest? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't remember exactly. It was relatively significant though. I may even think in the ballpark of 150MB or so. It was, indeed, the lowest hanging fruit. I could have gone with python minimal, but since I was trying to really size this down as much as possible, I thought I'd save those additional dozens of MB that python minimal would have left us with, as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. However, the effect on the RAM was rather small (maybe 30-60MB or so?), ostensible due to a somewhat efficient caching and on-demand decompression of the squashfs, while having a (much!) smaller impact while compressed. |
||
|
|
||
| # does not link with iptables enabled | ||
| iprouteStatic = pkgs.pkgsStatic.iproute2.override { iptables = null; }; | ||
|
|
@@ -56,6 +56,7 @@ in | |
| environment.etc.is_kexec.text = "true"; | ||
|
|
||
| systemd.services.restore-network = { | ||
| path = [pkgs.jq]; | ||
| before = [ "network-pre.target" ]; | ||
| wants = [ "network-pre.target" ]; | ||
| wantedBy = [ "multi-user.target" ]; | ||
|
|
||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| #!/usr/bin/env bash | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cc @Lassulus for review of this. |
||
|
|
||
| # filter_interfaces function | ||
| filter_interfaces() { | ||
| # This function takes a list of network interfaces as input and filters | ||
| # out loopback interfaces, interfaces without a MAC address, and addresses | ||
| # with a "link" scope or marked as dynamic (from DHCP or router | ||
| # advertisements). The filtered interfaces are returned one by one on stdout. | ||
| local network=("$@") | ||
|
|
||
| for net in "${network[@]}"; do | ||
| local link_type="$(jq -r '.link_type' <<< "$net")" | ||
| local address="$(jq -r '.address // ""' <<< "$net")" | ||
| local addr_info="$(jq -r '.addr_info | map(select(.scope != "link" and (.dynamic | not)))' <<< "$net")" | ||
| local has_dynamic_address=$(jq -r '.addr_info | any(.dynamic)' <<< "$net") | ||
|
|
||
| # echo "Link Type: $link_type -- Address: $address -- Has Dynamic Address: $has_dynamic_address -- Addr Info: $addr_info" | ||
|
|
||
| if [[ "$link_type" != "loopback" && -n "$address" && ("$addr_info" != "[]" || "$has_dynamic_address" == "true") ]]; then | ||
| net=$(jq -c --argjson addr_info "$addr_info" '.addr_info = $addr_info' <<< "$net") | ||
| echo "$net" # "return" | ||
| fi | ||
| done | ||
| } | ||
|
|
||
| # filter_routes function | ||
| filter_routes() { | ||
| # This function takes a list of routes as input and filters out routes | ||
| # with protocols "dhcp", "kernel", or "ra". The filtered routes are | ||
| # returned one by one on stdout. | ||
| local routes=("$@") | ||
|
|
||
| for route in "${routes[@]}"; do | ||
| local protocol=$(jq -r '.protocol' <<< "$route") | ||
| if [[ $protocol != "dhcp" && $protocol != "kernel" && $protocol != "ra" ]]; then | ||
| echo "$route" # "return" | ||
| fi | ||
| done | ||
| } | ||
|
|
||
| # generate_networkd_units function | ||
| generate_networkd_units() { | ||
| # This function takes the filtered interfaces and routes, along with a | ||
| # directory path. It generates systemd-networkd unit files for each interface, | ||
| # including the configured addresses and routes. The unit files are written | ||
| # to the specified directory with the naming convention 00-<ifname>.network. | ||
| local -n interfaces=$1 | ||
| local -n routes=$2 | ||
| local directory="$3" | ||
|
|
||
| mkdir -p "$directory" | ||
|
|
||
| for interface in "${interfaces[@]}"; do | ||
| local ifname=$(jq -r '.ifname' <<< "$interface") | ||
| local address=$(jq -r '.address' <<< "$interface") | ||
| local addresses=$(jq -r '.addr_info | map("Address = \(.local)/\(.prefixlen)") | join("\n")' <<< "$interface") | ||
| local route_sections=() | ||
|
|
||
| for route in "${routes[@]}"; do | ||
| local dev=$(jq -r '.dev' <<< "$route") | ||
| if [[ $dev == $ifname ]]; then | ||
| local route_section="[Route]" | ||
| local dst=$(jq -r '.dst' <<< "$route") | ||
| if [[ $dst != "default" ]]; then | ||
| route_section+="\nDestination = $dst" | ||
| fi | ||
| local gateway=$(jq -r '.gateway // ""' <<< "$route") | ||
| if [[ -n $gateway ]]; then | ||
| route_section+="\nGateway = $gateway" | ||
| fi | ||
| route_sections+=("$route_section") | ||
| fi | ||
| done | ||
|
|
||
| local unit=$(cat <<-EOF | ||
| [Match] | ||
| MACAddress = $address | ||
|
|
||
| [Network] | ||
| DHCP = yes | ||
| LLDP = yes | ||
| IPv6AcceptRA = yes | ||
| MulticastDNS = yes | ||
|
|
||
| $addresses | ||
| $(printf '%s\n' "${route_sections[@]}") | ||
| EOF | ||
| ) | ||
| echo -e "$unit" > "$directory/00-$ifname.network" | ||
| done | ||
| } | ||
|
|
||
| # main function | ||
| main() { | ||
| if [[ $# -lt 4 ]]; then | ||
| echo "USAGE: $0 addresses routes-v4 routes-v6 networkd-directory" >&2 | ||
| # exit 1 | ||
| return 1 | ||
| fi | ||
|
|
||
| local addresses | ||
| readarray -t addresses < <(jq -c '.[]' "$1") # Read JSON data into array | ||
|
|
||
| local v4_routes | ||
| readarray -t v4_routes < <(jq -c '.[]' "$2") | ||
|
|
||
| local v6_routes | ||
| readarray -t v6_routes < <(jq -c '.[]' "$3") | ||
|
|
||
| local networkd_directory="$4" | ||
|
|
||
| local relevant_interfaces | ||
| readarray -t relevant_interfaces < <(filter_interfaces "${addresses[@]}") | ||
|
|
||
| local relevant_routes | ||
| readarray -t relevant_routes < <(filter_routes "${v4_routes[@]}" "${v6_routes[@]}") | ||
|
|
||
| generate_networkd_units relevant_interfaces relevant_routes "$networkd_directory" | ||
| } | ||
|
|
||
| main "$@" | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also question here: Do we actually care about this? We are not shipping manpages afaik and they are hopefully in a separate output?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately not, at least in nixos-23.11:
minimalisfalseon-full