Converting SBC into Network 3D Print Server

Using an old SBC like a Raspberry Pi as some kind of network (3D) print server for simple USB printers (or any USB device) without network capabilities. The setup is quite easy and can be done in 30 minutes. 
 
In my case I will use an old odroid-mc1 for my Flashforge Creator Pro 2 3D printer. The printer is connected to the odroid-mc1 via USB and the odroid-mc1 is connected via wired ethernet to my network. For the remote USB functionality I usethe  VirtualHere "trial" edition which allows sharing one device  and its Windows client has a nice GUI. Download the client from: https://www.virtualhere.com/usb_client_software. There are open source USBIP solutions, but Virtualhere is much more convenient and IMHO also more reliable. This print server costs me 2.2 Watt all the time, which is much less than the 15 Watt the printer draws when idle. 
 
On the client side, just run the downloaded client and you can configure a server connection. Then a list of connected USB devices is shown and you can connect/disconnect via right click on each device. When connected, a USB device will behave as it would have been connected directly to your PC. You even need the same drivers as for a locally connected device.
 
 
Required skills: 
- Knowing the model of your SBC
- Writing Image to SD card
- Basic shell/command line experience
- Logging viah SSH
- Edit config files 
 

Basic installation

  1. Download armbian for your device from https://www.armbian.com/download/ the CLI editions are sufficient and have no UI. If you cannot find your device or device version, check something similar named or the first model from your model line, e.g. if you have a Raspberry Pi 3, check the Raspberry Pi download, you device revision may be listed unter "Compatible".  The filter does not show all manufacturer, so just scroll the list down. For my odroid-mc1 I have to scroll down and choose Odroid XU4 / HCx. Read the notes on the page, there might be important settings, as for my odroid-mc1 I can configure an optimized board configuration after installation. 
  2. Flash Armbian Image to sdcard, e.g. BalenaEtcher
  3. Boot Armbian, wait until it is online, this may take some time. I check this by looking at my DHCP logs from my dnsmasq server, you may also get the IP address from your router if  the name registration resolution is not working 
  4. Login as root (any ssh client like PuTTY on windows),password 1234.
    1. Change the root password
    2. Choose your shell
    3. Cancel user account creation with ctrl-c or create a user account if you prefer to type sudo all the time. Your choice.
  5. Do apt update && apt dist-upgrade && reboot
  6. Edit the hostname in the file /etc/hostname. nano is installed, vi needs to be installed with apt install vim or your prefered vi version. My guess the hostname is always the model name. 
  7. If you haven't applied any recommended changes for your machine, do it now, for me it required a reboot, so afterwards the device should be available under the new hostname. 
  8. Install VirtualHere Server on the device by running curl https://raw.githubusercontent.com/virtualhere/script/main/install_server | sh . If you aren't root, write sudo before the sh (not the curl!) as usual. The service is automatically started. On your client, install the VirtualHere client. For some reason he cannot find the server automatically, so I have to add it manually by right clicking on USB Hubs and do "Specify Hubs". Add here your choosen hostname or IP adress + the default port. If any device is connected to your new print server, it should be visible where and with right click yoo can connect it.
  9. Do a reboot with the command reboot and test if  it comes up again. 
  10. If you have connected any USB device, starting the client on the PC and scanning (did not work for me) or configuring a host manually should should the connected USB devices. 
  11. You are ready to use the now "networked" device. Oh and it's by default not encrypted nor password protected. 

Some minor hardening

If you want to power off the server by simply cutting its power, the root filesystem won't be happy about this, even with a journal. To make this safe, we'll make the filesystem read-only, and overlay it with a in-memory filesystem, so logs and other runtime stuff can be written, but every change will be gone after reboot as the underlying filesystem is readonly. 
  1. apt install overlayroot
  2. edit /etc/overlayroot.conf and change the last line to overlayroot="tmpfs"
  3. reboot
By default the system will be updated automatically by unattended-upgrade which is now a little pointless as the updates will be gone after reboot.. As a good exercise on how to make changes, we will remove it and some other packages. 
The normal worklow is the command sequence
  1. overlayroot-chroot
  2. make your changes
  3. exit 
Only this particular session can write to the root filesystem, and with exit you end this session. But I had trouble doing this, often getting the following messages, which make me a bit nervous: 
mount: /media/root-ro: mount point is busy.
ERROR: Note that [/media/root-ro] is still mounted read/write
This happend even with sync before exiting or even when Doing minor changes like config file ediiting.
 
My recommendation is this procedure:
  1. overlayroot-chroot
  2. edit /etc/overlayroot.conf and comment out the line we added earlier by prepending a hash sign. Then do a clean reboot and after that the filesystem is writable again for everybody
  3. reboot
  4. make your changes 
  5. remove the comment hash sign in /etc/overlayroot.conf
  6. reboot
