Skip to content

gh-95023: Add os.setns() and os.unshare() for Linux namespaces #95025

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add :func:`os.setns` and :func:`os.unshare` to manage namespaces on Linux.
92 changes: 91 additions & 1 deletion Modules/clinic/posixmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

94 changes: 94 additions & 0 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -14743,6 +14743,54 @@ os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
}
#endif

#ifdef HAVE_SETNS
/*[clinic input]
os.setns

fd: fildes
nstype: int

Reassociate thread with a namespace
[clinic start generated code]*/

static PyObject *
os_setns_impl(PyObject *module, int fd, int nstype)
/*[clinic end generated code: output=5dbd055bfb66ecd0 input=9d2de6d8a880014b]*/
{
int result;
Py_BEGIN_ALLOW_THREADS
result = setns(fd, nstype);
Py_END_ALLOW_THREADS
if (result == -1) {
return PyErr_SetFromErrno(PyExc_OSError);
}
Py_RETURN_NONE;
}
#endif

#ifdef HAVE_UNSHARE
/*[clinic input]
os.unshare

flags: int

Disassociate parts of the process execution context
[clinic start generated code]*/

static PyObject *
os_unshare_impl(PyObject *module, int flags)
/*[clinic end generated code: output=1b3177906dd237ee input=4d655e499ec28dd6]*/
{
int result;
Py_BEGIN_ALLOW_THREADS
result = unshare(flags);
Py_END_ALLOW_THREADS
if (result == -1) {
return PyErr_SetFromErrno(PyExc_OSError);
}
Py_RETURN_NONE;
}
#endif

static PyMethodDef posix_methods[] = {

Expand Down Expand Up @@ -14930,6 +14978,8 @@ static PyMethodDef posix_methods[] = {
OS__ADD_DLL_DIRECTORY_METHODDEF
OS__REMOVE_DLL_DIRECTORY_METHODDEF
OS_WAITSTATUS_TO_EXITCODE_METHODDEF
OS_SETNS_METHODDEF
OS_UNSHARE_METHODDEF
{NULL, NULL} /* Sentinel */
};

Expand Down Expand Up @@ -15468,6 +15518,50 @@ all_ins(PyObject *m)
if (PyModule_AddIntMacro(m, EFD_SEMAPHORE)) return -1;
#endif

// setns(2) and unshare(2) constants
#ifdef CLONE_FILES
if (PyModule_AddIntMacro(m, CLONE_FILES)) return -1;
#endif
#ifdef CLONE_FS
if (PyModule_AddIntMacro(m, CLONE_FS)) return -1;
#endif
#ifdef CLONE_NEWCGROUP
if (PyModule_AddIntMacro(m, CLONE_NEWCGROUP)) return -1;
#endif
#ifdef CLONE_NEWIPC
if (PyModule_AddIntMacro(m, CLONE_NEWIPC)) return -1;
#endif
#ifdef CLONE_NEWNET
if (PyModule_AddIntMacro(m, CLONE_NEWNET)) return -1;
#endif
#ifdef CLONE_NEWNS
if (PyModule_AddIntMacro(m, CLONE_NEWNS)) return -1;
#endif
#ifdef CLONE_NEWPID
if (PyModule_AddIntMacro(m, CLONE_NEWPID)) return -1;
#endif
#ifdef CLONE_NEWTIME
if (PyModule_AddIntMacro(m, CLONE_NEWTIME)) return -1;
#endif
#ifdef CLONE_NEWUSER
if (PyModule_AddIntMacro(m, CLONE_NEWUSER)) return -1;
#endif
#ifdef CLONE_NEWUTS
if (PyModule_AddIntMacro(m, CLONE_NEWUTS)) return -1;
#endif
#ifdef CLONE_SYSVSEM
if (PyModule_AddIntMacro(m, CLONE_SYSVSEM)) return -1;
#endif
#ifdef CLONE_THREAD
if (PyModule_AddIntMacro(m, CLONE_THREAD)) return -1;
#endif
#ifdef CLONE_SIGHAND
if (PyModule_AddIntMacro(m, CLONE_SIGHAND)) return -1;
#endif
#ifdef CLONE_VM
if (PyModule_AddIntMacro(m, CLONE_VM)) return -1;
#endif

#if defined(__APPLE__)
if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
if (PyModule_AddIntConstant(m, "_COPYFILE_STAT", COPYFILE_STAT)) return -1;
Expand Down
4 changes: 2 additions & 2 deletions configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -4669,12 +4669,12 @@ AC_CHECK_FUNCS([ \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
sched_setparam sched_setscheduler sem_clockwait sem_getvalue sem_open \
sem_timedwait sem_unlink sendfile setegid seteuid setgid sethostname \
setitimer setlocale setpgid setpgrp setpriority setregid setresgid \
setitimer setlocale setns setpgid setpgrp setpriority setregid setresgid \
setresuid setreuid setsid setuid setvbuf shutdown sigaction sigaltstack \
sigfillset siginterrupt sigpending sigrelse sigtimedwait sigwait \
sigwaitinfo snprintf splice strftime strlcpy strsignal symlinkat sync \
sysconf system tcgetpgrp tcsetpgrp tempnam timegm times tmpfile \
tmpnam tmpnam_r truncate ttyname umask uname unlinkat utimensat utimes vfork \
tmpnam tmpnam_r truncate ttyname umask uname unlinkat unshare utimensat utimes vfork \
wait wait3 wait4 waitid waitpid wcscoll wcsftime wcsxfrm wmemcmp writev \
])

Expand Down
6 changes: 6 additions & 0 deletions pyconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,9 @@
/* Define to 1 if you have the `setlocale' function. */
#undef HAVE_SETLOCALE

/* Define to 1 if you have the `setns' function. */
#undef HAVE_SETNS

/* Define to 1 if you have the `setpgid' function. */
#undef HAVE_SETPGID

Expand Down Expand Up @@ -1383,6 +1386,9 @@
/* Define to 1 if you have the `unlinkat' function. */
#undef HAVE_UNLINKAT

/* Define to 1 if you have the `unshare' function. */
#undef HAVE_UNSHARE

/* Define if you have a useable wchar_t type defined in wchar.h; useable means
wchar_t must be an unsigned type with at least 16 bits. (see
Include/unicodeobject.h). */
Expand Down