Copy QuecManager beta to non-beta
QM BETA --> regular/non-beta
This commit is contained in:
201
ipk-source/sdxpinn-quecmanager/root/www/cgi-bin/services/memory_daemon.sh
Executable file
201
ipk-source/sdxpinn-quecmanager/root/www/cgi-bin/services/memory_daemon.sh
Executable file
@@ -0,0 +1,201 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Memory Daemon - Monitors system memory usage and writes to JSON file
|
||||
# This daemon only runs when memory monitoring is enabled via settings
|
||||
|
||||
set -eu
|
||||
|
||||
# Ensure PATH for OpenWrt/BusyBox
|
||||
export PATH="/usr/sbin:/usr/bin:/sbin:/bin:$PATH"
|
||||
|
||||
# Load centralized logging
|
||||
. /www/cgi-bin/services/quecmanager_logger.sh
|
||||
|
||||
# Configuration
|
||||
TMP_DIR="/tmp/quecmanager"
|
||||
OUT_JSON="$TMP_DIR/memory.json"
|
||||
PID_FILE="$TMP_DIR/memory_daemon.pid"
|
||||
CONFIG_FILE="/etc/quecmanager/settings/memory_settings.conf"
|
||||
[ -f "$CONFIG_FILE" ] || CONFIG_FILE="/tmp/quecmanager/settings/memory_settings.conf"
|
||||
DEFAULT_INTERVAL=1
|
||||
SCRIPT_NAME="memory_daemon"
|
||||
|
||||
# Ensure temp directory exists
|
||||
ensure_tmp_dir() {
|
||||
[ -d "$TMP_DIR" ] || mkdir -p "$TMP_DIR" || exit 1
|
||||
}
|
||||
|
||||
# Logging function
|
||||
log() {
|
||||
qm_log_info "daemon" "$SCRIPT_NAME" "$1"
|
||||
}
|
||||
|
||||
# Check if this daemon instance is already running
|
||||
daemon_is_running() {
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
pid="$(cat "$PID_FILE" 2>/dev/null || true)"
|
||||
if [ -n "${pid:-}" ] && kill -0 "$pid" 2>/dev/null; then
|
||||
# Verify it's actually our daemon by checking process cmdline
|
||||
if [ -r "/proc/$pid/cmdline" ] && grep -q "memory_daemon.sh" "/proc/$pid/cmdline" 2>/dev/null; then
|
||||
return 0
|
||||
else
|
||||
# PID file is stale, remove it
|
||||
rm -f "$PID_FILE" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Write our PID to file
|
||||
write_pid() {
|
||||
echo "$$" > "$PID_FILE"
|
||||
}
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
rm -f "$PID_FILE" 2>/dev/null || true
|
||||
log "Memory daemon stopped"
|
||||
}
|
||||
|
||||
# Create default config if none exists
|
||||
create_default_config() {
|
||||
local primary_config="/etc/quecmanager/settings/memory_settings.conf"
|
||||
local fallback_config="/tmp/quecmanager/settings/memory_settings.conf"
|
||||
|
||||
if [ ! -f "$primary_config" ] && [ ! -f "$fallback_config" ]; then
|
||||
log "No config file found, creating default configuration"
|
||||
|
||||
# Try primary location first
|
||||
if mkdir -p "/etc/quecmanager/settings" 2>/dev/null; then
|
||||
{
|
||||
echo "MEMORY_ENABLED=false"
|
||||
echo "MEMORY_INTERVAL=1"
|
||||
} > "$primary_config" 2>/dev/null && {
|
||||
chmod 644 "$primary_config" 2>/dev/null || true
|
||||
CONFIG_FILE="$primary_config"
|
||||
log "Created default config at $primary_config"
|
||||
return 0
|
||||
}
|
||||
fi
|
||||
|
||||
# Fallback to tmp location
|
||||
mkdir -p "/tmp/quecmanager/settings" 2>/dev/null || true
|
||||
{
|
||||
echo "MEMORY_ENABLED=false"
|
||||
echo "MEMORY_INTERVAL=1"
|
||||
} > "$fallback_config" && {
|
||||
chmod 644 "$fallback_config" 2>/dev/null || true
|
||||
CONFIG_FILE="$fallback_config"
|
||||
log "Created default config at $fallback_config"
|
||||
return 0
|
||||
}
|
||||
|
||||
log "Failed to create default config file"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Read configuration from file
|
||||
read_config() {
|
||||
ENABLED="false"
|
||||
INTERVAL="$DEFAULT_INTERVAL"
|
||||
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
MEMORY_ENABLED=$(grep -E "^MEMORY_ENABLED=" "$CONFIG_FILE" 2>/dev/null | tail -n1 | cut -d'=' -f2 | tr -d '\r' | tr -d '"')
|
||||
MEMORY_INTERVAL=$(grep -E "^MEMORY_INTERVAL=" "$CONFIG_FILE" 2>/dev/null | tail -n1 | cut -d'=' -f2 | tr -d '\r')
|
||||
|
||||
case "${MEMORY_ENABLED:-}" in
|
||||
true|1|on|yes|enabled) ENABLED="true" ;;
|
||||
*) ENABLED="false" ;;
|
||||
esac
|
||||
|
||||
if echo "${MEMORY_INTERVAL:-}" | grep -qE '^[0-9]+$'; then
|
||||
if [ "$MEMORY_INTERVAL" -ge 1 ] && [ "$MEMORY_INTERVAL" -le 10 ]; then
|
||||
INTERVAL="$MEMORY_INTERVAL"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Write JSON data atomically
|
||||
write_json_atomic() {
|
||||
local json_data="$1"
|
||||
local tmpfile="$(mktemp "$TMP_DIR/memory.XXXXXX" 2>/dev/null || echo "$TMP_DIR/memory.tmp.$$")"
|
||||
|
||||
if [ -n "$tmpfile" ] && printf '%s' "$json_data" > "$tmpfile" 2>/dev/null; then
|
||||
mv "$tmpfile" "$OUT_JSON" 2>/dev/null || {
|
||||
# Fallback if move fails
|
||||
printf '%s' "$json_data" > "$OUT_JSON" 2>/dev/null || true
|
||||
rm -f "$tmpfile" 2>/dev/null || true
|
||||
}
|
||||
else
|
||||
# Direct write fallback
|
||||
printf '%s' "$json_data" > "$OUT_JSON" 2>/dev/null || true
|
||||
rm -f "$tmpfile" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution starts here
|
||||
ensure_tmp_dir
|
||||
log "Starting memory daemon (PID: $$)"
|
||||
|
||||
# Check if already running
|
||||
if daemon_is_running; then
|
||||
log "Memory daemon already running, exiting"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Create default config if needed
|
||||
create_default_config
|
||||
|
||||
# Set up signal handlers
|
||||
trap cleanup EXIT INT TERM
|
||||
write_pid
|
||||
|
||||
# Main monitoring loop
|
||||
while true; do
|
||||
read_config
|
||||
|
||||
# Exit if disabled
|
||||
if [ "$ENABLED" != "true" ]; then
|
||||
log "Memory monitoring disabled in config, exiting"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get current timestamp
|
||||
ts="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
||||
|
||||
# Get memory information using /proc/meminfo (most reliable method)
|
||||
if [ -r "/proc/meminfo" ]; then
|
||||
# Extract values from /proc/meminfo (values are in kB)
|
||||
TOTAL_KB=$(grep "^MemTotal:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
|
||||
AVAIL_KB=$(grep "^MemAvailable:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
|
||||
FREE_KB=$(grep "^MemFree:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
|
||||
|
||||
# If MemAvailable is not available (older kernels), estimate it
|
||||
if [ "$AVAIL_KB" = "0" ]; then
|
||||
CACHED_KB=$(grep "^Cached:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
|
||||
BUFFERS_KB=$(grep "^Buffers:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
|
||||
AVAIL_KB=$((FREE_KB + CACHED_KB + BUFFERS_KB))
|
||||
fi
|
||||
|
||||
# Convert to bytes (multiply by 1024)
|
||||
TOTAL_BYTES=$((TOTAL_KB * 1024))
|
||||
AVAIL_BYTES=$((AVAIL_KB * 1024))
|
||||
USED_BYTES=$((TOTAL_BYTES - AVAIL_BYTES))
|
||||
|
||||
json="{\"total\": $TOTAL_BYTES, \"used\": $USED_BYTES, \"available\": $AVAIL_BYTES, \"timestamp\": \"$ts\"}"
|
||||
else
|
||||
# Fallback if /proc/meminfo is not available
|
||||
log "Warning: /proc/meminfo not readable, using error response"
|
||||
json="{\"total\": 0, \"used\": 0, \"available\": 0, \"timestamp\": \"$ts\", \"error\": \"meminfo_unavailable\"}"
|
||||
fi
|
||||
|
||||
# Write the JSON data
|
||||
write_json_atomic "$json"
|
||||
log "Updated memory data: total=${TOTAL_KB:-0}KB, used=${USED_BYTES:-0}B, available=${AVAIL_KB:-0}KB"
|
||||
|
||||
# Sleep for the configured interval
|
||||
sleep "$INTERVAL"
|
||||
done
|
||||
Reference in New Issue
Block a user