Hotplug doesn't allow access like a gadget slot does

So I’ve been poking about with the experimental hotplug support and there’s a gap in my understanding (and the docs). I’m trying this with the Turtlebot 2 and a snap that uses a serial port plug:

$ snap interface serial-port
name:    serial-port
summary: allows accessing a specific serial port
  - turtlebot-demo-kyrofa:kobuki
  - core:iclebokobuki (allows accessing a specific serial port)

They connect fine:

$ snap connections turtlebot-demo-kyrofa 
Interface     Plug                                Slot           Notes
network       turtlebot-demo-kyrofa:network       :network       -
network-bind  turtlebot-demo-kyrofa:network-bind  :network-bind  -
serial-port   turtlebot-demo-kyrofa:kobuki        :iclebokobuki  manual

However, at this point it’s entirely unclear which device I should be accessing. With the slot I created in my gadget I was able to tell it where the device should show up, but with hotplug I seemingly have no way of knowing. I know from dmesg that it’s on /dev/ttyUSB0, though:

[37251.605731] usb 1-9: new full-speed USB device number 13 using xhci_hcd
[37251.760973] usb 1-9: New USB device found, idVendor=0403, idProduct=6001
[37251.760978] usb 1-9: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[37251.760982] usb 1-9: Product: iClebo Kobuki
[37251.760984] usb 1-9: Manufacturer: Yujin Robot
[37251.760987] usb 1-9: SerialNumber: kobuki_AI02MUL8
[37251.764192] ftdi_sio 1-9:1.0: FTDI USB Serial Device converter detected
[37251.764483] usb 1-9: Detected FT232RL
[37251.764975] usb 1-9: FTDI USB Serial Device converter now attached to ttyUSB0

So I tried to access that, and got a denial in my syslog:

Nov 10 11:22:15 protege kernel: [37917.450407] audit: type=1400 audit(1573413735.502:2503): apparmor="DENIED" operation="file_lock" profile="snap.turtlebot-demo-kyrofa.system" name="/dev/ttyUSB0" pid=22127 comm="nodelet" requested_mask="k" denied_mask="k" fsuid=0 ouid=0

So, I have two questions:

  1. Is there a way to predict where the device will be using hotplug?
  2. Why can’t I access /dev/ttyUSB0 in this case? Should I be using something else?

Regarding 2,
In the denial I see that you have:

I think the issue is that your snap is trying to lock the device file, not just read or write. I’m not sure if omitting file locking is intentional or not. @jdstrand thoughts on allowing snaps to lock device files from serial interface?

(see the serial port interface rule:

Can you use snapctl to determine the path? This is untested, but presumably something like this would do:

  1. add a connect-plug-kobuki interface hook to your turtlebot-demo-kyrofa snap.
  2. in the hook, retrieve the path from the connected slot with snapctl get :kobuki --slot path and save it somewhere your app can read it (possibly with snapctl set).

It seems you can’t just execute the snapctl get command outside of the interface hook: presumably because the interface hook provides the context for which connection on the plug or slot to read the attributes from.


That’s interesting. That rule hasn’t changed since 2017-05-17, when the snap I’m testing was published, but when connecting to the serial slot from my gadget, it worked perfectly. Is something different when the slot is exposed via hotplugging?

Can you use snapctl to determine the path?

That’s actually a great idea for determining the path, thanks @jamesh. I’ll give that a shot and report back (unless @pstolowski can tell me offhand that this isn’t included).

AFAICT, no there should be no difference. There actually is a slightly different codepath if the slot doesn’t have slot attrs defined for the usb-vendor or usb-product as you can see in that function, but the generated rule should be exactly the same for both codepaths and both codepaths are actually from the same commit 3 years ago.

However note that if you were using this snap with a gadget snap exposed slot, you probably did have those attributes defined for the slot, so it is quite possible that something has regressed here when it comes to hotplug. Not sure what though TBH

Yes, @jamesh is spot, reading the path attribute is the way to go, and how it is supposed to be used.

And James is correct about snapctl requiring interface hook context to read connection attributes, no way to use it outside of hooks in this case, at least for now.

1 Like

As for the permission issue I need to investigate/ In theory the snippet should be effectively the same as when declared through gadget (with the path dynamically adjusted for the plugged device of course). We have a spread test that exercies hotplug with serial port via qemu’s virtual device, but perhaps the test isn’t good enough.

@kyrofa I’ve investigated this with our spread test & virtual serial port on a classic image. I can provoke the denial you saw in the log by modyfing our test snap to not only write to the serial port, but also try to flock it. Since we are not giving locking permissions for serial port at the moment, this is kind of expected… I’m confused why did it work before for your snap and the gadget; did you by any chance rebuild your snap with possibly newer dependencies, and locking is now attempted and it simply wasn’t done in the old version?

I’ll admit this has me second-guessing myself, but I have proof that this worked. Take a look at this moment in this youtube video and note the snap revision (13). It worked for that video, and it hasn’t changed since (rev 13 is still on stable, and is what I used in the OP).

Note also that the dependency in question has been locking as far back in the history as I can go (2012). Once I return back home I’ll try that image again and confirm for real, but this is very odd.

Interesting. By the way we have another thread the mentions locking permission issue, but with gadget-provided serial-port slot: Not able to start/configure custom built ubuntu core

1 Like

@pstolowski (cc @kyrofa) - we should add ‘k’ to the policy. Please see Not able to start/configure custom built ubuntu core


@pstolowski - I have a batch of updates to do and will add this to my list.