#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;
}