$NetBSD: patch-xe-update-guest-attrs,v 1.6 2025/03/31 12:26:19 sborrill Exp $

Support pkgsrc, NetBSD/FreeBSD ifconfig and FreeBSD memory stats

--- xe-update-guest-attrs.orig	2010-12-20 15:34:07.000000000 +0000
+++ xe-update-guest-attrs	2025-03-28 12:41:56.862749000 +0000
@@ -39,11 +39,27 @@
 
 IPADDR_RE="\([[:digit:]]\{1,3\}\.\)\{3\}[[:digit:]]\{1,3\}"
 
-export PATH=/usr/sbin:/usr/bin:/sbin:/bin
-XENSTORE=${XENSTORE:-xenstore}
+export PATH=/usr/sbin:/usr/bin:/sbin:/bin:@PREFIX@/sbin:@PREFIX@/bin
+XENSTORE=${XENSTORE:-@PREFIX@/bin/xenstore}
 
+CACHEROOT="@VARBASE@/cache/xenstore"
 XENSTORE_UPDATED=0
 
+case `uname -s` in
+NetBSD)
+	os=netbsd
+	sysctl_balloon="machdep.xen.balloon.current"
+	;;
+FreeBSD)
+	os=freebsd
+	sysctl_balloon="dev.xen.balloon.current"
+	;;
+*)
+	echo "OS not supported" > /dev/stderr
+	exit 1
+	;;
+esac
+
 # parse command line opts
 
 MEMORY_MODE=0 # do not update memory stats 
@@ -56,7 +72,7 @@
 
 xenstore_write_cached() {
     key="$1" newval="$2"
-    cache=/var/cache/xenstore/$key
+    cache=${CACHEROOT}/$key
     if [ -f $cache ] ; then
 	# cache exists
 	oldval=$(cat "$cache")
@@ -84,13 +100,13 @@
 
 # If we detect a domain change then delete our cache and force a refresh
 domid=$(xenstore-read "domid")
-cache=/var/cache/xenstore/unique-domain-id
+cache=${CACHEROOT}/unique-domain-id
 newval=$(xenstore-read "/local/domain/${domid}/unique-domain-id")
 if [ -e $cache ]; then
     oldval=$(cat "$cache")
     if [ "$oldval" != "$newval" ]; then
 	# domain changed
-	rm -rf /var/cache/xenstore
+	rm -rf ${CACHEROOT}
     fi
 fi
 mkdir -p $(dirname "$cache")
@@ -112,7 +128,7 @@
 }
 
 xenstore_list_interfaces_cached() {
-    topdir=/var/cache/xenstore/attr
+    topdir=${CACHEROOT}/attr
     if [ -d $topdir ] ; then
 	cd $topdir 
 	for dir in * ; do 
@@ -121,61 +137,113 @@
     fi
 }
 
+# Memory needs to be reported in kB
+# NetBSD:
+# cat /proc/meminfo
+#        total:    used:    free:  shared: buffers: cached:
+#Mem:  16616656896 4481732608 12134924288        0 4078817280 4106203136
+#Swap: 1073737728        0 1073737728
+#MemTotal:  16227204 kB
+#MemFree:   11850512 kB
+#MemShared:        0 kB
+#Buffers:   11850512 kB
+#Cached:     4009964 kB
+#SwapTotal:  1048572 kB
+#SwapFree:   1048572 kB
+
+# FreeBSD:
+# Inspired by https://github.com/ocochard/myscripts/blob/master/FreeBSD/freebsd-memory.sh
+
 if [ $MEMORY_MODE -eq 1 ] ; then
