Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weird problem on a Vagrant VM with NFS shared folders #3706

Closed
rombat opened this issue Mar 21, 2015 · 11 comments
Closed

Weird problem on a Vagrant VM with NFS shared folders #3706

rombat opened this issue Mar 21, 2015 · 11 comments

Comments

@rombat
Copy link

rombat commented Mar 21, 2015

Here's my setup:
My host OS is Windows 8.1, and my guest VM is Vagrant Homestead (Ubuntu 14.04).
I'm using oh-my-zsh in my VM.

Since it was terribly slow with VirtualBox shared folders, I installed vagrant winnfsd.
Then I edited my Homestead.yaml, and added type: nfs after my folder map:

folders:
- map: D:/VagrantBoxes/HomesteadImproved
  to: /home/vagrant/Code
  type: nfs

If I do a vagrant up, everything is working just fine: the folder is mounted, and I can see my projet from my host machine.

The only problem is, when I vagrant ssh, if I want to go to my project folder (cd ~/Code/laravel), my shell just hang and I can't do anything more.
I can ls ~/Code/laravel, but if I try to cd ~/Code/laravel, it's stuck.

I've tried to remove oh-my-zsh, and I can browse the folders with bash or zsh. The problem seem to be related to oh-my-zsh (with a clean install of oh-my-zsh), but I don't understand why:

It only happens if the folder is mounted with NFS. If I use VirtualBox shared folders, I can browse whatever I want (but laravel is painfully slow).

Does anyone know how to fix this?

Thanks in advance.

@mcornella
Copy link
Member

I remember there being problems with NFS and zsh. See #2217. I couldn't figure out why or how to follow up on that, so you might get better answers in the official mailing list.

Let's make sure it's a zsh issue and not an oh-my-zsh one first, though:

  1. First, backup your current zshrc file and overwrite it with this one.
  2. If the behavior still happens, it's default zsh. Ask in the mailing list.
  3. If not, then it's oh-my-zsh, so let's debug a little:
  • Open the terminal (with your zshrc file enabled).
  • Run set -xv. This is to enable verbosity and debug information.
  • Run cd /path/to/nfs/folder and see where the output stops. Post back this output so I can analyze it.

Let me know what you find.
Cheers

@rombat
Copy link
Author

rombat commented Mar 22, 2015

Ok, thanks.

So, with the default .zshrc, no problem.
With set -xv, here's the output:

