#!/bin/bash # Use bash since ash can only do math on 32bit numbers, which is not sufficient for ID44 calculations # also for negative length to ${x:0:-1} # This script gathers information about the hardware and configuration and reports it back to the server . /opt/openslx/config if [ -z "$SLX_REMOTE_LOG" ]; then echo "No remote log url given, will not report" exit 1 fi # 1) Get MAC Address used for booting eval $(grep -Eo BOOTIF=\\S+ /proc/cmdline) if [ "${#BOOTIF}" -ne "20" ]; then echo "Getting MAC from /proc/cmdline failed, using 'ip a'..." BOOTIF=01-$(ip a | grep -A 1 ': br0' | grep -o 'ether ..:..:..:..:..:..' | cut -d' ' -f2 | sed s/:/-/g) if [ "${#BOOTIF}" -ne "20" ]; then echo "FAIL FAIL FAIL" BOOTIF="99-88-77-66-55-44-33" fi fi MAC=${BOOTIF:3} which dmidecode || sleep 5 # 2) Get machine UUID, with fallback to MAC address if it fails for some reason UUID=$(dmidecode -s system-uuid) if [ "${#UUID}" -ne "36" ]; then echo "Determined UUID (${UUID}) has not expected length of 36, falling back to MAC..." UUID="000000000000000-$BOOTIF" fi # 3) Uptime in seconds UPTIME=$(grep -o -E '^[0-9]+' /proc/uptime) # 4) Number of real CPU cores CPUCORES=$(cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | sort -u | wc -l) # Fallback 1... if [ -z "$CPUCORES" ] || [ "$CPUCORES" = "0" ]; then for c in $(dmidecode -t 4 | grep 'Core Enabled' | awk -F ':' '{print $2}'); do CPUCORES=$(( $CPUCORES + $c )) done fi # Fallback 2... if [ -z "$CPUCORES" ] || [ "$CPUCORES" = "0" ]; then CPUCORES=$(grep -E -e '^core id\s*:' -e '^physical\s*:' /proc/cpuinfo | xargs -l2 echo | sort -u | wc -l) fi # 5) CPU model name CPUMODEL=$(grep -m1 '^model name\s*:' /proc/cpuinfo | sed 's/^model name\s*:\s*//') # 6) RAM RAM=$(grep '^MemTotal:' /proc/meminfo | awk '{print $2}') RAM=$(( $RAM / 1024 )) if [ -z "$RAM" ] || [ "$RAM" -lt 500 ]; then # Fallback to dmidecode RAM=0 for c in $(dmidecode -t 17 | grep -o 'Size:.*MB$' | awk '{print $2}'); do RAM=$(( $RAM + $c )) done fi # 7) 64bit virtualization support VT="UNSUPPORTED" VIRTTYPE=$(grep -m1 '^flags\s*:' /proc/cpuinfo | grep -wo -e svm -e vmx) [ -n "$VIRTTYPE" ] && modprobe msr if [ "$VIRTTYPE" = "vmx" ]; then # intel BIT1=$(rdmsr --bitfield 0:0 0x3a 2>/dev/null || echo "fail") BIT2=$(rdmsr --bitfield 2:2 0x3a 2>/dev/null || echo "fail") if [ "$BIT1" = "fail" -o "$BIT2" = "fail" ]; then VT="UNKNOWN" elif [ "$BIT1" = "0" -o "$BIT2" = "1" ]; then VT="ENABLED" else VT="DISABLED" fi elif [ "$VIRTTYPE" = "svm" ]; then # amd BIT=$(rdmsr --bitfield 4:4 0xc0010114 2>/dev/null || echo "fail") if [ "$BIT" = "fail" ]; then VT="UNKNOWN" elif [ "$BIT" = "0" ]; then VT="ENABLED" else VT="DISABLED" fi fi # 8) ID44 partition size ID44=0 for c in $(fdisk -l | grep -E '[0-9]+[\-\+]?\s+44\s+' | awk '{print $1}'); do val=$(blockdev --getsize64 "$c") [ -z "$val" ] && continue [ "$val" -gt "$ID44" ] && ID44=$val done ID44=$(( $ID44 / 1058576 )) # we'd rather underreport # 9) check smart values BADSECTORS=0 if which smartctl; then ALLSMART=$(mktemp) FILE=$(mktemp) [ -z "$FILE" ] && FILE="/tmp/smartctl.$$.$RANDOM.$RANDOM" for dev in $(fdisk -l | grep -o '^Disk /dev/\S*:' | cut -c 6-); do dev=${dev:0:-1} smartctl -i -H -A -f "brief" "$dev" > "$FILE" || continue cat "$FILE" >> "$ALLSMART" # parse OVERALL=$(grep -o "test result: .*$" "$FILE" | cut -c 14-) [ "x$OVERALL" = "xPASSED" ] && OVERALL="" REALLOC=$(grep "^ *5 " "$FILE" | awk '{print $8}') SPINRETRY_VAL=$(grep "^ *10 " "$FILE" | awk '{print $4}') SPINRETRY_THR=$(grep "^ *10 " "$FILE" | awk '{print $6}') [ -n "$OVERALL" ] && BADSECTORS=$(( $BADSECTORS + 100 )) if [ -n "$REALLOC" ] && [ "$REALLOC" -gt "0" ]; then BADSECTORS=$(( $BADSECTORS + $REALLOC )) fi if [ -n "$SPINRETRY_VAL" ] && [ "$SPINRETRY_VAL" -le "$SPINRETRY_THR" ]; then BADSECTORS=$(( $BADSECTORS + 100 )) fi done rm -f -- "$FILE" fi # A) Read system model and manufacturer MODEL=$(dmidecode -s system-product-name) case "$MODEL" in |System Product Name|*be filled*) MODEL="Unknown" ;; *) MANUF=$(dmidecode -s system-manufacturer) ;; esac if [ -n "$MANUF" ]; then MODEL="$MODEL ($MANUF)" fi # n) Dump raw data to a file DATAFILE=$(mktemp) [ -z "$DATAFILE" ] && DATAFILE="/root/power-stats.$$" cat > "$DATAFILE" <<-EOF ############################### CPU ##################################### Sockets: $(grep '^physical id' /proc/cpuinfo | sort -u | wc -l) Real cores: $CPUCORES Virtual cores: $(grep '^processor' /proc/cpuinfo | sort -u | wc -l) ######################## Partition tables ############################### EOF fdisk -l >> "$DATAFILE" cat >> "$DATAFILE" <<-EOF ############################ PCI ID ##################################### EOF lspci -n -m >> "$DATAFILE" cat >> "$DATAFILE" <<-EOF ########################## dmidecode #################################### EOF dmidecode >> "$DATAFILE" if [ -n "$ALLSMART" ] && [ -s "$ALLSMART" ]; then cat >> "$DATAFILE" <<-EOF ########################### smartctl #################################### EOF cat "$ALLSMART" >> "$DATAFILE" fi cat >> "$DATAFILE" <<-EOF ######################### EOF [ -n "$ALLSMART" ] && rm -f -- "$ALLSMART" # Fire away for DELAY in 1 1 0; do if curl --data-urlencode "type=~poweron" --data-urlencode "uuid=$UUID" --data-urlencode "macaddr=$MAC" \ --data-urlencode "uptime=$UPTIME" --data-urlencode "realcores=$CPUCORES" --data-urlencode "mbram=$RAM" \ --data-urlencode "kvmstate=$VT" --data-urlencode "cpumodel=$CPUMODEL" --data-urlencode "id44mb=$ID44" \ --data-urlencode "badsectors=$BADSECTORS" --data-urlencode "systemmodel=$MODEL" \ --data-urlencode "data@$DATAFILE" "$SLX_REMOTE_LOG" | grep -q "RESULT=0"; then rm -f -- "$DATAFILE" echo "$UUID" > "/run/system-uuid" exit 0 fi sleep "$DELAY" done echo "Server doesn't seem to support hardware/usage stats - disabling logging" rm -f -- "/etc/cron.d/usage_stats" exit 1