-    # Update the memory information
-    eval $(cat /proc/meminfo | \
-	sed -n -e 's/MemTotal\: *\([0-9]*\)[^$]*/memtotal=\1/gp;' \
-        -e 's/MemFree\: *\([0-9]*\)[^$]*/memfree=\1/gp;')
-    
-    xenstore_write_cached "data/meminfo_total" "${memtotal}"
-    xenstore_write_cached "data/meminfo_free" "${memfree}"
+	# Update the memory information
+	case "$os" in
+	netbsd)
+		eval $(cat /proc/meminfo | \
+		sed -n -e 's/MemTotal\: *\([0-9]*\)[^$]*/memtotal=\1/gp;' \
+	        -e 's/MemFree\: *\([0-9]*\)[^$]*/memfree=\1/gp;')
+		;;
+	freebsd)
+		memtotal=`sysctl -n hw.physmem`
+		memtotal=$(($memtotal/1024))
+		pagesize=`sysctl -n hw.pagesize`
+		freepages=`sysctl -n vm.stats.vm.v_free_count`
+		memfree=$(($freepages*$pagesize))
+		;;
+	esac
+	xenstore_write_cached "data/meminfo_total" "${memtotal}"
+	xenstore_write_cached "data/meminfo_free" "${memfree}"
 fi
 
 
+#NetBSD 7 and earlier:
+#
+#xennet0: flags=8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST> mtu 1500
+#	capabilities=2800<TCP4CSUM_Tx,UDP4CSUM_Tx>
+#	enabled=0
+#	address: 0e:7e:86:20:7b:82
+#	inet 192.168.1.109 netmask 0xffffff00 broadcast 192.168.1.255
+#	inet alias 10.20.30.40 netmask 0xffffff00 broadcast 10.20.30.255
+#	inet6 fe80::c7e:86ff:fe20:7b82%xennet0 prefixlen 64 scopeid 0x1
+#lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 33184
+#	inet 127.0.0.1 netmask 0xff000000
+#	inet6 ::1 prefixlen 128
+#	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
 
-# e.g.
-# $ ip addr show
-# 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue 
-#     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
-#     inet 127.0.0.1/8 scope host lo
-#     inet6 ::1/128 scope host 
-#        valid_lft forever preferred_lft forever
-# 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
-#     link/ether 00:13:20:95:e8:74 brd ff:ff:ff:ff:ff:ff
-#     inet 172.31.0.57/20 brd 172.31.15.255 scope global eth0
-#     inet6 fe80::213:20ff:fe95:e874/64 scope link 
-#        valid_lft forever preferred_lft forever
-# 3: sit0: <NOARP> mtu 1480 qdisc noop 
-#     link/sit 0.0.0.0 brd 0.0.0.0
+#NetBSD 8 and later:
+#
+#xennet0: flags=0x8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST> mtu 1500
+#	capabilities=2800<TCP4CSUM_Tx,UDP4CSUM_Tx>
+#	enabled=0ec_capabilities=1<VLAN_MTU>
+#	ec_enabled=0
+#	address: 5e:a4:a1:fc:eb:70
+#	inet 192.168.1.17/24 broadcast 192.168.1.255 flags 0x0
+#	inet 10.20.30.40/16 broadcast 10.20.255.255 flags 0x0
+#	inet6 fe80::5ca4:a1ff:fefc:eb70%xennet0/64 flags 0x0 scopeid 0x1
 
-#eval $(ip addr show | \
-#       sed -n -e 's/^[[:digit:]]*: \([a-z0-9]*\): .*/ifs="\$ifs \1"; current="\1"; /gp;' \
-#	      -e 's/^[[:space:]]\{4\}inet \('${IPADDR_RE}'\)\/.*/eval inet_\${current}="\1"; /gp;')
+#FreeBSD 14:
+#xn0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
+#        options=503<RXCSUM,TXCSUM,TSO4,LRO>
+#        ether 96:fe:50:f8:b9:e6
+#        inet 192.168.1.81 netmask 0xffffff00 broadcast 192.168.1.255
+#        media: Ethernet manual
+#        status: active
+#        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
 
