[SCRIPT] Unmount external devices from command line

Questions about SNMP, Power, System, Logs, disk, & RAID.
Locked
virtualdj
Experience counts
Posts: 2141
Joined: Wed May 26, 2010 2:44 am

[SCRIPT] Unmount external devices from command line

Post by virtualdj »

Hi, I don't know if someone has already done this, but as I use this script often, I thought it would be useful to share with others.
I regularly copy some files using rsync to USB Flash Drives and eSATA HDDs and don't want to use the web interface to unmount the drive when the copy is finished, so I run the script attached to this post.

Simply copy the attached file to the Public share, and then move it on a directory on your PATH, e.g. /opt/bin in this way:

Code: Select all

[~] # cd /share/Public
[/share/Public] # tar zxf uumount.tar.gz -C /opt/bin/
and the script is installed.

To use it and unmount a device, simply type:

Code: Select all

[~] # uumount
Select the drive to unmount:
1) eSATADisk1
Drive to unmount (or 'q' to quit)?
and a textual menu will appear.
Alternatively, you can unmount a device directly, for example:

Code: Select all

[~] # uumount USBDisk1
USE IT AT YOUR OWN RISK

Code: Select all

#!/bin/sh

# Unmount a folder (e.g. 'USBDisk1')
function unmount_folder() {
	if [ -d "/share/$1" ]; then
		# Remove Samba share
		/sbin/smbtools -k $1

		# Unmount the drive
		/bin/umount /share/$1

		# Remove the shared folder
		/bin/rm /share/$1

		# Remove the Samba configuration
		/sbin/rmcfg $1 -f /etc/smb.conf

		# Success
		/bin/echo "Successfully unmounted '/share/$1'."
	else
		# Error during unmounting
		/bin/echo "Unable to find '/share/$1' share." >&2
		exit 1
	fi
}

# Unmount a USB/eSata disk
if [ ! -z "$1" ]; then
	# Unmount the share specified
	unmount_folder $1	
