]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tmpfiles: add a new return code for "operational failure" when processing
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 29 Mar 2018 14:19:33 +0000 (16:19 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 5 Apr 2018 06:13:53 +0000 (08:13 +0200)
Things can fail, and we have no control over it:
- file system issues (immutable bits, file system errors, MAC refusals, etc)
- kernel refusing certain arguments when writing to /proc/sys or /sys
Let's add a new code for the case where we parsed configuration but failed
to execute it because of external errors.

man/systemd-tmpfiles.xml
src/basic/fd-util.h
src/tmpfiles/tmpfiles.c

index a6ae5e4f9793ce2ed5131e9742f1387f148dd3a3..7c64dfaf586e88851af4915b40a20777ff6e2b2d 100644 (file)
   <refsect1>
     <title>Exit status</title>
 
-    <para>On success, 0 is returned. If the configuration was invalid (invalid syntax, missing
-    arguments, …), so some lines had to be ignored, but no other errors occurred,
+    <para>On success, 0 is returned. If the configuration was syntactically invalid (syntax errors,
+    missing arguments, …), so some lines had to be ignored, but no other errors occurred,
     <constant>65</constant> is returned (<constant>EX_DATAERR</constant> from
-    <filename>/usr/include/sysexits.h</filename>). Otherwise, <constant>1</constant> is returned
-    (<constant>EXIT_FAILURE</constant> from <filename>/usr/include/stdlib.h</filename>).
+    <filename>/usr/include/sysexits.h</filename>). If the configuration was syntactically valid, but
+    could not be executed (lack of permissions, creation of files in missing directories, invalid
+    contents when writing to <filename>/sys/</filename> values, …), <constant>73</constant> is
+    returned (<constant>EX_DATAERR</constant> from <filename>/usr/include/sysexits.h</filename>).
+    Otherwise, <constant>1</constant> is returned (<constant>EXIT_FAILURE</constant> from
+    <filename>/usr/include/stdlib.h</filename>).
     </para>
   </refsect1>
 
index 007580b48f4ac3d740e20c830483d075c99737e2..a87d8bdb4174eb679e86ed95eceaaa86ff7f74ff 100644 (file)
@@ -98,6 +98,10 @@ int acquire_data_fd(const void *data, size_t size, unsigned flags);
 #define ERRNO_IS_DISCONNECT(r) \
         IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH)
 
+/* Resource exhaustion, could be our fault or general system trouble */
+#define ERRNO_IS_RESOURCE(r) \
+        IN_SET(r, ENOMEM, EMFILE, ENFILE)
+
 int fd_move_above_stdio(int fd);
 
 int rearrange_stdio(int original_input_fd, int original_output_fd, int original_error_fd);
index 61e76570b1524d125308869755ad3a2c5e7d8541..9bb6a4f7e61c40a399b455e7589d901e26058795 100644 (file)
@@ -1292,7 +1292,7 @@ static int write_one_file(Item *i, const char *path) {
 
         fd = safe_close(fd);
 
-done:
+ done:
         if (stat(path, &st) < 0)
                 return log_error_errno(errno, "stat(%s) failed: %m", path);
 
@@ -2728,7 +2728,7 @@ static int read_config_files(char **config_dirs, char **args, bool *invalid_conf
 }
 
 int main(int argc, char *argv[]) {
-        int r, k;
+        int r, k, r_process = 0;
         ItemArray *a;
         Iterator iterator;
         _cleanup_strv_free_ char **config_dirs = NULL;
@@ -2775,7 +2775,7 @@ int main(int argc, char *argv[]) {
 
                 t = strv_join(config_dirs, "\n\t");
                 if (t)
-                        log_debug("Looking for configuration files in (higher priority first:\n\t%s", t);
+                        log_debug("Looking for configuration files in (higher priority first):\n\t%s", t);
         }
 
         /* If command line arguments are specified along with --replace, read all
@@ -2791,22 +2791,20 @@ int main(int argc, char *argv[]) {
         if (r < 0)
                 goto finish;
 
-
-
         /* The non-globbing ones usually create things, hence we apply
          * them first */
         ORDERED_HASHMAP_FOREACH(a, items, iterator) {
                 k = process_item_array(a);
-                if (k < 0 && r == 0)
-                        r = k;
+                if (k < 0 && r_process == 0)
+                        r_process = k;
         }
 
         /* The globbing ones usually alter things, hence we apply them
          * second. */
         ORDERED_HASHMAP_FOREACH(a, globs, iterator) {
                 k = process_item_array(a);
-                if (k < 0 && r == 0)
-                        r = k;
+                if (k < 0 && r_process == 0)
+                        r_process = k;
         }
 
 finish:
@@ -2821,10 +2819,12 @@ finish:
 
         mac_selinux_finish();
 
-        if (r < 0)
+        if (r < 0 || ERRNO_IS_RESOURCE(-r_process))
                 return EXIT_FAILURE;
         else if (invalid_config)
                 return EX_DATAERR;
+        else if (r_process < 0)
+                return EX_CANTCREAT;
         else
                 return EXIT_SUCCESS;
 }