+ /* Notify the child that the parent is ready with all
+ * its setup, and that the child can now hand over
+ * control to the code to run inside the container. */
+ (void) barrier_place(&barrier); /* #2 */
+
+ if (arg_userns) {
+ char uid_map[strlen("/proc//uid_map") + DECIMAL_STR_MAX(uid_t) + 1], line[DECIMAL_STR_MAX(uid_t)*3+3+1];
+
+ (void) barrier_place_and_sync(&barrier); /* #3 */
+
+ xsprintf(uid_map, "/proc/" PID_FMT "/uid_map", pid);
+ xsprintf(line, UID_FMT " " UID_FMT " " UID_FMT "\n", 0, arg_uid_shift, arg_uid_range);
+ r = write_string_file(uid_map, line);
+ if (r < 0) {
+ log_error_errno(r, "Failed to write UID map: %m");
+ goto finish;
+ }
+
+ /* We always assign the same UID and GID ranges */
+ xsprintf(uid_map, "/proc/" PID_FMT "/gid_map", pid);
+ r = write_string_file(uid_map, line);
+ if (r < 0) {
+ log_error_errno(r, "Failed to write GID map: %m");
+ goto finish;
+ }
+
+ (void) barrier_place(&barrier); /* #4 */
+ }
+