IgnorantGuru's Blog

Linux software, news, and tips

devmon Update

devmon 0.8.1 is available. This update adds one feature and includes some very minor housekeeping:

  • added ––unmount-on-exit option which causes devmon to automatically unmount all removable drives on exit. This helps prevent vacant directories being left behind in /media when you reboot, for example.
  • if you try to run devmon as root, it will exit with an error
  • adjusted start udisks daemon trigger and timing to make it more universally functional (on systems without a CD drive, for example)
  • added trap to ignore SIGHUP signal (if you close the terminal you started devmon in, it should now keep running in the background)
  • the use and installation instructions have been updated

January 29, 2011 Posted by | Scripts | 3 Comments

devmon Rewritten

The devmon script introduced below has been rewritten. The new version should work without modification and adds some new features. And my thanks to Bernard Baeyens for some nice bash 4 code borrowed from his udisksvm script.

devmon is a configuration-less bash wrapper script for udisks which automounts optical discs and removable drives. It can also selectively autostart apps or execute commands after mounting, ignore specified devices and volume labels, and unmount removable drives.

udisks has the advantage that it works directly through udev and policykit, requires no configuration or udev/rules.d changes, and does not require HAL. You simply install udisks using your package manager, then run devmon to enable auto-mounting. udisks allows you to mount and unmount drives as a normal user.

The aim for this version of devmon was to make it a simple yet flexible automounting solution. Here are some possible ways you can use it:

Automounter
With a single command added to your startup script, you have automounting – when CD/DVDs or removable drives are inserted they are immediately mounted to /media. It can also unmount all removable drives with one command so they are safe to remove.

Autostarter
By adding a few options on the command line, devmon becomes an autostarter which can start apps based on the media type, or run other commands you specify. For example, when you insert a DVD video, it can play automatically.

Custom Uses
Using only command-line options, devmon gives you almost complete control over what happens when devices are added. You can run custom scripts or commands, or inhibit automounting to handle that yourself as well. devmon takes care of the device events, allowing you to design a custom automounting solution.

If you encounter any problems, please let me know so I can try to address them – thanks.

devmon Instructions

January 27, 2011 Posted by | Scripts | Comments Off on devmon Rewritten

A Custom udisks Automounter

UPDATE: Please see the new version of this script. The information below is outdated.

Below is my initial attempt to write my own auto-mounting script for DVD and removable drives using udisks. On Arch Linux with Openbox, there is no auto-mounting by default so you have to setup your own. I’ve used autofs for awhile, but it is unreliable (ignores some devices entirely, and with other devices sometimes it works, sometimes not). I see some things like udiskie, but why load python just for that? So I thought I would explore what udisks can do.

udisks seems to have some relationship to udev and policykit – it is a replacement for HAL. It includes a command-line tool that easily lets normal users monitor, mount, and unmount devices. It seems pretty trouble free thus far – when you use the command-line tool, the daemon automatically starts, so there is no configuration or udev/rules.d involved. Just install udisks from your package manager.

To monitor changes to drives:

udisks --monitor

Monitoring activity from the disks daemon. Press Ctrl+C to cancel.
changed:     /org/freedesktop/UDisks/devices/sr0
job-changed: /org/freedesktop/UDisks/devices/sr0
changed:     /org/freedesktop/UDisks/devices/sr0

Anytime drives are added, removed, or a DVD is inserted, the change will be shown.

To get info on a drive (is it mounted, is it mountable, etc):

udisks --show-info /dev/sr0

To mount a drive (my DVD drive in this example):

udisks --mount /dev/sr0

To unmount a drive:

udisks --unmount /dev/sr0

This gave me all I needed to build my own custom auto-mounter in bash. One advantage to doing it this way is that I can directly make it do whatever I want when changes are detected. I decided that I wanted it to mount DVDs and USB devices instantly, without prompt, and open the drive in a tab in my file manager.

First, I would start a monitor and send the output to a file:

udisks --monitor > /tmp/udisks-monitor.log

Leaving that running, I can then watch for any changes to that file using inotifywait (requires installation of inotifytools):

inotifywait /tmp/udisks-monitor.log

That will quit when the file changes (passing execution to the rest of the script). The script can then read /tmp/udisks-monitor.log to see what drive changed, check the ––show-info for that drive, and take suitable actions.

This devmon script is what I came up with:
UPDATE: Please see the new version of this script. The information below is outdated.

#!/bin/bash

# REQUIRES: udisks inotifytools zenity

monfile=/tmp/udisks-monitor.log
devmon="$0" # pathname of this script
devmonname="$(basename "$devmon")"  # name of this script

startmon()
{
	test=`ps -Af | grep -v grep | grep "$devmonname --monitor"`
	if [ "$test" = "" ]; then
		echo "startmon"
		$devmon --monitor &
	fi
}

