Vscode: code cannot start with AFS homedir

Created on 14 Mar 2017  路  20Comments  路  Source: microsoft/vscode

  • VSCode Version: 1.10.2 (code_1.10.2-1488981323_amd64.deb)
  • OS Version: Ubuntu 16.04 LTS

Steps to Reproduce:

  1. Have home directory w/ .config on AFS.
  2. Run code --verbose.
  3. Get the following error:
Error: listen EPERM /home/l/lars/.config/Code/1.10.2-main.sock
    at Object.exports._errnoException (util.js:1026:11)
    at exports._exceptionWithHostPort (util.js:1049:20)
    at Server._listen2 (net.js:1240:19)
    at listen (net.js:1289:10)
    at Server.listen (net.js:1378:5)
    at /usr/share/code/resources/app/out/vs/code/electron-main/main.js:7:11235
    at new n.Class.derive._oncancel (/usr/share/code/resources/app/out/vs/code/electron-main/main.js:6:13143)
    at Object.p [as serve] (/usr/share/code/resources/app/out/vs/code/electron-main/main.js:7:11165)
    at o (/usr/share/code/resources/app/out/vs/code/electron-main/main.js:13:9918)
    at te (/usr/share/code/resources/app/out/vs/code/electron-main/main.js:13:10989)

Code starts normally if moving the .config/Code directory to a local filesystem and symlinking it in. I would reckon that it's probably not portable to put the kind of thing that 1.10.2-main.sock is in the homedir, as it may very well be mounted in fun ways or on network filesystems.

This behaviour is new since the previous release I ran, which I believe was code_1.9.1-1486597190_amd64.deb.

bug linux verified workbench-os-integration

Most helpful comment

I don't have any choice in AFS for my home directory where the default XDG config directory is located. Sure I could point the config elsewhere, but then I'd lose access to the same configuration across machines which is the whole point of a shared homedir.

AFS doesn't support named pipes in the filesystem intentionally as it's a distributed filesystem and the semantics for how they would work across the world is hard to pin down.

As far as I interpret the XDG specification, you should not use the config directory for runtime state. They explicitly mention the runtime dir for that.
I don't know where in the stack this is done, but it's quite wrong to use the possibly shared homedir for machine-local state.

$XDG_RUNTIME_DIR supports things like mkfifo's named pipes

All 20 comments

Squinting at the XDG Base Directory Specification it seems like sockets and other runtime files shall be created in XDG_RUNTIME_DIR, which on my system is down in /run/user/3121.

Not sure what to do here. Best I can do is to recommend not using AFS. Does it support socket files?

I don't have any choice in AFS for my home directory where the default XDG config directory is located. Sure I could point the config elsewhere, but then I'd lose access to the same configuration across machines which is the whole point of a shared homedir.

AFS doesn't support named pipes in the filesystem intentionally as it's a distributed filesystem and the semantics for how they would work across the world is hard to pin down.

As far as I interpret the XDG specification, you should not use the config directory for runtime state. They explicitly mention the runtime dir for that.
I don't know where in the stack this is done, but it's quite wrong to use the possibly shared homedir for machine-local state.

$XDG_RUNTIME_DIR supports things like mkfifo's named pipes

Got it, thanks.

the same thing for the socket files in /tmp/ like /tmp/vscode-9106d11a-a2f2-4ba7-8e8c-269c06c6710f.sock= they should go in $XDG_RUNTIME_DIR (if available, if not /tmp is ok).

the added benefit of $XDG_RUNTIME_DIR is it goes away when the user logs out.

The same issue appears with sshfs mounted home directory

We were force to undo this change since it breaks many assumptions at startup, when this variable may or may not be set.

Unfortunately, the correct workaround for these cases is to call code with code --user-data-dir=$XDG_RUNTIME_DIR/code-user-data-dir.

Hi!

Now 1.17. stopped working on AFS @joaomoreno. Not sure if the workaround you gave makes sense, as the $XDG_RUNTIME_DIR directory gets deleted every time the user restarts. I would be happy if you could fix that. Thanks!

Does the workaround work for you at all?

Thanks for the fast reply. It does work for one session, but settings for example get deleted when I reboot.

Why is that? I don't really know AFS.

Me neither, but what I think right now: The XDG_RUNTIME_DIR variable gives something like /run/user/1234 on my machine, which apparently gets deleted when rebooting or the XDG_RUNTIME_DIR changes. I can鈥檛 say right now as I am not at my computer. If you call code using your workaround, all user data gets stored in that directory and is inaccessible after reboot.

But the problem ia not the user data, it is the .sock file that has trouble with AFS. So it is just this file that needs to be stored somewhere else in a non AFS directory.

Currently the .sock files are within user data dir. So... in your system should they live somewhere else? XDG_RUNTIME_DIR?

Yeah, for example. I don鈥檛 know what the .sock file does, but if it is not a problem that it is removed after reboot that might be an option. But isn鈥檛 that what the pull request #28816 did? Just storing the .sock file somewhere else...

Yes, #28816 did exactly that, but based on an env variable, which is very problematic in many cases. So, I propose to introduce a cli option to set the socket files location on Linux. So you'd need to launch it as:

code --icp-path $XDG_RUNTIME_DIR

Would that work for you?

Cool, I would expect that to work for me. Thanks! Let me know if you want me to test.

Yes, #28816 did exactly that, but based on an env variable, which is very problematic in many cases. So, I propose to introduce a cli option to set the socket files location on Linux. So you'd need to launch it as:

problematic in what cases? the XDG recommendations are pretty clear and easy to follow. You have a DATA dir, CONFIG dir and RUNTIME dir. There are environment variables to specify the directories or there are defaults when the env vars are not there.

What doesn't work in vscode with that setup?

Let's talk Linux only.

It makes a big difference in terms of process environment if you open an application from within a shell or using a UI gesture. The shell usually has all you favourite environments, often set up in .bash_profile files or similar (think nvm, GOPATH). The process (usually some Gnome or KDE process) which spawns Code using the UI gesture doesn't have this environment because it never went through a shell, never really parsed and interpreted .bash_profile. So, users complain they can't use Node or Go within Code; the real problem is that Code's env doesn't match what their shell has.

So: on startup, and only if Code wasn't launched in a shell, Code will _try_ to infere the user's shell environment as best as it can. This is possibly a lengthy process (have you ever waited 1-2 seconds until you see that $ bash prompt?) so we can't have that as part of Code's critical startup sequence, otherwise we risk being slow to start as well. We do it in parallel while Code actually starts up and spawns a window. Eventually, when that env is know, it is promptly applied to all Code's processes.

There's a race condition here. You see, we need to know the exact location of the IPC sockets at startup, before any window opens. If XDG_RUNTIME_DIR is (re)defined in the user's .bash_profile, we can't rely on it to compute the location of the sockets. We must know that value independently of the _env loading code path_.

For the past few months we were relying on reading XDG_RUNTIME_DIR to determine the sockets paths. For some, this works well. For others, Code breaks in very unrelated ways: if XDG_RUNTIME_DIR is (re)defined in .bash_profile, there was a race condition between reading that value from .bash_profile and computing the sockets paths. It would often happen that the process which served the socket pointed one way while all other processes pointed the other way. We simply can't have that.


One alternative for a fix is to ignore the XDG_RUNTIME_DIR value coming in from the user's .bash_profile. @gdamjan Do you think this would make sense?

XDG_RUNTIME_DIR is typically set by pam_systemd, even before their Desktop Envrionment or login shell is started.
If people redefine that in .bashrc (for interactive shells only) a lot of things will break for those shells. just an example of the sockets I have there (i.e. software that would break if I changed tne env var):

/run/user/1000/Nextcloud/socket
/run/user/1000/KSMserver__0
/run/user/1000/dconf/user
/run/user/1000/klauncherMTJ581.1.slave-socket
/run/user/1000/kdeinit5__0
/run/user/1000/kwallet5.socket
/run/user/1000/bus
/run/user/1000/pulse/pid
/run/user/1000/pulse/native
/run/user/1000/gnupg/S.gpg-agent.extra
/run/user/1000/gnupg/S.gpg-agent.ssh
/run/user/1000/gnupg/S.gpg-agent.browser
/run/user/1000/gnupg/S.dirmngr
/run/user/1000/gnupg/S.gpg-agent
/run/user/1000/systemd/private
/run/user/1000/systemd/notify

So in conclusion I have not heard of anyone redefining XDG_RUNTIME_DIR for interactive shells only, but if they do that, that's the users mistake to break things intentionally.

Alright, then let's do that: we'll simply ignore it when reading it after startup.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sijad picture sijad  路  3Comments

ryan-wong picture ryan-wong  路  3Comments

omidgolparvar picture omidgolparvar  路  3Comments

philipgiuliani picture philipgiuliani  路  3Comments

biij5698 picture biij5698  路  3Comments