cd ~/Code/laravel
+omz_termsupport_preexec:1> [[ '' == true ]]
+omz_termsupport_preexec:5> emulate -L zsh
+omz_termsupport_preexec:6> setopt extended_glob
+omz_termsupport_preexec:9> local 'CMD=cd'
+omz_termsupport_preexec:10> local 'LINE=cd ~/Code/laravel'
+omz_termsupport_preexec:12> title '$CMD' '%100>...>$LINE%<<'
+title:1> [[ '' == *term* ]]
+title:5> : '%100>...>$LINE%<<'
+title:7> [[ cygwin == screen* ]]
+title:9> [[ cygwin == xterm* ]]
+title:9> [[ cygwin == rxvt* ]]
+title:9> [[ cygwin == ansi ]]
+title:9> [[ '' == iTerm.app ]]
+zsh:2> cd /home/vagrant/Code/laravel
+omz_termsupport_precmd:1> [[ '' == true ]]
+omz_termsupport_precmd:5> title '%15<..<%~%<<' '%n@%m: %~'
+title:1> [[ '' == *term* ]]
+title:5> : '%n@%m: %~'
+title:7> [[ cygwin == screen* ]]
+title:9> [[ cygwin == xterm* ]]
+title:9> [[ cygwin == rxvt* ]]
+title:9> [[ cygwin == ansi ]]
+title:9> [[ '' == iTerm.app ]]
+omz_termsupport_cwd:3> [[ '' == Apple_Terminal ]]
+zsh:3> git_prompt_info
+git_prompt_info:1> [[+git_prompt_info:1> git config --get oh-my-zsh.hide-status
+git_prompt_info:1> [[ '' != 1 ]]
+git_prompt_info:2> ref=+git_prompt_info:2> git symbolic-ref HEAD
+git_prompt_info:2> ref=refs/heads/master
+git_prompt_info:4> parse_git_dirty
+parse_git_dirty:1> local 'STATUS='
+parse_git_dirty:2> local FLAGS
+parse_git_dirty:3> FLAGS=( --porcelain )
+parse_git_dirty:4> [[+parse_git_dirty:4> git config --get oh-my-zsh.hide-dirty
+parse_git_dirty:4> [[ '' != 1 ]]
+parse_git_dirty:5> [[ 1 -gt 0 ]]
+parse_git_dirty:6> FLAGS+='--ignore-submodules=dirty'
+parse_git_dirty:8> [[ '' == true ]]
+parse_git_dirty:11> STATUS=+parse_git_dirty:11> git status --porcelain '--ignore-submodules=dirty'
+parse_git_dirty:11> STATUS=+parse_git_dirty:11> tail -n1

@apjanke
Copy link
Contributor

apjanke commented Mar 24, 2015

Well, this stops at the git status command issued by git_prompt_info() when constructing the git status part of the prompt. That makes some sense; git status is one of the slower things done from within the prompt, and it involves a lot of file I/O since it checks the whole repo. We've seen issues with slow prompt display with large git repos even on local directories. The per-file overhead of a network filesystem could exacerbate that.

To check this, could you:
a) Switch to an oh-my-zsh theme that does not include git status info in the prompt, such as cypher, and see if it is still slow?
b) With oh-my-zsh disabled, cd to ~/Code/laravel and do a time git status and see how long it takes?

If it really is the git status slowing things down, switching to a git-less theme should be a sufficient workaround. A grep -L git themes/*.zsh-theme inside ~/.oh-my-zsh will give you a list of candidates.

It would be nice if OMZ could add a timeout to its git status and other potentially slow calls from within the prompt construction code. A slow prompt display is a usability issue.

@mcornella
Copy link
Member

I'd say you're assessment of the issue is correct exactly right. I got confused by the last tail command but then I remembered that shells run commands separated by pipes (cmd1 | cmd2) in parallel, so it makes sense that it shows last.

If you've noticed, the prompt stuff runs a check to see if it needs to check the status: git config --get oh-my-zsh.hide-status, so if you run git config oh-my-zsh.hide-status 1 on repositories that take so long you'll bypass the git prompt check and hopefully the issue is gone.

@apjanke
Copy link
Contributor

apjanke commented Mar 24, 2015

I wasn't aware of that hide-status config option. That'll be useful; thanks.

@rombat
Copy link
Author

rombat commented Mar 24, 2015

@apjanke :
a) no problem with cypher, I can cd almost instantly
b) it takes forever (I did it ~15 min. ago and still no response)

@mcornella git config oh-my-zsh.hide-status 1 is working. It's a shame I can't see git informations, but anyway, as soon as I git status, my shell is stuck.

@apjanke
Copy link
Contributor

apjanke commented Mar 24, 2015

In that case, sounds like it's just git being slow to get the status on a large repo and/or slow filesystem: it has to check for modifications to any file in the repo, and over NFS there's nothing it can do to optimize that, so you get a lot of traffic with high latencies. Since mtimes don't necessarily propagate up directory trees in NFS's file model, that means it's basically having to stat (or read? not sure how closely it looks) each file in the tree with an NFS request. Not an ideal situation. There's some discussion of Git specifically being unhappy with NFS or CIFS. Git is designed for local operation, and I think they really mean local in some cases.

I think this is different from the #2217 case that @mcornella, because you'll get this slowdown even when your NFS server is up; you're probably getting some or all of the slowdown from lots of NFS requests that are succeeding but have latency, not a single one that's hung b/c the server is down.

Are you cool with closing this out? I don't think this is caused by anything specific to OMZ aside from that it calls git status for many of its prompts, and there's nothing OMZ can do to fix it.

If you want to tackle the git + filesharing issue directly there's a couple things you could try. You could use a traffic analyzer like Wireshark to look at the NFS activity and make sure nothing perverse is going on. (Though I'd bet there isn't. Only times I've seen serious shared FS + SCM breakage is when antivirus or security software was involved with a Windows client.) Or instead of doing VM or NFS shared folders directly, you could clone your git repos from the shared HomesteadImproved location to local directories inside the Vagrant instance, avoiding the need for git over shared filesystems entirely except when you push or pull changes.

Or just stick with a git-less theme or the oh-my-zsh.hide-status option.

@rombat
Copy link
Author

rombat commented Mar 24, 2015

Yep, it's ok to close this issue, it doesn't seem to be OMZ related after all.

@apjanke
Copy link
Contributor

apjanke commented Mar 24, 2015

Okay, thanks. You're the one who has permission to close it. :) Only the initial reporter and repo maintainers (only robbyrussell for OMZ) have rights to close issues and PRs.

@apjanke
Copy link
Contributor

apjanke commented Mar 26, 2015

FYI, there's an open issue for general git status slowness at #3009. Further discussion can go there.

@apjanke
Copy link
Contributor

apjanke commented Mar 26, 2015

@rombat – I put together a timeout mechanism to keep the prompt from hanging in slow git repos, in PR #3725. Would you mind testing it with your vagrant setup to see if it fixes this particular issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants