Tagmount

Mounting USB stick systemd

udev rules 99-usb-mount-rules

# Warning this mounts only the first partition to the defined place, assuming first partition is 1
KERNEL=="sd[a-z]*1", SUBSYSTEMS=="usb", ACTION=="add", RUN+="/bin/systemctl start automount@%k.service"
KERNEL=="sd[a-z]*1", SUBSYSTEMS=="usb", ACTION=="remove", RUN+="/bin/systemctl stop automount@%k.service"

Add systemd service: automount@.service

[Unit]
Description=Automount usb drive to %i

[Service]
Type=oneshot
RemainAfterExit=true

Environment="MOUNTPOINT=/media/user_data/EXTERNAL"

ExecStart=/usr/bin/mount-usb-drive.sh add %i
ExecStop=/usr/bin/mount-usb-drive.sh remove %i

Add script to filesystem that actually mounts the usb drive:

#!/bin/bash

# First parameter indicates to add or remove drive.
# last parameter indicates the device name.

WATCHDIR="/tmp/swuwatchdir"
mkdir -p ${WATCHDIR}

usage()
{
    echo "Usage: $0 {add|remove} device_name (e.g. sdb1)"
    exit 1
}

function do_mount()
{
    check_mount_state

    # Get formatting of the drive. TYPE
    # "blkid -o udev" option does not work for busybox version of blkid.
    eval $(/sbin/blkid ${DEVICE} | tr " " "\n" | tail -n 1)

    echo "Mounting ${DEVICE} of type ${TYPE} to ${MOUNTPOINT}"

    /bin/mkdir -p ${MOUNTPOINT}

    # Global mount options
    OPTS="rw,relatime,sync"

    # File system type specific mount options
    if [[ ${TYPE} == "vfat" ]]; then
        OPTS+=",users,gid=100,umask=000,shortname=mixed,utf8=1,flush"
    fi

    if ! /bin/mount -o ${OPTS} ${DEVICE} ${MOUNTPOINT}; then
        echo "Error mounting ${DEVICE} (status = $?)"
        /bin/rmdir ${MOUNTPOINT}
        exit 1
    fi

    # Place dummy file in MOUNTPOINT/../mountWatch to not
    # have to watch the entire user directory.
    touch ${WATCHDIR}/asdf
    echo "**** Mounted ${DEVICE} at ${MOUNTPOINT} ****"
}

function do_unmount()
{
    if [[ ! -d ${MOUNTPOINT} ]]; then
        echo "Warning: ${DEVICE} is not mounted"
    else
        /bin/umount -l ${DEVICE}
        echo "**** Unmounted ${DEVICE}"
    fi


    rm ${WATCHDIR}/asdf
    /bin/rmdir ${MOUNTPOINT}
}

function check_mount_state() {
    # See if this drive is already mounted, and if so where
    MOUNTED_TO=$(/bin/mount | /bin/grep ${DEVICE} | /usr/bin/awk '{ print $3 }')
    if [[ -n ${MOUNTED_TO} ]]; then
        echo "Warning: ${DEVICE} is already mounted at ${MOUNTED_TO}"
        echo "We only expect one USB drive to be inserted at a time."
        exit 1
    fi
}

function main() {

    if [[ $# -ne 2 ]]; then
        usage
    fi

    ACTION=$1
    DEVBASE=$2
    DEVICE="/dev/${DEVBASE}"

    # Var MOUNTPOINT should be set by the systemd script. Check it.
    if [[ -z ${MOUNTPOINT} ]]; then
        echo "MOUNTPOINT is not set by systemd script."
        exit 1
    fi

    case "${ACTION}" in
        add)
            do_mount
            ;;
        remove)
            do_unmount
            ;;
        *)
            usage
            ;;
    esac
}

main $@

Based on: https://serverfault.com/questions/766506/automount-usb-drives-with-systemd

Mount docker volume as same user as on host machine

docker containers often run as the root user (uid = 0, guid = 0). Files that the users generates are therefore also owned by the root user.

By creating an extra user on the docker system, and giving that user the same uid and guid as the user on you host system you will be able to modify your files without the need to be root on you host machine.

The following assumes you created an additional user in your docker container, and that it got 1000 for uid and guid.

#!/bin/bash

# Mr. R
# 06-2020

args=$@
cmd="builder.sh ${args}"

# current working directory is a volume mount to something on the host system.
# Therefore stat -c will provide the uid and gid of the host user.
# setting this uid and gid for the container user results in files written to the
# volume as host user.
usr=`id -nu 1000`
grp=`id -ng 1000`
groupmod -g $(stat -c "%g" .) $grp
usermod -u $(stat -c "%u" .) -g $(stat -c "%g" .) $usr

# Force all volume mounts to be of the appuser!
chown -R ${usr}:${grp} ${WORKDIR}

# If nothing given, start a shell, else run the builder script with arguments.
if [ "x${args}x" == "xx" ]; then
  cmd="/bin/bash"
fi

su -m -c "PATH=${PATH}; ${cmd}" ${usr}

How to check if path is a mountpoint in C

For an application in C I wanted to know if a provided path is a mountpoint, so that a drive is mounted at that path.

With the help of the mtab file, which include all the mounts, we can iterate over that list and see if provided path is actually a mount point.
See ‘cat /etc/mtab’ to see the content of this file.

#include <mntent.h>
#include <stdio.h>
#include <string.h>

static bool path_is_mountpoint( CHAR* path )
{
  // Return if path is mountpoint (true), or not (false)
  BOOLEAN mounted = false;

  // Open mtab file.
  FILE * mtab = setmntent ("/etc/mtab", "r");
  struct mntent* mountpoint = nullptr;

  // Return directly if we could not open the file.
  if ( mtab == nullptr) return mounted;

  // Iterate over each entry in mtab list, and check if path is present
  while ( ( mountpoint = getmntent(mtab) ) != nullptr) {
    if ( (mountpoint->mnt_fsname != nullptr ) &&
         (strcmp(mountpoint->mnt_fsname, path ) == 0) )
    {
      // We found path in mtab, so path is mountpoint.
      // Stop iterating.
      mounted = true;
      break;
    }
  }

  endmntent (mtab);

  printf("path: %s, Is mountpoint: %d", path, mounted);

  return mounted;
}

© 2025 Roholt

Thema door Anders NorénOmhoog ↑