mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-95023: Added os.setns and os.unshare functions (#95046)
Added os.setns and os.unshare to easily switch between namespaces on Linux. Co-authored-by: Christian Heimes <christian@python.org> Co-authored-by: CAM Gerlach <CAM.Gerlach@Gerlach.CAM> Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
c1e02d4e4e
commit
a371a7e03e
11 changed files with 418 additions and 1 deletions
|
@ -2191,6 +2191,53 @@ class TestPosixWeaklinking(unittest.TestCase):
|
|||
os.utime("path", dir_fd=0)
|
||||
|
||||
|
||||
class NamespacesTests(unittest.TestCase):
|
||||
"""Tests for os.unshare() and os.setns()."""
|
||||
|
||||
@unittest.skipUnless(hasattr(os, 'unshare'), 'needs os.unshare()')
|
||||
@unittest.skipUnless(hasattr(os, 'setns'), 'needs os.setns()')
|
||||
@unittest.skipUnless(os.path.exists('/proc/self/ns/uts'), 'need /proc/self/ns/uts')
|
||||
@support.requires_linux_version(3, 0, 0)
|
||||
def test_unshare_setns(self):
|
||||
code = """if 1:
|
||||
import errno
|
||||
import os
|
||||
import sys
|
||||
fd = os.open('/proc/self/ns/uts', os.O_RDONLY)
|
||||
try:
|
||||
original = os.readlink('/proc/self/ns/uts')
|
||||
try:
|
||||
os.unshare(os.CLONE_NEWUTS)
|
||||
except OSError as e:
|
||||
if e.errno == errno.ENOSPC:
|
||||
# skip test if limit is exceeded
|
||||
sys.exit()
|
||||
raise
|
||||
new = os.readlink('/proc/self/ns/uts')
|
||||
if original == new:
|
||||
raise Exception('os.unshare failed')
|
||||
os.setns(fd, os.CLONE_NEWUTS)
|
||||
restored = os.readlink('/proc/self/ns/uts')
|
||||
if original != restored:
|
||||
raise Exception('os.setns failed')
|
||||
except PermissionError:
|
||||
# The calling process did not have the required privileges
|
||||
# for this operation
|
||||
pass
|
||||
except OSError as e:
|
||||
# Skip the test on these errors:
|
||||
# - ENOSYS: syscall not available
|
||||
# - EINVAL: kernel was not configured with the CONFIG_UTS_NS option
|
||||
# - ENOMEM: not enough memory
|
||||
if e.errno not in (errno.ENOSYS, errno.EINVAL, errno.ENOMEM):
|
||||
raise
|
||||
finally:
|
||||
os.close(fd)
|
||||
"""
|
||||
|
||||
assert_python_ok("-c", code)
|
||||
|
||||
|
||||
def tearDownModule():
|
||||
support.reap_children()
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue