Reputation: 974
I just configured docker to run under wsl2. That worked without any relevant problems and our projects are running fine.
I followed this article by docker on how to setup the wsl2 docker environment: https://www.docker.com/blog/docker-desktop-wsl-2-best-practices/
The article recommends to put the project files into the linux system and NOT access it by using the mounts under /mnt
for performance reasons.
For accessing the files, the article suggests the following options:
\\wsl$\
Some collegues use IDE's that are neither compatible with linux nor can access wsl. So I tried to let them access the project through the network share. Those collegues use the git integration in their IDE's and are not comfortable with the git cli.
Git works well, with just a little problem. We have files in the repository, that have the executable permission (+x). Thoses file have the perms 755 on linux and 644 on windows network drive.
Because the actual file perms differ from the linux environment, git detects a change for those files.
Is there a way, to expose the correct file perms to the windows environment?
Do you have any other ideas on how to solve the problem?
Upvotes: 1
Views: 2855
Reputation: 478
I had a similar problem with git
where you may not be able to run a commit with various cryptic errors. Part of that is how git
opens files, so hopefully this post goes some way to unpicking that.
Background
In the latest Windows builds there are some changes in WSL regarding how it interacts with your file system. One problem is the fact that previously, the incompatibility between Windows and Linux file-systems meant most files effectively had permissions ‘777’ on external storage, so any user could read/write/execute anything. This isn’t really ideal for Linux, as you can’t store private keys etc. Microsoft have changed that behaviour now so files can have both Windows (NTFS) and Linux permissions, through extension attributes. On a normal drive it’s fine to overcome, you can mount the drive with metadata using the following command:
umount /mnt/c;
mount -t drvfs C:\\ /mnt/c/ -o metadata
Unfortunately they seem to have rolled that change out to network and external filesystems too (like exFAT
), which doesn’t have extensible attributes and gets in a bit of a mess, making external drives unusable. For example, if the file is read-only in Windows then you can’t write to it in WSL; you can’t override it with sudo
either because Windows permissions override WSL ones regardless. The changes break a lot of programs, which I found out today trying to upload changes to git. It’s one of those new problems which doesn’t actually have solutions on the Internet yet, so I’ve attached a file will solve that issue.
To run, first compile the shared object:
cc -Wall -O3 -D_GNU_SOURCE -fPIC -c -o githack.o githack.c; gcc -o githack.so -nostartfiles -shared githack.o -ldl;
Then run the command prefixed with LD_PRELOAD
:
LD_PRELOAD=./githack.so git commit -a -m "Another interesting commit"
How to investigate for other programs
For git
, the issue specifically is seen:
error: insufficient permission for adding an object to repository database .git/objects
To find out why it failed, you can use strace
:
strace git commit -a -m "Another interesting commit"
>
...
gettimeofday({tv_sec=1592618056, tv_usec=52991}, NULL) = 0
getpid() = 651
openat(AT_FDCWD, ".git/objects/78/tmp_obj_flbKNc", O_RDWR|O_CREAT|O_EXCL, 0444) = -1 EACCES (Permission denied)
write(2, "error: insufficient permission f"..., 88error: insufficient permission for adding an object to repository database .git/objects
) = 88
close(4) = 0
...
Immediately before the error line printed we see why it failed (-1
), so to fix it requires intercepting that call. You can determine that from ltrace
:
ltrace git commit -a -m "Latest local copy from George"
>
...
open64(".git/objects/78/tmp_obj_zDayCc", 194, 0444) = -1
__errno_location() = 0x7f2777001000
__errno_location() = 0x7f2777001000
__vsnprintf_chk(0x7fffd4786d00, 4096, 1, 4096) = 80
__fprintf_chk(0x7f277631c680, 1, 0x7f27773eacfc, 0x7f27773c8083error: insufficient permission for adding an object to repository database .git/objects
) = 88
close(4)
...
And so the attached code at the bottom of this post intercepts the open64
code with flags equal 194
.
Solution code (name githack.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
//#define openat ignorethisopen
#define open ignorethisopen
#define open64 ignorethisopen64
#include <fcntl.h>
//#undef openat
#undef open
#undef open64
#include <dlfcn.h>
/*
'strace git ...' will show git fail on an openat() command
this is probably implemented as open64() on your system
you can confirm this by use of 'ltrace git ...'
you may also need to adjust the oflag comparison of 194
George O'Neill 2020/06/20 (feel free to reach out if issues remain)
*/
/*static int (*___openat)(int, char *, int, mode_t);*/
static int (*___open)(const char *, int, mode_t);
static int (*___open64)(const char *, int, mode_t);
static void* dlwrap(const char *fn)
{
const char *e;
void *p = dlsym(RTLD_NEXT, fn);
if ((e=dlerror())!=0)
fprintf(stderr, "dlsym(RTLD_NEXT,'%s'): %s\r\n", fn, e);
return p;
}
void _init(void)
{
___open = dlwrap("open");
___open64 = dlwrap("open64");
}
/*int openat(int dirfd, const char *pathname, int oflag, mode_t mode)*/
int open(const char *pathname, int oflag, mode_t mode)
{
if (oflag && oflag == 194)
return ___open(pathname, oflag, S_IRWXU);
return ___open(pathname, oflag, mode);
}
int open64(const char *pathname, int oflag, mode_t mode)
{
if (oflag && oflag == 194)
return ___open64(pathname, oflag, S_IRWXU);
return ___open64(pathname, oflag, mode);
}
Upvotes: 0
Reputation: 1482
To sync Linux file permissions, you need to enable metadata for your Linux distro. Create /etc/wsl.conf
file with this content:
[automount]
root = /
options = "metadata"
root
is optional but useful, mounting your Windows drive to /c
instead of /mnt/c
, which saves you a few keystrokes.
To make sure this takes effect, sign out Windows and in again.
Check out the documentation for more details, as well as advanced settings like setting umask
.
While at that, remember to enable Git's auto CRLF handling:
$ git config --global core.autocrlf true
Which will save you a lot of trouble when working with Git on WSL.
Upvotes: 1