killmon()
{
	monpid=`ps -eo pid,cmd | grep -v grep | grep -m 1 "$devmonname --monitor" \
	        | sed 's/\([0-9 ]*\).*/\1/'`
	if [ "$monpid" != "" ]; then
		echo "killmon"
		pkill -P $monpid # kill udisks owned
		kill $monpid
	fi
}

mountdrive()  # $1=drive
{
	# mount drive $1
	echo "devmon mount $1"
	test=`udisks --mount $1 --mount-options noexec,nosuid | \
	      sed 's/^Mounted .* at \(.*\)/\1/'`
	err="$?"
	if [ "$err" = "0" ] && [ "$test" != "" ]; then
		# open file manager at new drive
		pcmanfm-mod -t "$test" &
	fi
}

case "$1" in
	"--watch" )
		# watch udisks log for changes
		sleep 1
		startmon
		sleep 1
		while [ 1 ]; do
			# check udisks log for change
			test=`stat -c %Y "$monfile"`
			if [ "$test" != "" ]; then
				if [ "$test" != "$timedisk" ]; then
					timedisk="$test"
					echo "udisks-monitor $(date +%H:%M:%S)"
					test=`ps -Af | grep -v grep | grep "$devmonname --change"`
					if [ "$test" = "" ]; then
						echo "devmon --change"
						$devmon --change &
					fi
				fi
			else
				echo "missing monfile - restart"
				killmon
				sleep 1
				killmon
				sleep 1
				startmon
				sleep 1
			fi
			# wait for change to $monfile
			inotifywait -t 300 -q -e modify -e moved_to -e create \
								  -e delete $monfile
		done
		;;
	"--start" )
		# start udisks monitoring of drives
		sleep 1
		startmon
		exit
		;;
	"--stop" )
		# stop udisks monitoring of drives
		killmon
		sleep 1
		killmon
		sleep 1
		rm -f "$monfile"
		exit
		;;
	"--restart" )
		# restart udisks monitoring of drives
		echo "devmon restart"
		killmon
		sleep 1
		killmon
		sleep 1
		rm -f "$monfile"
		sleep 2
		startmon
		exit
		;;
	"--monitor" )
		# call udisks	
		udisks --monitor > $monfile   # stays running
		exit
		;;
	"--change" )
		# run when changed is detected
		startmon
		sleep .3
		# $monfile recently change?
		test=`find $monfile -cmin -1`
		if [ "$test" != "" ]; then
			l=`tail -n 1 $monfile`
			if [ "$l" = "changed:     /org/freedesktop/UDisks/devices/sr0" ]; then
				# DVD
				test=`udisks --show-info /dev/sr0 | grep -c \
				      -e "^  optical disc:" \
					  -e "    blank:                     0" \
					  -e "  usage:                       filesystem" \
					  -e "  is mounted:                  0"`
				if [ "$test" = "4" ]; then
					mountdrive /dev/sr0
				fi
			elif [ "${l:0:6}" = "added:" ]; then
				# USB?
				drive=${l##*/}
				if [ "${drive:0:3}" = "sdd" ] || [ "${drive:0:3}" = "sde" ] \
				   || [ "${drive:0:3}" = "sdf" ]; then
					if [ "${#drive}" = "3" ]; then
						# select first partition?
						test=`cat /proc/partitions | grep " ${drive}1$"`
						if [ "$test" != "" ]; then
							drive="${drive}1"
						fi
					fi
					test=`udisks --show-info /dev/$drive | grep -c \
					      -e "  is mounted:                  0" \
						  -e "  usage:                       filesystem" \
						  -e "  has media:                   1"`
					if [ "$test" = "3" ]; then
						mountdrive /dev/$drive
					fi
				fi
			else
				# need to restart mon to limit log file size?
				test=`find $monfile -cmin +300`  # older than 5 hours?
				if [ "$test" != "" ]; then
					echo "devmon monitor restart - older than 5 hours"
					killmon
					sleep 1
					rm -f "$monfile"
					sleep 2
					startmon
				fi
			fi
		fi
		exit
		;;
	"--unmount" )
		# unmount all removables
		alldrives="sdd1 sde1 sdf1 sdd sde sdf"
		drives=""
		for drive in $alldrives; do
			test=`mount | grep "^/dev/$drive "`
			if [ "$test" != "" ]; then
				drives="$drives $drive"
			fi
		done
		if [ "$drives" = "" ]; then
			msg="No removable drives mounted"
		else
			msg="Unmounting$drives..."
		fi
		zenity --info --title="Unmount" --text="$msg" &
		zpid=$!
		sync
		for drive in $alldrives; do
			test=`mount | grep "^/dev/$drive "`
			if [ "$test" != "" ]; then
				udisks --unmount /dev/$drive
			fi
		done
		sync
		sleep 2
		kill $zpid
		exit
		;;
