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

Wait for popen3 execution of goodhosts #43

Open
conradolandia opened this issue Oct 14, 2021 · 28 comments
Open

Wait for popen3 execution of goodhosts #43

conradolandia opened this issue Oct 14, 2021 · 28 comments
Labels
enhancement New feature or request hacktoberfest help wanted Extra attention is needed

Comments

@conradolandia
Copy link

I block malware sites and ads from the internet using a large hosts file (600.000+ lines), redirecting all these bad hosts to 0.0.0.0. When I try to use goodhosts, it just freezes and whatever process I was on won't go on. If I remove most of the entries form /etc/hosts, the process completes without problems. Is this a bug or expected behavior?

@Mte90
Copy link
Member

Mte90 commented Oct 14, 2021

I think that https://github.com/goodhosts/cli doesn't support a big hosts file at all.
I used to have an hosts file huge like you but was like 100000~ lines and was working.
I can't do anything for this as this is not a vagrant issue but the cli tool that the plugin uses.

@conradolandia
Copy link
Author

Thank you, will take the problem there.

@tomjn
Copy link
Contributor

tomjn commented Oct 14, 2021

@Mte90 how do you know it's goodhosts itself that's stalling?

@conradolandia conradolandia reopened this Oct 14, 2021
@Mte90
Copy link
Member

Mte90 commented Oct 15, 2021

So I had in the past a lot of hosts inside the file and goodhosts was parsing all of them for rewriting (clean as example) and this was changing the whole file and delay everything.
As the plugin just call the command with the hosts we need to add the stall should be on the goodhosts side as need to parse 600000~ urls for cleaning and look if there are duplicates and so on.

At the end I removed everything on my hosts file and there are no issues anymore, also as goodhosts development is stalled I didn't opened a ticket for it.

@tomjn
Copy link
Contributor

tomjn commented Oct 15, 2021

@Mte90 that's cleaning, we don't clean anymore on VVV where this was first seen, haven't for a long time.

But even ignoring that, you've shared an anecdote, no actual data has been shared proving it, just assumptions. Instead, @conradolandia should be able to test the theory by trying to add a host with the goodhosts CLI to see if it still hangs. If so, it's the CLI. If not, it's the vagrant plugin.

You're also assuming they have the latest version of the plugin, we don't know that

@tomjn
Copy link
Contributor

tomjn commented Oct 15, 2021

@conradolandia grab the latest goodhosts from https://github.com/goodhosts/cli/releases and try to use it to add a host, e.g. goodhosts add 127.0.0.1 example.test

@tomjn
Copy link
Contributor

tomjn commented Oct 15, 2021

and run vagrant plugin list --local to get the version of the plugin

@conradolandia
Copy link
Author

Results:

Downloaded the goodhosts binary from https://github.com/goodhosts/cli/releases, where it reports the last version as 1.0.7.
It adds the entry with no problems, even in the 600.000+ lines file, where it takes a couple seconds, but it makes the addition. Removing also works fine.

$ vagrant plugin list --local
vagrant-goodhosts (1.1.0, local)

@Mte90
Copy link
Member

Mte90 commented Oct 15, 2021

How much times takes? maybe is the ruby api that has issues with the timeout or similar.

@conradolandia
Copy link
Author

~ wc -l /etc/hosts
610748 /etc/hosts
~ time sudo goodhosts add 127.0.0.1 loquesea.test
hosts entry added: 127.0.0.1 loquesea.test
sudo goodhosts add 127.0.0.1 loquesea.test  3,61s user 0,37s system 156% cpu 2,545 total

@Mte90
Copy link
Member

Mte90 commented Oct 18, 2021

So I guess that the issue is at https://github.com/goodhosts/vagrant/blob/master/lib/vagrant-goodhosts/GoodHosts.rb#L119
A solution could be execute the command in a different thread but this not ensure that it works always.

Looking at the doc a pid is created but we are no printing it, https://ruby-doc.org/stdlib-2.4.2/libdoc/open3/rdoc/Open3.html#method-c-popen3

We can add a code that wait for the execution of the process like this https://stackoverflow.com/questions/11710542/wait-for-popen3-process-to-finish but I am not sure.

@tomjn
Copy link
Contributor

