Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Feb 2012 09:43:59 +0100
From:      vermaden <vermaden@interia.pl>
To:        freebsd-hackers@freebsd.org
Cc:        matt <sendtomatt@gmail.com>, gleb.kurtsou@gmail.com, freebsd-stable@freebsd.org, uffe@uffe.org, joe.culler@gmail.com, Hans Petter Selasky <hselasky@c2i.net>, freebsd-current@freebsd.org, lars.engels@0x20.net
Subject:   Re: devd based AUTOMOUNTER
Message-ID:  <dusvifyxcdqegubftcgz@lvhf>
In-Reply-To: <evbvqmovseenzzafkvdy@cufm>
References:  <hkubftdrahxmtuzcfqzh@ziad> <4F3EE186.4020801@gmail.com> <uhhupehcnrebtwjfedhg@xlkc> <201202181409.08859.hselasky@c2i.net> <evbvqmovseenzzafkvdy@cufm>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi,

new version with new features (and BUGs ;p)

Added check if ntfsfix from sysutils/ntfsprogs is available, if Yes then
try to fix the NTFS filesystem before mouting it.

Added GPL3 License ... just joking ;) ... added FreeBSD License to the file=
.

Added 'noatime' as a default mount option when possible.

Added TIMEOUT so when an 'orphan' STATE file lock remains, it will be delet=
ed after a TIMEOUT.

Added /usr/local/etc/devd/automount.devd file instead of messing with the b=
ase system config at /etc/devd.conf.

Added config file to be used from /usr/local/etc/automount.conf file, possi=
ble options are (these are defaults):
  MNTPREFIX=3D"/media"
  LOG=3D"/var/log/automount.log"
  STATE=3D"/var/run/automount.state"
  ENCODING=3D"en_US.ISO8859-1"
  CODEPAGE=3D"cp437"
  DATEFMT=3D"%Y-%m-%d %H:%M:%S"
  USERUMOUNT=3D"NO"

Mine config currently has only these:
  ENCODING=3D"pl_PL.ISO8859-2"
  CODEPAGE=3D"cp852"
  USERUMOUNT=3D"YES"

The USERMOUNT otions if set to YES (default to NO) will 'chmod +s /sbin/umo=
unt',
so You can click the ^ button on the devices list in NAUTILUS.

These newly mounted devices appear on NAUTILUS sidebar (only with /media pr=
efix).

But THUNAR and PCMANFM does not do that, You know any other FMs that displa=
y mounted thumb drives/devices?

EXAMPLE: http://i.imgur.com/qdKdl.png

First BUG: (not fixed yet, but workaround already is working)

TEST/BUG/CASE:
Plug in FAT32 and NTFS drives at the same time, when FAT32 device will be d=
etected first, it will get mounted and the NTFS drive will be mounted TWICE=
, so I added __check_already_mounted function to check if it is not already=
 mounted.



Below are current script and config files.

/usr/local/etc/devd/automount.devd
---------------------------------------------------------------------------=
----
notify 0 {
  match "system" "DEVFS";
	match "type" "CREATE";
	match "cdev" "(da|mmcsd)[0-9]+";
	action "/usr/local/sbin/automount.sh $cdev attach";
};

notify 0 {
	match "system" "DEVFS";
	match "type" "DESTROY";
	match "cdev" "(da|mmcsd)[0-9]+";
	action "/usr/local/sbin/automount.sh $cdev detach";
};
---------------------------------------------------------------------------=
----

/usr/local/etc/automout.conf (can be empty)
---------------------------------------------------------------------------=
----
MNTPREFIX=3D"/media"
LOG=3D"/var/log/automount.log"
STATE=3D"/var/run/automount.state"
ENCODING=3D"en_US.ISO8859-1"
CODEPAGE=3D"cp437"
DATEFMT=3D"%Y-%m-%d %H:%M:%S"
USERUMOUNT=3D"NO"
---------------------------------------------------------------------------=
----

/usr/local/sbin/automount.sh
---------------------------------------------------------------------------=
----
#! /bin/sh

# Copyright (c) 2011 Slawomir Wojciech Wojtczak (vermaden)
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are me=
t:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS 'AS IS' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR A=
NY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGE=
S
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVIC=
ES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED A=
ND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TOR=
T
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

PATH=3D/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

[ -f /usr/local/etc/automount.conf ] && . /usr/local/etc/automount.conf

: ${MNTPREFIX=3D"/media"}
: ${LOG=3D"/var/log/automount.log"}
: ${STATE=3D"/var/run/automount.state"}
: ${ENCODING=3D"en_US.ISO8859-1"}       # /* US/Canada */
: ${CODEPAGE=3D"cp437"}                 # /* US/Canada */
: ${DATEFMT=3D"%Y-%m-%d %H:%M:%S"}      # /* 2012-02-20 07:49:09 */
: ${USERUMOUNT=3D"NO"}                  # /* when YES add suid bit to umoun=
t(8) */

[ "${USERUMOUNT}" =3D "YES" ] && chmod u+s /sbin/umount # /* WHEEL group me=
mber */

__create_mount_point() { # /* 1=3DDEV */
  MNT=3D"${MNTPREFIX}/$( basename ${1} )"
  mkdir -p ${MNT}
  chown 1000 ${MNT}
}

