1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-12-24 21:34:08 +03:00

core: avoid calling path_simplify() unnecessarilly for u.requires_mounts_for keys

We would always call path_simplify() before doing a lookup, which requires the
path key to be duplicated first. But the hashmap lookup doesn't require this…
So let's opportunistically skip the allocation if the key is already present.

Inspired by https://github.com/systemd/systemd/pull/19973.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2021-06-23 17:32:15 +02:00
parent 0fb789af20
commit ac19bdd04b
2 changed files with 18 additions and 22 deletions

View File

@ -4511,16 +4511,14 @@ void manager_status_printf(Manager *m, StatusType type, const char *status, cons
va_end(ap);
}
Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
char p[strlen(path)+1];
Set* manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
assert(m);
assert(path);
strcpy(p, path);
path_simplify(p);
if (path_equal(path, "/"))
path = "";
return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p);
return hashmap_get(m->units_requiring_mounts_for, path);
}
int manager_update_failed_units(Manager *m, Unit *u, bool failed) {

View File

@ -4562,45 +4562,43 @@ int unit_kill_context(
}
int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask) {
_cleanup_free_ char *p = NULL;
UnitDependencyInfo di;
int r;
assert(u);
assert(path);
/* Registers a unit for requiring a certain path and all its prefixes. We keep a hashtable of these paths in
* the unit (from the path to the UnitDependencyInfo structure indicating how to the dependency came to
* be). However, we build a prefix table for all possible prefixes so that new appearing mount units can easily
* determine which units to make themselves a dependency of. */
/* Registers a unit for requiring a certain path and all its prefixes. We keep a hashtable of these
* paths in the unit (from the path to the UnitDependencyInfo structure indicating how to the
* dependency came to be). However, we build a prefix table for all possible prefixes so that new
* appearing mount units can easily determine which units to make themselves a dependency of. */
if (!path_is_absolute(path))
return -EINVAL;
r = hashmap_ensure_allocated(&u->requires_mounts_for, &path_hash_ops);
if (r < 0)
return r;
if (hashmap_contains(u->requires_mounts_for, path)) /* Exit quickly if the path is already covered. */
return 0;
p = strdup(path);
_cleanup_free_ char *p = strdup(path);
if (!p)
return -ENOMEM;
/* Use the canonical form of the path as the stored key. We call path_is_normalized()
* only after simplification, since path_is_normalized() rejects paths with '.'.
* path_is_normalized() also verifies that the path fits in PATH_MAX. */
path = path_simplify(p);
if (!path_is_normalized(path))
return -EPERM;
if (hashmap_contains(u->requires_mounts_for, path))
return 0;
di = (UnitDependencyInfo) {
UnitDependencyInfo di = {
.origin_mask = mask
};
r = hashmap_put(u->requires_mounts_for, path, di.data);
r = hashmap_ensure_put(&u->requires_mounts_for, &path_hash_ops, p, di.data);
if (r < 0)
return r;
p = NULL;
assert(r > 0);
TAKE_PTR(p); /* path remains a valid pointer to the string stored in the hashmap */
char prefix[strlen(path) + 1];
PATH_FOREACH_PREFIX_MORE(prefix, path) {