esac

exit

A few important things to notice about this script:

  • It requires: udisks inotifytools zenity
  • It is hard-coded for /dev/sr0 and my removable drives start at /dev/sdd. It looks for changes to sr0, sdd, sde, and sdf only. (This can easily be changed in two places – the $alldrives line and the “if [ ${drive:0:3} = sdd ]” line.
  • It uses pcmanfm-mod as the file manager to open on a new mount – this can easily be changed

This script is daemon, monitor, and client all in one, depending on how you run it.

To start things off:

devmon --watch

That will do several things. It will start a process “devmon ––monitor”, which will in turn start “udisks ––monitor > /tmp/udisks-monitor.log”, both of which will keep running in the background.

It will then start “inotifywait /tmp/udisks-monitor.log”, which will watch for changes to that file (and thus detect drive changes such as CD and USB insertions). When a change to that file is detected, it will run “devmon ––change” to process the change. One item to note is that the script tries to insure that only one instance of ––monitor is running, and only one instance of ––change is running at any given time.

To process the change, the script will first make sure the monitor file /tmp/udisks-monitor.log has changed in the last minute (to make sure its fresh). If so, it will use tail to read the last line of that file. It uses that line to determine what drive changed, and then calls “udisks ––show-info” to find the status of the drive. If the drive has filesystem content and is unmounted, it will mount the drive and then open the file manager.

By default, udisks mounts drives to /media using /media/cd for the DVD drive and a name based on the volume label for USB drives. I don’t know how to change this behavior, but it works well enough for me thus far as is.

The script can also unmount all USB drives – I associate this with a shortcut key:

devmon --unmount

One thing to note about udisks: The way it mounts/unmount, when you press the eject button on the DVD drive, the disk will come out regardless of what’s going on. If you happen to be copying a file from the disc, it won’t stop it. I actually like it like this. In the case of USB drives, which aren’t read-only, I use my unmount shortcut key to sync and unmount them before unplugging.

To stop the watch process, in another console issue:

devmon --stop

which stops the ––monitor daemon and its udisks monitor child process. Then stop the ––watch process. This insures that you don’t leave the udisks monitor running. You can also use:

killall devmon devmon.sh udisks

Also note that this script contains ––start ––stop and ––restart options. However, these are only useful if you have another script doing the watching and running “devmon ––change”, as I have on my system (I have a custom daemon that watches a bunch of things on the system and takes various actions, so I use this instead of “devmon ––watch”). Otherwise you won’t need these options.

So far this script is working like a charm – much more reliable than autofs and I like having direct control over what happens. The only problem I have thus far is that sometimes pcmanfm-mod won’t start if its not already running – I’m not sure why that is but I’ll update this if I figure it out. It’s probably an expired environment variable.

You can find more info on udisks in the Arch Wiki, including other wrappers such as udiskie (which I didn’t try).

January 26, 2011 Posted by | Scripts, Tips | 2 Comments

Script Installation Instructions Updated

This site’s Script Installation Instructions have been rewritten to simplify the process. /usr/local/bin is now the recommended install directory and installation is done using the ‘install’ program, rather than the older installscript which installed to /opt/scripts/

If you were used to using installscript, the new method works similarly except that you’ll need to manually install the script’s dependencies with your package manager.

If you still want to use or setup /opt/scripts or another custom scripts folder, those instructions are still available on the Script Installation Instructions page.

If you have scripts installed to /opt/scripts and prefer the new location, just move the files to /usr/local/bin This location has the advantage that it is already in the PATH variables for normal users and root, including when sudo is used.

January 23, 2011 Posted by | Tips | Comments Off on Script Installation Instructions Updated

Xtract Passwordless ISO Mounts

Xtract has been updated with mountiso support. This means that if mountiso is available, Xtract can now extract or list the contents of ISO files without prompting for a password.

January 23, 2011 Posted by | Scripts | Comments Off on Xtract Passwordless ISO Mounts

How To Read PCManFM-Mod’s Stats Line

PCManFM-Mod 1.2.0 includes a new Stats line in the copy dialog…

It’s hard to keep everyone happy on something like this – uncluttered vs detailed. People copying over a network or to/from USB devices usually appreciate more info on real-time and average speeds, whereas copying on a local PC rarely requires it. If all you want to know is the time remaining, the time to the far right is all you need to pay attention to, or even just watch the progress bar.

You can interpret the Stats line in the example above as follows:
#1/1
the current item being copied out of the total number of items to copy
(350.7 MB / 700.0 MB)
350 out of a total of 700 MB has been copied so far
[:06]
elapsed time – this is just a clock showing the total copy time thus far
@cur 42.3 MB/s
the current copy speed (based on the most recent two-second interval)
(:08)
estimated time remaining based on the current speed
@avg 58.5 MB/s
the average copy speed thus far
(:05)
estimated time remaining based on the average speed – this is usually the most reliable

January 23, 2011 Posted by | Mods | 1 Comment

HOW TO: Allow Mounting Of ISO Files By A Regular User

The following HOW-TO describes a method to allow mounting of ISO files by a regular (non-root) user, something normally lacking in Linux. This method, including setup, has also been automated in the new mountiso script. Also note that bic and Xtract have been updated to make use of mountiso if installed.

Setting Up The System

Edit your /etc/fstab file and add these lines:

/tmp/mountiso-image.iso /mnt/iso auto ro,loop=/dev/loop7,user,noexec,noauto 0 0
/dev/loop7 /mnt/iso auto user,noexec,noauto 0 0

2) Issue these commands to ensure you have seven loop devices and a mount point:

