aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2019-08-03 11:40:31 -0700
committerZac Medico <zmedico@gentoo.org>2019-08-04 10:41:25 -0700
commit7d05c3e88dd313e3298d74ce7241cbc5b85df54a (patch)
tree62ced3fb1f5b006332712f671e105d2f7b16b742
parentebuild: apply_priorities (PORTAGE_NICENESS) (diff)
downloadportage-7d05c3e88dd313e3298d74ce7241cbc5b85df54a.tar.gz
portage-7d05c3e88dd313e3298d74ce7241cbc5b85df54a.tar.bz2
portage-7d05c3e88dd313e3298d74ce7241cbc5b85df54a.zip
process: add _has_ipv6() function
Add _has_ipv6() function and use it in _configure_loopback_interface() to decide whether to add an IPv6 address. Bug: https://bugs.gentoo.org/691290 Reviewed-by: Mike Gilbert <floppym@gentoo.org> Signed-off-by: Zac Medico <zmedico@gentoo.org>
-rw-r--r--lib/portage/process.py43
1 files changed, 40 insertions, 3 deletions
diff --git a/lib/portage/process.py b/lib/portage/process.py
index 690421815..2a2cbd972 100644
--- a/lib/portage/process.py
+++ b/lib/portage/process.py
@@ -339,6 +339,9 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
fd_pipes[1] = pw
fd_pipes[2] = pw
+ # Cache _has_ipv6() result for use in child processes.
+ _has_ipv6()
+
# This caches the libc library lookup and _unshare_validator results
# in the current process, so that results are cached for use in
# child processes.
@@ -446,6 +449,41 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
# Everything succeeded
return 0
+__has_ipv6 = None
+
+def _has_ipv6():
+ """
+ Test that both userland and kernel support IPv6, by attempting
+ to create a socket and listen on any unused port of the IPv6
+ ::1 loopback address.
+
+ @rtype: bool
+ @return: True if IPv6 is supported, False otherwise.
+ """
+ global __has_ipv6
+
+ if __has_ipv6 is None:
+ if socket.has_ipv6:
+ sock = None
+ try:
+ # With ipv6.disable=0 and ipv6.disable_ipv6=1, socket creation
+ # succeeds, but then the bind call fails with this error:
+ # [Errno 99] Cannot assign requested address.
+ sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
+ sock.bind(('::1', 0))
+ except EnvironmentError:
+ __has_ipv6 = False
+ else:
+ __has_ipv6 = True
+ finally:
+ # python2.7 sockets do not support context management protocol
+ if sock is not None:
+ sock.close()
+ else:
+ __has_ipv6 = False
+
+ return __has_ipv6
+
def _configure_loopback_interface():
"""
Configure the loopback interface.
@@ -478,9 +516,8 @@ def _configure_loopback_interface():
try:
subprocess.call(['ip', 'address', 'add', '10.0.0.1/8', 'dev', 'lo'])
- with open(os.devnull, 'wb', 0) as devnull:
- subprocess.call(['ip', 'address', 'add', 'fd00::1/8', 'dev', 'lo'],
- stdout=devnull, stderr=devnull)
+ if _has_ipv6():
+ subprocess.call(['ip', 'address', 'add', 'fd00::1/8', 'dev', 'lo'])
except EnvironmentError as e:
writemsg("Error calling 'ip': %s\n" % e.strerror, noiselevel=-1)