mounting multiple STM32 boards

I’m trying to set up a small build farm on a RasPi 3B+ for STM32 embedded µC boards. These all have an ST-Link USB interface which appears as serial port and as usb drive. The trouble is how to keep them apart, since they all end up being some /dev/ttyACM and the drives all have UUID 2702-1974 (stlink-org/stlink on GitHub helps with this). If I manually connect them using dietpi-drivemanager, I see this:

$ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda           8:0    1  228K  0 disk
sdb           8:16   1  228K  0 disk
sdc           8:32   1  416K  0 disk
sdd           8:48   1   84K  0 disk
sde           8:64   1  1.5M  0 disk
sdf           8:80   1  420K  0 disk
sdg           8:96   1    6M  0 disk /mnt/l432
sdh           8:112  1  804K  0 disk
mmcblk0     179:0    0 14.8G  0 disk
├─mmcblk0p1 179:1    0  128M  0 part /boot
└─mmcblk0p2 179:2    0 14.7G  0 part /

Trouble is, that “l432” drive is not the right one - after a reboot, drive-manager seems to randomly connect each drive to the /dev/sd devices. Not a surprise, as they are all the same, here’s /etc/fstab:

UUID=2702-1974 /mnt/l053 vfat noatime,lazytime,rw,nofail,noauto,x-systemd.automount
UUID=2702-1974 /mnt/f303 vfat noatime,lazytime,rw,nofail,noauto,x-systemd.automount
UUID=2702-1974 /mnt/f103 vfat noatime,lazytime,rw,nofail,noauto,x-systemd.automount
UUID=2702-1974 /mnt/l011 vfat noatime,lazytime,rw,nofail,noauto,x-systemd.automount
UUID=2702-1974 /mnt/f722 vfat noatime,lazytime,rw,nofail,noauto,x-systemd.automount
UUID=2702-1974 /mnt/g431 vfat noatime,lazytime,rw,nofail,noauto,x-systemd.automount
UUID=2702-1974 /mnt/h743 vfat noatime,lazytime,rw,nofail,noauto,x-systemd.automount
UUID=2702-1974 /mnt/l432 vfat noatime,lazytime,rw,nofail,noauto,x-systemd.automount

There is a way to disambiguate, though:

$ ls -l /dev/disk/by-label/
total 0
lrwxrwxrwx 1 root root 9 Aug 18 10:45 NODE_F303K8 -> ../../sdb
lrwxrwxrwx 1 root root 9 Aug 18 10:45 NODE_F722ZE -> ../../sde
lrwxrwxrwx 1 root root 9 Aug 18 10:45 NODE_H743ZI -> ../../sdg
lrwxrwxrwx 1 root root 9 Aug 18 10:45 NODE_L011K4 -> ../../sdd
lrwxrwxrwx 1 root root 9 Aug 18 10:45 NODE_L053R8 -> ../../sda
lrwxrwxrwx 1 root root 9 Aug 18 10:45 NODE_L432KC -> ../../sdh
lrwxrwxrwx 1 root root 9 Aug 18 10:45 NOD_G431KB -> ../../sdf
lrwxrwxrwx 1 root root 9 Aug 18 10:45 NUCLEO -> ../../sdc

As you can see, L432 got mis-assigned after a reboot (sdg iso sdh).

Is there a way in dietpi to make use of the label information, somehow?
Or some other workaround, outside of dietpi-drivemanager perhaps?
Otherwise, I don’t see how I can avoid these random drive assignments on each reboot.

-jcw

Can you check if they all have same PARTUUID as well

lsblk -o name,fstype,label,size,ro,type,mountpoint,partuuid,uuid

Another try could be to change UUID/PARTUUID for each disk https://askubuntu.com/questions/1250224/how-to-change-partuuid

These are emulated disks (saving a firmware image to them re-flashes the attached µC).
There’s no real storage, i.e. no way to change a disk label or UUID, AFAICT.