So, back to the uninstallation. run apt autoremove <packages>. I recommend to uninstall these packages
  • Automated updates: unattended-upgrade
  • WiFi functionality: wireless-regdb wireless-tools wpasupplicant
  • Development stuff: gcc-12 cpp-12 gcc-11 git
  • When not running from a real SSD or HDD: smartmontools
  • NFS (this is not file server): rpcbind
Now the system is down to only 100MB RAM consumption, mostly for systemd & networkmanager
 
I had issues like connection losses, reconnection issues, even resets of the printer when trying to connect to the USB device. In the end I solved this issue by disabling the power management for the network chip. Long story cut short: 
  1. Make the root file system writable (see above) 
  2. echo 'SUBSYSTEM=="net", ATTR{power/control}="on"' >>  /etc/udev/rules.d/99-nic-powermanagement.rules
  3. reboot
This is the most generic solution and should work for almost any network device.
 
Now throw the SBC it into some corner and forget it. 
 
Rubrik: 

Disabling power management for network card with udev

I tried to disable power saving on the "network card" in my odroid-mc1 (SBC like Raspberry Pi) which I use as network print server as my 3D printer can be controlled via  USB and SD card . Per default powersaving is on and I assume this is cause of various USB-over-IP issues when the system is idle.
 
# lsusb
Bus 006 Device 002: ID 0bda:8153 Realtek Semiconductor Corp. RTL8153 Gigabit Ethernet Adapter
 
The interface name is enx001e06373d78 and can be found in /sys/class/net/enx001e06373d78 and with the power management setting in power/control: 
# cat /sys/class/net/enx001e06373d78/power/control
auto
 
auto means activated power management and on is no power powermanagement as per https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-power
 
As usual, settings in sysfs are not persisted and gone after a reboot or reconnect, it's not configurable via sysctl, so the most generic way is in udev and doing so makes it work with other USB ports, other devices, multiple device of the same type, etc. 
 
Either edit an existing udev rule file in /etc/udev/rules.d/ or a create a new one like 99-my-powersettings.rules. The order in which udev rules are processed is sorted by the number in the file name and you want to do this after your network card is configured, so put it at the end. 
 
Udev rules consist of conditions or "filters" and actions. Here are 3 rules that set power/control to on on the odroid-mc1: 
 
# Condition: is network device, actions: write on into its power/control sysfs file (if it exists..)
#SUBSYSTEM=="net", ATTR{power/control}="on"

# Conditions: is network device and has productId 8513, actions: write on into its power/control sysfs file
SUBSYSTEM=="net", ATTRS{idProduct}=="8153" , ATTR{power/control}="on"

# Conditions: is network device and has productId 8513 and power/control is set to auto, then set it to on
#SUBSYSTEM=="net", ATTRS{idProduct}=="8153", ATTR{power/control}=="auto", ATTR{power/control}="on"
 
Parts with == are one type of conditions and single equal sign set values. You cat get a list of possible conditions with 
# udevadm info -a -p /sys/class/net/enx001e06373d78
Be as generic or specific as you like. 
 
Now the funny part and pitfall. It took me some time to get this working, the setting was never applied. Other people had the same issue, sometimes there was a solution provided which did not work.. The issue was that I tried to apply the setting to the "USB device", not the "network device". That does that mean. 
 
In /etc/udev/rules.d/50-usb-realtek-net.rules is a rule (slightly modified for easier reading) for the NIC on the system: 
SUBSYSTEM=="usb", ATTR{idVendor}=="0bda", ATTR{idProduct}=="8153", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}"
which sets some NIC Mode, whatever this means. But this is my network chip, so I just add ATTR{power/control}="on" and it should never ever go into power management mode again? 
 
Wrong. This operates on the USB endpoint: 
# readlink -f /sys/class/net/enx001e06373d78/device
/sys/devices/platform/soc/soc:usb3-1/12400000.dwc3/xhci-hcd.8.auto/usb6/6-1/6-1:1.0 
 
or shorter /sys/bus/usb/devices/6-1:1.0 which has the referenced bConfigurationValue: 
# ls -al /sys/bus/usb/devices/6-1:1.0/
total 0
drwxr-xr-x 7 root root    0 Jul 15 04:46 .
drwxr-xr-x 6 root root    0 Jul 15 04:46 ..
-rw-r--r-- 1 root root 4096 Jul 15 04:51 authorized
-r--r--r-- 1 root root 4096 Jul 15 04:51 bAlternateSetting
-r--r--r-- 1 root root 4096 Jul 15 04:46 bInterfaceClass
-r--r--r-- 1 root root 4096 Jul 15 04:46 bInterfaceNumber
-r--r--r-- 1 root root 4096 Jul 15 04:51 bInterfaceProtocol
-r--r--r-- 1 root root 4096 Jul 15 04:51 bInterfaceSubClass
-r--r--r-- 1 root root 4096 Jul 15 04:51 bNumEndpoints
...
 
and it does not even have a power/control setting: 
 
