From 4795c51b74e189d8e93d5dd14617c004af6520f3b7bc237c8452886ff214e2f0 Mon Sep 17 00:00:00 2001 From: Stephan Kulow Date: Tue, 29 Jan 2013 06:05:16 +0000 Subject: [PATCH] Accepting request 150160 from Base:System - Add tmpfiles-X-type.patch: allow to clean directories with removing them. - Add systemd-fix-merge-ignore-dependencies.patch: fix merging with --ignore-dependencies waiting for dependencies (bnc#800365). - Update systemd-numlock-suse.patch: udev-trigger.service is now called systemd-udev-trigger.service. - Add improve-man-environment.patch: improve manpage regarding Environment value. (forwarded request 150151 from fcrozat) OBS-URL: https://build.opensuse.org/request/show/150160 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/systemd?expand=0&rev=124 --- improve-man-environment.patch | 44 +++ systemd-fix-merge-ignore-dependencies.patch | 26 ++ systemd-mini.changes | 12 + systemd-mini.spec | 9 + systemd-numlock-suse.patch | 2 +- systemd.changes | 12 + systemd.spec | 9 + tmpfiles-X-type.patch | 369 ++++++++++++++++++++ 8 files changed, 482 insertions(+), 1 deletion(-) create mode 100644 improve-man-environment.patch create mode 100644 systemd-fix-merge-ignore-dependencies.patch create mode 100644 tmpfiles-X-type.patch diff --git a/improve-man-environment.patch b/improve-man-environment.patch new file mode 100644 index 00000000..a5fa5967 --- /dev/null +++ b/improve-man-environment.patch @@ -0,0 +1,44 @@ +From 2cfd1ed4d853be4a22cc102037347c9041bf5ced Mon Sep 17 00:00:00 2001 +From: Frederic Crozat +Date: Thu, 24 Jan 2013 17:55:42 +0100 +Subject: [PATCH] man: systemd.exec - explicit Environment assignment + +Be more verbose about using space in Environment field and not +using value of other variables + +Fixes https://bugzilla.redhat.com/show_bug.cgi?id=840260 +--- + man/systemd.exec.xml | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +Index: systemd-195/man/systemd.exec.xml +=================================================================== +--- systemd-195.orig/man/systemd.exec.xml ++++ systemd-195/man/systemd.exec.xml +@@ -269,9 +269,24 @@ + in which case all listed variables + will be set. If the same variable is + set twice the later setting will +- override the earlier setting. See ++ override the earlier setting. ++ Variable expansion is not performed ++ inside the strings, and $ has no special ++ meaning. ++ If you need to assign a value containing spaces ++ to a variable, use double quotes (") ++ for the assignment. ++ ++ Example: ++ Environment="VAR1=word1 word2" VAR2=word3 "VAR3=word 5 6" ++ gives three variables VAR1, ++ VAR2, VAR3. ++ ++ ++ ++ See + environ7 +- for details. ++ for details about environment variables. + + + EnvironmentFile= diff --git a/systemd-fix-merge-ignore-dependencies.patch b/systemd-fix-merge-ignore-dependencies.patch new file mode 100644 index 00000000..3e9f9454 --- /dev/null +++ b/systemd-fix-merge-ignore-dependencies.patch @@ -0,0 +1,26 @@ +From e45460d666512db4f908f86e8722d7932dcf0f82 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 25 Jan 2013 19:54:21 +0100 +Subject: [PATCH] job: fix merging with --ignore-dependencies + +This fixes a bug where a job with --ignore-dependencies would wait for +other jobs because it merged into a previously queued job. +--- + src/core/job.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/core/job.c b/src/core/job.c +index e381ea2..6a03d17 100644 +--- a/src/core/job.c ++++ b/src/core/job.c +@@ -166,6 +166,7 @@ static void job_merge_into_installed(Job *j, Job *other) { + assert(other->type == JOB_NOP); + + j->override = j->override || other->override; ++ j->ignore_order = j->ignore_order || other->ignore_order; + } + + Job* job_install(Job *j) { +-- +1.7.10.4 + diff --git a/systemd-mini.changes b/systemd-mini.changes index 130639ed..25bdb532 100644 --- a/systemd-mini.changes +++ b/systemd-mini.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Mon Jan 28 10:49:21 UTC 2013 - fcrozat@suse.com + +- Add tmpfiles-X-type.patch: allow to clean directories with + removing them. +- Add systemd-fix-merge-ignore-dependencies.patch: fix merging with + --ignore-dependencies waiting for dependencies (bnc#800365). +- Update systemd-numlock-suse.patch: udev-trigger.service is now + called systemd-udev-trigger.service. +- Add improve-man-environment.patch: improve manpage regarding + Environment value. + ------------------------------------------------------------------- Tue Jan 22 17:02:04 UTC 2013 - fcrozat@suse.com diff --git a/systemd-mini.spec b/systemd-mini.spec index 568f40f8..f18c5a44 100644 --- a/systemd-mini.spec +++ b/systemd-mini.spec @@ -254,6 +254,12 @@ Patch119: shutdown-ignore-loop-devices-without-backing-file.patch Patch120: fix-bad-mem-access.patch # PATCH-FIX-UPSTREAM parse-multiline-env-file.patch fcrozat@suse.com bnc#793411 -- correctly parse multiline environment files Patch121: parse-multiline-env-file.patch +# PATCH-FIX-UPSTREAM improve-man-environment.patch fcrozat@suse.com -- improve Environment section in manpage +Patch122: improve-man-environment.patch +# PATCH-FIX-UPSTREAM tmpfiles-X-type.patch fcrozat@suse.com -- allow to clean directories with removing them +Patch123: tmpfiles-X-type.patch +# PATCH-FIX-UPSTREAM systemd-fix-merge-ignore-dependencies.patch fcrozat@suse.com bnc#800365 -- fix merging with --ignore-dependencies waiting for dependencies +Patch124: systemd-fix-merge-ignore-dependencies.patch # udev patches # PATCH-FIX-OPENSUSE 1001-Reinstate-TIMEOUT-handling.patch @@ -552,6 +558,9 @@ cp %{SOURCE7} m4/ %patch119 -p1 %patch120 -p1 %patch121 -p1 +%patch122 -p1 +%patch123 -p1 +%patch124 -p1 %build autoreconf -fiv diff --git a/systemd-numlock-suse.patch b/systemd-numlock-suse.patch index 245a4bc3..1e89d398 100644 --- a/systemd-numlock-suse.patch +++ b/systemd-numlock-suse.patch @@ -179,7 +179,7 @@ Index: systemd-195/units/systemd-vconsole-setup.service.in Conflicts=shutdown.target After=systemd-readahead-collect.service systemd-readahead-replay.service -Before=sysinit.target shutdown.target -+Before=sysinit.target shutdown.target udev-trigger.service ++Before=sysinit.target shutdown.target systemd-udev-trigger.service ConditionPathExists=/dev/tty0 [Service] diff --git a/systemd.changes b/systemd.changes index 130639ed..25bdb532 100644 --- a/systemd.changes +++ b/systemd.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Mon Jan 28 10:49:21 UTC 2013 - fcrozat@suse.com + +- Add tmpfiles-X-type.patch: allow to clean directories with + removing them. +- Add systemd-fix-merge-ignore-dependencies.patch: fix merging with + --ignore-dependencies waiting for dependencies (bnc#800365). +- Update systemd-numlock-suse.patch: udev-trigger.service is now + called systemd-udev-trigger.service. +- Add improve-man-environment.patch: improve manpage regarding + Environment value. + ------------------------------------------------------------------- Tue Jan 22 17:02:04 UTC 2013 - fcrozat@suse.com diff --git a/systemd.spec b/systemd.spec index e62ea2ec..9546bb7b 100644 --- a/systemd.spec +++ b/systemd.spec @@ -249,6 +249,12 @@ Patch119: shutdown-ignore-loop-devices-without-backing-file.patch Patch120: fix-bad-mem-access.patch # PATCH-FIX-UPSTREAM parse-multiline-env-file.patch fcrozat@suse.com bnc#793411 -- correctly parse multiline environment files Patch121: parse-multiline-env-file.patch +# PATCH-FIX-UPSTREAM improve-man-environment.patch fcrozat@suse.com -- improve Environment section in manpage +Patch122: improve-man-environment.patch +# PATCH-FIX-UPSTREAM tmpfiles-X-type.patch fcrozat@suse.com -- allow to clean directories with removing them +Patch123: tmpfiles-X-type.patch +# PATCH-FIX-UPSTREAM systemd-fix-merge-ignore-dependencies.patch fcrozat@suse.com bnc#800365 -- fix merging with --ignore-dependencies waiting for dependencies +Patch124: systemd-fix-merge-ignore-dependencies.patch # udev patches # PATCH-FIX-OPENSUSE 1001-Reinstate-TIMEOUT-handling.patch @@ -547,6 +553,9 @@ cp %{SOURCE7} m4/ %patch119 -p1 %patch120 -p1 %patch121 -p1 +%patch122 -p1 +%patch123 -p1 +%patch124 -p1 %build autoreconf -fiv diff --git a/tmpfiles-X-type.patch b/tmpfiles-X-type.patch new file mode 100644 index 00000000..40d9940e --- /dev/null +++ b/tmpfiles-X-type.patch @@ -0,0 +1,369 @@ +From 78a92a5a2306709e4587e332728a76901323ade9 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 18 Jan 2013 16:13:08 +0100 +Subject: [PATCH] tmpfiles: introduce type X + +Type X will exclude path itself from clean-up. However, if the path is a +directory systemd-tmpfiles will clean-up its content. + +In contrast to type x, where path is ignored completely, type X needs some +Age parameter. In order to determine Age parameter, we will look for config +entries of type d or D and pick the best match. Best match is either +exact match or longest prefix match. +--- + man/tmpfiles.d.xml | 15 ++++ + src/tmpfiles/tmpfiles.c | 192 ++++++++++++++++++++++++++++++----------------- + 2 files changed, 138 insertions(+), 69 deletions(-) + +Index: systemd-195/man/tmpfiles.d.xml +=================================================================== +--- systemd-195.orig/man/tmpfiles.d.xml ++++ systemd-195/man/tmpfiles.d.xml +@@ -166,6 +166,21 @@ L /tmp/foobar - - - - /dev + + + ++ X ++ Ignore a path ++ during cleanup. Use this type ++ to prevent path removal as ++ controlled with the Age parameter. ++ Note that if path is a directory, ++ content of a directory is not ++ excluded from clean-up, only ++ directory itself. Lines of this ++ type accept shell-style globs ++ in place of normal path ++ names. ++ ++ ++ + r + Remove a file + or directory if it +Index: systemd-195/src/tmpfiles/tmpfiles.c +=================================================================== +--- systemd-195.orig/src/tmpfiles/tmpfiles.c ++++ systemd-195/src/tmpfiles/tmpfiles.c +@@ -70,6 +70,7 @@ typedef enum ItemType { + + /* These ones take globs */ + IGNORE_PATH = 'x', ++ IGNORE_DIRECTORY_PATH = 'X', + REMOVE_PATH = 'r', + RECURSIVE_REMOVE_PATH = 'R', + RELABEL_PATH = 'z', +@@ -119,7 +120,7 @@ static const char * const conf_file_dirs + #define MAX_DEPTH 256 + + static bool needs_glob(ItemType t) { +- return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH || t == RELABEL_PATH || t == RECURSIVE_RELABEL_PATH; ++ return t == IGNORE_PATH || t == IGNORE_DIRECTORY_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH || t == RELABEL_PATH || t == RECURSIVE_RELABEL_PATH; + } + + static struct Item* find_glob(Hashmap *h, const char *match) { +@@ -218,6 +219,7 @@ static bool unix_socket_alive(const char + } + + static int dir_cleanup( ++ Item *i, + const char *p, + DIR *d, + const struct stat *ds, +@@ -297,7 +299,7 @@ static int dir_cleanup( + continue; + } + +- q = dir_cleanup(sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1, false); ++ q = dir_cleanup(i, sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1, false); + closedir(sub_dir); + + if (q < 0) +@@ -320,12 +322,14 @@ static int dir_cleanup( + if (age >= cutoff) + continue; + +- log_debug("rmdir '%s'\n", sub_path); ++ if (!i->type == IGNORE_DIRECTORY_PATH || !streq(dent->d_name, p)) { ++ log_debug("rmdir '%s'\n", sub_path); + +- if (unlinkat(dirfd(d), dent->d_name, AT_REMOVEDIR) < 0) { +- if (errno != ENOENT && errno != ENOTEMPTY) { +- log_error("rmdir(%s): %m", sub_path); +- r = -errno; ++ if (unlinkat(dirfd(d), dent->d_name, AT_REMOVEDIR) < 0) { ++ if (errno != ENOENT && errno != ENOTEMPTY) { ++ log_error("rmdir(%s): %m", sub_path); ++ r = -errno; ++ } + } + } + +@@ -395,68 +399,6 @@ finish: + return r; + } + +-static int clean_item(Item *i) { +- DIR *d; +- struct stat s, ps; +- bool mountpoint; +- int r; +- usec_t cutoff, n; +- +- assert(i); +- +- if (i->type != CREATE_DIRECTORY && +- i->type != TRUNCATE_DIRECTORY && +- i->type != IGNORE_PATH) +- return 0; +- +- if (!i->age_set || i->age <= 0) +- return 0; +- +- n = now(CLOCK_REALTIME); +- if (n < i->age) +- return 0; +- +- cutoff = n - i->age; +- +- d = opendir(i->path); +- if (!d) { +- if (errno == ENOENT) +- return 0; +- +- log_error("Failed to open directory %s: %m", i->path); +- return -errno; +- } +- +- if (fstat(dirfd(d), &s) < 0) { +- log_error("stat(%s) failed: %m", i->path); +- r = -errno; +- goto finish; +- } +- +- if (!S_ISDIR(s.st_mode)) { +- log_error("%s is not a directory.", i->path); +- r = -ENOTDIR; +- goto finish; +- } +- +- if (fstatat(dirfd(d), "..", &ps, AT_SYMLINK_NOFOLLOW) != 0) { +- log_error("stat(%s/..) failed: %m", i->path); +- r = -errno; +- goto finish; +- } +- +- mountpoint = s.st_dev != ps.st_dev || +- (s.st_dev == ps.st_dev && s.st_ino == ps.st_ino); +- +- r = dir_cleanup(i->path, d, &s, cutoff, s.st_dev, mountpoint, MAX_DEPTH, i->keep_first_level); +- +-finish: +- if (d) +- closedir(d); +- +- return r; +-} +- + static int item_set_perms(Item *i, const char *path) { + /* not using i->path directly because it may be a glob */ + if (i->mode_set) +@@ -667,6 +609,7 @@ static int create_item(Item *i) { + switch (i->type) { + + case IGNORE_PATH: ++ case IGNORE_DIRECTORY_PATH: + case REMOVE_PATH: + case RECURSIVE_REMOVE_PATH: + return 0; +@@ -850,6 +793,7 @@ static int remove_item_instance(Item *i, + case CREATE_BLOCK_DEVICE: + case CREATE_CHAR_DEVICE: + case IGNORE_PATH: ++ case IGNORE_DIRECTORY_PATH: + case RELABEL_PATH: + case RECURSIVE_RELABEL_PATH: + case WRITE_FILE: +@@ -894,6 +838,7 @@ static int remove_item(Item *i) { + case CREATE_CHAR_DEVICE: + case CREATE_BLOCK_DEVICE: + case IGNORE_PATH: ++ case IGNORE_DIRECTORY_PATH: + case RELABEL_PATH: + case RECURSIVE_RELABEL_PATH: + case WRITE_FILE: +@@ -909,6 +854,84 @@ static int remove_item(Item *i) { + return r; + } + ++static int clean_item_instance(Item *i, const char* instance) { ++ DIR *d; ++ struct stat s, ps; ++ bool mountpoint; ++ int r; ++ usec_t cutoff, n; ++ ++ assert(i); ++ ++ if (!i->age_set) ++ return 0; ++ ++ n = now(CLOCK_REALTIME); ++ if (n < i->age) ++ return 0; ++ ++ cutoff = n - i->age; ++ ++ d = opendir(instance); ++ if (!d) { ++ if (errno == ENOENT || errno == ENOTDIR) ++ return 0; ++ ++ log_error("Failed to open directory %s: %m", i->path); ++ return -errno; ++ } ++ ++ if (fstat(dirfd(d), &s) < 0) { ++ log_error("stat(%s) failed: %m", i->path); ++ r = -errno; ++ goto finish; ++ } ++ ++ if (!S_ISDIR(s.st_mode)) { ++ log_error("%s is not a directory.", i->path); ++ r = -ENOTDIR; ++ goto finish; ++ } ++ ++ if (fstatat(dirfd(d), "..", &ps, AT_SYMLINK_NOFOLLOW) != 0) { ++ log_error("stat(%s/..) failed: %m", i->path); ++ r = -errno; ++ goto finish; ++ } ++ ++ mountpoint = s.st_dev != ps.st_dev || ++ (s.st_dev == ps.st_dev && s.st_ino == ps.st_ino); ++ ++ r = dir_cleanup(i, instance, d, &s, cutoff, s.st_dev, mountpoint, MAX_DEPTH, i->keep_first_level); ++ ++finish: ++ if (d) ++ closedir(d); ++ ++ return r; ++} ++ ++static int clean_item(Item *i) { ++ int r = 0; ++ ++ assert(i); ++ ++ switch (i->type) { ++ case CREATE_DIRECTORY: ++ case TRUNCATE_DIRECTORY: ++ case IGNORE_PATH: ++ clean_item_instance(i, i->path); ++ break; ++ case IGNORE_DIRECTORY_PATH: ++ r = glob_item(i, clean_item_instance); ++ break; ++ default: ++ break; ++ } ++ ++ return r; ++} ++ + static int process_item(Item *i) { + int r, q, p; + +@@ -1028,6 +1051,7 @@ static int parse_line(const char *fname, + case TRUNCATE_DIRECTORY: + case CREATE_FIFO: + case IGNORE_PATH: ++ case IGNORE_DIRECTORY_PATH: + case REMOVE_PATH: + case RECURSIVE_REMOVE_PATH: + case RELABEL_PATH: +@@ -1264,6 +1288,8 @@ static int read_config_file(const char * + FILE *f; + unsigned v = 0; + int r = 0; ++ Iterator iterator; ++ Item *i; + + assert(fn); + +@@ -1296,6 +1322,34 @@ static int read_config_file(const char * + r = k; + } + ++ /* we have to determine age parameter for each entry of type X */ ++ HASHMAP_FOREACH(i, globs, iterator) { ++ Iterator iter; ++ Item *j, *candidate_item = NULL; ++ ++ if (i->type != IGNORE_DIRECTORY_PATH) ++ continue; ++ ++ HASHMAP_FOREACH(j, items, iter) { ++ if (j->type != CREATE_DIRECTORY && j->type != TRUNCATE_DIRECTORY) ++ continue; ++ ++ if (path_equal(j->path, i->path)) { ++ candidate_item = j; ++ break; ++ } ++ ++ if ((!candidate_item && path_startswith(i->path, j->path)) || ++ (candidate_item && path_startswith(j->path, candidate_item->path) && (fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0))) ++ candidate_item = j; ++ } ++ ++ if (candidate_item) { ++ i->age = candidate_item->age; ++ i->age_set = true; ++ } ++ } ++ + if (ferror(f)) { + log_error("Failed to read from file %s: %m", fn); + if (r == 0) +Index: systemd-195/tmpfiles.d/tmp.conf +=================================================================== +--- systemd-195.orig/tmpfiles.d/tmp.conf ++++ systemd-195/tmpfiles.d/tmp.conf +@@ -10,3 +10,7 @@ + # Clear tmp directories separately, to make them easier to override + d /tmp 1777 root root 10d + d /var/tmp 1777 root root 30d ++ ++# Exclude namespace mountpoints created with PrivateTmp=yes ++X /tmp/systemd-private-* ++X /var/tmp/systemd-private-* +Index: systemd-195/man/systemd.exec.xml +=================================================================== +--- systemd-195.orig/man/systemd.exec.xml ++++ systemd-195/man/systemd.exec.xml +@@ -1022,15 +1022,17 @@ + Takes a boolean + argument. If true sets up a new file + system namespace for the executed +- processes and mounts a private +- /tmp directory +- inside it, that is not shared by ++ processes and mounts private ++ /tmp and ++ /var/tmp directories ++ inside it, that are not shared by + processes outside of the + namespace. This is useful to secure + access to temporary files of the + process, but makes sharing between + processes via +- /tmp ++ /tmp or ++ /var/tmp + impossible. Defaults to + false. +