From: Lennart Poettering Date: Wed, 9 Aug 2023 09:37:46 +0000 (+0200) Subject: tmpfiles: move static vars into Context object X-Git-Tag: v255-rc1~763 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a5e4f3ab4ec8964cba9accbc23bf5e1523a833f9;p=thirdparty%2Fsystemd.git tmpfiles: move static vars into Context object Same as #28722, but for tmpfiles rather than sysusers --- diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index b8fb5c3b3ba..e765db4895d 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -212,12 +212,11 @@ static ImagePolicy *arg_image_policy = NULL; #define MAX_DEPTH 256 -static OrderedHashmap *items = NULL, *globs = NULL; -static Set *unix_sockets = NULL; +typedef struct Context { + OrderedHashmap *items, *globs; + Set *unix_sockets; +} Context; -STATIC_DESTRUCTOR_REGISTER(items, ordered_hashmap_freep); -STATIC_DESTRUCTOR_REGISTER(globs, ordered_hashmap_freep); -STATIC_DESTRUCTOR_REGISTER(unix_sockets, set_freep); STATIC_DESTRUCTOR_REGISTER(arg_include_prefixes, freep); STATIC_DESTRUCTOR_REGISTER(arg_exclude_prefixes, freep); STATIC_DESTRUCTOR_REGISTER(arg_root, freep); @@ -232,6 +231,15 @@ static const char *const creation_mode_verb_table[_CREATION_MODE_MAX] = { DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(creation_mode_verb, CreationMode); +static void context_done(Context *c) { + assert(c); + + ordered_hashmap_free(c->items); + ordered_hashmap_free(c->globs); + + set_free(c->unix_sockets); +} + /* Different kinds of errors that mean that information is not available in the environment. */ static inline bool ERRNO_IS_NOINFO(int r) { return IN_SET(abs(r), @@ -428,12 +436,12 @@ static struct Item* find_glob(OrderedHashmap *h, const char *match) { return NULL; } -static int load_unix_sockets(void) { +static int load_unix_sockets(Context *c) { _cleanup_set_free_ Set *sockets = NULL; _cleanup_fclose_ FILE *f = NULL; int r; - if (unix_sockets) + if (c->unix_sockets) return 0; /* We maintain a cache of the sockets we found in /proc/net/unix to speed things up a little. */ @@ -480,17 +488,18 @@ static int load_unix_sockets(void) { return log_warning_errno(r, "Failed to add AF_UNIX socket to set, ignoring: %m"); } - unix_sockets = TAKE_PTR(sockets); + c->unix_sockets = TAKE_PTR(sockets); return 1; } -static bool unix_socket_alive(const char *fn) { +static bool unix_socket_alive(Context *c, const char *fn) { + assert(c); assert(fn); - if (load_unix_sockets() < 0) + if (load_unix_sockets(c) < 0) return true; /* We don't know, so assume yes */ - return set_contains(unix_sockets, fn); + return set_contains(c->unix_sockets, fn); } /* Accessors for the argument in binary format */ @@ -595,6 +604,7 @@ static bool needs_cleanup( } static int dir_cleanup( + Context *c, Item *i, const char *p, DIR *d, @@ -612,6 +622,10 @@ static int dir_cleanup( bool deleted = false; int r = 0; + assert(c); + assert(i); + assert(d); + FOREACH_DIRENT_ALL(de, d, break) { _cleanup_free_ char *sub_path = NULL; nsec_t atime_nsec, mtime_nsec, ctime_nsec, btime_nsec; @@ -689,12 +703,12 @@ static int dir_cleanup( } /* Is there an item configured for this path? */ - if (ordered_hashmap_get(items, sub_path)) { + if (ordered_hashmap_get(c->items, sub_path)) { log_debug("Ignoring \"%s\": a separate entry exists.", sub_path); continue; } - if (find_glob(globs, sub_path)) { + if (find_glob(c->globs, sub_path)) { log_debug("Ignoring \"%s\": a separate glob exists.", sub_path); continue; } @@ -727,7 +741,7 @@ static int dir_cleanup( continue; } - q = dir_cleanup(i, + q = dir_cleanup(c, i, sub_path, sub_dir, atime_nsec, mtime_nsec, cutoff_nsec, rootdev_major, rootdev_minor, @@ -782,7 +796,7 @@ static int dir_cleanup( } /* Ignore sockets that are listed in /proc/net/unix */ - if (S_ISSOCK(sx.stx_mode) && unix_socket_alive(sub_path)) { + if (S_ISSOCK(sx.stx_mode) && unix_socket_alive(c, sub_path)) { log_debug("Skipping \"%s\": live socket.", sub_path); continue; } @@ -892,6 +906,7 @@ static mode_t process_mask_perms(mode_t mode, mode_t current) { } static int fd_set_perms( + Context *c, Item *i, int fd, const char *path, @@ -905,6 +920,7 @@ static int fd_set_perms( gid_t new_gid; int r; + assert(c); assert(i); assert(fd >= 0); assert(path); @@ -1038,12 +1054,14 @@ static int path_open_safe(const char *path) { } static int path_set_perms( + Context *c, Item *i, const char *path, CreationMode creation) { _cleanup_close_ int fd = -EBADF; + assert(c); assert(i); assert(path); @@ -1051,7 +1069,7 @@ static int path_set_perms( if (fd < 0) return fd; - return fd_set_perms(i, fd, path, /* st= */ NULL, creation); + return fd_set_perms(c, i, fd, path, /* st= */ NULL, creation); } static int parse_xattrs_from_arg(Item *i) { @@ -1091,12 +1109,14 @@ static int parse_xattrs_from_arg(Item *i) { } static int fd_set_xattrs( + Context *c, Item *i, int fd, const char *path, const struct stat *st, CreationMode creation) { + assert(c); assert(i); assert(fd >= 0); assert(path); @@ -1111,12 +1131,14 @@ static int fd_set_xattrs( } static int path_set_xattrs( + Context *c, Item *i, const char *path, CreationMode creation) { _cleanup_close_ int fd = -EBADF; + assert(c); assert(i); assert(path); @@ -1124,7 +1146,7 @@ static int path_set_xattrs( if (fd < 0) return fd; - return fd_set_xattrs(i, fd, path, /* st = */ NULL, creation); + return fd_set_xattrs(c, i, fd, path, /* st = */ NULL, creation); } static int parse_acls_from_arg(Item *item) { @@ -1277,6 +1299,7 @@ finish: } static int path_set_acl( + Context *c, const char *path, const char *pretty, acl_type_t type, @@ -1287,8 +1310,9 @@ static int path_set_acl( _cleanup_(acl_freep) acl_t dup = NULL; int r; - /* Returns 0 for success, positive error if already warned, - * negative error otherwise. */ + assert(c); + + /* Returns 0 for success, positive error if already warned, negative error otherwise. */ if (modify) { r = acls_for_file(path, type, acl, &dup); @@ -1332,6 +1356,7 @@ static int path_set_acl( #endif static int fd_set_acls( + Context *c, Item *item, int fd, const char *path, @@ -1343,6 +1368,7 @@ static int fd_set_acls( _cleanup_(acl_freep) acl_t access_with_exec_parsed = NULL; struct stat stbuf; + assert(c); assert(item); assert(fd >= 0); assert(path); @@ -1373,13 +1399,13 @@ static int fd_set_acls( if (r < 0) return log_error_errno(r, "Failed to parse conditionalized execute bit for \"%s\": %m", path); - r = path_set_acl(FORMAT_PROC_FD_PATH(fd), path, ACL_TYPE_ACCESS, access_with_exec_parsed, item->append_or_force); + r = path_set_acl(c, FORMAT_PROC_FD_PATH(fd), path, ACL_TYPE_ACCESS, access_with_exec_parsed, item->append_or_force); } else if (item->acl_access) - r = path_set_acl(FORMAT_PROC_FD_PATH(fd), path, ACL_TYPE_ACCESS, item->acl_access, item->append_or_force); + r = path_set_acl(c, FORMAT_PROC_FD_PATH(fd), path, ACL_TYPE_ACCESS, item->acl_access, item->append_or_force); /* set only default acls to folders */ if (r == 0 && item->acl_default && S_ISDIR(st->st_mode)) - r = path_set_acl(FORMAT_PROC_FD_PATH(fd), path, ACL_TYPE_DEFAULT, item->acl_default, item->append_or_force); + r = path_set_acl(c, FORMAT_PROC_FD_PATH(fd), path, ACL_TYPE_DEFAULT, item->acl_default, item->append_or_force); if (ERRNO_IS_NOT_SUPPORTED(r)) { log_debug_errno(r, "ACLs not supported by file system at %s", path); @@ -1399,11 +1425,17 @@ static int fd_set_acls( return r; } -static int path_set_acls(Item *item, const char *path, CreationMode creation) { +static int path_set_acls( + Context *c, + Item *item, + const char *path, + CreationMode creation) { + int r = 0; #if HAVE_ACL _cleanup_close_ int fd = -EBADF; + assert(c); assert(item); assert(path); @@ -1411,7 +1443,7 @@ static int path_set_acls(Item *item, const char *path, CreationMode creation) { if (fd < 0) return fd; - r = fd_set_acls(item, fd, path, /* st= */ NULL, creation); + r = fd_set_acls(c, item, fd, path, /* st= */ NULL, creation); #endif return r; } @@ -1501,6 +1533,7 @@ static int parse_attribute_from_arg(Item *item) { } static int fd_set_attribute( + Context *c, Item *item, int fd, const char *path, @@ -1512,6 +1545,7 @@ static int fd_set_attribute( unsigned f; int r; + assert(c); assert(item); assert(fd >= 0); assert(path); @@ -1556,9 +1590,17 @@ static int fd_set_attribute( return 0; } -static int path_set_attribute(Item *item, const char *path, CreationMode creation) { +static int path_set_attribute( + Context *c, + Item *item, + const char *path, + CreationMode creation) { + _cleanup_close_ int fd = -EBADF; + assert(c); + assert(item); + if (!item->attribute_set || item->attribute_mask == 0) return 0; @@ -1566,7 +1608,7 @@ static int path_set_attribute(Item *item, const char *path, CreationMode creatio if (fd < 0) return fd; - return fd_set_attribute(item, fd, path, /* st= */ NULL, creation); + return fd_set_attribute(c, item, fd, path, /* st= */ NULL, creation); } static int write_argument_data(Item *i, int fd, const char *path) { @@ -1590,11 +1632,12 @@ static int write_argument_data(Item *i, int fd, const char *path) { return 0; } -static int write_one_file(Item *i, const char *path, CreationMode creation) { +static int write_one_file(Context *c, Item *i, const char *path, CreationMode creation) { _cleanup_close_ int fd = -EBADF, dir_fd = -EBADF; _cleanup_free_ char *bn = NULL; int r; + assert(c); assert(i); assert(path); assert(i->type == WRITE_FILE); @@ -1633,16 +1676,21 @@ static int write_one_file(Item *i, const char *path, CreationMode creation) { if (r < 0) return r; - return fd_set_perms(i, fd, path, NULL, creation); + return fd_set_perms(c, i, fd, path, NULL, creation); } -static int create_file(Item *i, const char *path) { +static int create_file( + Context *c, + Item *i, + const char *path) { + _cleanup_close_ int fd = -EBADF, dir_fd = -EBADF; _cleanup_free_ char *bn = NULL; struct stat stbuf, *st = NULL; CreationMode creation; int r = 0; + assert(c); assert(i); assert(path); assert(i->type == CREATE_FILE); @@ -1698,10 +1746,14 @@ static int create_file(Item *i, const char *path) { creation = CREATION_NORMAL; } - return fd_set_perms(i, fd, path, st, creation); + return fd_set_perms(c, i, fd, path, st, creation); } -static int truncate_file(Item *i, const char *path) { +static int truncate_file( + Context *c, + Item *i, + const char *path) { + _cleanup_close_ int fd = -EBADF, dir_fd = -EBADF; _cleanup_free_ char *bn = NULL; struct stat stbuf, *st = NULL; @@ -1709,6 +1761,7 @@ static int truncate_file(Item *i, const char *path) { bool erofs = false; int r = 0; + assert(c); assert(i); assert(path); assert(i->type == TRUNCATE_FILE || (i->type == CREATE_FILE && i->append_or_force)); @@ -1787,10 +1840,10 @@ static int truncate_file(Item *i, const char *path) { return r; } - return fd_set_perms(i, fd, path, st, creation); + return fd_set_perms(c, i, fd, path, st, creation); } -static int copy_files(Item *i) { +static int copy_files(Context *c, Item *i) { _cleanup_close_ int dfd = -EBADF, fd = -EBADF; _cleanup_free_ char *bn = NULL; struct stat st, a; @@ -1834,7 +1887,7 @@ static int copy_files(Item *i) { return 0; } - return fd_set_perms(i, fd, i->path, &st, _CREATION_MODE_INVALID); + return fd_set_perms(c, i, fd, i->path, &st, _CREATION_MODE_INVALID); } static int create_directory_or_subvolume( @@ -1922,11 +1975,16 @@ static int create_directory_or_subvolume( return fd; } -static int create_directory(Item *i, const char *path) { +static int create_directory( + Context *c, + Item *i, + const char *path) { + _cleanup_close_ int fd = -EBADF; CreationMode creation; struct stat st; + assert(c); assert(i); assert(IN_SET(i->type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY)); @@ -1936,15 +1994,20 @@ static int create_directory(Item *i, const char *path) { if (fd < 0) return fd; - return fd_set_perms(i, fd, path, &st, creation); + return fd_set_perms(c, i, fd, path, &st, creation); } -static int create_subvolume(Item *i, const char *path) { +static int create_subvolume( + Context *c, + Item *i, + const char *path) { + _cleanup_close_ int fd = -EBADF; CreationMode creation; struct stat st; int r, q = 0; + assert(c); assert(i); assert(IN_SET(i->type, CREATE_SUBVOLUME, CREATE_SUBVOLUME_NEW_QUOTA, CREATE_SUBVOLUME_INHERIT_QUOTA)); @@ -1971,18 +2034,24 @@ static int create_subvolume(Item *i, const char *path) { log_debug("Quota for subvolume \"%s\" already in place, no change made.", i->path); } - r = fd_set_perms(i, fd, path, &st, creation); + r = fd_set_perms(c, i, fd, path, &st, creation); if (q < 0) /* prefer the quota change error from above */ return q; return r; } -static int empty_directory(Item *i, const char *path, CreationMode creation) { +static int empty_directory( + Context *c, + Item *i, + const char *path, + CreationMode creation) { + _cleanup_close_ int fd = -EBADF; struct stat st; int r; + assert(c); assert(i); assert(i->type == EMPTY_DIRECTORY); @@ -2005,16 +2074,21 @@ static int empty_directory(Item *i, const char *path, CreationMode creation) { return 0; } - return fd_set_perms(i, fd, path, &st, creation); + return fd_set_perms(c, i, fd, path, &st, creation); } -static int create_device(Item *i, mode_t file_type) { +static int create_device( + Context *c, + Item *i, + mode_t file_type) { + _cleanup_close_ int dfd = -EBADF, fd = -EBADF; _cleanup_free_ char *bn = NULL; CreationMode creation; struct stat st; int r; + assert(c); assert(i); assert(IN_SET(i->type, CREATE_BLOCK_DEVICE, CREATE_CHAR_DEVICE)); assert(IN_SET(file_type, S_IFBLK, S_IFCHR)); @@ -2104,7 +2178,7 @@ static int create_device(Item *i, mode_t file_type) { i->type == CREATE_BLOCK_DEVICE ? "block" : "char", i->path, major(i->mode), minor(i->mode)); - return fd_set_perms(i, fd, i->path, &st, creation); + return fd_set_perms(c, i, fd, i->path, &st, creation); handle_privilege: log_debug_errno(r, @@ -2113,13 +2187,14 @@ handle_privilege: return 0; } -static int create_fifo(Item *i) { +static int create_fifo(Context *c, Item *i) { _cleanup_close_ int pfd = -EBADF, fd = -EBADF; _cleanup_free_ char *bn = NULL; CreationMode creation; struct stat st; int r; + assert(c); assert(i); assert(i->type == CREATE_FIFO); @@ -2195,10 +2270,10 @@ static int create_fifo(Item *i) { log_debug("%s fifo \"%s\".", creation_mode_verb_to_string(creation), i->path); - return fd_set_perms(i, fd, i->path, &st, creation); + return fd_set_perms(c, i, fd, i->path, &st, creation); } -static int create_symlink(Item *i) { +static int create_symlink(Context *c, Item *i) { _cleanup_close_ int pfd = -EBADF, fd = -EBADF; _cleanup_free_ char *bn = NULL; CreationMode creation; @@ -2206,6 +2281,7 @@ static int create_symlink(Item *i) { bool good = false; int r; + assert(c); assert(i); r = path_extract_filename(i->path, &bn); @@ -2284,13 +2360,14 @@ static int create_symlink(Item *i) { } log_debug("%s symlink \"%s\".", creation_mode_verb_to_string(creation), i->path); - return fd_set_perms(i, fd, i->path, &st, creation); + return fd_set_perms(c, i, fd, i->path, &st, creation); } -typedef int (*action_t)(Item *i, const char *path, CreationMode creation); -typedef int (*fdaction_t)(Item *i, int fd, const char *path, const struct stat *st, CreationMode creation); +typedef int (*action_t)(Context *c, Item *i, const char *path, CreationMode creation); +typedef int (*fdaction_t)(Context *c, Item *i, int fd, const char *path, const struct stat *st, CreationMode creation); static int item_do( + Context *c, Item *i, int fd, const char *path, @@ -2300,6 +2377,7 @@ static int item_do( struct stat st; int r = 0, q; + assert(c); assert(i); assert(path); assert(fd >= 0); @@ -2310,7 +2388,7 @@ static int item_do( } /* This returns the first error we run into, but nevertheless tries to go on */ - r = action(i, fd, path, &st, creation); + r = action(c, i, fd, path, &st, creation); if (S_ISDIR(st.st_mode)) { _cleanup_closedir_ DIR *d = NULL; @@ -2342,7 +2420,7 @@ static int item_do( q = log_oom(); else /* Pass ownership of dirent fd over */ - q = item_do(i, de_fd, de_path, CREATION_EXISTING, action); + q = item_do(c, i, de_fd, de_path, CREATION_EXISTING, action); } if (q < 0 && r == 0) @@ -2354,19 +2432,22 @@ finish: return r; } -static int glob_item(Item *i, action_t action) { +static int glob_item(Context *c, Item *i, action_t action) { _cleanup_globfree_ glob_t g = { .gl_opendir = (void *(*)(const char *)) opendir_nomod, }; int r = 0, k; + assert(c); + assert(i); + k = safe_glob(i->path, GLOB_NOSORT|GLOB_BRACE, &g); if (k < 0 && k != -ENOENT) return log_error_errno(k, "glob(%s) failed: %m", i->path); STRV_FOREACH(fn, g.gl_pathv) { /* We pass CREATION_EXISTING here, since if we are globbing for it, it always has to exist */ - k = action(i, *fn, CREATION_EXISTING); + k = action(c, i, *fn, CREATION_EXISTING); if (k < 0 && r == 0) r = k; } @@ -2374,7 +2455,11 @@ static int glob_item(Item *i, action_t action) { return r; } -static int glob_item_recursively(Item *i, fdaction_t action) { +static int glob_item_recursively( + Context *c, + Item *i, + fdaction_t action) { + _cleanup_globfree_ glob_t g = { .gl_opendir = (void *(*)(const char *)) opendir_nomod, }; @@ -2400,7 +2485,7 @@ static int glob_item_recursively(Item *i, fdaction_t action) { continue; } - k = item_do(i, fd, *fn, CREATION_EXISTING, action); + k = item_do(c, i, fd, *fn, CREATION_EXISTING, action); if (k < 0 && r == 0) r = k; @@ -2584,9 +2669,10 @@ static int mkdir_parents_item(Item *i, mode_t child_mode) { return 0; } -static int create_item(Item *i) { +static int create_item(Context *c, Item *i) { int r; + assert(c); assert(i); log_debug("Running create action for entry %c %s", (char) i->type, i->path); @@ -2606,9 +2692,9 @@ static int create_item(Item *i) { return r; if ((i->type == CREATE_FILE && i->append_or_force) || i->type == TRUNCATE_FILE) - r = truncate_file(i, i->path); + r = truncate_file(c, i, i->path); else - r = create_file(i, i->path); + r = create_file(c, i, i->path); if (r < 0) return r; break; @@ -2618,13 +2704,13 @@ static int create_item(Item *i) { if (r < 0) return r; - r = copy_files(i); + r = copy_files(c, i); if (r < 0) return r; break; case WRITE_FILE: - r = glob_item(i, write_one_file); + r = glob_item(c, i, write_one_file); if (r < 0) return r; @@ -2636,7 +2722,7 @@ static int create_item(Item *i) { if (r < 0) return r; - r = create_directory(i, i->path); + r = create_directory(c, i, i->path); if (r < 0) return r; break; @@ -2648,13 +2734,13 @@ static int create_item(Item *i) { if (r < 0) return r; - r = create_subvolume(i, i->path); + r = create_subvolume(c, i, i->path); if (r < 0) return r; break; case EMPTY_DIRECTORY: - r = glob_item(i, empty_directory); + r = glob_item(c, i, empty_directory); if (r < 0) return r; break; @@ -2664,7 +2750,7 @@ static int create_item(Item *i) { if (r < 0) return r; - r = create_fifo(i); + r = create_fifo(c, i); if (r < 0) return r; break; @@ -2674,7 +2760,7 @@ static int create_item(Item *i) { if (r < 0) return r; - r = create_symlink(i); + r = create_symlink(c, i); if (r < 0) return r; @@ -2694,7 +2780,7 @@ static int create_item(Item *i) { if (r < 0) return r; - r = create_device(i, i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR); + r = create_device(c, i, i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR); if (r < 0) return r; @@ -2702,49 +2788,49 @@ static int create_item(Item *i) { case ADJUST_MODE: case RELABEL_PATH: - r = glob_item(i, path_set_perms); + r = glob_item(c, i, path_set_perms); if (r < 0) return r; break; case RECURSIVE_RELABEL_PATH: - r = glob_item_recursively(i, fd_set_perms); + r = glob_item_recursively(c, i, fd_set_perms); if (r < 0) return r; break; case SET_XATTR: - r = glob_item(i, path_set_xattrs); + r = glob_item(c, i, path_set_xattrs); if (r < 0) return r; break; case RECURSIVE_SET_XATTR: - r = glob_item_recursively(i, fd_set_xattrs); + r = glob_item_recursively(c, i, fd_set_xattrs); if (r < 0) return r; break; case SET_ACL: - r = glob_item(i, path_set_acls); + r = glob_item(c, i, path_set_acls); if (r < 0) return r; break; case RECURSIVE_SET_ACL: - r = glob_item_recursively(i, fd_set_acls); + r = glob_item_recursively(c, i, fd_set_acls); if (r < 0) return r; break; case SET_ATTRIBUTE: - r = glob_item(i, path_set_attribute); + r = glob_item(c, i, path_set_attribute); if (r < 0) return r; break; case RECURSIVE_SET_ATTRIBUTE: - r = glob_item_recursively(i, fd_set_attribute); + r = glob_item_recursively(c, i, fd_set_attribute); if (r < 0) return r; break; @@ -2753,9 +2839,15 @@ static int create_item(Item *i) { return 0; } -static int remove_item_instance(Item *i, const char *instance, CreationMode creation) { +static int remove_item_instance( + Context *c, + Item *i, + const char *instance, + CreationMode creation) { + int r; + assert(c); assert(i); switch (i->type) { @@ -2782,9 +2874,10 @@ static int remove_item_instance(Item *i, const char *instance, CreationMode crea return 0; } -static int remove_item(Item *i) { +static int remove_item(Context *c, Item *i) { int r; + assert(c); assert(i); log_debug("Running remove action for entry %c %s", (char) i->type, i->path); @@ -2802,7 +2895,7 @@ static int remove_item(Item *i) { case REMOVE_PATH: case RECURSIVE_REMOVE_PATH: - return glob_item(i, remove_item_instance); + return glob_item(c, i, remove_item_instance); default: return 0; @@ -2827,6 +2920,7 @@ static char *age_by_to_string(AgeBy ab, bool is_dir) { } static int clean_item_instance( + Context *c, Item *i, const char* instance, CreationMode creation) { @@ -2893,7 +2987,7 @@ static int clean_item_instance( ab_f, ab_d); } - return dir_cleanup(i, instance, d, + return dir_cleanup(c, i, instance, d, load_statx_timestamp_nsec(&sx.stx_atime), load_statx_timestamp_nsec(&sx.stx_mtime), cutoff * NSEC_PER_USEC, @@ -2902,12 +2996,14 @@ static int clean_item_instance( i->age_by_file, i->age_by_dir); } -static int clean_item(Item *i) { +static int clean_item(Context *c, Item *i) { + assert(c); assert(i); log_debug("Running clean action for entry %c %s", (char) i->type, i->path); switch (i->type) { + case CREATE_DIRECTORY: case CREATE_SUBVOLUME: case CREATE_SUBVOLUME_INHERIT_QUOTA: @@ -2915,22 +3011,29 @@ static int clean_item(Item *i) { case TRUNCATE_DIRECTORY: case IGNORE_PATH: case COPY_FILES: - clean_item_instance(i, i->path, CREATION_EXISTING); + clean_item_instance(c, i, i->path, CREATION_EXISTING); return 0; + case EMPTY_DIRECTORY: case IGNORE_DIRECTORY_PATH: - return glob_item(i, clean_item_instance); + return glob_item(c, i, clean_item_instance); + default: return 0; } } -static int process_item(Item *i, OperationMask operation) { +static int process_item( + Context *c, + Item *i, + OperationMask operation) { + OperationMask todo; _cleanup_free_ char *_path = NULL; const char *path; int r, q, p; + assert(c); assert(i); todo = operation & ~i->done; @@ -2959,37 +3062,42 @@ static int process_item(Item *i, OperationMask operation) { if (r < 0) log_debug_errno(r, "Failed to determine whether '%s' is below autofs, ignoring: %m", i->path); - r = FLAGS_SET(operation, OPERATION_CREATE) ? create_item(i) : 0; + r = FLAGS_SET(operation, OPERATION_CREATE) ? create_item(c, i) : 0; /* Failure can only be tolerated for create */ if (i->allow_failure) r = 0; - q = FLAGS_SET(operation, OPERATION_REMOVE) ? remove_item(i) : 0; - p = FLAGS_SET(operation, OPERATION_CLEAN) ? clean_item(i) : 0; + q = FLAGS_SET(operation, OPERATION_REMOVE) ? remove_item(c, i) : 0; + p = FLAGS_SET(operation, OPERATION_CLEAN) ? clean_item(c, i) : 0; return r < 0 ? r : q < 0 ? q : p; } -static int process_item_array(ItemArray *array, OperationMask operation) { +static int process_item_array( + Context *c, + ItemArray *array, + OperationMask operation) { + int r = 0; size_t n; + assert(c); assert(array); /* Create any parent first. */ if (FLAGS_SET(operation, OPERATION_CREATE) && array->parent) - r = process_item_array(array->parent, operation & OPERATION_CREATE); + r = process_item_array(c, array->parent, operation & OPERATION_CREATE); /* Clean up all children first */ if ((operation & (OPERATION_REMOVE|OPERATION_CLEAN)) && !set_isempty(array->children)) { - ItemArray *c; + ItemArray *cc; - SET_FOREACH(c, array->children) { + SET_FOREACH(cc, array->children) { int k; - k = process_item_array(c, operation & (OPERATION_REMOVE|OPERATION_CLEAN)); + k = process_item_array(c, cc, operation & (OPERATION_REMOVE|OPERATION_CLEAN)); if (k < 0 && r == 0) r = k; } @@ -2998,7 +3106,7 @@ static int process_item_array(ItemArray *array, OperationMask operation) { for (n = 0; n < array->n_items; n++) { int k; - k = process_item(array->items + n, operation); + k = process_item(c, array->items + n, operation); if (k < 0 && r == 0) r = k; } @@ -3315,6 +3423,7 @@ static bool is_duplicated_item(ItemArray *existing, const Item *i) { } static int parse_line( + Context *c, const char *fname, unsigned line, const char *buffer, @@ -3334,6 +3443,7 @@ static int parse_line( bool append_or_force = false, boot = false, allow_failure = false, try_replace = false, unbase64 = false, from_cred = false, missing_user_or_group = false; + assert(c); assert(fname); assert(line >= 1); assert(buffer); @@ -3786,7 +3896,7 @@ static int parse_line( i.age_set = true; } - h = needs_glob(i.type) ? globs : items; + h = needs_glob(i.type) ? c->globs : c->items; existing = ordered_hashmap_get(h, i.path); if (existing) { @@ -4053,6 +4163,7 @@ static int parse_argv(int argc, char *argv[]) { } static int read_config_file( + Context *c, char **config_dirs, const char *fn, bool ignore_enoent, @@ -4066,6 +4177,7 @@ static int read_config_file( ItemArray *ia; int r = 0; + assert(c); assert(fn); if (streq(fn, "-")) { @@ -4106,7 +4218,7 @@ static int read_config_file( if (IN_SET(*l, 0, '#')) continue; - k = parse_line(fn, v, l, &invalid_line, &uid_cache, &gid_cache); + k = parse_line(c, fn, v, l, &invalid_line, &uid_cache, &gid_cache); if (k < 0) { if (invalid_line) /* Allow reporting with a special code if the caller requested this */ @@ -4118,7 +4230,7 @@ static int read_config_file( } /* we have to determine age parameter for each entry of type X */ - ORDERED_HASHMAP_FOREACH(ia, globs) + ORDERED_HASHMAP_FOREACH(ia, c->globs) for (size_t ni = 0; ni < ia->n_items; ni++) { ItemArray *ja; Item *i = ia->items + ni, *candidate_item = NULL; @@ -4126,7 +4238,7 @@ static int read_config_file( if (i->type != IGNORE_DIRECTORY_PATH) continue; - ORDERED_HASHMAP_FOREACH(ja, items) + ORDERED_HASHMAP_FOREACH(ja, c->items) for (size_t nj = 0; nj < ja->n_items; nj++) { Item *j = ja->items + nj; @@ -4163,11 +4275,17 @@ static int read_config_file( return r; } -static int parse_arguments(char **config_dirs, char **args, bool *invalid_config) { +static int parse_arguments( + Context *c, + char **config_dirs, + char **args, + bool *invalid_config) { int r; + assert(c); + STRV_FOREACH(arg, args) { - r = read_config_file(config_dirs, *arg, false, invalid_config); + r = read_config_file(c, config_dirs, *arg, false, invalid_config); if (r < 0) return r; } @@ -4175,11 +4293,18 @@ static int parse_arguments(char **config_dirs, char **args, bool *invalid_config return 0; } -static int read_config_files(char **config_dirs, char **args, bool *invalid_config) { +static int read_config_files( + Context *c, + char **config_dirs, + char **args, + bool *invalid_config) { + _cleanup_strv_free_ char **files = NULL; _cleanup_free_ char *p = NULL; int r; + assert(c); + r = conf_files_list_with_replacement(arg_root, config_dirs, arg_replace, &files, &p); if (r < 0) return r; @@ -4188,22 +4313,25 @@ static int read_config_files(char **config_dirs, char **args, bool *invalid_conf if (p && path_equal(*f, p)) { log_debug("Parsing arguments at position \"%s\"%s", *f, special_glyph(SPECIAL_GLYPH_ELLIPSIS)); - r = parse_arguments(config_dirs, args, invalid_config); + r = parse_arguments(c, config_dirs, args, invalid_config); if (r < 0) return r; } else /* Just warn, ignore result otherwise. * read_config_file() has some debug output, so no need to print anything. */ - (void) read_config_file(config_dirs, *f, true, invalid_config); + (void) read_config_file(c, config_dirs, *f, true, invalid_config); return 0; } -static int read_credential_lines(bool *invalid_config) { +static int read_credential_lines(Context *c, bool *invalid_config) { + _cleanup_free_ char *j = NULL; const char *d; int r; + assert(c); + r = get_credentials_dir(&d); if (r == -ENXIO) return 0; @@ -4214,15 +4342,16 @@ static int read_credential_lines(bool *invalid_config) { if (!j) return log_oom(); - (void) read_config_file(/* config_dirs= */ NULL, j, /* ignore_enoent= */ true, invalid_config); + (void) read_config_file(c, /* config_dirs= */ NULL, j, /* ignore_enoent= */ true, invalid_config); return 0; } -static int link_parent(ItemArray *a) { +static int link_parent(Context *c, ItemArray *a) { const char *path; char *prefix; int r; + assert(c); assert(a); /* Finds the closest "parent" item array for the specified item array. Then registers the specified item array @@ -4237,9 +4366,9 @@ static int link_parent(ItemArray *a) { PATH_FOREACH_PREFIX(prefix, path) { ItemArray *j; - j = ordered_hashmap_get(items, prefix); + j = ordered_hashmap_get(c->items, prefix); if (!j) - j = ordered_hashmap_get(globs, prefix); + j = ordered_hashmap_get(c->globs, prefix); if (j) { r = set_ensure_put(&j->children, NULL, a); if (r < 0) @@ -4262,6 +4391,7 @@ static int run(int argc, char *argv[]) { _cleanup_(umount_and_freep) char *mounted_dir = NULL; #endif _cleanup_strv_free_ char **config_dirs = NULL; + _cleanup_(context_done) Context c = {}; bool invalid_config = false; ItemArray *a; enum { @@ -4364,9 +4494,9 @@ static int run(int argc, char *argv[]) { assert(!arg_image); #endif - items = ordered_hashmap_new(&item_array_hash_ops); - globs = ordered_hashmap_new(&item_array_hash_ops); - if (!items || !globs) + c.items = ordered_hashmap_new(&item_array_hash_ops); + c.globs = ordered_hashmap_new(&item_array_hash_ops); + if (!c.items || !c.globs) return log_oom(); /* If command line arguments are specified along with --replace, read all @@ -4376,24 +4506,24 @@ static int run(int argc, char *argv[]) { * read configuration and execute it. */ if (arg_replace || optind >= argc) - r = read_config_files(config_dirs, argv + optind, &invalid_config); + r = read_config_files(&c, config_dirs, argv + optind, &invalid_config); else - r = parse_arguments(config_dirs, argv + optind, &invalid_config); + r = parse_arguments(&c, config_dirs, argv + optind, &invalid_config); if (r < 0) return r; - r = read_credential_lines(&invalid_config); + r = read_credential_lines(&c, &invalid_config); if (r < 0) return r; /* Let's now link up all child/parent relationships */ - ORDERED_HASHMAP_FOREACH(a, items) { - r = link_parent(a); + ORDERED_HASHMAP_FOREACH(a, c.items) { + r = link_parent(&c, a); if (r < 0) return r; } - ORDERED_HASHMAP_FOREACH(a, globs) { - r = link_parent(a); + ORDERED_HASHMAP_FOREACH(a, c.globs) { + r = link_parent(&c, a); if (r < 0) return r; } @@ -4414,15 +4544,15 @@ static int run(int argc, char *argv[]) { continue; /* The non-globbing ones usually create things, hence we apply them first */ - ORDERED_HASHMAP_FOREACH(a, items) { - k = process_item_array(a, op); + ORDERED_HASHMAP_FOREACH(a, c.items) { + k = process_item_array(&c, a, op); if (k < 0 && r >= 0) r = k; } /* The globbing ones usually alter things, hence we apply them second. */ - ORDERED_HASHMAP_FOREACH(a, globs) { - k = process_item_array(a, op); + ORDERED_HASHMAP_FOREACH(a, c.globs) { + k = process_item_array(&c, a, op); if (k < 0 && r >= 0) r = k; }