Contents

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 😊”

link

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

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