Bound the fqdn lookup in the hostname resolvers - #177
Conversation
When the short hostname carries no domain, the hostname resolvers ask the name service for the canonical name with getaddrinfo(3). That call had no upper bound, so a hung resolver stalled fact collection until the agent's runtimeout fired an hour later (OpenVoxProject/openvox#485). Switch to Addrinfo.getaddrinfo and pass a 10 second timeout on Rubies that honour it (MRI 4.0 and later; older MRI accepts and ignores the keyword, JRuby does not accept it, so it is omitted there). On Linux, a timed-out lookup no longer falls through to the FFI getaddrinfo fallback, which has no timeout of its own and holds the GVL while it waits. The domain then comes from /etc/resolv.conf as it already does when the lookup fails. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Steven Pritchard <steven.pritchard@gmail.com>
|
This comment was generated by Claude Code, which wrote the change on this branch; posted by @silug. Why this call, and why a timeout works here The debug log in OpenVoxProject/openvox#485 (comment of Sep 7) shows fact collection stopping right after What Checked against the Ruby source tree:
Test results
Behaviour notes for review
|
There was a problem hiding this comment.
🟢 Approval recommended
The change is narrowly scoped, covered by updated unit tests, and only minor comment typos were identified.
Pull request overview
This pull request bounds FQDN lookups in the hostname resolvers to prevent fact collection from stalling when DNS/name service resolution hangs, by switching to Addrinfo.getaddrinfo and applying a 10-second timeout on Ruby versions that honor it.
Changes:
- Use
Addrinfo.getaddrinfo(instead ofSocket.getaddrinfo) for canonical-name lookups and introduceFQDN_LOOKUP_TIMEOUT = 10. - Conditionally pass
timeout:only on MRI Ruby >= 4.0, omitting it where it’s ignored or unsupported. - Add/adjust unit tests to validate timeout behavior and avoid falling back to the FFI lookup on timeout (Linux).
File summaries
| File | Description |
|---|---|
| lib/facter/resolvers/linux/hostname.rb | Adds a bounded Addrinfo-based FQDN lookup and avoids FFI fallback on timeout. |
| lib/facter/resolvers/hostname.rb | Adds a bounded Addrinfo-based FQDN lookup in the generic hostname resolver. |
| spec/facter/resolvers/linux/hostname_spec.rb | Updates tests to stub Addrinfo.getaddrinfo and adds timeout-related coverage. |
| spec/facter/resolvers/hostname_spec.rb | Updates tests for Addrinfo.getaddrinfo and adds coverage for timeout/no-timeout behavior. |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
This looks okay but I'm not 100% confident in merging. Anybody else around who wants to take a look? Or maybe create a test build? |
|
I did a test build: swapped the two resolver files from this PR into a 9.0.0-rc1 agent (Ruby 4.0.6, CentOS Stream 9) in my lab, with a short hostname and the resolver black-holed so glibc gives up after 40 s per lookup.
One thing to settle before merging: on JRuby, Scripts and logs available on request. +1 from me once the JRuby point is addressed. |
|
@miharp thanks a lot for testing! |
Short description
When the short hostname carries no domain, the hostname resolvers ask the name service for the canonical name with getaddrinfo(3). That call had no upper bound, so a hung resolver stalled fact collection until the agent's runtimeout fired an hour later (OpenVoxProject/openvox#485).
Switch to Addrinfo.getaddrinfo and pass a 10 second timeout on Rubies that honour it (MRI 4.0 and later; older MRI accepts and ignores the keyword, JRuby does not accept it, so it is omitted there). On Linux, a timed-out lookup no longer falls through to the FFI getaddrinfo fallback, which has no timeout of its own and holds the GVL while it waits. The domain then comes from /etc/resolv.conf as it already does when the lookup fails.
Generated by Claude Code
Checklist
I have:
Signed-off-byannotation to each of my commitsGenerated-byorAssisted-byannotations to each of my commits created with the help of an AI agent