Expected behaviour of "copyOwnershipFromParent"?

Scenario

I have a mix of Windows and Linux machines on my home network. What I want to do is sync both user’s personal files (just the XFG_DATA_DIRS type content, no dotfiles) and a set of shared directories between them.

I originally tried to set this up using Syncthing several years ago, but ran aground on the perennial problem of Windows and Linux’s incompatible notions of file ownership and permissions.

With the advent of the copyOwnershipFromParent advanced option for Syncthing I had hopes of being able to get this working. It is (“kinda”), but i’m not sure if what I am seeing is the expected behaviour.

Directory Structure

On Linux the setup is as shown below

Directory  Owner  Group
---------  -----  -----
/personal  root   admin
├── alpha  alpha  alpha
├── beta   beta   beta
├── gamma  gamma  gamma
└── delta  delta  delta
/shared    alpha  admin
├── music  alpha  admin
├── photo  alpha  admin
└── video  alpha  admin

On Windows there is a disk mounted as D: with Personal and Shared as top-level subfolders.

Syncthing is running as a service on both machines. On the Linux box I have enabled AmbientCapabilities=CAP_CHOWN CAP_FOWNER in the service configuraion and checked that the running service has those capabilities.

The synchronised folders have the Copy Ownership From Parent option set on the Linux side (i’m not sure yet whether this is the best option for the Windows side).

The top level directories were pre-populated on each machine, with the appropriate ownerships and permissions (on Linux, 2770 for dirs and 660 for files)

The Question

The way I read the description of the copyOwnershipFromParentoption, both in the copyOwnershipFromParent online docs, and the original description of the solution I should be able to share the Personal folder (that is /personal on Linux, D:\Personal on Windows). The user-level subfolders, such as /personal/alpha are not being changed, only files below those folders are being modified.

Therefore, even with just a single shared root folder being synced, files written under (say) /personal/beta/Documents should inherit the owner beta, as should everything else belonging to beta.

In practice, when i tried this setup the ownership search went right up to the top of the sync root (/personal) and I ended up with the equivalent of a chown -R root /personal being run, changing the ownership of over 20,000 files.

I ended up working around the problem (after re-correcting all the file ownerships) by setting up separate sync relationships at the user level, i.e. /personal/alpha, /personal/beta etc.

So my question is, was my original understanding incorrect, and a Copy Ownership From Parent relationship will ALWAYS copy the permissions and ownership recursively down from the root of the sync?

Or was my understanding correct, so a pre-populated root structure should only ever see permissions and ownership copied downwards in the folder structure, but existing top level dirs should not have their permissions changed?

If it’s the latter, then something strange is going on and i need to investigate further.

I suspect that if Syncthing sees a reason to touch /personal/alpha, say the permissions differ and it is going to correct that, then it will also inherit the ownership /personal → /personal/alpha at that point, which would not be what you want.

What you can do though is run Syncthing as root and share the four folders /personal/{alpha,beta,gamma,delta} separately, then Syncthing will never modify the folder root and hence ownership underneath each would be preserved.

(The option has no effect at all on Windows IIRC. Obviously should not be combined with the newer sync-ownership option.)

That’s essentially the configuration I have ended up as a fallback. I have the subdirs of /personal all synced separately, the only difference I followed the docs and rather than running the daemon as root, it’s running as s normal user (syncthing) but with the AmbientCapabilities=CAP_CHOWN CAP_FOWNER capabilities set.

TBH, trying to sync ownership and permissions is still such a pain that I have resigned myself to needing to have a “permissions fixer” on each side of the sync that runs in the background and walks the filesystem to correct any permissions errors.

I already have something basic that fits my needs running on the Windows side, written in Powershell. I haven’t decided what the best tool for the job is in Linux.

Perhaps if this is how copyOwnershipFromParent behaves it would be better renamed as copyOwnershipFromSyncRootas that’s what will actually happen over time in an active filesystem.

I strongly suspect I will need a “permissions fixup” script running as a cron job on the Linux side to deal with ownership and permissions glitches.

On that basis, it’s an interesting question as to whether I would be worse off if I just set Syncthing to “ignore permissions” and fixed everything post-hoc.

My guess would be that using copyOwnershipFromParent, if it at least applies a “reasonable guess” at owner+perms, would be helpful in a situation where (say) a user changes a file on one machine then immediately opens it on another (not an unreasonable situation in a home or small office environment). Otherwise if the timing of the Syncthing sync passes happens to align poorly with the permissions fixup job, there could be regular windows where permissions are out of whack and users could run into problems accessing files.

Is there a specific reason you don’t want to/can’t use syncthing’s sync ownership feature? If your users are the same across machines, this might do what you want?

From that document sync ownership feature

The two are not mixed – that is, ownership information is not synchronised between POSIX and Windows systems, only POSIX-to-POSIX and Windows-to-Windows.

Which is exactly what I need to do.

I realise this is complex in the general case, but for me on a small home network I have files belonging to 6 family members I want to sync, and each person has the same (text) user name on every machine, so what I’m looking for is essentially running “chown fred {}” on every file sent or updated from a Windows machine where the source file is owned by “fred”.

copyOwnershipFromParent when configured correctly does this, for the simple case where files that should be owned by fred are always written under the home directory of fred.

This works maybe 95%-99% of the time. The exceptions tend to be, ironically, hidden files created by applications like file synchronisers (Syncthing, FreeFileSync etc.), Git and others that create status files in hidden folders inside user directories that aren’t owned by that user. Plus the things that are OS-specific, like NTFS’ System Volume Information file.

My “permissions fixer” script will be limited to the same basic principle, by the time I get to look at a newly created file, the username that owned it on the source side has been lost by the synchronising process.

The only difference is that I have the opportunity to create custom rules based on the file pathname, like Syncthing’s Ignore rules but more flexible. For example I’m finding that git files created with my umask are causing problem because they need read access for “others”. I can have a custom rule to set a different permission mode in paths under .git

The machine-local side of things is getting better. There is now a btrfs driver for Windows that supports uid mapping, so a having a common filesystem for user files locally on a dual-boot Windows/Luinux machine is a lot nicer than it used to be.