mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-07-30 12:28:23 +00:00
Update 1.2.4
This commit is contained in:
@@ -497,7 +497,7 @@ force_apt_ipv4() {
|
||||
# ==========================================================
|
||||
|
||||
apply_network_optimizations() {
|
||||
local FUNC_VERSION="1.0"
|
||||
local FUNC_VERSION="1.1"
|
||||
# description: Tune TCP buffers, somaxconn, IPv4 hardening and disable rp_filter on fw bridges (PVE 9 compatible).
|
||||
msg_info "$(translate "Optimizing network settings...")"
|
||||
NECESSARY_REBOOT=1
|
||||
@@ -548,8 +548,38 @@ EOF
|
||||
|
||||
sysctl --system > /dev/null 2>&1
|
||||
|
||||
cat > /usr/local/sbin/proxmenux-fwbr-tune <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
# Set rp_filter=0 and log_martians=0 on Proxmox fw bridge interfaces.
|
||||
# No arg → sweep every interface currently under /proc/sys/net/ipv4/conf/.
|
||||
# One arg → tune only that interface (used by the udev rule).
|
||||
set -u
|
||||
|
||||
cat >/etc/systemd/system/proxmenux-fwbr-tune.service <<'EOF'
|
||||
tune_interface() {
|
||||
local iface="$1"
|
||||
local sysctl_path="/proc/sys/net/ipv4/conf/${iface}"
|
||||
case "$iface" in
|
||||
fwbr*|fwln*|fwpr*|tap*)
|
||||
[[ -d "$sysctl_path" ]] || return 0
|
||||
[[ -w "$sysctl_path/rp_filter" ]] && printf '0\n' > "$sysctl_path/rp_filter"
|
||||
[[ -w "$sysctl_path/log_martians" ]] && printf '0\n' > "$sysctl_path/log_martians"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [[ $# -gt 0 ]]; then
|
||||
tune_interface "$1"
|
||||
else
|
||||
for sysctl_path in /proc/sys/net/ipv4/conf/*; do
|
||||
[[ -d "$sysctl_path" ]] || continue
|
||||
tune_interface "${sysctl_path##*/}"
|
||||
done
|
||||
fi
|
||||
EOF
|
||||
chmod 0755 /usr/local/sbin/proxmenux-fwbr-tune
|
||||
chown root:root /usr/local/sbin/proxmenux-fwbr-tune
|
||||
|
||||
cat > /etc/systemd/system/proxmenux-fwbr-tune.service <<'EOF'
|
||||
[Unit]
|
||||
Description=ProxMenux - Tune rp_filter/log_martians on virtual fw bridges
|
||||
After=network-online.target
|
||||
@@ -557,14 +587,26 @@ Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash -c 'for i in /proc/sys/net/ipv4/conf/*; do n=${i##*/}; case "$n" in fwbr*|fwln*|fwpr*|tap*) echo 0 > /proc/sys/net/ipv4/conf/$n/rp_filter; echo 0 > /proc/sys/net/ipv4/conf/$n/log_martians; esac; done'
|
||||
ExecStart=/usr/local/sbin/proxmenux-fwbr-tune
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
cat > /etc/udev/rules.d/99-proxmenux-fwbr-tune.rules <<'EOF'
|
||||
ACTION=="add", SUBSYSTEM=="net", KERNEL=="fwbr*", RUN+="/usr/local/sbin/proxmenux-fwbr-tune %k"
|
||||
ACTION=="add", SUBSYSTEM=="net", KERNEL=="fwln*", RUN+="/usr/local/sbin/proxmenux-fwbr-tune %k"
|
||||
ACTION=="add", SUBSYSTEM=="net", KERNEL=="fwpr*", RUN+="/usr/local/sbin/proxmenux-fwbr-tune %k"
|
||||
ACTION=="add", SUBSYSTEM=="net", KERNEL=="tap*", RUN+="/usr/local/sbin/proxmenux-fwbr-tune %k"
|
||||
EOF
|
||||
chmod 0644 /etc/udev/rules.d/99-proxmenux-fwbr-tune.rules
|
||||
chown root:root /etc/udev/rules.d/99-proxmenux-fwbr-tune.rules
|
||||
|
||||
systemctl daemon-reload >/dev/null 2>&1 || true
|
||||
udevadm control --reload-rules >/dev/null 2>&1 || true
|
||||
systemctl enable --now proxmenux-fwbr-tune.service >/dev/null 2>&1 || true
|
||||
/usr/local/sbin/proxmenux-fwbr-tune >/dev/null 2>&1 || true
|
||||
|
||||
|
||||
local interfaces_file="/etc/network/interfaces"
|
||||
@@ -638,7 +680,7 @@ EOF
|
||||
|
||||
|
||||
install_log2ram_auto() {
|
||||
local FUNC_VERSION="1.2"
|
||||
local FUNC_VERSION="1.3"
|
||||
|
||||
# description: Install Log2RAM with size auto-tuned to host RAM (128M/256M/512M); SSD/M.2 detection skips on rotational disks.
|
||||
|
||||
@@ -727,6 +769,52 @@ install_log2ram_auto() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Drop ACL preservation from the upstream rsync call: some
|
||||
# /var/log.hdd filesystems reject POSIX ACLs and log2ram write
|
||||
# exits 23 with `set_acl: Operation not supported`. xattrs stay.
|
||||
local _l2r_bin
|
||||
for _l2r_bin in \
|
||||
"$(command -v log2ram 2>/dev/null)" \
|
||||
/usr/local/bin/log2ram \
|
||||
/usr/sbin/log2ram \
|
||||
/usr/bin/log2ram
|
||||
do
|
||||
[[ -n "$_l2r_bin" && -f "$_l2r_bin" ]] || continue
|
||||
if grep -q 'rsync -aAXv ' "$_l2r_bin" 2>/dev/null; then
|
||||
cp -a "$_l2r_bin" "${_l2r_bin}.proxmenux.bak"
|
||||
sed -i 's/rsync -aAXv /rsync -aXv --no-acls /g' "$_l2r_bin"
|
||||
fi
|
||||
break
|
||||
done
|
||||
|
||||
# Size-based rotation for the PBS API logs — the upstream package
|
||||
# ships no logrotate rule and pvestatd's local-datastore poll fills
|
||||
# them fast enough to saturate a tmpfs /var/log.
|
||||
if dpkg-query -W -f='${Status}' proxmox-backup-server 2>/dev/null \
|
||||
| grep -q 'install ok installed'; then
|
||||
mkdir -p /var/log/proxmox-backup/api 2>/dev/null || true
|
||||
cat > /etc/logrotate.d/proxmox-backup-api <<'EOF'
|
||||
/var/log/proxmox-backup/api/access.log /var/log/proxmox-backup/api/auth.log {
|
||||
size 20M
|
||||
rotate 3
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
copytruncate
|
||||
}
|
||||
EOF
|
||||
chmod 0644 /etc/logrotate.d/proxmox-backup-api
|
||||
chown root:root /etc/logrotate.d/proxmox-backup-api
|
||||
cat > /etc/cron.hourly/proxmox-backup-logrotate <<'EOF'
|
||||
#!/bin/sh
|
||||
/usr/sbin/logrotate /etc/logrotate.d/proxmox-backup-api >/dev/null 2>&1
|
||||
EOF
|
||||
chmod 0755 /etc/cron.hourly/proxmox-backup-logrotate
|
||||
chown root:root /etc/cron.hourly/proxmox-backup-logrotate
|
||||
msg_ok "$(translate "PBS API log rotation configured (hourly, size-based)")"
|
||||
fi
|
||||
|
||||
systemctl enable --now log2ram >/dev/null 2>&1 || true
|
||||
systemctl daemon-reload >/dev/null 2>&1 || true
|
||||
|
||||
@@ -766,13 +854,10 @@ EOF
|
||||
|
||||
cat > /usr/local/bin/log2ram-check.sh <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
# v1.2 — `log2ram write` only copies tmpfs→disk; it does NOT shrink
|
||||
# the tmpfs. When journald or pveproxy/access.log grow past their
|
||||
# limits the tmpfs hit 100% and PVE crashed with "No space left on
|
||||
# device" on Shell open (community-reported: JC Miñarro, Nicolás P.
|
||||
# de A., 17-18/05). We now vacuum the journal and truncate the
|
||||
# non-rotating logs that actually consume the tmpfs before calling
|
||||
# `log2ram write`.
|
||||
# Watch /var/log usage on Log2RAM's tmpfs and act at two thresholds:
|
||||
# > 80% → vacuum journald down to ~30% of SIZE, then log2ram write
|
||||
# > 92% → aggressive: journal to ~5%, rotate PBS API logs if present,
|
||||
# truncate pveproxy/pveam, then log2ram write
|
||||
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
CONF_FILE="/etc/log2ram.conf"
|
||||
@@ -793,15 +878,13 @@ LOCK="/run/log2ram-check.lock"
|
||||
exec 9>"$LOCK" 2>/dev/null || exit 0
|
||||
flock -n 9 || exit 0
|
||||
|
||||
# `log2ram write` alone leaves the tmpfs full. Real recovery requires:
|
||||
# (a) journal vacuum — journald respects --vacuum-size unconditionally,
|
||||
# unlike SystemMaxUse which only enforces on rotation boundaries;
|
||||
# (b) truncating logs that aren't rotated by logrotate (pveproxy, pveam);
|
||||
# (c) THEN syncing to disk so the persistent copy reflects reality.
|
||||
if (( USED_BYTES > EMERGENCY_BYTES )); then
|
||||
SAFE_JOURNAL_MB=$(( SIZE_MiB * 5 / 100 ))
|
||||
[[ "$SAFE_JOURNAL_MB" -lt 16 ]] && SAFE_JOURNAL_MB=16
|
||||
journalctl --vacuum-size="${SAFE_JOURNAL_MB}M" >/dev/null 2>&1 || true
|
||||
if [[ -x /usr/sbin/logrotate && -f /etc/logrotate.d/proxmox-backup-api ]]; then
|
||||
/usr/sbin/logrotate -f /etc/logrotate.d/proxmox-backup-api >/dev/null 2>&1 || true
|
||||
fi
|
||||
: > /var/log/pveproxy/access.log 2>/dev/null || true
|
||||
: > /var/log/pveproxy/error.log 2>/dev/null || true
|
||||
: > /var/log/pveam.log 2>/dev/null || true
|
||||
@@ -820,8 +903,7 @@ EOF
|
||||
SHELL=/bin/bash
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
MAILTO=""
|
||||
# Runs every 10 min starting at :03 to avoid overlap with debian-sa1 (:00/:10/:20...)
|
||||
# nice -n 19 + ionice -c 3 ensures minimum CPU/IO priority (no visible spikes)
|
||||
# nice/ionice keep the check off the priority queue for scheduled tasks.
|
||||
3-59/10 * * * * root nice -n 19 ionice -c 3 /usr/local/bin/log2ram-check.sh >/dev/null 2>&1
|
||||
EOF
|
||||
chmod 0644 /etc/cron.d/log2ram-auto-sync
|
||||
@@ -1011,57 +1093,37 @@ enable_zfs_autotrim() {
|
||||
|
||||
|
||||
setup_persistent_network() {
|
||||
local FUNC_VERSION="1.0"
|
||||
local FUNC_VERSION="1.1"
|
||||
# description: Pin NIC names to MAC addresses via systemd .link files so kernel updates don't shuffle interface names.
|
||||
local LINK_DIR="/etc/systemd/network"
|
||||
local BACKUP_DIR="/etc/systemd/network/backup-$(date +%Y%m%d-%H%M%S)"
|
||||
local pve_version
|
||||
pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+' | head -1)
|
||||
|
||||
msg_info "$(translate "Setting up persistent network interfaces")"
|
||||
sleep 2
|
||||
|
||||
# Same legacy-conflict warning as in customizable_post_install.sh.
|
||||
if [[ -f /etc/network/interfaces ]]; then
|
||||
if grep -qE '^[[:space:]]*allow-hotplug[[:space:]]' /etc/network/interfaces 2>/dev/null; then
|
||||
msg_warn "$(translate '/etc/network/interfaces uses allow-hotplug. Renaming interfaces via systemd .link can break that flow — review the file after reboot.')"
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p "$LINK_DIR"
|
||||
local count=0 removed_stale=0 removed_legacy=0
|
||||
while IFS='=' read -r key value; do
|
||||
case "$key" in
|
||||
COUNT) count="$value" ;;
|
||||
REMOVED_STALE) removed_stale="$value" ;;
|
||||
REMOVED_LEGACY) removed_legacy="$value" ;;
|
||||
esac
|
||||
done < <(pmx_setup_persistent_network)
|
||||
|
||||
if ls "$LINK_DIR"/*.link >/dev/null 2>&1; then
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
cp "$LINK_DIR"/*.link "$BACKUP_DIR"/ 2>/dev/null || true
|
||||
if (( removed_legacy > 0 )); then
|
||||
msg_ok "$(translate "Migrated") $removed_legacy $(translate "legacy .link file(s) to the ProxMenux-managed format")"
|
||||
fi
|
||||
|
||||
local count=0
|
||||
for iface in $(ls /sys/class/net/ | grep -vE "lo|docker|veth|br-|vmbr|tap|fwpr|fwln|virbr|bond|cilium|zt|wg"); do
|
||||
if [[ -e "/sys/class/net/$iface/device" ]] || [[ -e "/sys/class/net/$iface/phy80211" ]]; then
|
||||
local MAC=$(cat /sys/class/net/$iface/address 2>/dev/null)
|
||||
|
||||
if [[ "$MAC" =~ ^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$ ]]; then
|
||||
local LINK_FILE="$LINK_DIR/10-$iface.link"
|
||||
|
||||
cat > "$LINK_FILE" <<EOF
|
||||
[Match]
|
||||
MACAddress=$MAC
|
||||
|
||||
[Link]
|
||||
Name=$iface
|
||||
EOF
|
||||
chmod 644 "$LINK_FILE"
|
||||
((count++))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $count -gt 0 ]]; then
|
||||
if (( removed_stale > 0 )); then
|
||||
msg_ok "$(translate "Reconciled") $removed_stale $(translate "stale entry/entries for interfaces no longer present")"
|
||||
fi
|
||||
if (( count > 0 )); then
|
||||
msg_ok "$(translate "Created persistent names for") $count $(translate "interfaces")"
|
||||
# In PVE9, systemd-networkd is the native network backend and udev processes
|
||||
# .link files directly. Reloading udev rules makes the new .link files effective
|
||||
# immediately for any interface added later (hotplug, new NICs) without waiting
|
||||
# for a full reboot. On PVE8 (ifupdown2), names are resolved at boot anyway.
|
||||
if [[ "$pve_version" -ge 9 ]]; then
|
||||
udevadm control --reload-rules 2>/dev/null || true
|
||||
msg_ok "$(translate "PVE9: udev rules reloaded — new interfaces will get correct names without reboot")"
|
||||
|
||||
@@ -778,7 +778,7 @@ force_apt_ipv4() {
|
||||
|
||||
|
||||
apply_network_optimizations() {
|
||||
local FUNC_VERSION="1.0"
|
||||
local FUNC_VERSION="1.1"
|
||||
# description: Tune TCP buffers, somaxconn, IPv4 hardening and disable rp_filter on fw bridges (PVE 9 compatible).
|
||||
msg_info "$(translate "Optimizing network settings...")"
|
||||
NECESSARY_REBOOT=1
|
||||
@@ -839,6 +839,66 @@ EOF
|
||||
|
||||
sysctl --system > /dev/null 2>&1
|
||||
|
||||
cat > /usr/local/sbin/proxmenux-fwbr-tune <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
# Set rp_filter=0 and log_martians=0 on Proxmox fw bridge interfaces.
|
||||
# No arg → sweep every interface currently under /proc/sys/net/ipv4/conf/.
|
||||
# One arg → tune only that interface (used by the udev rule).
|
||||
set -u
|
||||
|
||||
tune_interface() {
|
||||
local iface="$1"
|
||||
local sysctl_path="/proc/sys/net/ipv4/conf/${iface}"
|
||||
case "$iface" in
|
||||
fwbr*|fwln*|fwpr*|tap*)
|
||||
[[ -d "$sysctl_path" ]] || return 0
|
||||
[[ -w "$sysctl_path/rp_filter" ]] && printf '0\n' > "$sysctl_path/rp_filter"
|
||||
[[ -w "$sysctl_path/log_martians" ]] && printf '0\n' > "$sysctl_path/log_martians"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [[ $# -gt 0 ]]; then
|
||||
tune_interface "$1"
|
||||
else
|
||||
for sysctl_path in /proc/sys/net/ipv4/conf/*; do
|
||||
[[ -d "$sysctl_path" ]] || continue
|
||||
tune_interface "${sysctl_path##*/}"
|
||||
done
|
||||
fi
|
||||
EOF
|
||||
chmod 0755 /usr/local/sbin/proxmenux-fwbr-tune
|
||||
chown root:root /usr/local/sbin/proxmenux-fwbr-tune
|
||||
|
||||
cat > /etc/systemd/system/proxmenux-fwbr-tune.service <<'EOF'
|
||||
[Unit]
|
||||
Description=ProxMenux - Tune rp_filter/log_martians on virtual fw bridges
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/sbin/proxmenux-fwbr-tune
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
cat > /etc/udev/rules.d/99-proxmenux-fwbr-tune.rules <<'EOF'
|
||||
ACTION=="add", SUBSYSTEM=="net", KERNEL=="fwbr*", RUN+="/usr/local/sbin/proxmenux-fwbr-tune %k"
|
||||
ACTION=="add", SUBSYSTEM=="net", KERNEL=="fwln*", RUN+="/usr/local/sbin/proxmenux-fwbr-tune %k"
|
||||
ACTION=="add", SUBSYSTEM=="net", KERNEL=="fwpr*", RUN+="/usr/local/sbin/proxmenux-fwbr-tune %k"
|
||||
ACTION=="add", SUBSYSTEM=="net", KERNEL=="tap*", RUN+="/usr/local/sbin/proxmenux-fwbr-tune %k"
|
||||
EOF
|
||||
chmod 0644 /etc/udev/rules.d/99-proxmenux-fwbr-tune.rules
|
||||
chown root:root /etc/udev/rules.d/99-proxmenux-fwbr-tune.rules
|
||||
|
||||
systemctl daemon-reload >/dev/null 2>&1 || true
|
||||
udevadm control --reload-rules >/dev/null 2>&1 || true
|
||||
systemctl enable --now proxmenux-fwbr-tune.service >/dev/null 2>&1 || true
|
||||
/usr/local/sbin/proxmenux-fwbr-tune >/dev/null 2>&1 || true
|
||||
|
||||
|
||||
local interfaces_file="/etc/network/interfaces"
|
||||
if ! grep -q 'source /etc/network/interfaces.d/*' "$interfaces_file"; then
|
||||
@@ -1147,86 +1207,58 @@ EOF
|
||||
|
||||
|
||||
optimize_zfs_arc() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Cap ZFS ARC to a sensible fraction of host RAM so VMs don't fight the kernel for memory.
|
||||
msg_info2 "$(translate "Optimizing ZFS ARC size according to available memory...")"
|
||||
local FUNC_VERSION="1.1"
|
||||
# description: Cap ZFS ARC max to a sensible fraction of host RAM so VMs don't fight the kernel for memory. Only sets zfs_arc_max; other OpenZFS tunables stay at their defaults.
|
||||
local zfs_conf="/etc/modprobe.d/99-zfsarc.conf"
|
||||
local ram_bytes arc_max
|
||||
|
||||
# Check if ZFS is installed
|
||||
if ! command -v zfs > /dev/null; then
|
||||
msg_info2 "$(translate "Optimizing ZFS ARC maximum size...")"
|
||||
|
||||
if ! command -v zpool >/dev/null 2>&1; then
|
||||
msg_warn "$(translate "ZFS not detected. Skipping ZFS ARC optimization.")"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Ensure RAM_SIZE_GB is set
|
||||
if [ -z "$RAM_SIZE_GB" ]; then
|
||||
RAM_SIZE_GB=$(free -g | awk '/^Mem:/{print $2}')
|
||||
if [ -z "$RAM_SIZE_GB" ] || [ "$RAM_SIZE_GB" -eq 0 ]; then
|
||||
msg_warn "$(translate "Failed to detect RAM size. Using default value of 16GB for ZFS ARC optimization.")"
|
||||
RAM_SIZE_GB=16 # Default to 16GB if detection fails
|
||||
fi
|
||||
if ! zpool list -H -o name 2>/dev/null | grep -q .; then
|
||||
msg_warn "$(translate "No ZFS pools detected. Skipping ZFS ARC optimization.")"
|
||||
return 0
|
||||
fi
|
||||
|
||||
msg_ok "$(translate "Detected RAM size: ${RAM_SIZE_GB} GB")"
|
||||
ram_bytes=$(awk '/MemTotal:/ { print $2 * 1024 }' /proc/meminfo)
|
||||
if [[ -z "$ram_bytes" || "$ram_bytes" -le 0 ]]; then
|
||||
msg_error "$(translate "Unable to determine the installed memory.")"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Calculate ZFS ARC sizes
|
||||
if [[ "$RAM_SIZE_GB" -le 16 ]]; then
|
||||
MY_ZFS_ARC_MIN=536870911 # 512MB
|
||||
MY_ZFS_ARC_MAX=536870912 # 512MB
|
||||
elif [[ "$RAM_SIZE_GB" -le 32 ]]; then
|
||||
MY_ZFS_ARC_MIN=1073741823 # 1GB
|
||||
MY_ZFS_ARC_MAX=1073741824 # 1GB
|
||||
if (( ram_bytes <= 16 * 1024 * 1024 * 1024 )); then
|
||||
arc_max=$((512 * 1024 * 1024))
|
||||
elif (( ram_bytes <= 32 * 1024 * 1024 * 1024 )); then
|
||||
arc_max=$((1024 * 1024 * 1024))
|
||||
else
|
||||
# Use 1/16 of RAM for min and 1/8 for max
|
||||
MY_ZFS_ARC_MIN=$((RAM_SIZE_GB * 1073741824 / 16))
|
||||
MY_ZFS_ARC_MAX=$((RAM_SIZE_GB * 1073741824 / 8))
|
||||
arc_max=$((ram_bytes / 8))
|
||||
fi
|
||||
(( arc_max < 512 * 1024 * 1024 )) && arc_max=$((512 * 1024 * 1024))
|
||||
|
||||
if [[ -f "$zfs_conf" && ! -f "${zfs_conf}.bak" ]]; then
|
||||
cp -p "$zfs_conf" "${zfs_conf}.bak"
|
||||
fi
|
||||
|
||||
# Enforce the minimum values
|
||||
MY_ZFS_ARC_MIN=$((MY_ZFS_ARC_MIN > 536870911 ? MY_ZFS_ARC_MIN : 536870911))
|
||||
MY_ZFS_ARC_MAX=$((MY_ZFS_ARC_MAX > 536870912 ? MY_ZFS_ARC_MAX : 536870912))
|
||||
|
||||
# Apply ZFS tuning parameters
|
||||
local zfs_conf="/etc/modprobe.d/99-zfsarc.conf"
|
||||
local config_changed=false
|
||||
|
||||
if [ -f "$zfs_conf" ]; then
|
||||
msg_info "$(translate "Checking existing ZFS ARC configuration...")"
|
||||
if ! grep -q "zfs_arc_min=$MY_ZFS_ARC_MIN" "$zfs_conf" || \
|
||||
! grep -q "zfs_arc_max=$MY_ZFS_ARC_MAX" "$zfs_conf"; then
|
||||
msg_ok "$(translate "Changes detected. Updating ZFS ARC configuration...")"
|
||||
cp "$zfs_conf" "${zfs_conf}.bak"
|
||||
config_changed=true
|
||||
else
|
||||
msg_ok "$(translate "ZFS ARC configuration is up to date")"
|
||||
fi
|
||||
else
|
||||
msg_info "$(translate "Creating new ZFS ARC configuration...")"
|
||||
config_changed=true
|
||||
fi
|
||||
|
||||
if $config_changed; then
|
||||
cat <<EOF > "$zfs_conf"
|
||||
# ZFS tuning
|
||||
# Use 1/8 RAM for MAX cache, 1/16 RAM for MIN cache, or 512MB/1GB for systems with <= 32GB RAM
|
||||
options zfs zfs_arc_min=$MY_ZFS_ARC_MIN
|
||||
options zfs zfs_arc_max=$MY_ZFS_ARC_MAX
|
||||
|
||||
# Enable prefetch method
|
||||
options zfs l2arc_noprefetch=0
|
||||
|
||||
# Set max write speed to L2ARC (500MB)
|
||||
options zfs l2arc_write_max=524288000
|
||||
options zfs zfs_txg_timeout=60
|
||||
cat > "$zfs_conf" <<EOF
|
||||
# ProxMenux ZFS ARC configuration
|
||||
# Only zfs_arc_max is set; zfs_arc_min stays at the OpenZFS default (auto).
|
||||
options zfs zfs_arc_max=$arc_max
|
||||
EOF
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
msg_ok "$(translate "ZFS ARC configuration file created/updated successfully")"
|
||||
NECESSARY_REBOOT=1
|
||||
else
|
||||
msg_error "$(translate "Failed to create/update ZFS ARC configuration file")"
|
||||
fi
|
||||
msg_info "$(translate "Updating initramfs so the ARC cap applies at next boot...")"
|
||||
if ! update-initramfs -u -k all >/dev/null 2>&1; then
|
||||
msg_error "$(translate "Failed to update initramfs.")"
|
||||
return 1
|
||||
fi
|
||||
if command -v proxmox-boot-tool >/dev/null 2>&1; then
|
||||
proxmox-boot-tool refresh >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
NECESSARY_REBOOT=1
|
||||
msg_ok "$(translate "ZFS ARC maximum configured:") $arc_max $(translate "bytes")"
|
||||
msg_success "$(translate "ZFS ARC optimization completed")"
|
||||
register_tool "zfs_arc" true "$FUNC_VERSION"
|
||||
}
|
||||
@@ -2493,7 +2525,7 @@ update_pve_appliance_manager() {
|
||||
|
||||
|
||||
configure_log2ram() {
|
||||
local FUNC_VERSION="1.2"
|
||||
local FUNC_VERSION="1.3"
|
||||
# description: Install Log2RAM with user-chosen RAM size; prompts for size and SSD/M.2 awareness before applying.
|
||||
msg_info2 "$(translate "Preparing Log2RAM configuration")"
|
||||
sleep 1
|
||||
@@ -2591,6 +2623,52 @@ configure_log2ram() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Drop ACL preservation from the upstream rsync call: some
|
||||
# /var/log.hdd filesystems reject POSIX ACLs and log2ram write
|
||||
# exits 23 with `set_acl: Operation not supported`. xattrs stay.
|
||||
local _l2r_bin
|
||||
for _l2r_bin in \
|
||||
"$(command -v log2ram 2>/dev/null)" \
|
||||
/usr/local/bin/log2ram \
|
||||
/usr/sbin/log2ram \
|
||||
/usr/bin/log2ram
|
||||
do
|
||||
[[ -n "$_l2r_bin" && -f "$_l2r_bin" ]] || continue
|
||||
if grep -q 'rsync -aAXv ' "$_l2r_bin" 2>/dev/null; then
|
||||
cp -a "$_l2r_bin" "${_l2r_bin}.proxmenux.bak"
|
||||
sed -i 's/rsync -aAXv /rsync -aXv --no-acls /g' "$_l2r_bin"
|
||||
fi
|
||||
break
|
||||
done
|
||||
|
||||
# Size-based rotation for the PBS API logs — the upstream package
|
||||
# ships no logrotate rule and pvestatd's local-datastore poll fills
|
||||
# them fast enough to saturate a tmpfs /var/log.
|
||||
if dpkg-query -W -f='${Status}' proxmox-backup-server 2>/dev/null \
|
||||
| grep -q 'install ok installed'; then
|
||||
mkdir -p /var/log/proxmox-backup/api 2>/dev/null || true
|
||||
cat > /etc/logrotate.d/proxmox-backup-api <<'EOF'
|
||||
/var/log/proxmox-backup/api/access.log /var/log/proxmox-backup/api/auth.log {
|
||||
size 20M
|
||||
rotate 3
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
copytruncate
|
||||
}
|
||||
EOF
|
||||
chmod 0644 /etc/logrotate.d/proxmox-backup-api
|
||||
chown root:root /etc/logrotate.d/proxmox-backup-api
|
||||
cat > /etc/cron.hourly/proxmox-backup-logrotate <<'EOF'
|
||||
#!/bin/sh
|
||||
/usr/sbin/logrotate /etc/logrotate.d/proxmox-backup-api >/dev/null 2>&1
|
||||
EOF
|
||||
chmod 0755 /etc/cron.hourly/proxmox-backup-logrotate
|
||||
chown root:root /etc/cron.hourly/proxmox-backup-logrotate
|
||||
msg_ok "$(translate "PBS API log rotation configured (hourly, size-based)")"
|
||||
fi
|
||||
|
||||
systemctl daemon-reload >/dev/null 2>&1 || true
|
||||
systemctl enable --now log2ram >/dev/null 2>&1 || true
|
||||
|
||||
@@ -2620,13 +2698,10 @@ EOF
|
||||
if [[ "$ENABLE_AUTOSYNC" == true ]]; then
|
||||
cat > /usr/local/bin/log2ram-check.sh <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
# v1.2 — `log2ram write` only copies tmpfs→disk; it does NOT shrink
|
||||
# the tmpfs. When journald or pveproxy/access.log grow past their
|
||||
# limits the tmpfs hit 100% and PVE crashed with "No space left on
|
||||
# device" on Shell open (community-reported: JC Miñarro, Nicolás P.
|
||||
# de A., 17-18/05). We now vacuum the journal and truncate the
|
||||
# non-rotating logs that actually consume the tmpfs before calling
|
||||
# `log2ram write`.
|
||||
# Watch /var/log usage on Log2RAM's tmpfs and act at two thresholds:
|
||||
# > 80% → vacuum journald down to ~30% of SIZE, then log2ram write
|
||||
# > 92% → aggressive: journal to ~5%, rotate PBS API logs if present,
|
||||
# truncate pveproxy/pveam, then log2ram write
|
||||
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
CONF_FILE="/etc/log2ram.conf"
|
||||
L2R_BIN="$(command -v log2ram || true)"
|
||||
@@ -2646,15 +2721,13 @@ LOCK="/run/log2ram-check.lock"
|
||||
exec 9>"$LOCK" 2>/dev/null || exit 0
|
||||
flock -n 9 || exit 0
|
||||
|
||||
# `log2ram write` alone leaves the tmpfs full. Real recovery requires:
|
||||
# (a) journal vacuum — journald respects --vacuum-size unconditionally,
|
||||
# unlike SystemMaxUse which only enforces on rotation boundaries;
|
||||
# (b) truncating logs that aren't rotated by logrotate (pveproxy, pveam);
|
||||
# (c) THEN syncing to disk so the persistent copy reflects reality.
|
||||
if (( USED_BYTES > EMERGENCY_BYTES )); then
|
||||
SAFE_JOURNAL_MB=$(( SIZE_MiB * 5 / 100 ))
|
||||
[[ "$SAFE_JOURNAL_MB" -lt 16 ]] && SAFE_JOURNAL_MB=16
|
||||
journalctl --vacuum-size="${SAFE_JOURNAL_MB}M" >/dev/null 2>&1 || true
|
||||
if [[ -x /usr/sbin/logrotate && -f /etc/logrotate.d/proxmox-backup-api ]]; then
|
||||
/usr/sbin/logrotate -f /etc/logrotate.d/proxmox-backup-api >/dev/null 2>&1 || true
|
||||
fi
|
||||
: > /var/log/pveproxy/access.log 2>/dev/null || true
|
||||
: > /var/log/pveproxy/error.log 2>/dev/null || true
|
||||
: > /var/log/pveam.log 2>/dev/null || true
|
||||
@@ -2763,64 +2836,37 @@ EOF
|
||||
|
||||
|
||||
setup_persistent_network() {
|
||||
local FUNC_VERSION="1.0"
|
||||
local FUNC_VERSION="1.1"
|
||||
# description: Pin NIC names to MAC addresses via systemd .link files so kernel updates don't shuffle interface names.
|
||||
local LINK_DIR="/etc/systemd/network"
|
||||
local BACKUP_DIR="/etc/systemd/network/backup-$(date +%Y%m%d-%H%M%S)"
|
||||
local pve_version
|
||||
pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+' | head -1)
|
||||
|
||||
msg_info "$(translate "Setting up persistent network interfaces")"
|
||||
sleep 2
|
||||
|
||||
# Detect legacy `/etc/network/interfaces` setups that depend on the
|
||||
# default udev naming. If the file references `allow-hotplug` rules
|
||||
# or uses physical interface names directly, the .link rules below
|
||||
# could rename interfaces and break network on reboot. Warn loudly so
|
||||
# the user can review before continuing. Audit Tier 6 —
|
||||
# `setup_persistent_network` no detecta conflicto con legacy.
|
||||
if [[ -f /etc/network/interfaces ]]; then
|
||||
if grep -qE '^[[:space:]]*allow-hotplug[[:space:]]' /etc/network/interfaces 2>/dev/null; then
|
||||
msg_warn "$(translate '/etc/network/interfaces uses allow-hotplug. Renaming interfaces via systemd .link can break that flow — review the file after reboot.')"
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p "$LINK_DIR"
|
||||
local count=0 removed_stale=0 removed_legacy=0
|
||||
while IFS='=' read -r key value; do
|
||||
case "$key" in
|
||||
COUNT) count="$value" ;;
|
||||
REMOVED_STALE) removed_stale="$value" ;;
|
||||
REMOVED_LEGACY) removed_legacy="$value" ;;
|
||||
esac
|
||||
done < <(pmx_setup_persistent_network)
|
||||
|
||||
|
||||
if ls "$LINK_DIR"/*.link >/dev/null 2>&1; then
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
cp "$LINK_DIR"/*.link "$BACKUP_DIR"/ 2>/dev/null || true
|
||||
if (( removed_legacy > 0 )); then
|
||||
msg_ok "$(translate "Migrated") $removed_legacy $(translate "legacy .link file(s) to the ProxMenux-managed format")"
|
||||
fi
|
||||
|
||||
# Process physical interfaces
|
||||
local count=0
|
||||
for iface in $(ls /sys/class/net/ | grep -vE "lo|docker|veth|br-|vmbr|tap|fwpr|fwln|virbr|bond|cilium|zt|wg"); do
|
||||
if [[ -e "/sys/class/net/$iface/device" ]] || [[ -e "/sys/class/net/$iface/phy80211" ]]; then
|
||||
local MAC=$(cat /sys/class/net/$iface/address 2>/dev/null)
|
||||
|
||||
if [[ "$MAC" =~ ^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$ ]]; then
|
||||
local LINK_FILE="$LINK_DIR/10-$iface.link"
|
||||
|
||||
cat > "$LINK_FILE" <<EOF
|
||||
[Match]
|
||||
MACAddress=$MAC
|
||||
|
||||
[Link]
|
||||
Name=$iface
|
||||
EOF
|
||||
chmod 644 "$LINK_FILE"
|
||||
((count++))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $count -gt 0 ]]; then
|
||||
if (( removed_stale > 0 )); then
|
||||
msg_ok "$(translate "Reconciled") $removed_stale $(translate "stale entry/entries for interfaces no longer present")"
|
||||
fi
|
||||
if (( count > 0 )); then
|
||||
msg_ok "$(translate "Created persistent names for") $count $(translate "interfaces")"
|
||||
# In PVE9, systemd-networkd is the native network backend and udev processes
|
||||
# .link files directly. Reloading udev rules makes the new .link files effective
|
||||
# immediately for any interface added later (hotplug, new NICs) without waiting
|
||||
# for a full reboot. On PVE8 (ifupdown2), names are resolved at boot anyway.
|
||||
if [[ "$pve_version" -ge 9 ]]; then
|
||||
udevadm control --reload-rules 2>/dev/null || true
|
||||
msg_ok "$(translate "PVE9: udev rules reloaded — new interfaces will get correct names without reboot")"
|
||||
|
||||
@@ -455,11 +455,14 @@ uninstall_network_optimization() {
|
||||
|
||||
systemctl disable --now proxmenux-fwbr-tune.service >/dev/null 2>&1 || true
|
||||
rm -f /etc/systemd/system/proxmenux-fwbr-tune.service
|
||||
rm -f /usr/local/sbin/proxmenux-fwbr-tune
|
||||
rm -f /etc/udev/rules.d/99-proxmenux-fwbr-tune.rules
|
||||
udevadm control --reload-rules >/dev/null 2>&1 || true
|
||||
|
||||
systemctl daemon-reload >/dev/null 2>&1 || true
|
||||
sysctl --system >/dev/null 2>&1 || true
|
||||
|
||||
|
||||
|
||||
msg_ok "$(translate "Network optimizations removed")"
|
||||
register_tool "network_optimization" false
|
||||
}
|
||||
@@ -573,22 +576,28 @@ uninstall_log2ram() {
|
||||
################################################################
|
||||
|
||||
uninstall_persistent_network() {
|
||||
local LINK_DIR="/etc/systemd/network"
|
||||
|
||||
msg_info "$(translate "Removing all .link files from") $LINK_DIR"
|
||||
sleep 2
|
||||
|
||||
if ! ls "$LINK_DIR"/*.link >/dev/null 2>&1; then
|
||||
msg_warn "$(translate "No .link files found in") $LINK_DIR"
|
||||
return 0
|
||||
msg_info "$(translate "Removing ProxMenux persistent NIC .link files...")"
|
||||
sleep 1
|
||||
|
||||
if ! type pmx_uninstall_persistent_network &>/dev/null; then
|
||||
if [[ -f "$LOCAL_SCRIPTS/global/utils-install-functions.sh" ]]; then
|
||||
source "$LOCAL_SCRIPTS/global/utils-install-functions.sh"
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f "$LINK_DIR"/*.link
|
||||
local removed=0
|
||||
while IFS='=' read -r key value; do
|
||||
[[ "$key" == "REMOVED" ]] && removed="$value"
|
||||
done < <(pmx_uninstall_persistent_network)
|
||||
|
||||
msg_ok "$(translate "Removed all .link files from") $LINK_DIR"
|
||||
msg_info "$(translate "Interface names will return to default systemd behavior.")"
|
||||
if (( removed > 0 )); then
|
||||
msg_ok "$(translate "Removed") $removed $(translate "ProxMenux-managed .link file(s). User-authored .link files were left in place.")"
|
||||
msg_info "$(translate "Interface names will return to default systemd behavior.")"
|
||||
NECESSARY_REBOOT=1
|
||||
else
|
||||
msg_warn "$(translate "No ProxMenux-managed .link files found — nothing to remove.")"
|
||||
fi
|
||||
register_tool "persistent_network" false
|
||||
NECESSARY_REBOOT=1
|
||||
}
|
||||
|
||||
|
||||
@@ -906,6 +915,10 @@ uninstall_zfs_arc() {
|
||||
rm -f /etc/modprobe.d/99-zfsarc.conf
|
||||
msg_ok "$(translate 'ZFS ARC config removed (kernel defaults will apply on reboot)')"
|
||||
fi
|
||||
update-initramfs -u -k all >/dev/null 2>&1 || true
|
||||
if command -v proxmox-boot-tool >/dev/null 2>&1; then
|
||||
proxmox-boot-tool refresh >/dev/null 2>&1 || true
|
||||
fi
|
||||
register_tool "zfs_arc" false
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user