-# e.g.
-# eth0      Link encap:Ethernet  HWaddr 00:13:20:95:E8:74  
-#           inet addr:172.31.0.57  Bcast:172.31.15.255  Mask:255.255.240.0
-#           inet6 addr: fe80::213:20ff:fe95:e874/64 Scope:Link
-#           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
-#           RX packets:98001128 errors:0 dropped:0 overruns:0 frame:0
-#           TX packets:87728920 errors:0 dropped:0 overruns:0 carrier:0
-#           collisions:0 txqueuelen:1000 
-#           RX bytes:35864034092 (33.4 GiB)  TX bytes:27544025180 (25.6 GiB)
-#           Interrupt:177 
-# 
-# lo        Link encap:Local Loopback  
-#           inet addr:127.0.0.1  Mask:255.0.0.0
-#           inet6 addr: ::1/128 Scope:Host
-#           UP LOOPBACK RUNNING  MTU:16436  Metric:1
-#           RX packets:32928 errors:0 dropped:0 overruns:0 frame:0
-#           TX packets:32928 errors:0 dropped:0 overruns:0 carrier:0
-#           collisions:0 txqueuelen:0 
-#           RX bytes:3604609 (3.4 MiB)  TX bytes:3604609 (3.4 MiB)
+# Original:
+#
+#/sbin/ifconfig | \
+#        sed -n -e '/^[0-9a-z][0-9a-z]*\:/,/^$/d' \
+#               -e 's/^\([0-9a-z][0-9a-z]*\) .*/ifs="\$ifs \1"; current="\1"; /gp;' \
+#               -e 's/  *inet \('$IPADDR_RE'\) .*/eval inet_\${current}="\1"; /gp;'
 
-eval $(/sbin/ifconfig | \
-        sed -n -e '/^[0-9a-z][0-9a-z]*\:/,/^$/d' \
-               -e 's/^\([0-9a-z][0-9a-z]*\) .*/ifs="\$ifs \1"; current="\1"; /gp;' \
-               -e 's/  *inet addr:\('$IPADDR_RE'\) .*/eval inet_\${current}="\1"; /gp;')
+eval $(/sbin/ifconfig -a | \
+	awk '{
+		if ($0~"^[a-z][a-z0-9]*[0-9]:") {
+			if ($0~"^xennet[0-9]+:") {
+				current = $1
+				sub(":.*", "", current)
+				sub("xennet", "eth", current)
+				iflist = iflist " " current
+				ifs[current] = ""
+			} else {
+				current =""
+			}
+		}
+		if (($1 == "inet" || $1 == "inet6") && current != "") {
+			if ($2 == "alias") ip = $3
+			else ip = $2
+			if ($1 == "inet6") sub("%.*", "", ip)
+			sub("/.*", "", ip)
+			if (ifs[current] != "") ifs[current] = ifs[current] ", " ip
+			else ifs[current] = ip
+		}
+	}
+	END {
+		sub("^ ", "", iflist)
+		printf "ifs=%c%s%c\n", 39, iflist, 39
+		for (i in ifs)
+			printf "inet_%s=%c%s%c\n", i, 39, ifs[i], 39
+	}')
 
 # network
 for if in $ifs ; do
@@ -206,16 +274,18 @@
 fi
 
 # whether I support ballooning or not
-xenstore_write_cached "control/feature-balloon" "1"
+sysctl -n $sysctl_balloon > /dev/null 2>&1
+if [ "$?" = 0 ]; then
+	xenstore_write_cached "control/feature-balloon" "1"
+else
+	xenstore_write_cached "control/feature-balloon" "0"
+fi
 
-# whether I support ballooning or not
-xenstore_write_cached "control/feature-balloon" "1"
-
 # build time addons
-xenstore_write_cached "attr/PVAddons/MajorVersion" "5"
-xenstore_write_cached "attr/PVAddons/MinorVersion" "6"
-xenstore_write_cached "attr/PVAddons/MicroVersion" "0" 
-xenstore_write_cached "attr/PVAddons/BuildVersion" "39674"
+xenstore_write_cached "attr/PVAddons/MajorVersion" "@XENMAJOR@"
+xenstore_write_cached "attr/PVAddons/MinorVersion" "@XENMINOR@"
+xenstore_write_cached "attr/PVAddons/MicroVersion" "@XENTEENY@"
+xenstore_write_cached "attr/PVAddons/BuildVersion" "@XENBUILD@"
 xenstore_write_cached "attr/PVAddons/Installed" "1" 
 
 # update xenstore if necc