$ lsblk -o name,fstype,label,size,ro,type,mountpoint,partuuid,uuid
NAME        FSTYPE LABEL        SIZE RO TYPE MOUNTPOINT PARTUUID                             UUID
sda         vfat   NODE_L053R8  228K  0 disk                                                 2702-1974
sdb         vfat   NODE_F303K8  228K  0 disk                                                 2702-1974
sdc         vfat   NUCLEO       416K  0 disk                                                 2702-1974
sdd         vfat   NODE_L011K4   84K  0 disk                                                 2702-1974
sde         vfat   NODE_F722ZE  1.5M  0 disk                                                 2702-1974
sdf         vfat   NOD_G431KB   420K  0 disk /mnt/g431                                       2702-1974
sdg         vfat   NODE_H743ZI    6M  0 disk                                                 2702-1974
sdh         vfat   NODE_L432KC  804K  0 disk                                                 2702-1974

The /mnt/g431 instance was mounted manually by me. But I can’t get it to allow non-root writes (chmod & chown don’t do anything).

From dmesg, one of the disks:

[24772.808972] scsi 5:0:0:0: Direct-Access     MBED     microcontroller  1.0  PQ: 0 ANSI: 2
[24772.809474] sd 5:0:0:0: Attached scsi generic sg5 type 0
[24772.809821] sd 5:0:0:0: [sdf] 840 512-byte logical blocks: (430 kB/420 KiB)
[24772.810063] sd 5:0:0:0: [sdf] Write Protect is off
[24772.810075] sd 5:0:0:0: [sdf] Mode Sense: 00 00 00 00
[24772.810365] sd 5:0:0:0: [sdf] Asking for cache data failed
[24772.810378] sd 5:0:0:0: [sdf] Assuming drive cache: write through
[24772.863441] sd 5:0:0:0: [sdf] Attached SCSI removable disk

it is a vfat file system and not supporting unix file system permissions. Best would be to use ext4

Not sure if it is possible to mount a file system by lable. At least I found a web site describing it https://linuxhint.com/mount_partition_uuid_label_linux/

Just have a look to the last section.

LABEL=Data   /data  vfat  defaults   0    0

But this is not supported by drive manager and would need to be done manually in /etc/fstab

I have no control over the file system. It’s a µC emulating a USB drive, there is no real storage, you copy a file containing a firmware image to this emulated disk and that contents gets flashed into the attached µC (i.e. a fixed µC called an “ST-Link” with fixed USB disk emulation behaviour, and a target µC attached to it, which gets re-flashed).

How do I add entries to /etc/fstab which don’t get deleted when drive manager runs?
When I tried this, the changed entries were all removed.

PS. This works fine in fstab: “LABEL=NODE_L432KC /mnt/l432 vfat noatime,rw,nofail,user”, but the line is deleted by drive manager.

How do I add entries to /etc/fstab which don’t get deleted when drive manager runs?
When I tried this, the changed entries were all removed.

Driver manager is not capable to keep such entries added by LABLE. If you add them manually, you would need to stay away from drive manager to avoid getting them overwritten

Ok, I’ll make drive-manager non-executable on this system.
Perhaps it’s an idea to add support for a section which is user-managed.

Anyway, looks like it’s a workable solution, many thanks.

Update: disabled by adding this line to the start of /boot/dietpi/dietpi-drive_manager:

#!/bin/echo disabled

I guess it’s somewhere on the looong to-do list. :wink:

I looked into drive-manager a bit. I may be able to create a simple mod for it:

  • scan for all lines starting with ‘LABEL=’
  • re-insert them in a new “LABELED drives (manually managed)” section
  • i.e. this would carry over such entries with little impact on the rest of the logic

Shall I give that a try?

UPDATE - Never mind. It’s really a small change:

# diff -u2 ~/dietpi-drive_manager /boot/dietpi/dietpi-drive_manager
--- /root/dietpi-drive_manager	2021-07-27 17:24:56.000000000 +0200
+++ /boot/dietpi/dietpi-drive_manager	2021-08-19 13:17:58.000000000 +0200
@@ -108,5 +108,5 @@

 		# Special mounts
-		local swap_mounts tmpfs_mounts misc_mounts net_mounts
+		local swap_mounts tmpfs_mounts misc_mounts net_mounts label_mounts

 		# Mode 4: Force reset/clean fstab (PREP)
@@ -122,4 +122,5 @@
 			swap_mounts=$(grep '^[[:blank:]]*[^#].*[[:blank:]]swap[[:blank:]]' $fp_fstab_tmp)
 			tmpfs_mounts=$(grep '^[[:blank:]]*tmpfs[[:blank:]]' $fp_fstab_tmp)
