Project

General

Profile

Feature #827

Updated by Daniel Curtis over 7 years ago

Once in a while I will need to do a two-way synchronization of the contents of an owncloud sync folder to a specific USB drive, and having this task done automagically by systemd. 

 *NOTE*: The USB drive used in this guide is FAT32. If using NTFS, you must install the ntfs-3g-fuse package from the AUR. 

 * Make sure rsync is installed: 
 <pre> 
 sudo pacman -S rsync 
 </pre> 

 h2. Device Identification 

 * Get the list of drives: 
 <pre> 
 sudo fdisk -l 
 </pre> 

 * Start by getting the device label: 
 <pre> 
 sudo blkid /dev/sdb1 
 </pre> 

 * Create a label for the USB drive: 
 <pre> 
 sudo dosfslabel /dev/disk/by-uuid/ACE7-1996 "SYNCSHARE" 
 </pre> 

 * Make a temporary mount directory: 
 <pre> 
 sudo mkdir /media/SYNCSHARE 
 </pre> 

 * Edit the fstab file: 
 <pre> 
 sudo nano /etc/fstab 
 </pre> 
 #* Add an fstab entry for the SYNCSHARE device: 
 <pre> 
 UUID=ACE7-1996 	 /media/SYNCSHARE 	 vfat 	 users,noauto 	 0 0 
 </pre> 

 h2. Sync Script 

 * Create a simple two-way rsync script: 
 <pre> 
 sudo nano /usr/local/bin/syncshare.sh 
 </pre> 
 #* And add the following 
 <pre> 
 #!/bin/sh 
 # Script to do a two-way sync with a USB drive 

 if [ $(mount | grep -c /media/SYNCSHARE) != 1 ] 
 then 
   /sbin/mount /dev/disk/by-uuid/ACE7-1996 || exit 1 
   echo "/media/SYNCSHARE is now mounted" 

   rsync -rtuv --modify-window=1 --size-only --exclude ".csync*" --exclude ".owncloud*" --delete /home/bob/owncloudshare/ /media/SYNCSHARE/owncloudshare/ /home/bob/owncloudshare/ 
   rsync -rtuv --modify-window=1 --size-only --exclude ".csync*" --exclude ".owncloud*" --delete-delay /media/SYNCSHARE/owncloudshare/ /home/bob/owncloudshare/ /media/SYNCSHARE/owncloudshare/ 
  
   sync 

   sudo -u bob DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send "SYNCSHARE Finished Synchronizing!" 

   sleep 5 

   umount /media/SYNCSHARE 
 else 
   rsync -rtuv --modify-window=1 --size-only --exclude ".csync*" --exclude ".owncloud*" --delete /home/bob/owncloudshare/ /media/SYNCSHARE/owncloudshare/ /home/bob/owncloudshare/ 
   rsync -rtuv --modify-window=1 --size-only --exclude ".csync*" --exclude ".owncloud*" --delete-delay /media/SYNCSHARE/owncloudshare/ /home/bob/owncloudshare/ /media/SYNCSHARE/owncloudshare/ 
  
   sync 

   sudo -u bob DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send "SYNCSHARE Finished Synchronizing!" 

   sleep 5 

   umount /media/SYNCSHARE 
 fi 
 </pre> 
 *NOTE*: Adding the @-n@ flag to the rsync commands will help when testing whether or not the script will run correctly. 
 *NOTE*: Make sure to change the username and uid number to the correct values for the notify-send commands. 
 *NOTE*: FAT filesystems require the @--modify-window=1 --size-only@ flags in order to synchronize correctly. 

 * Then make it executable: 
 <pre> 
 sudo chmod +x /usr/local/bin/syncshare.sh 
 </pre> 

 h2. Systemd Service 

 * Create a systemd unit file: 
 <pre> 
 sudo nano /etc/systemd/system/syncshare.service 
 </pre> 
 #* And add the following: 
 <pre> 
 [Unit] 
 Description=SyncShare trigger 
 Requires=dev-disk-by\x2dlabel-SYNCSHARE.device Requires=media-SYNCSHARE.mount 
 After=dev-disk-by\x2dlabel-SYNCSHARE.device After=media-SYNCSHARE.mount 

 [Service] 
 ExecStart=/usr/local/bin/syncshare.sh 

 [Install] 
 WantedBy=dev-disk-by\x2dlabel-SYNCSHARE.device WantedBy=media-SYNCSHARE.mount 
 </pre> 

 * And reload the systemd daemon: 
 <pre> 
 sudo systemctl daemon-reload 
 </pre> 

 * Enable the syncshare service: 
 <pre> 
 sudo systemctl enable syncshare 
 </pre> 

 h2. Udev Rule 

 * List the attached USB devices and get the vendor and product IDs: 
 <pre> 
 lsusb 
 </pre> 
 #* _Example output_: 
 <pre> 
 Bus 003 Device 004: ID 0781:3528 SanDisk Corp. Cruzer 
 </pre> 
 NOTE: The above example uses *0781* Vendor ID and *3528* Product ID. 

 * Add a udev rule to start the syncshare systemd service on device hotplug: 
 <pre> 
 sudo nano /etc/udev/rules.d/99-local.rules 
 </pre> 
 #* And add the following: 
 <pre> 
 SUBSYSTEMS=="usb", ATTRS{idVendor}=="0781", ATTRS{idProduct}=="3528", ATTRS{idVendor}=="002b", ATTRS{idProduct}=="1905", ACTION=="add", TAGS+="systemd", ENV{SYSTEMD_WANTS}=="syncshare.service" 
 </pre> 

 * Restart udev: 
 <pre> 
 sudo systemctl restart systemd-udevd 
 </pre> 

 h2. Resources 

 * http://serverfault.com/questions/766506/automount-usb-drives-with-systemd 
 * https://bbs.archlinux.org/viewtopic.php?id=207050 
 * https://bbs.archlinux.org/viewtopic.php?id=192461 
 * https://wiki.archlinux.org/index.php/Persistent_block_device_naming#by-label 
 * https://askubuntu.com/questions/25071/how-to-run-a-script-when-a-specific-flash-drive-is-mounted/190366 
 * http://jasonwryan.com/blog/2014/01/20/udev/ 
 * https://wiki.archlinux.org/index.php/NTFS-3G#Manual_mounting

Back