mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
nsresource: allow multiple userns from the same process in parallel
When generating a name for a transient userns automatically we so far just included our PID to make it unique. That doens't really work if multiple userns shall be kept in parallel by a single process. Let's hence include a counter as well.
This commit is contained in:
@@ -15,30 +15,44 @@
|
||||
#include "process-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
/* Maximum namespace name length */
|
||||
#define NAMESPACE_NAME_MAX 16U
|
||||
|
||||
/* So the namespace name should be 16 chars at max (because we want that it is usable in usernames, which
|
||||
* have a limit of 31 chars effectively, and the nsresourced service wants to prefix/suffix some bits). But
|
||||
* it also should be unique if we are called multiple times in a row. Hence we take the "comm" name (which is
|
||||
* 15 chars), and suffix it with the PID and a counter, possibly overriding the end. */
|
||||
assert_cc(TASK_COMM_LEN == NAMESPACE_NAME_MAX);
|
||||
|
||||
static int make_pid_name(char **ret) {
|
||||
char comm[TASK_COMM_LEN];
|
||||
static uint64_t counter = 0;
|
||||
|
||||
assert(ret);
|
||||
|
||||
if (prctl(PR_GET_NAME, comm) < 0)
|
||||
return -errno;
|
||||
|
||||
/* So the namespace name should be 16 chars at max (because we want that it is usable in usernames,
|
||||
* which have a limit of 31 chars effectively, and the nsresourced service wants to prefix/suffix
|
||||
* some bits). But it also should be unique if we are called multiple times in a row. Hence we take
|
||||
* the "comm" name (which is 15 chars), and suffix it with the PID, possibly overriding the end. */
|
||||
assert_cc(TASK_COMM_LEN == 15 + 1);
|
||||
|
||||
char spid[DECIMAL_STR_MAX(pid_t)];
|
||||
xsprintf(spid, PID_FMT, getpid_cached());
|
||||
|
||||
assert(strlen(spid) <= 16);
|
||||
strshorten(comm, 16 - strlen(spid));
|
||||
/* Include a counter in the name, so that we can allocate multiple namespaces per process, with
|
||||
* unique names. For the first namespace we suppress the suffix */
|
||||
char scounter[sizeof(counter) * 2 + 1];
|
||||
if (counter == 0)
|
||||
scounter[0] = 0;
|
||||
else
|
||||
xsprintf(scounter, "%" PRIx64, counter);
|
||||
counter++;
|
||||
|
||||
_cleanup_free_ char *s = strjoin(comm, spid);
|
||||
strshorten(comm, LESS_BY(NAMESPACE_NAME_MAX, strlen(spid) + strlen(scounter)));
|
||||
|
||||
_cleanup_free_ char *s = strjoin(comm, spid, scounter);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
strshorten(s, NAMESPACE_NAME_MAX);
|
||||
|
||||
*ret = TAKE_PTR(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user