+			label_mounts=$(grep '^[[:blank:]]*LABEL=' $fp_fstab_tmp)
 			# ecryptfs, vboxsf, glusterfs, bind mounts
 			misc_mounts=$(grep -E '^[[:blank:]]*[^#].*([[:blank:]](ecryptfs|vboxsf|glusterfs)[[:blank:]]|[[:blank:],]bind[[:blank:],])' $fp_fstab_tmp)
@@ -152,4 +153,9 @@

 #----------------------------------------------------------------
+# LABELED drives (manually managed)
+#----------------------------------------------------------------
+$label_mounts
+
+#----------------------------------------------------------------
 # PHYSICAL DRIVES
 #----------------------------------------------------------------" > $fp_fstab_tmp

let’s check with the developer. Maybe it would be good to have a more broader approach to facilitate other cases as well

MichaIng
your view?

For certain drive/mount types indeed dietpi-drive_manager should be skipped. I’m not yet sure how to handle best:

  • It detects some mount types, like tmpfs, network drives, ecryptfs, …, and leaves those fstab entries untouched already. But for this, there needs to be a way to identify them. See https://github.com/MichaIng/DietPi/blob/2366ab9/dietpi/dietpi-drive_manager#L122-L127 and https://github.com/MichaIng/DietPi/blob/2366ab9/dietpi/dietpi-drive_manager#L271. If those virtual drives appear exactly like physical drives, this method cannot be used. So is there any way, like with lsblk, findmnt, blkid, to know whether a block device is such a virtual one or not?
  • A custom section is actually not a bad idea. The problem is that fstab is edited by some other scripts as well, so we’d need to implement the custom section detection in several places. And then also sometimes entries are removed first and added with changed options again, like when increasing the /tmp tmpfs size, moving the rootfs to an external drive, restoring a dietpi-backup at first boot etc. So not sure how to handle custom entries then when something in them needs to be changed. Keeping them in custom place, re-adding them outside, how we know whether this will work then. So nice in theory, but it gets complicated :thinking:.
  • I was thinking about using systemd mount units with dietpi-drive_manager and keeping the whole fstab untouched. So instead of adding an fstab entry, which is parsed and translated into a mount unit at boot, we can create such a mount unit directly. But it may be confusing for admins when seeing an empty fstab. At least it requires some explanation. But that way we wouldn’t mess with any custom entries.
  • However, while using labels is a workaround, if multiple block devices have the same UUID, this is gonna cause issues earlier or later outside of our scripts. So while I agree that dietpi-drive_manager requires a better handling of custom entries, in your case I’d invest some time to find out how to have unique “Universally Unique Identifier” for those drives. Often block devices simply have no label, so a general option to use labels instead of UUIDs is not possible, same with PARTUUIDs, considering that a filesystem can be created on a drive without any partition table. UUIDs are the only reliable “unique” identifier which is aimed to always work, so if this is broken by some virtual drive implementation, then that implementation requires fixing :wink:.

Many thanks for the detailed info. First off: I understand the complexity, and respect any choice you guys make on this. Just keep in mind that, as the saying goes, “perfection is the enemy of done” - it may not be possible to address every concern, so I’ll be keeping my “label-saving” workaround for now, until a better option emerges.

My solution is not perfect. I don’t know how the setup will work if I plug in two identical boards, for example (not a very useful scenario for a build farm). AFAICT, this will lead to duplicate disk labels.

The chance of this getting fixed by the manufacturer is zero: ST Microelectronics is a company with $10B yearly revenues. They have other priorities than helping out an open-source developer.

Each µC on the board has a unique 96-bit ID. This is used to construct the unique serial number of the serial port, also implemented as part of the USB interface. I use it to uniquely identify the serial port, via /dev/serial/by-id/… I have not yet found a unique way to associate each virtual drive with this same serial number, but I also haven’t looked deeply since the disk label was good enough.

Haha, yes I agree, and this is particular issue for me quite often, as I tend to be perfectionist :smiley:. However, what is important to me is, when we add a feature to our scripts, it needs to be well supported (not conflicting) with our other scripts. And for a custom section in fstab, this is a bit difficult to achieve. Switching from fstab to system mount units is a large task as well, but is solves a lot of other issues and it is much easier then to leave fstab consequently as custom file and strictly only handle systemd mount units we created. All is also possible with a custom section, but it implies a lot more grep/sed action then, at least.