else
	# Display menu, if necessary
	# Get mounted dirs
	mounted_dirs=()
	for dir in /share/USBDisk* /share/eSATADisk*
	do
		if [ -d "$dir" ]; then
			mounted_dirs+=("${dir##*/}")
		fi
	done

	# Check if there are mounted dirs
	if [ ${#mounted_dirs[@]} -gt 0 ]; then
		# Display menu
		/bin/echo "Select the drive to unmount:"	

		# Set the prompt
		PS3="Drive to unmount (or 'q' to quit)? "

		# Show the menu
		select drive in "${mounted_dirs[@]}"
		do
			if [ ! -z "$drive" ]; then
				unmount_folder $drive
			fi
			break
		done
	else
		# No mounted drives
		/bin/echo "No mounted drives to unmount." >&2
	fi
fi
You do not have the required permissions to view the files attached to this post.
Last edited by virtualdj on Mon Feb 25, 2013 1:36 am, edited 1 time in total.
User avatar
pwilson
Guru
Posts: 22533
Joined: Fri Mar 06, 2009 11:20 am
Location: Victoria, BC, Canada (UTC-08:00)

Re: [SCRIPT] Unmount external devices from command line

Post by pwilson »

virtualdj wrote:USE IT AT YOUR OWN RISK

Code: Select all

#!/bin/sh

# Unmount a folder (e.g. 'USBDisk1')
function unmount_folder() {
	if [ -d "/share/$1" ]; then
		# Remove Samba share
		/sbin/smbtools -k $1

		# Unmount the drive
		/bin/umount /share/$1

		# Remove the shared folder
		/bin/rm /share/$1

		# Remove the Samba configuration
		/sbin/rmcfg $1 -f /etc/smb.conf

		# Success
		/bin/echo "Successfully unmounted '/share/$1'."
	else
		# Error during unmounting
		/bin/echo "Unable to find '/share/$1' share." >&2
		exit 1
	fi
}

# Unmount a USB/eSata disk
if [ ! -z "$1" ]; then
	# Unmount the share specified
	unmount_folder $1	
else
	# Display menu, if necessary
	# Get mounted dirs
	mounted_dirs=()
	for dir in /share/USBDisk* /share/eSATADisk*
	do
		if [ -d "$dir" ]; then
			mounted_dirs+=("${dir##*/}")
		fi
	done

	# Check if there are mounted dirs
	if [ ${#mounted_dirs[@]} -gt 0 ]; then
		# Display menu
		/bin/echo "Select the drive to unmount:"	

		# Set the prompt
		PS3="Drive to unmount (or 'q' to quit)? "

		# Show the menu
		select drive in "${mounted_dirs[@]}"
		do
			if [ ! -z "$drive" ]; then
				unmount_folder $drive
			fi
			break
		done
	else
		# No mounted drives
		/bin/echo "No mounted drives to unmount." >&2
	fi
fi
Your script is quite elegant. It is a shame you chose to post it as a download, rather than providing it inside a BBCode code segment, so that it can be discussed easily. I've been running Linux for over 20 years, and I learned something. Thank-you for sharing your efforts with the QNAP NAS Community.

Patrick M. Wilson
Victoria, BC Canada
QNAP TS-470 Pro w/ 4 * Western Digital WD30EFRX WD Reds (RAID5) - - Single 8.1TB Storage Pool FW: QTS 4.2.0 Build 20151023 - Kali Linux v1.06 (64bit)
Forums: View My Profile - Search My Posts - View My Photo - View My Location - Top Community Posters
QNAP: Turbo NAS User Manual - QNAP Wiki - QNAP Tutorials - QNAP FAQs

Please review: When you're asking a question, please include the following.
virtualdj
Experience counts
Posts: 2141
Joined: Wed May 26, 2010 2:44 am

Re: [SCRIPT] Unmount external devices from command line

Post by virtualdj »

Thanks Patrick,
actually I've posted it as a download because it's easier for "non-putty-guys" to copy it in the QNAP and also (I have to admit it... :D) for the download counter (I wanted to see how many user had the same issue to solve). Anyway I've edited the post to provide both flavours.

However, I still have to fix some "quircks":
  1. With eSATA, the QNAP Web UI still thinks that the disk is there, although it marks it as "unmounted" (in red)
  2. When connecting a disk with multiple partitions, each one is mounted on a different folder (e.g. eSATADisk1, eSATADisk2, etc.) and you cannot know how to unmount the disk "as a whole". However it's the same with the web UI so it might not be a problem.
User avatar
pwilson
Guru
Posts: 22533
Joined: Fri Mar 06, 2009 11:20 am
Location: Victoria, BC, Canada (UTC-08:00)

Re: [SCRIPT] Unmount external devices from command line

Post by pwilson »

virtualdj wrote:Simply copy the attached file to the Public share, and then move it on a directory on your PATH, e.g. /opt/bin in this way:

Code: Select all

[~] # cd /share/Public
[/share/Public] # tar zxf uumount.tar.gz -C /opt/bin/
and the script is installed.
Alternate installation instructions:

Code: Select all

cd /share/Public
wget http://forum.qnap.com/download/file.php?id=8372 -O uumount.tar.gz
tar zxf uumount.tar.gz -C /opt/bin/
rm uumount.tar.gz

Patrick M. Wilson
Victoria, BC Canada
QNAP TS-470 Pro w/ 4 * Western Digital WD30EFRX WD Reds (RAID5) - - Single 8.1TB Storage Pool FW: QTS 4.2.0 Build 20151023 - Kali Linux v1.06 (64bit)
Forums: View My Profile - Search My Posts - View My Photo - View My Location - Top Community Posters
QNAP: Turbo NAS User Manual - QNAP Wiki - QNAP Tutorials - QNAP FAQs

Please review: When you're asking a question, please include the following.
anj747
New here
Posts: 2
Joined: Fri Jan 06, 2012 3:56 am

Re: [SCRIPT] Unmount external devices from command line

Post by anj747 »

Thanks guys, very useful.

Would you be kind enough to post a mount script also (the reverse procedure?)

Thanks again - Anj
virtualdj
Experience counts
Posts: 2141
Joined: Wed May 26, 2010 2:44 am

Re: [SCRIPT] Unmount external devices from command line

Post by virtualdj »

anj747 wrote:Would you be kind enough to post a mount script also (the reverse procedure?)
Sorry, can you better explain what you want to do?
Isn't the NAS automatically mounting the USB devices? :?
anj747
New here
Posts: 2
Joined: Fri Jan 06, 2012 3:56 am

Re: [SCRIPT] Unmount external devices from command line

Post by anj747 »

Thanks for the reply. Essentially I have a USB drive attached to my QNAP TS-119P which I use for weekly backups.

Right now, it is on 24 hrs a day. I'd essentially like to have the USB drive switched off when it's not in use (does the script above also cause the USB drive to power down?).

This means, I wanted to create a cron job which powered up and mounted the USB drive just prior to the backup job - and then unmount it/power it down straight after.

Any help would be much appreciated. Thanks.
huge_cow2
New here
Posts: 4
Joined: Fri Nov 16, 2012 3:35 am

Re: [SCRIPT] Unmount external devices from command line

Post by huge_cow2 »

Great script! Thanks for sharing.

How can I mount the external HDD again?
virtualdj
Experience counts
Posts: 2141
Joined: Wed May 26, 2010 2:44 am

Re: [SCRIPT] Unmount external devices from command line

Post by virtualdj »

I think there are no possibilities other than re-attaching the device phisically to the USB port.
huge_cow2
New here
Posts: 4
Joined: Fri Nov 16, 2012 3:35 am

Re: [SCRIPT] Unmount external devices from command line

Post by huge_cow2 »

virtualdj wrote:I think there are no possibilities other than re-attaching the device phisically to the USB port.
That makes sense but worth I try a guess. I never know what kind of tricks these linux gurus have in store.

Thanks for the info!
micattack
Starting out
Posts: 14
Joined: Sat Mar 06, 2021 12:25 am

Re: [SCRIPT] Unmount external devices from command line

Post by micattack »

Any chance on updating this script for 2021? I have a TS-351 with FW 4.5.3 and somewhere in the last 8 years the /share/USBDisk* /share/eSATADisk* directories do not exist anymore.
My drive shows up as /share/external/DEV3301_1/ and a share with the Volumes name at /share/My\ Book is also created (this is also the name of the automatic samba share)

So your script doesn't work as expected anymore. Or is there a Qnap ssh cli command that can do this now?

I want to add this in my own backup script to eject the external USB drive once my backup has finished
--
QLocker survivor; backup enthusiast
TS-351 with 5. + something FW (always up2date)
Celeron J1800/8GB RAM
RAID-5 (2x 256GB Transcent TS256GMTE110S + 3x 6TB Seagate ST6000VN001)
virtualdj
Experience counts
Posts: 2141
Joined: Wed May 26, 2010 2:44 am

Re: [SCRIPT] Unmount external devices from command line

Post by virtualdj »

micattack wrote: Sun May 09, 2021 5:37 pm My drive shows up as /share/external/DEV3301_1/ and a share with the Volumes name at /share/My\ Book is also created (this is also the name of the automatic samba share)

So your script doesn't work as expected anymore.
I tried to take a look... we can extract the share name and paths from /etc/smb.conf using AWK, like so:

Code: Select all

[~] # awk '/^\[/ { section = $0; gsub(/\[|\]/, "", section); next; } /path\s?=\s?.+external/ { print section "|" substr($0,index($0,"/")); }' /etc/smb.conf
The problem is how to unmount them. It seems that simpy doing:

Code: Select all

[~] # umount /share/external/path
is not enough, as the device remains displayed on the web UI.
micattack wrote: Sun May 09, 2021 5:37 pm Or is there a Qnap ssh cli command that can do this now?
I wish to know that! Looking at the web interface, when disconnecting it posts a XML content to this CGI:

Code: Select all

/home/httpd/cgi-bin/disk/disk_manage.cgi
which is not a script but an ELF executable. The two commands are:

Code: Select all

func=external_disk_disconnect&volumeID=6
to disconnect a volume and:

Code: Select all

func=external_get_all
to probably list them.

But you must authenticate, so it's not easy even with curl. I wish I could "decompile" the ELF in a way to know what functions it calls.
Help needed! :(
virtualdj
Experience counts
Posts: 2141
Joined: Wed May 26, 2010 2:44 am

Re: [SCRIPT] Unmount external devices from command line

Post by virtualdj »

virtualdj
Experience counts
Posts: 2141
Joined: Wed May 26, 2010 2:44 am

Re: [SCRIPT] Unmount external devices from command line

Post by virtualdj »

OK, seems to work if we edit the script linked above (the first one).
If the curl request is:

Code: Select all

func=external_get_all
we get some interesting XML:

Code: Select all

<Disk_Num>1</Disk_Num>
<Disk_Vol>
	<Device_ID>1</Device_ID>
	<Part_No>1</Part_No>
	<enclosureID>33</enclosureID>
	<Device_Type>1</Device_Type>
	<Disk_List>5:Dev1Partition1</Disk_List>
	<Disk_Selected>5</Disk_Selected>
	<Vol_Label><![CDATA[My_Disk_Label]]></Vol_Label>
	<Share_Folder><![CDATA[My_Disk_Label]]></Share_Folder>
	<Disk_Path>/dev/sde</Disk_Path>
	<Disk_Manufacture>General</Disk_Manufacture>
	<Disk_Model>UDisk</Disk_Model>
	<Disk_Type>USB 2.0</Disk_Type>
	<Disk_Size_Info>3.75 GB / 2.99 GB</Disk_Size_Info>
	<Disk_File_System>NTFS</Disk_File_System>
	<Disk_Status>IEI_DEVICE_MSG31</Disk_Status>
	<Disk_Format_Progress>(100%)</Disk_Format_Progress>
	<DISK_STOPPING>0</DISK_STOPPING>
	<Disk_Is_ODD>0</Disk_Is_ODD>
	<used_size>780.72 MB</used_size>
	<total_size>3.75 GB</total_size>
	<isEncrypted>0</isEncrypted>
	<Disk_Is_MTP>0</Disk_Is_MTP>
</Disk_Vol>
Then if we would like to eject this drive (look at the Vol_Label to identify it) we must extract the ID on Disk_Selected probably and finally issue a:

Code: Select all

func=external_disk_remove&volumeID=5
The function waits, ejects and returns a success (and the drive is actually ejected, most importantly!):

Code: Select all

<eject_msg>success</eject_msg>
<eject_disk_ret>0</eject_disk_ret>
<result>0</result>
So, in the end, it should be possible to rewrite the script and make it ask the webserver to provide information about the mounted external drives and eject them. The only drawback is the requirement to type/provide the administrator password.
Locked

Return to “System & Disk Volume Management”