#!/bin/bash
# sysfs-netns.sh: one sysfs superblock per network namespace; the first mount picks ro or rw.
# Run as root. Uses throwaway namespaces; writes read_ahead_kb back with its current value.
BDI=$(ls /sys/class/bdi | head -1)
LIB=$(mktemp)
cat > $LIB <<LIB
show() { awk '\$5 ~ /^(\/sys|\/tmp\/s[AB])\$/ {print \$5, "dev="\$3, "per-mount="\$6, "superblock="\$NF}' /proc/self/mountinfo; }
try()  { v=\$(cat \$1/class/bdi/$BDI/read_ahead_kb); e=\$( { echo \$v > \$1/class/bdi/$BDI/read_ahead_kb; } 2>&1 ) && echo "write via \$1: OK" || echo "write via \$1: \${e##*: }"; }
mkdir -p /tmp/sA /tmp/sB
LIB
echo "== host netns"; . $LIB; show
echo "== new mount ns, same netns: mount sysfs at /tmp/sA"
unshare --mount --propagation private bash -c ". $LIB; mount -t sysfs sysfs /tmp/sA; show"
for order in "ro rw" "rw ro"; do
  set -- $order
  echo "== new netns: mount sysfs $1 at /tmp/sA, then $2 at /tmp/sB"
  unshare --net --mount --propagation private bash -c ". $LIB
    mount -t sysfs -o $1 sysfs /tmp/sA; mount -t sysfs -o $2 sysfs /tmp/sB
    show; echo \"/tmp/sA/class/net: \$(ls /tmp/sA/class/net)\"; try /tmp/sA; try /tmp/sB" 2>&1
done
echo "== new netns: ro first; bind remount, then superblock remount of /tmp/sB"
unshare --net --mount --propagation private bash -c ". $LIB
  mount -t sysfs -o ro sysfs /tmp/sA; mount -t sysfs -o rw sysfs /tmp/sB; try /tmp/sB
  echo '-- mount -o remount,bind,rw /tmp/sB'; mount -o remount,bind,rw /tmp/sB; show; try /tmp/sB
  echo '-- mount -o remount,rw /tmp/sB';      mount -o remount,rw /tmp/sB;      show; try /tmp/sB; try /tmp/sA" 2>&1
rm -f $LIB