# ls -al /sys/bus/usb/devices/6-1:1.0/power
total 0
drwxr-xr-x 2 root root    0 Jul 15 04:46 .
drwxr-xr-x 7 root root    0 Jul 15 04:46 ..
-rw-r--r-- 1 root root 4096 Jul 15 04:51 async
-r--r--r-- 1 root root 4096 Jul 15 04:51 runtime_active_kids
-r--r--r-- 1 root root 4096 Jul 15 04:51 runtime_enabled
-r--r--r-- 1 root root 4096 Jul 15 04:51 runtime_status
-r--r--r-- 1 root root 4096 Jul 15 04:51 runtime_usage
 
And it's not even a network card, remember the NIC was in /sys/class/net, but the SUBSYSTEM in the rule is usb.. So my rule worked on the wrong device, on the "usb device" instead of the network device..
 
A few hours wasted on my first udev adventure & a lesson learned. Always work on the correct device. 
 
Rubrik: 

Virtuelles USB-CDROM iodd / Zalman VE

Leider findet man nicht viel über diese nützliche Gerät, dabei ist es einfach genial. Jeder der viel installiert und häufig viele verschiedene Boot- oder Live-CDs benutzt, könnte mit diesem Gerät glücklich werden.

Hardwaremässig ist das iodd Virtual ROM erstmal nur ein externes Festplattengehäuse für 2,5" Festplatten oder SSDs, das über USB und bei einigen Modellen auch über eSata an den PC angeschlossen wird. Der Clou ist allerdings, dass man in das Verzeichnis _iso einfach Iso-Images von CDs/DVDs/Blu-Rays/etc legen kann, die das iodd dann als USB-CDROM zur Verfügung stellt. Und man kann davon dann auch booten. Perfekt um Betriebssystem zu installieren oder um Live-Rescue-Systeme zu starten.
Für die ISO-Auswahl hat das iodd ein kleines beleuchtetes LCD-Display und einen Auswahlknopf an der Seite. Man kann jederzeit ISOs ein und aushängen. Zu dem wählt man darüber einen der drei Modi aus: Reiner Festplatten-Modus, reiner CD-ROM-Modus und den praktischen Dual-Modus, in dem sowohl die HDD als Platte zur Verfügung steht, als auch ein Image eingebunden werden kann. Dies ist beispielsweise in Verbindung Clonezilla die perfekte Lösung um System-Backups zu machen, da man direkt ein Backup-Medium hat.
Das Gehäuse macht einen sehr stabilen Eindruck und ist aus Metall, die empfindlichsten Stelle dürften das Display und vor allem der Knopf an der Seite sein.

Die Festplatte muss man selber noch kaufen, man sollte eine 2,5" SATA (-2/-3) Festplatte mit 9,5mm Dicke wählen, möglichst mit niedrigem Stromverbrauch. Ich denke auf den Verbrauch sollte man achten, da USB wohl nur 2,5Watt liefern kann und neben der HDD auch die iodd Elektronik Strom verbraucht. In meinem iodd läuft eine 500GB Toshiba MK5076GSX mit einem angegebenen Verbrauch von 1,85Watt.

Leider ist das iodd in Deutschland direkt wohl nicht erhältlich, man kann es über eBay aber direkt aus Südkorea ordern. Der Preis liegt momentan bei 43€ (mit Versand) aufwärts, allerdings wird der Zoll da noch 19% drauf berechnen. Dafür bekommt man das iodd, eine einfache Polstertasche, ein kurzes USB-Kabel und einen koreanischen Beipackzettel. Ich rate dazu direkt das letzte Firmware-Update auf die NTFS-fähige Firmware einzuspielen.

Die bessere Alternative ist es wahrscheinlich ein baugleiches Zalman VE-XXX für ~40€ zu kaufen, da sind Modelle auf dem deutschen Markt erhältlich. Zalman bietet unterschiedliche Modelle an beispielsweise mit USB 3.0 Unterstützung. Hier bekommt man dann auch eine englische Kurzanleitung und hat keine Probleme mit dem Zoll.

Noch ein Nachtrag: Warum NTFS? Man kann zwar mehrere Partitionen anlegen, aber die erste wird für die Images genutzt. Unterstützt werden FAT32, NTFS & exFat. FAT32 kann keine Dateien größer als 4GB, somit können keine DVD-Images genutzt werden. iodd hat zwar ein Split-Tool, das die Teil-Dateien in einem bestimmten Format benennt und dann trotzdem als ein Image genutzt werden können, aber bequem ist das nicht. exFat hat wiederum das Problem mit der Unterstützung. Nicht alle OS können exFat lesen und/oder schreiben und es gibt da wohl auch rechtliche Probleme. NTFS wiederum kann natürlich von Windows genutzt werden und die meisten Linux-Distributionen können auch von Haus aus NTFS lesen und meistens sogar schreiben. Ist zwar nicht ganz so schnell, aber die 30MB/s die USB 2.0 kann, kriegt man schon hin. 
 

iodd von vorne. Mattes einfaches Metall-Gehäuseiodd Display im CD-ROM Modus