Mounting a storage device (not USB)

I feel I should understand this, but I’m not seeing it.

I have an application installed on a device. There is another (internal) storage unit /dev/sda1 that I want to mount and access from a container. This is external data that I need to be able to read and write.

I’m unclear on whether (and how) I should be referencing this other storage unit in the docker_compose.yml, or should I just be putting a mount command into a script which is run when the container is started (and if did that, how would I be sure to unmount the storage device)?

The documentation on named volumes seems to all be talking about resin-data, which is provided. I don’t see any instructions for creating my own named volumes (if that is what I need in this situation).

And I’m unclear what happens if I do a mount in a container and that container is stopped.

Any advice would be much appreciated!

Take care,

Caligari

Hi

We have some documentation on how to go about using external media - https://www.balena.io/docs/learn/develop/runtime/#mounting-external-storage-media

Here we talk about UDEV rules, mounting, automounting, and so on.
Is this what you are looking for?

That all seems focused on USB drives that can be removed, or that was how I read it. I’m talking about a second drive in the unit - always there.

And I suppose the real question is whether I need to explicitly unmount a storage device that I explicitly mount, when a container is stopping (eg. when it is being updated)? If so, I’ll need to have a script that catches the appropriate signals. But if, for some reason, everything is automatically unmounted when the container is stopping, then that won’t be necessary. I guess I just expected this all to be stated a little more clearly, somewhere.

And from what you’ve said I’m assuming that named volumes are not relevant here, is that right? Further reading seemed to indicate they are named areas created in the resin-data partition, is that right?

Thanks!

Hello @Caligari

I think it should be treated as if it was an external storage device, but I’ll ask for more information internally. I have a few questions that would help us narrow down the search:

  • What device are you using?
  • How is the external media connected to the device? I mean which interface is it connected with?

Cheers,
Nico.

I’m using an Intel NUC (NUC8i3BEH) with Balena on a 500G SSD, and a separate SATA 2T HDD in there with my data. That HDD is listed as /dev/sda.

I want to work out, in particular, what I have to do in order to unmount the drive safely from inside the container, so that there are no problems when I update the containers, or shutdown the machine.

Any advice is much appreciated!

Hi, you should be able to un-mount the drive using umount <mount-point> command, if you are running the container in privileged mode. To run in privileged mode you’ll need to update the docker-compose.yml to include privileged: true. Since the current mountpoint in /dev/sda, you’ll have to run umount /dev/sda to unmount from within the container.

Sure, but when do I unmount it? I want to make certain that I don’t do anything bad to the partition when, for example, I update the container and it is shutdown and restarted. Otherwise, I’m going to be accessing the data frequently, so I’m planning to mount the drive on startup. I just want to know how I should be making sure to unmount it on shutdown.

Hello! Can you describe what you want to do in more detail. Do you have concerns about corrupting the data when you trigger an update let’s say?

My, limited, knowledge is that you have to unmount something that you mounted - you can’t just abandon it. Since the drive in question is external to the container, I am concerned that if I do not unmount it, it will be left in a less-than-ideal state. I figure this must be a fairly common issue, so I’m puzzled that no-one seems to understand my concern. Perhaps my limited knowledge is making me see a problem where there is none?

Regarding your first concern, you are right but in this case, it’s your application, you control how the writes and reads are done. You can unmount the disk and re-mount it on the new container if you are sure that the data you wanted to write is there. The only issue you have to keep in mind is that if you trigger an update the supervisor will kill the old app and run the new one, in order to avoid this when updating you can use an update lock https://www.balena.io/docs/learn/deploy/release-strategy/update-locking/ . Your application’s code would have to handle writing and reading, if you are sure that your app has finished writing to the disk then you can unmount it and release the lock in order to be updated to the new one. If for some reason you want zero downtime you can check the hand-over update strategy https://www.balena.io/docs/learn/deploy/release-strategy/update-strategies/#hand-over.

Here’s what I’ve done.

I found some shell scripting that filled in the final piece of the puzzle for me, and I’ve added the following to the script being run from my ENTRYPOINT:

#Define cleanup procedure
cleanup() {
    echo "Container stopped, performing cleanup..."

#whatever cleanup is needed, eg bringing down daemons

    if [ "$EXTERNAL_DEVICE" != "none" ]; then
       echo "unmounting /external..."
       umount /external
    fi
    exit 0
}

#Trap SIGTERM
trap 'cleanup' SIGTERM

if [ "$EXTERNAL_DEVICE" != "none" ]; then
  echo "Mounting external storage..."
  echo "mounting $EXTERNAL_DEVICE"
  mount $EXTERNAL_DEVICE /external
fi

#the rest of the inititalization here

#exec the CMD in the background
"$@" &

#Wait
wait $!

#Cleanup
cleanup

I’ve done some testing, and when I override the $EXTERNAL_DEVICE env var (set to “none” in the docker-compose.yml) this will mount and umount the device, regardless of whether the supervisor brings down the container, or it falls over for some reason.

Thanks for the advice here!

(BTW I’m now looking at some other use-cases that I’ve previously done with manually configured devices… balena, and the whole container/docker idea, seems to be a lot more maintainable than a txt doc reminding me of the steps to set up a whole system from scratch…)

Thanks for supplying your solution…

Is there another way to do the mount and umount that I’ve missed?

Hi @Liam unfortunately no, currently the only way to do this is basically as you have done. We have some ideas to do this more automatically, especially in the case where users want to auto mount USB drives and have them accessible to all their containers, but that is no in the implementation stage yet.