diff options
Diffstat (limited to 'recipes-containers/vcontainer/files/vcontainer-init-common.sh')
| -rwxr-xr-x | recipes-containers/vcontainer/files/vcontainer-init-common.sh | 121 |
1 files changed, 92 insertions, 29 deletions
diff --git a/recipes-containers/vcontainer/files/vcontainer-init-common.sh b/recipes-containers/vcontainer/files/vcontainer-init-common.sh index fe488ae2..ab8762b2 100755 --- a/recipes-containers/vcontainer/files/vcontainer-init-common.sh +++ b/recipes-containers/vcontainer/files/vcontainer-init-common.sh | |||
| @@ -27,6 +27,43 @@ setup_base_environment() { | |||
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | # ============================================================================ | 29 | # ============================================================================ |
| 30 | # Hypervisor Detection | ||
| 31 | # ============================================================================ | ||
| 32 | |||
| 33 | # Detect hypervisor type and set device prefixes accordingly. | ||
| 34 | # Must be called after /proc and /sys are mounted. | ||
| 35 | # Sets: HV_TYPE, BLK_PREFIX, NINE_P_TRANSPORT | ||
| 36 | detect_hypervisor() { | ||
| 37 | # Check kernel cmdline for explicit block prefix (set by Xen backend) | ||
| 38 | local cmdline_blk="" | ||
| 39 | for param in $(cat /proc/cmdline 2>/dev/null); do | ||
| 40 | case "$param" in | ||
| 41 | vcontainer.blk=*) cmdline_blk="${param#vcontainer.blk=}" ;; | ||
| 42 | esac | ||
| 43 | done | ||
| 44 | |||
| 45 | if [ -n "$cmdline_blk" ]; then | ||
| 46 | # Explicit prefix from kernel cmdline (most reliable) | ||
| 47 | BLK_PREFIX="$cmdline_blk" | ||
| 48 | if [ "$cmdline_blk" = "xvd" ]; then | ||
| 49 | HV_TYPE="xen" | ||
| 50 | NINE_P_TRANSPORT="xen" | ||
| 51 | else | ||
| 52 | HV_TYPE="qemu" | ||
| 53 | NINE_P_TRANSPORT="virtio" | ||
| 54 | fi | ||
| 55 | elif [ -d /proc/xen ] || grep -q "xen" /sys/hypervisor/type 2>/dev/null; then | ||
| 56 | HV_TYPE="xen" | ||
| 57 | BLK_PREFIX="xvd" | ||
| 58 | NINE_P_TRANSPORT="xen" | ||
| 59 | else | ||
| 60 | HV_TYPE="qemu" | ||
| 61 | BLK_PREFIX="vd" | ||
| 62 | NINE_P_TRANSPORT="virtio" | ||
| 63 | fi | ||
| 64 | } | ||
| 65 | |||
| 66 | # ============================================================================ | ||
| 30 | # Filesystem Mounts | 67 | # Filesystem Mounts |
| 31 | # ============================================================================ | 68 | # ============================================================================ |
| 32 | 69 | ||
| @@ -40,6 +77,9 @@ mount_base_filesystems() { | |||
| 40 | mkdir -p /dev/pts | 77 | mkdir -p /dev/pts |
| 41 | mountpoint -q /dev/pts || mount -t devpts devpts /dev/pts | 78 | mountpoint -q /dev/pts || mount -t devpts devpts /dev/pts |
| 42 | 79 | ||
| 80 | # Detect hypervisor type now that /proc and /sys are available | ||
| 81 | detect_hypervisor | ||
| 82 | |||
| 43 | # Enable IP forwarding (container runtimes check this) | 83 | # Enable IP forwarding (container runtimes check this) |
| 44 | echo 1 > /proc/sys/net/ipv4/ip_forward | 84 | echo 1 > /proc/sys/net/ipv4/ip_forward |
| 45 | 85 | ||
| @@ -178,29 +218,24 @@ detect_disks() { | |||
| 178 | log "Waiting for block devices..." | 218 | log "Waiting for block devices..." |
| 179 | sleep 2 | 219 | sleep 2 |
| 180 | 220 | ||
| 181 | log "Block devices:" | 221 | log "Block devices (${HV_TYPE:-qemu}, /dev/${BLK_PREFIX}*):" |
| 182 | [ "$QUIET_BOOT" = "0" ] && ls -la /dev/vd* 2>/dev/null || log "No /dev/vd* devices" | 222 | [ "$QUIET_BOOT" = "0" ] && ls -la /dev/${BLK_PREFIX}* 2>/dev/null || log "No /dev/${BLK_PREFIX}* devices" |
| 183 | 223 | ||
| 184 | # Determine which disk is input and which is state | 224 | # Determine which disk is input and which is state |
| 185 | # Drive layout (rootfs.img is always /dev/vda, mounted by preinit as /): | 225 | # Drive layout (rootfs is always the first block device, mounted by preinit as /): |
| 186 | # /dev/vda = rootfs.img (already mounted as /) | 226 | # QEMU: /dev/vda, /dev/vdb, /dev/vdc |
| 187 | # /dev/vdb = input (if present) | 227 | # Xen: /dev/xvda, /dev/xvdb, /dev/xvdc |
| 188 | # /dev/vdc = state (if both input and state present) | ||
| 189 | # /dev/vdb = state (if only state, no input) | ||
| 190 | 228 | ||
| 191 | INPUT_DISK="" | 229 | INPUT_DISK="" |
| 192 | STATE_DISK="" | 230 | STATE_DISK="" |
| 193 | 231 | ||
| 194 | if [ "$RUNTIME_INPUT" != "none" ] && [ "$RUNTIME_STATE" = "disk" ]; then | 232 | if [ "$RUNTIME_INPUT" != "none" ] && [ "$RUNTIME_STATE" = "disk" ]; then |
| 195 | # Both present: rootfs=vda, input=vdb, state=vdc | 233 | INPUT_DISK="/dev/${BLK_PREFIX}b" |
| 196 | INPUT_DISK="/dev/vdb" | 234 | STATE_DISK="/dev/${BLK_PREFIX}c" |
| 197 | STATE_DISK="/dev/vdc" | ||
| 198 | elif [ "$RUNTIME_STATE" = "disk" ]; then | 235 | elif [ "$RUNTIME_STATE" = "disk" ]; then |
| 199 | # Only state: rootfs=vda, state=vdb | 236 | STATE_DISK="/dev/${BLK_PREFIX}b" |
| 200 | STATE_DISK="/dev/vdb" | ||
| 201 | elif [ "$RUNTIME_INPUT" != "none" ]; then | 237 | elif [ "$RUNTIME_INPUT" != "none" ]; then |
| 202 | # Only input: rootfs=vda, input=vdb | 238 | INPUT_DISK="/dev/${BLK_PREFIX}b" |
| 203 | INPUT_DISK="/dev/vdb" | ||
| 204 | fi | 239 | fi |
| 205 | } | 240 | } |
| 206 | 241 | ||
| @@ -250,30 +285,56 @@ configure_networking() { | |||
| 250 | # Bring up the interface | 285 | # Bring up the interface |
| 251 | ip link set "$NET_IFACE" up | 286 | ip link set "$NET_IFACE" up |
| 252 | 287 | ||
| 253 | # QEMU slirp provides: | 288 | if [ "$HV_TYPE" = "xen" ]; then |
| 254 | # Guest IP: 10.0.2.15/24 | 289 | # Xen bridge networking: use DHCP or static config |
| 255 | # Gateway: 10.0.2.2 | 290 | # Try DHCP first if udhcpc is available |
| 256 | # DNS: 10.0.2.3 | 291 | if command -v udhcpc >/dev/null 2>&1; then |
| 257 | ip addr add 10.0.2.15/24 dev "$NET_IFACE" | 292 | log "Requesting IP via DHCP (Xen bridge)..." |
| 258 | ip route add default via 10.0.2.2 | 293 | udhcpc -i "$NET_IFACE" -t 5 -T 3 -q 2>/dev/null || { |
| 294 | log "DHCP failed, using static fallback" | ||
| 295 | ip addr add 10.0.0.15/24 dev "$NET_IFACE" | ||
| 296 | ip route add default via 10.0.0.1 | ||
| 297 | } | ||
| 298 | else | ||
| 299 | # Static fallback for Xen bridge | ||
| 300 | ip addr add 10.0.0.15/24 dev "$NET_IFACE" | ||
| 301 | ip route add default via 10.0.0.1 | ||
| 302 | fi | ||
| 303 | else | ||
| 304 | # QEMU slirp provides: | ||
| 305 | # Guest IP: 10.0.2.15/24 | ||
| 306 | # Gateway: 10.0.2.2 | ||
| 307 | # DNS: 10.0.2.3 | ||
| 308 | ip addr add 10.0.2.15/24 dev "$NET_IFACE" | ||
| 309 | ip route add default via 10.0.2.2 | ||
| 310 | fi | ||
| 259 | 311 | ||
| 260 | # Configure DNS | 312 | # Configure DNS |
| 261 | mkdir -p /etc | 313 | mkdir -p /etc |
| 262 | rm -f /etc/resolv.conf | 314 | rm -f /etc/resolv.conf |
| 263 | cat > /etc/resolv.conf << 'DNSEOF' | 315 | if [ "$HV_TYPE" = "xen" ]; then |
| 316 | cat > /etc/resolv.conf << 'DNSEOF' | ||
| 317 | nameserver 8.8.8.8 | ||
| 318 | nameserver 1.1.1.1 | ||
| 319 | DNSEOF | ||
| 320 | else | ||
| 321 | cat > /etc/resolv.conf << 'DNSEOF' | ||
| 264 | nameserver 10.0.2.3 | 322 | nameserver 10.0.2.3 |
| 265 | nameserver 8.8.8.8 | 323 | nameserver 8.8.8.8 |
| 266 | nameserver 1.1.1.1 | 324 | nameserver 1.1.1.1 |
| 267 | DNSEOF | 325 | DNSEOF |
| 326 | fi | ||
| 268 | 327 | ||
| 269 | sleep 1 | 328 | sleep 1 |
| 270 | 329 | ||
| 271 | # Verify connectivity | 330 | # Verify connectivity |
| 331 | local gw_ip | ||
| 332 | gw_ip=$(ip route | awk '/default/{print $3}' | head -n 1) | ||
| 272 | log "Testing network connectivity..." | 333 | log "Testing network connectivity..." |
| 273 | if ping -c 1 -W 3 10.0.2.2 >/dev/null 2>&1; then | 334 | if [ -n "$gw_ip" ] && ping -c 1 -W 3 "$gw_ip" >/dev/null 2>&1; then |
| 274 | log " Gateway (10.0.2.2): OK" | 335 | log " Gateway ($gw_ip): OK" |
| 275 | else | 336 | else |
| 276 | log " Gateway (10.0.2.2): FAILED" | 337 | log " Gateway: FAILED" |
| 277 | fi | 338 | fi |
| 278 | 339 | ||
| 279 | if ping -c 1 -W 3 8.8.8.8 >/dev/null 2>&1; then | 340 | if ping -c 1 -W 3 8.8.8.8 >/dev/null 2>&1; then |
| @@ -282,7 +343,9 @@ DNSEOF | |||
| 282 | log " External (8.8.8.8): FAILED (may be filtered)" | 343 | log " External (8.8.8.8): FAILED (may be filtered)" |
| 283 | fi | 344 | fi |
| 284 | 345 | ||
| 285 | log "Network configured: $NET_IFACE (10.0.2.15)" | 346 | local my_ip |
| 347 | my_ip=$(ip -4 addr show "$NET_IFACE" 2>/dev/null | awk '/inet /{print $2}' | head -n 1) | ||
| 348 | log "Network configured: $NET_IFACE ($my_ip)" | ||
| 286 | [ "$QUIET_BOOT" = "0" ] && ip addr show "$NET_IFACE" | 349 | [ "$QUIET_BOOT" = "0" ] && ip addr show "$NET_IFACE" |
| 287 | [ "$QUIET_BOOT" = "0" ] && ip route | 350 | [ "$QUIET_BOOT" = "0" ] && ip route |
| 288 | [ "$QUIET_BOOT" = "0" ] && cat /etc/resolv.conf | 351 | [ "$QUIET_BOOT" = "0" ] && cat /etc/resolv.conf |
| @@ -325,11 +388,11 @@ run_daemon_mode() { | |||
| 325 | 388 | ||
| 326 | # Mount virtio-9p shared directory for file I/O | 389 | # Mount virtio-9p shared directory for file I/O |
| 327 | mkdir -p /mnt/share | 390 | mkdir -p /mnt/share |
| 328 | MOUNT_ERR=$(mount -t 9p -o trans=virtio,version=9p2000.L,cache=none ${VCONTAINER_SHARE_NAME} /mnt/share 2>&1) | 391 | MOUNT_ERR=$(mount -t 9p -o trans=${NINE_P_TRANSPORT},version=9p2000.L,cache=none ${VCONTAINER_SHARE_NAME} /mnt/share 2>&1) |
| 329 | if [ $? -eq 0 ]; then | 392 | if [ $? -eq 0 ]; then |
| 330 | log "Mounted virtio-9p share at /mnt/share" | 393 | log "Mounted 9p share at /mnt/share (transport: ${NINE_P_TRANSPORT})" |
| 331 | else | 394 | else |
| 332 | log "WARNING: Could not mount virtio-9p share: $MOUNT_ERR" | 395 | log "WARNING: Could not mount 9p share: $MOUNT_ERR" |
| 333 | log "Available filesystems:" | 396 | log "Available filesystems:" |
| 334 | cat /proc/filesystems 2>/dev/null | head -20 | 397 | cat /proc/filesystems 2>/dev/null | head -20 |
| 335 | fi | 398 | fi |
| @@ -644,7 +707,7 @@ graceful_shutdown() { | |||
| 644 | 707 | ||
| 645 | # Final sync and flush | 708 | # Final sync and flush |
| 646 | sync | 709 | sync |
| 647 | for dev in /dev/vd*; do | 710 | for dev in /dev/${BLK_PREFIX}*; do |
| 648 | [ -b "$dev" ] && blockdev --flushbufs "$dev" 2>/dev/null || true | 711 | [ -b "$dev" ] && blockdev --flushbufs "$dev" 2>/dev/null || true |
| 649 | done | 712 | done |
| 650 | sync | 713 | sync |
