From 72794f914b58fface4749d7bb8c451142b2e7d1b Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Thu, 12 Feb 2015 12:21:16 +0100
Subject: [PATCH] core: don't fail to run services in --user instances if $HOME
 is missing

Otherwise we cannot even invoke systemd-exit.service anymore, thus not
even exit.

https://bugs.freedesktop.org/show_bug.cgi?id=83100
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=759320

(cherry picked from commit 4c08c8242a687e00b289e948ccd07b96f0bc4866)

exec: also evaluate working_directory_missing_ok when not applying chroots

(cherry picked from commit cf1d0302aeaf4e44a6a643fb41e5525fdd04b1d5)
---
 src/core/execute.c | 10 ++++++----
 src/core/execute.h |  1 +
 src/core/unit.c    |  4 ++++
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/core/execute.c b/src/core/execute.c
index 88d094e..b6cb6f6 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1611,7 +1611,8 @@ int exec_spawn(ExecCommand *command,
                                         goto fail_child;
                                 }
 
-                        if (chdir(context->working_directory ? context->working_directory : "/") < 0) {
+                        if (chdir(context->working_directory ?: "/") < 0 &&
+                            !context->working_directory_missing_ok) {
                                 err = -errno;
                                 r = EXIT_CHDIR;
                                 goto fail_child;
@@ -1620,14 +1621,15 @@ int exec_spawn(ExecCommand *command,
                         _cleanup_free_ char *d = NULL;
 
                         if (asprintf(&d, "%s/%s",
-                                     context->root_directory ? context->root_directory : "",
-                                     context->working_directory ? context->working_directory : "") < 0) {
+                                     context->root_directory ?: "",
+                                     context->working_directory ?: "") < 0) {
                                 err = -ENOMEM;
                                 r = EXIT_MEMORY;
                                 goto fail_child;
                         }
 
-                        if (chdir(d) < 0) {
+                        if (chdir(d) < 0 &&
+                            !context->working_directory_missing_ok) {
                                 err = -errno;
                                 r = EXIT_CHDIR;
                                 goto fail_child;
diff --git a/src/core/execute.h b/src/core/execute.h
index 9d05d3a..9cef482 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -97,6 +97,7 @@ struct ExecContext {
 
         struct rlimit *rlimit[_RLIMIT_MAX];
         char *working_directory, *root_directory;
+        bool working_directory_missing_ok;
 
         mode_t umask;
         int oom_score_adjust;
diff --git a/src/core/unit.c b/src/core/unit.c
index 0e4ebfd..c585ea6 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -2887,6 +2887,10 @@ int unit_patch_contexts(Unit *u) {
                         r = get_home_dir(&ec->working_directory);
                         if (r < 0)
                                 return r;
+
+                        /* Allow user services to run, even if the
+                         * home directory is missing */
+                        ec->working_directory_missing_ok = true;
                 }
 
                 if (u->manager->running_as == SYSTEMD_USER &&
-- 
2.1.4