__check_already_mounted() { # /* 1=3DMNT */
  mount | grep " ${1} " 1> /dev/null 2> /dev/null && {
    __log "${I}:already mounted (ntfs)"
    continue
  }
}

__state_lock() {
  TIMEOUT=3D60
  COUNT=3D0
  while [ -f ${STATE}.lock ]
  do
    sleep 0.5
    [ ${COUNT} -gt ${TIMEOUT} ] && break
    COUNT=3D$(( ${COUNT} + 1 ))
  done
  :> ${STATE}.lock
}

__state_unlock() {
  rm ${STATE}.lock
}

__state_add() { # /* 1=3DDEV 2=3DPROVIDER 3=3DMNT */
  __state_lock
  grep -E "${3}" ${STATE} 1> /dev/null 2> /dev/null && {
    __log "${1}:duplicated '${STATE}'"
    return 1
  }
  echo "${1} ${2} ${3}" >> ${STATE}
  __state_unlock
}

__state_remove() { # /* 1=3DMNT 2=3DSTATE 3=3DLINE */
  BSMNT=3D$( echo ${1} | sed 's/\//\\\//g' ) # /* backslash the slashes ;) =
*/
  sed -i '' "/${BSMNT}\$/d" ${2}
}

__log() { # /* @=3DMESSAGE */
  echo $( date +"${DATEFMT}" ) ${@} >> ${LOG}
}

case ${2} in
  (attach)
    for I in /dev/${1}*
    do
      case $( file -b -L -s ${I} | sed -E 's/label:\ \".*\"//g' ) in
        (*NTFS*)
          dd < ${I} count=3D1 2> /dev/null | strings | head -1 | grep -q "N=
TFS" && {
              __create_mount_point ${I}
              which ntfsfix 1> /dev/null 2> /dev/null && {
                ntfsfix ${I} # /* sysutils/ntfsprogs */
              }
              __check_already_mounted ${MNT}
              which ntfs-3g 1> /dev/null 2> /dev/null && {
                ntfs-3g -o noatime ${I} ${MNT} # /* sysutils/fusefs-ntfs */
              } || {
                mount_ntfs -o noatime ${I} ${MNT}
              }
              __log "${I}:mount (ntfs)"
          }
          ;;
        (*FAT*)
          dd < ${I} count=3D1 2> /dev/null | strings | grep -q "FAT32" && {
              __create_mount_point ${I}
              fsck_msdosfs -y ${I}
              __check_already_mounted ${MNT}
              mount_msdosfs -o large -L ${ENCODING} -D ${CODEPAGE} ${I} ${M=
NT}
              __log "${I}:mount (fat)"
          }
          ;;
        (*ext2*)
          __create_mount_point ${I}
          fsck.ext2 -y ${I}
          mount -t ext2fs -o noatime ${I} ${MNT}
          __check_already_mounted ${MNT}
          __log "${I}:mount (ext2)"
          ;;
        (*ext3*)
          __create_mount_point ${I}
          fsck.ext3 -y ${I}
          __check_already_mounted ${MNT}
          mount -t ext2fs -o noatime ${I} ${MNT}
          __log "${I}:mount (ext3)"
          ;;
        (*ext4*)
          __create_mount_point ${I}
          fsck.ext4 -y ${I}
          __check_already_mounted ${MNT}
          ext4fuse ${I} ${MNT} # /* sysutils/fusefs-ext4fuse */
          __log "${I}:mount (ext4)"
          ;;
        (*Unix\ Fast\ File*)
          __create_mount_point ${I}
          fsck_ufs -y ${I}
          __check_already_mounted ${MNT}
          mount -o noatime ${I} ${MNT}
          __log "${I}:mount (ufs)"
          ;;
        (*)
          case $( dd < ${I} count=3D1 2> /dev/null | strings | head -1 ) in
            (EXFAT)
              __create_mount_point ${I}
              __check_already_mounted ${MNT}
              mount.exfat -o noatime ${I} ${MNT} # /* sysutils/fusefs-exfat=
 */
              __log "${I}:mount (ufs)"
              ;;
            (*) continue ;;
          esac
          ;;
      esac
      __state_add ${I} $( mount | grep -m 1 " ${MNT} " | awk '{printf $1}' =
) ${MNT}
    done
    ;;

  (detach)
    MOUNT=3D$( mount )
    __state_lock
    grep ${1} ${STATE} \
      | while read DEV PROVIDER MNT
        do
          TARGET=3D$( echo "${MOUNT}" | grep -E "^${PROVIDER} " | awk '{pri=
nt $3}' )
          [ -z ${TARGET} ] && {
            __state_remove ${MNT} ${STATE} ${LINE}
            continue
          }
          umount -f ${TARGET} &
          unset TARGET
          __state_remove ${MNT} ${STATE} ${LINE}
          __log "${DEV}:umount"
        done
    __state_unlock
    __log "/dev/${1}:detach"
    find ${MNTPREFIX} -type d -empty -delete
    ;;

esac

---------------------------------------------------------------------------=
----



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?dusvifyxcdqegubftcgz>