tomjn commented Oct 18, 2021

we should wait for the command to finish before proceeding otherwise how do we know the command is finished, and how do we avoid multiple attempts happening at the same time from the same vagrant command

@Mte90 Mte90 added enhancement New feature or request help wanted Extra attention is needed hacktoberfest labels Oct 18, 2021
@Mte90 Mte90 changed the title vagrant-goodhosts stalls when the /etc/hosts file has too many entries Wait for popen3 execution of goodhosts Oct 18, 2021
@YouJiacheng
Copy link
Contributor

YouJiacheng commented Dec 7, 2022

Can we use backticks directly as suggested by following chart?

@Mte90
Copy link
Member

Mte90 commented Dec 7, 2022

We need the output of the command including also stderr https://github.com/goodhosts/vagrant/blob/main/lib/vagrant-goodhosts/GoodHosts.rb#L138

@YouJiacheng
Copy link
Contributor

So Open3.capture3 should be a drop-in replacement?

@Mte90
Copy link
Member

Mte90 commented Dec 7, 2022

We already use popen3 https://github.com/goodhosts/vagrant/blob/main/lib/vagrant-goodhosts/GoodHosts.rb#L113 so I need to know what are the differences between the two methods.

@tomjn
Copy link
Contributor

tomjn commented Dec 7, 2022 via email

@YouJiacheng
Copy link
Contributor

capture3 is a light weight wrapper of block form popen, which waits for the process when it returns.
Okay I found that wait_thr.value also waits for the termination of the process. So why this issue is not closed?

@YouJiacheng
Copy link
Contributor

Okay, it might be the deadlock problem of popen3.

@YouJiacheng
Copy link
Contributor

YouJiacheng commented Dec 7, 2022

https://www.rubydoc.info/stdlib/open3/Open3.popen3

You should be careful to avoid deadlocks. Since pipes are fixed length buffers, Open3.popen3(“prog”) {|i, o, e, t| o.read } deadlocks if the program generates too much output on stderr. You should read stdout and stderr simultaneously (using threads or IO.select). However, if you don't need stderr output, you can use Open3.popen2. If merged stdout and stderr output is not a problem, you can use Open3.popen2e. If you really need stdout and stderr output as separate strings, you can consider Open3.capture3.

@YouJiacheng
Copy link
Contributor

Not only the stderr, since we never read from stdout before join the waiting thread(wait_thr.value), too much output on stdout will cause deadlock as well.
Even worse, we don't close stdin, stdout and stderr, which is required by docs: "stdin, stdout and stderr should be closed explicitly in this form."

stdin, stdout, stderr, wait_thr = Open3.popen3([env,] cmd... [, opts])
pid = wait_thr[:pid]  # pid of the started process
...
stdin.close  # stdin, stdout and stderr should be closed explicitly in this form.
stdout.close
stderr.close
exit_status = wait_thr.value  # Process::Status object returned.

@YouJiacheng
Copy link
Contributor

According to "When I try to use goodhosts, it just freezes and whatever process I was on won't go on.", it seems a deadlock. However, the cli never output too much.
Anyone can reproduce the issue?

@YouJiacheng
Copy link
Contributor

Since capture3 is more robust than popen3, can we use it instead? Hope that can solve this issue.

@Mte90
Copy link
Member

Mte90 commented Dec 9, 2022

I am not able to reproduce the issue but I think that to test it is required a big hosts file that take a lot to parse it.

@tomjn
Copy link
Contributor

tomjn commented Dec 9, 2022

@Mte90 I'm not sure why a big hosts file would matter here as this code isn't inside goodhosts, it's the vagrant plugin that calls it, no host files are being touched by ruby itself

@tomjn
Copy link
Contributor

tomjn commented Dec 9, 2022

Since capture3 is more robust than popen3, can we use it instead? Hope that can solve this issue.

can you make a PR?

@Mte90
Copy link
Member

Mte90 commented Dec 9, 2022

The problem is the execution of the cli command that takes a while and probably this freeze something in vagrant. In our case the output is very tiny anyway from this so I think that it is something to be improved on the cli side and not on the vagrant side.

@tomjn
Copy link
Contributor

tomjn commented Dec 9, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request hacktoberfest help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants