Symbolic Links in Windows with Unison

September 7th, 2020

It is possible to use unison on windows and synchronize symbolic links with remote systems and keep these symbolic links as actual links and not “follow” or copy the files. The windows version of Unison does not support syncing symbolic links as actual links, but there is a way to get symlinks supported.

The trick to getting symbolic links to work is to use the cygwin version of unison. When you install cygwin using the cygwin setup program, there are options to install various different versions of unison compiled for cygwin. By using cygwin, unison thinks it is running in a Posix environment which does support symbolic links, cygwin unison does not realize that it is actually running in Windows.

There may be some limitations such as if you have remote drives attached then windows itself may not support symbolic links. However your local NTFS file systems can and do support symbolic links.

In order to enable symbolic link support in cygwin and Windows, there are a few extra steps you need to take before you start syncing.

Configurate cygwin to have ‘exec’ file rights and handle permissions with ‘noacl’

This step is optional, you’ll be able to sync with symlinks without using ‘exec’ and ‘noacl’. But syncing will be slower without ‘exec’, and there may be permissions issues without ‘noacl’.

unison is interested in syncing file permissions. If a file is not obviously executable (like having .exe extension), by default cygwin checks for “exec” permission by opening a file and looking for the “hashbang” or “#!”. This can slow down syncing significantly. You can tell cygwin to think each file is executable by assigning “exec” to mounted file systems in the “/etc/fstab” file.

I also find that it is useful to setup the “noacl” property in /etc/fstab, otherwise I don’t see permissions synced properly.

Take note that there is already an existing entry in your /etc/fstab without “exec” or “noacl”. You’ll either want to delete it or comment it out with a # character at the start of the line. Also note that if you keep your home directory in the standard “/home” in cygwin, you’ll need to add an entry for /home. You can modify the entiry for /home if you want your home directory outside of the “c:/cygwin64” directory.

My /etc/fstab file looks like the following:

# See http://old.nabble.com/vim-and-file-permissions-on-Windows-7-td29162830.html
# and http://stackoverflow.com/questions/5828037/cygwin-sets-file-permission-to-000
# Using "exec" flag to make cygwin faster and not open each file to check for hashbang
# to see if it is executable. On windows all files are executable anyway.
# Using "noacl" for better handling of file permissions
none /cygdrive cygdrive binary,exec,noacl,posix=0,user 0 0
c:/cygwin64/home /home home binary,exec,noacl,posix=0,user 0 0

You will need to reboot your PC after making this change for it to take effect, however the next step (give rights to create symbolic links) also involves a reboot so you can perform the next step and have its reboot be the 1 reboot for this step and the next one.

You can check if the settings of fstab took place by running at cygwin prompt the “mount” command, which will show you the options for the /cygdrive and /home mounts.

Give your user the rights to create symbolic links

Before syncing symlinks with windows, you need to give your user the rights to create symbolic links. By default, Windows requires admin rights to create symlinks. You can enable this by:

  • Start a cygwin prompt as Administrator
    • Start->Cygwin
    • Right click on Cygwin64 terminal
    • select “more”
    • left click on “Run as administrator”
  • Type and run the “editrights” command as below
    • editrights -u $(whoami) -a SeCreateSymbolicLinkPrivilege
  • Check that you actually have the “SeCreateSymbolicLinkPrivilege” right
    • editrights -l -u $(whoami)
    • You should in the output: “SeCreateSymbolicLinkPrivilege”
  • For this right to take effect you need to sign out/sign back in or restart windows

Set CYGWIN variable to enable native symbolic link support

cygwin by default uses symbolic links that only cygwin programs understand. If you want native windows programs that do not use cygwin to also “see” the symbolic links, you need to set the CYGWIN environment variable properly. I prefer using “winsymlinks:native” and not “winsymlinks:nativestrict” because there may be some cases where you are syncing symlinks that don’t point to existing targets so in those cases cygwin will use the cygwin symlink to at least have a link, whereas native symlinks do not support pointing to non-existing targets.

To enable CYGWIN support of symbolic links for when you launch a cygwin shell from your desktop:

  • Click “Start” in windows
  • Start typing “Edit the system environment variables”
  • Click “Edit the system environment variables”
  • In the “System properties” (or “user properties” if you just want it for your user), check if CYGWIN is already defined.
    • If not defined, click “New”
      • Variable name: CYGWIN
      • Variable value: “winsymlinks:native”
    • If already defined, edit the CYGWIN variable and add “winsymlinks:native”




ssh server setup to handle symbolic links

If you have previously setup an ssh server, you may have not configured it to set the CYGWIN environment variable to properly handle symbolic links. To change your ssh server’s CYGWIN, you’ll need to uninstall and re-install your cygwin ssh server.

  • Before proceeding, make a backup of your /etc/sshd_config file
  • Start a cygwin prompt as administrator
  • Stop your existing ssh server from running
    • net stop cygsshd
  • Delete the service
    • cygrunsrv –remove cygsshd
  • Rerun ssh-host-config, tell it to overwrite the existing /etc/sshd_config file and then when it asks for the CYGWIN environment variable setting specify “winsymlinks:native”. A log of how I have done this is shown below

*** Info: Generating missing SSH host keys
*** Query: Overwrite existing /etc/ssh_configfile? (yes/no) no
*** Query: Overwrite existing /etc/sshd_configfile? (yes/no) yes
*** Info: Creating default /etc/sshd_configfile

*** Info: StrictModes is setto 'yes'by default.
*** Info: This is the recommended setting, but it requires that the POSIX
*** Info: permissions of the user's home directory, the user's .ssh
*** Info: directory, and the user's sshkey files are tight so that
*** Info: only the user has write permissions.
*** Info: On the other hand, StrictModes don't work well with default
*** Info: Windows permissions of a home directory mounted with the
*** Info: 'noacl'option, and they don't work at all ifthe home
*** Info: directory is on a FAT or FAT32 partition.
*** Query: Should StrictModes be used? (yes/no) no
*** Info: Updating /etc/sshd_configfile

*** Query: Do you want to installsshd as a service?
*** Query: (Say "no"ifit is already installed as a service) (yes/no) yes
*** Query: Enter the value of CYGWIN forthe daemon: [] winsymlinks:native

*** Info: The sshd service has been installed under the LocalSystem
*** Info: account (also known as SYSTEM). To start the service now, call
*** Info: `net start cygsshd' or `cygrunsrv -S cygsshd'.  Otherwise, it
*** Info: will start automatically after the next reboot.
*** Info: Host configuration finished. Have fun!

  • Edit your new /etc/sshd_config and restore any settings you had there
  • Restart the ssh server
    • net start cygsshd
  • Test that you can ssh into your machine
  • Once you are in an ssh session, do “echo $CYGWIN” and check that the “winsymlinks:native” property is in the CYGWIN environment variable

Happy syncing with symlinks

That’s it. Now when you perform syncs, from either a linux or windows machine that has symbolic links, these symbolic links should get preserved. With the “exec” setting of your /etc/fstab, the syncs should be faster.

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.