The Unlimited Thumbdrive
Some days ago, Synology posted a tweet about an old device, asking users if somebody knows what the product does.
Somebody responded:
“It’s an iSCSI target that present the virtual disc to a computer using USB πππ just kidding π”
I immediatly tweeted my tought: “This is actually a great idea! Maybe itβs doable with a raspberry pi zero w.”
And this is now stuck in my head. I knew it was possible, so it’s time for a POC.
What you need
- A Raspberry Pi Zero W
- A microSD card (at least 2GiB)
- An iSCSI server (any decent NAS will go)
iSCSI
If you have a NAS, access the admin interface and create a new target for the usb thumbdrive and a LUN to associate. This can be as big as you want.
Take note of the following parameters:
- host IP (of your NAS)
- port (usually 3260)
- IQN (this is the identifier of the iSCSI target)
microSD card preparation
You have to follow the well-known instruction to copy the OS image on the microSD card. I used the Raspberry Pi OS Lite (Legacy) image which is small and has very little requirements to run.
You can use the official “Raspberry Pi Imager” or “Balena Etcher”, or plain dd.
Once the write is finished, change to the newly created boot partition and:
1touch ssh
2
3cat <<EOF >wpa_supplicant.conf
4ctrl_interface=/var/run/wpa_supplicant
5update_config=1
6country=IT
7
8network={
9 ssid="my-wifi-ssid"
10 scan_ssid=1
11 psk="my-wifi-password"
12}
13EOF
add this line to config.txt
1dtoverlay=dwc2
open cmdline.txt
and append this at the end of the line
1modules-load=dwc2,g_acm_ms
Now, move the SD card to the rPiZero and poweron.
Then open an ssh session and issue this command to install the needed iscsi packages:
1sudo apt install open-iscsi
Then use the raspi-config
to force the Pi to wait for network connection at boot.
Now modify the /etc/rc.local
file:
1#!/bin/sh -e
2#
3# rc.local
4#
5# This script is executed at the end of each multiuser runlevel.
6# Make sure that the script will "exit 0" on success or any other
7# value on error.
8#
9# In order to enable or disable this script just change the execution
10# bits.
11#
12# By default this script does nothing.
13
14# Print the IP address
15_IP=$(hostname -I) || true
16if [ "$_IP" ]; then
17 printf "My IP address is %s\n" "$_IP"
18fi
19
20IQN=iqn.2000-01.com.synology:MYNAS.Target-1.c12345678f9
21HOST=192.168.1.10
22PORT=3260
23
24iscsiadm --mode node --targetname "${IQN}" -p "${HOST}:${PORT}" --login
25sleep 5
26/sbin/modprobe g_acm_ms file=/dev/disk/by-path/ip-192.168.1.10:3260-iscsi-iqn.2000-01.com.synology:MYNAS.Target-1.c12345678f9-lun-1 removable=y ro=0 stall=0
27
28exit 0
You can copy-paste these commands in the (root) shell to check if it works.
Now, poweroff the RaspberryPiZero and connect the USB cable from the OTG port to a PC: you’ll get power from the PC and the Raspberry will boot, connect to wifi, connect to iSCSI and present the iSCSI block device via USB.
It’ll be a blank disk, the size you choose when creating the LUN.
possible improvements
- faster boot
- 3d printed case
- safe disconnect (r/o filesystem or RAM overlay)
- auto generate image from stock rpi
- console via emulated usb-rs232
- g_ether with web interface for config
- vpn connection before iscsi