sudo mknod -m660 /dev/loop0 b 7 0
sudo mknod -m660 /dev/loop1 b 7 1
sudo mknod -m660 /dev/loop2 b 7 2
sudo mknod -m660 /dev/loop3 b 7 3
sudo mknod -m660 /dev/loop4 b 7 4
sudo mknod -m660 /dev/loop5 b 7 5
sudo mknod -m660 /dev/loop6 b 7 6
sudo mknod -m660 /dev/loop7 b 7 7
sudo chown root:disk /dev/loop*
sudo mkdir /mnt/iso

Note that you can use any loop device and any mount point you prefer. In this example /dev/loop7 and /mnt/iso are used. A higher loop device is used so that it won’t be in use by the system for other purposes.

Mounting And Unmounting

Once the above changes are saved, the file “/tmp/mountiso-image.iso” can be mounted and unmounted by a normal user. This file can also be a link to any ISO file you choose.

For example, to mount /home/user/example.iso (all commands issued as a normal user):

# First create link:
ln -s /home/user/example.iso /tmp/mountiso-image.iso

# Then mount it:
mount /tmp/mountiso-image.iso

# Then you can delete the link immediately:
rm /tmp/mountiso-image.iso

# You can now browse the contents of the ISO:
ls /mnt/iso

# To unmount:
umount /mnt/iso

Note that when unmounting you may receive the error message:
loop: can’t delete device /dev/loop7: No such device or address

This error may be ignored – the unmount will be successful and will return a zero error code.

January 22, 2011 Posted by | Scripts, Tips | 5 Comments

PCManFM-Mod Update

PCManFM-Mod 1.2.0 is available. This update includes the following changes and additions:

  • The Copy/Move progress dialog now displays file count, size, transfer speeds, and time remaining
  • Nautilus-style .hidden files are now supported. Any filenames listed in a text file named “.hidden” will not be displayed. List one file per line (file name only, excluding path). Each folder may have a “.hidden” file which determines display of files in that folder. The total hidden count is shown in the status bar. The View|Show Hidden Files setting has no effect on this method.
  • The View|Refresh function has been improved yet again to really re-read the directory
  • The status bar text has been streamlined
  • A bug in the original 0.5.2 which caused some Find Files results to not be displayed has been corrected
  • A bug in the original 0.5.2 which caused the Find Files ‘Search in Sub Directories’ checkbox to be ignored has been corrected
  • A bug in the original 0.5.2 which sometimes produced an erroneous “Invalid cross-device link” error has been corrected

January 13, 2011 Posted by | Mods | 4 Comments

Bic Updated

Bic has been updated. The ––size option is a bit smarter (notices changes to the folder even while calculating sums, and will ignore write-open files until they’re closed). Also, a ––sizeonly option has been added which just monitors the size without calculating any sums.

A ––burn option has been added to auto-detect the media type.

A ––dvddl option has been added for burning to DVD Dual Layer discs. This is the same as a normal DVD burn except that it allows a different burn speed to be set in the user options.

Also, -iso-level 3 has been set for growisofs to accomodate files larger than 4GB.

January 11, 2011 Posted by | Scripts | Comments Off on Bic Updated

Sandfox 1.0.6

Sandfox has been updated. The default firefox profile now includes a bind for the ~/.Xauthority file, which is required to start a sandboxed Firefox in some cases. If you already have sandfox installed, you can delete the file /etc/sandfox/firefox.profile and sandfox will recreate it with the new default.

This version also issues a warning if you run a sandboxed firefox with an instance of firefox already running. (In general other instances should be closed before running sandfox, or firefox may simply open an additional window for the already running instance, rather than starting a sandboxed instance.)

January 11, 2011 Posted by | Scripts | Comments Off on Sandfox 1.0.6