Question

Okay, so I'm having to work within user quotas on a linux system, and need to be able to find out the device name (e.g - /dev/md2) for a given path so that I can lookup the correct quota for that path.

Now, I can get the mount point easily enough using:

df -k "/volume1/foo/bar" | tail -1 | awk '{ print $6 }'

However I'm not sure of the best way to then take that mount point and convert it into a device name?

To further complicate matters, the mount point that I get from the above command may in fact be an encrypted folder, in which case I may have something that looks like:

/dev/md2 -> /volume1
/volume1/@Foo@ -> /volume1/Foo

Meaning that the above df command will identify a mount point of /volume1/Foo. However, I need a reliable, platform independent way to work way my way through mount points and find the actual device name I need for use with quota.

Specifically; I can't just rely on the first part of the path being the mount point of the device, as I may be working with environments that mount volumes in more specific locations, such as OS X that puts mounts into /Volumes/ for example.

Was it helpful?

Solution

Okay, so I had a go and came up with the following solution; it's not desperately pretty, but mount and df should be available on most unix flavours, and this should return the correct device identifier by working through volumes until it can go no further. In most cases it should only require one or two iterations.

function get_device() {
    fs=$(df -k "$1" | tail -1)

    # Determine the device for the file-system
    device=
    mnt=$(echo "$fs" | awk '{ print $6 }')
    if [ "$cached_mnt" != "$mnt" ] 
        then
            cached_mnt="$mnt"

            mnts=$(mount)
            newmnt="$mnt"

            # Try to get a root mount point (for encrypted folders etc.)
            while [ -n "$newmnt" ] 
            do
                newmnt=$(echo "$mnts" | grep " on $mnt " | awk '{ print $1 }')
                [ "$newmnt" = "$mnt" ] && break

                if [ -n "$newmnt" ] 
                    then
                        device="$newmnt"
                        mnt=$(df "$newmnt" 2> /dev/null | tail -1 | awk '{print $6 }')

                        [ "$mnt" = "$device" -o "$mnt" = "$last" ] && break
                        last="$mnt"
                fi
            done

            cached_device="$device"
        else
            device="$cached_device"
    fi

    echo "$device"
}

Forgive any typos, as it's from a larger script. It uses very simple caching in case multiple device queries are made that resolve to the same disk/partition.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top