<term><varname>x</varname></term>
<listitem><para>Ignore a path during cleaning. Use this type
to exclude paths from clean-up as controlled with the Age
- parameter. Note that lines of this type do not influence the
- effect of <varname>r</varname> or <varname>R</varname>
- lines. Lines of this type accept shell-style globs in place
+ parameter. Lines of this type accept shell-style globs in place
of normal path names. </para></listitem>
</varlistentry>
to exclude paths from clean-up as controlled with the Age
parameter. Unlike <varname>x</varname>, this parameter will
not exclude the content if path is a directory, but only
- directory itself. Note that lines of this type do not
- influence the effect of <varname>r</varname> or
- <varname>R</varname> lines. Lines of this type accept
+ directory itself. Lines of this type accept
shell-style globs in place of normal path names.
</para>
}
finish:
- if (deleted) {
+ if (deleted && (self_atime_nsec < NSEC_INFINITY || self_mtime_nsec < NSEC_INFINITY)) {
struct timespec ts[2];
log_debug("Restoring access and modification time on \"%s\": %s, %s",
return 0;
}
-static int purge_item_instance(Context *c, Item *i, const char *instance, CreationMode creation) {
+static int remove_recursive(
+ Context *c,
+ Item *i,
+ const char *instance,
+ bool remove_instance) {
+
+ _cleanup_closedir_ DIR *d = NULL;
+ STRUCT_STATX_DEFINE(sx);
+ bool mountpoint;
int r;
- /* FIXME: we probably should use dir_cleanup() here instead of rm_rf() so that 'x' is honoured. */
- log_debug("rm -rf \"%s\"", instance);
- r = rm_rf(instance, REMOVE_ROOT|REMOVE_SUBVOLUME|REMOVE_PHYSICAL);
- if (r < 0 && r != -ENOENT)
- return log_error_errno(r, "rm_rf(%s): %m", instance);
+ r = opendir_and_stat(instance, &d, &sx, &mountpoint);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ if (remove_instance) {
+ log_debug("Removing file \"%s\".", instance);
+ if (remove(instance) < 0 && errno != ENOENT)
+ return log_error_errno(errno, "rm %s: %m", instance);
+ }
+ return 0;
+ }
+
+ r = dir_cleanup(c, i, instance, d,
+ /* self_atime_nsec= */ NSEC_INFINITY,
+ /* self_mtime_nsec= */ NSEC_INFINITY,
+ /* cutoff_nsec= */ NSEC_INFINITY,
+ sx.stx_dev_major, sx.stx_dev_minor,
+ mountpoint,
+ MAX_DEPTH,
+ /* keep_this_level= */ false,
+ /* age_by_file= */ 0,
+ /* age_by_dir= */ 0);
+ if (r < 0)
+ return r;
+ if (remove_instance) {
+ log_debug("Removing directory \"%s\".", instance);
+ r = RET_NERRNO(rmdir(instance));
+ if (r < 0 && !IN_SET(r, -ENOENT, -ENOTEMPTY))
+ return log_error_errno(r, "Failed to remove %s: %m", instance);
+ }
return 0;
}
-static int purge_item(Context *c, Item *i) {
+static int purge_item_instance(Context *c, Item *i, const char *instance, CreationMode creation) {
+ return remove_recursive(c, i, instance, /* remove_instance= */ true);
+}
+static int purge_item(Context *c, Item *i) {
assert(i);
if (!needs_purge(i->type))
return 0;
- log_debug("Running purge owned action for entry %c %s", (char) i->type, i->path);
+ log_debug("Running purge action for entry %c %s", (char) i->type, i->path);
if (needs_glob(i->type))
return glob_item(c, i, purge_item_instance);
const char *instance,
CreationMode creation) {
- int r;
-
assert(c);
assert(i);
case REMOVE_PATH:
if (remove(instance) < 0 && errno != ENOENT)
- return log_error_errno(errno, "rm(%s): %m", instance);
+ return log_error_errno(errno, "rm %s: %m", instance);
- break;
+ return 0;
case RECURSIVE_REMOVE_PATH:
- /* FIXME: we probably should use dir_cleanup() here instead of rm_rf() so that 'x' is honoured. */
- log_debug("rm -rf \"%s\"", instance);
- r = rm_rf(instance, REMOVE_ROOT|REMOVE_SUBVOLUME|REMOVE_PHYSICAL);
- if (r < 0 && r != -ENOENT)
- return log_error_errno(r, "rm_rf(%s): %m", instance);
-
- break;
+ return remove_recursive(c, i, instance, /* remove_instance= */ true);
default:
assert_not_reached();
}
-
- return 0;
}
static int remove_item(Context *c, Item *i) {
- int r;
-
assert(c);
assert(i);
switch (i->type) {
case TRUNCATE_DIRECTORY:
- /* FIXME: we probably should use dir_cleanup() here instead of rm_rf() so that 'x' is honoured. */
- log_debug("rm -rf \"%s\"", i->path);
- r = rm_rf(i->path, REMOVE_PHYSICAL);
- if (r < 0 && r != -ENOENT)
- return log_error_errno(r, "rm_rf(%s): %m", i->path);
-
- return 0;
+ return remove_recursive(c, i, i->path, /* remove_instance= */ false);
case REMOVE_PATH:
case RECURSIVE_REMOVE_PATH: