Unmounting USB on NI LinuxRT

This is going to be super specific!

Recently I had a project where we needed to move data from a LinuxRT controller to a USB stick for offline data transfer.

As reported on the NI forums at https://forums.ni.com/t5/LabVIEW/cRIO-Close-USB-Flash-Drive/td-p/3327336/page/2 the problem is, removing the USB stick without unmounting it causes a scan and fix dialog when attaching the USB stick to Windows instead.

Using the details in that post and some more research I found you could do it using the udisk method when you have the permissions set correctly.

Note: This has been tested on LV2020 images of RT Linux. In other versions your mileage may vary.

Permissions

First step is that you need the permissions to run the udisk tool. User code runs as the “lvuser” user so that must have access to the methods to unmount the disk.

I’ve tried to minimise the permissions granted to minimise any security risk from including this. (see principle of least privilege)

The UDisk tool uses the PolicyKit framework for granular permissions. To allow new permissions we create a new file in /etc/polkit-1/rules.d which it will read and apply. I called this 00-lvuser-unmount.rules. The contents I used are:

polkit.addRule(function(action, subject) {
  var YES = polkit.Result.YES;
  var permission = {
    // required for udisks1:
    "org.freedesktop.udisks.drive-eject": YES,
    "org.freedesktop.udisks.drive-detach": YES,
    // required for udisks2:
    "org.freedesktop.udisks2.eject-media": YES,
    "org.freedesktop.udisks2.power-off-drive": YES,
    "org.freedesktop.udisks2.filesystem-unmount-others": YES,
    "org.freedesktop.udisks2.eject-media-other-seat": YES,
    "org.freedesktop.udisks2.power-off-drive-other-seat": YES
  };
  if (subject.user == "lvuser") {
    return permission[action.id];
  }
});

I suspect this can be reduced further – now I see it again I’m trying to remember whether the “other” entries are needed and will now be testing without it! (Note: tested – it did not work without these).

Scripting the Unmount

We need to achieve a few things to unmount the drive:

  1. Identify the drive ID that is mounted. I’m assuming here that we are interested in the drive that is auto-mounted to /u on the cRIO
  2. Unmount the partition.
  3. Power down the device.

The script below can be provided to a system exec VI to achieve this. This uses findmnt based on the /u path and then lsblk to find the drive based on the partition name.

Then we use udisksctl to control the drive.

TARGET_PARTITION=$(findmnt -n -o source --target /u) &&
TARGET_DEVICE=/dev/$(lsblk -no pkname $TARGET_PARTITION) &&
udisksctl unmount -b $TARGET_PARTITION &&
udisksctl power-off -b $TARGET_DEVICE

That is it! With these two components you can unmount the drives from your LabVIEW code (or anything that can call a shell script).

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.


By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close