I Broke My Pi’s Networking!

While messing around with Raspberry Pis, Docker, bridged networks, wireless networks, etc. I managed to bork my Pis. If this happened at home, I could use a serial console cable, or plug the Pi into the spare HDMI port on my monitor and use a USB keyboard, or attach a USB SD card reader to another Pi. Unfortunately, this happened at work, where I have no Pi console cable, no HDMI monitor (one downside to the Apple Thunderbolt Display), no USB keyboard and no USB SD card reader (although since I borked both Pis, the SD card reader would have been useless).

I did have my Macbook Pro and its SD reader, and several Ubuntu Vagrant boxes (running on VirtualBox).

Problems

  1. The Macbook Pro SD reader does not show up as a USB device, so it can't be used directly in a VirtualBox VM / Vagrant Box.

  2. I'm using 64GB SD cards, and the filesystem is fully expanded, so dd'ing the image to a file, fixing it, then dd'ing it back to the SD card would be SLOW

  3. VirtualBox does not make it easy to access local disks directly in VMs.

Solution

There are "internal commands" for the VBoxManage command line tool, including ones to make virtual raw VMDK disks from real disks, which can then be attached to a Vagrant box.

First, you need to find the name of your SD card disk. With Raspberry Pi SD cards, there's always a FAT partition labeled boot - and your Mac will automatically mount it:

mac% mount | grep boot
/dev/disk4s1 on /Volumes/boot (msdos, ...)

Find your Linux partition (probably #2):

mac% sudo diskutil list /dev/disk4
/dev/disk4 (internal, physical):
   #:                   TYPE NAME    SIZE       IDENTIFIER
   0: FDisk_partition_scheme        *64.1 GB    disk4
   1:         Windows_FAT_32 boot    66.1 MB    disk4s1
   2:                  Linux         64.0 GB    disk4s2    

Unmount the disk (but don't eject it), change the ownership of the disk, then create a raw VMDK with it:

mac% sudo diskutil unmountDisk /dev/disk4
Unmount of all volumes on disk4 was successful
mac% sudo chown `id -un` /dev/disk4
mac% VBoxManage internalcommands createrawvmdk \
> -filename ./sd-card.vmdk -rawdisk /dev/disk4
RAW host disk access VMDK file ./sd-card.vmdk created successfully.

Find the full name and UUID of your vagrant box:

mac% VBoxManage list vms |\
> grep `cat .vagrant/machines/default/virtualbox/id`
"rpi_default_1469562661207_11553" {3079e67d-2395-4ad0-ae66-db1378093734}

Using either the name or the UUID, find the name of your box's Storage Controller:

mac% VBoxManage showvminfo rpi_default_1469562661207_11553 |\
> grep 'Storage Controller'
Storage Controller Name (0):            SATAController
Storage Controller Type (0):            IntelAhci
Storage Controller Instance Number (0): 0
Storage Controller Max Port Count (0):  30
Storage Controller Port Count (0):      2
Storage Controller Bootable (0):        on

Your Vagrant box must be halted before the disk can be added:

mac% vagrant halt

Your Mac probably (unhelpfully) re-mounted the boot partition again, so unmount it (again):

mac% sudo diskutil unmountDisk /dev/disk4
Unmount of all volumes on disk4 was successful

Attach the disk to your box:

mac% VBoxManage storageattach rpi_default_1469562661207_11553 \
> --storagectl SATAController --port 2 --type hdd \
> --medium sd-card.vmdk

Start your box:

mac% vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
...

If you get an error about the disk being in use, unmount the SD card again.

Connect to your Vagrant Box and sudo to root:

mac% vagrant ssh
...
box% sudo su -

Find the Linux partition on the SD card (probably dev/sdb2):

box# fdisk -l

Disk /dev/sda: 42.9 GB, 42949672960 bytes
...
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048    83886079    41942016   83  Linux

Disk /dev/sdb: 64.1 GB, 64054362112 bytes
...
   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            8192      137215       64512    c  W95 FAT32 (LBA)
/dev/sdb2          137216   125106175    62484480   83  Linux

Mount the disk

box# mount /dev/sdb2 /mnt

Fix things

box# vi /mnt/etc/network/interfaces

Unmount the disk when you're done

box# cd /
box# umount /mnt
box# exit
box% exit

Halt the box again:

mac% vagrant halt
==> default: Attempting graceful shutdown of VM...

Detach the disk

mac% VBoxManage storageattach rpi_default_1469562661207_11553 \
> --storagectl SATAController --port 2 --medium none

Remove the disk from VirtualBox's Virtual Media Manager:

mac% VBoxManage closemedium $PWD/sd-card.vmdk

Eject the disk from your Mac:

mac% sudo diskutil eject /dev/disk4
Disk /dev/disk4 ejected

Remove the SD card from your Mac, install it in your Pi, cross your fingers, and power on the Pi.