mirror of
https://github.com/systemd/systemd
synced 2026-04-11 09:34:51 +02:00
Compare commits
5 Commits
e99f8605e2
...
80bfc3b901
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80bfc3b901 | ||
|
|
69b5c7cf2a | ||
|
|
cf6562e456 | ||
|
|
7f304b8561 | ||
|
|
4b3ad81bfa |
@ -236,6 +236,31 @@ bool lookup_paths_timestamp_hash_same(const LookupPaths *lp, uint64_t timestamp_
|
|||||||
return updated == timestamp_hash;
|
return updated == timestamp_hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int directory_name_is_valid(const char *name) {
|
||||||
|
const char *suffix;
|
||||||
|
|
||||||
|
/* Accept a directory whose name is a valid unit file name ending in .wants/, .requires/ or .d/ */
|
||||||
|
|
||||||
|
FOREACH_STRING(suffix, ".wants", ".requires", ".d") {
|
||||||
|
_cleanup_free_ char *chopped = NULL;
|
||||||
|
const char *e;
|
||||||
|
|
||||||
|
e = endswith(name, suffix);
|
||||||
|
if (!e)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
chopped = strndup(name, e - name);
|
||||||
|
if (!chopped)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
if (unit_name_is_valid(chopped, UNIT_NAME_ANY) ||
|
||||||
|
unit_type_from_string(chopped) >= 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int unit_file_build_name_map(
|
int unit_file_build_name_map(
|
||||||
const LookupPaths *lp,
|
const LookupPaths *lp,
|
||||||
uint64_t *cache_timestamp_hash,
|
uint64_t *cache_timestamp_hash,
|
||||||
@ -287,50 +312,61 @@ int unit_file_build_name_map(
|
|||||||
FOREACH_DIRENT_ALL(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) {
|
FOREACH_DIRENT_ALL(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) {
|
||||||
_unused_ _cleanup_free_ char *_filename_free = NULL;
|
_unused_ _cleanup_free_ char *_filename_free = NULL;
|
||||||
_cleanup_free_ char *simplified = NULL;
|
_cleanup_free_ char *simplified = NULL;
|
||||||
|
bool symlink_to_dir = false;
|
||||||
const char *dst = NULL;
|
const char *dst = NULL;
|
||||||
char *filename;
|
char *filename;
|
||||||
|
|
||||||
/* We only care about valid units and dirs with certain suffixes, let's ignore the
|
/* We only care about valid units and dirs with certain suffixes, let's ignore the
|
||||||
* rest. */
|
* rest. */
|
||||||
|
|
||||||
if (IN_SET(de->d_type, DT_REG, DT_LNK)) {
|
if (de->d_type == DT_REG) {
|
||||||
|
|
||||||
|
/* Accept a regular file whose name is a valid unit file name. */
|
||||||
if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
|
if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Accept a regular file or symlink whose name is a valid unit file name. */
|
|
||||||
|
|
||||||
} else if (de->d_type == DT_DIR) {
|
} else if (de->d_type == DT_DIR) {
|
||||||
bool valid_dir_name = false;
|
|
||||||
const char *suffix;
|
|
||||||
|
|
||||||
/* Also accept a directory whose name is a valid unit file name ending in
|
|
||||||
* .wants/, .requires/ or .d/ */
|
|
||||||
|
|
||||||
if (!paths) /* Skip directories early unless path_cache is requested */
|
if (!paths) /* Skip directories early unless path_cache is requested */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
FOREACH_STRING(suffix, ".wants", ".requires", ".d") {
|
r = directory_name_is_valid(de->d_name);
|
||||||
_cleanup_free_ char *chopped = NULL;
|
if (r < 0)
|
||||||
const char *e;
|
return r;
|
||||||
|
if (r == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
e = endswith(de->d_name, suffix);
|
} else if (de->d_type == DT_LNK) {
|
||||||
if (!e)
|
|
||||||
|
/* Accept a symlink file whose name is a valid unit file name or
|
||||||
|
* ending in .wants/, .requires/ or .d/. */
|
||||||
|
|
||||||
|
if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY)) {
|
||||||
|
_cleanup_free_ char *target = NULL;
|
||||||
|
|
||||||
|
if (!paths) /* Skip symlink to a directory early unless path_cache is requested */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
chopped = strndup(de->d_name, e - de->d_name);
|
r = directory_name_is_valid(de->d_name);
|
||||||
if (!chopped)
|
if (r < 0)
|
||||||
return log_oom();
|
return r;
|
||||||
|
if (r == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (unit_name_is_valid(chopped, UNIT_NAME_ANY) ||
|
r = readlinkat_malloc(dirfd(d), de->d_name, &target);
|
||||||
unit_type_from_string(chopped) >= 0) {
|
if (r < 0) {
|
||||||
valid_dir_name = true;
|
log_warning_errno(r, "Failed to read symlink %s/%s, ignoring: %m",
|
||||||
break;
|
*dir, de->d_name);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = is_dir(target, /* follow = */ true);
|
||||||
|
if (r <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
symlink_to_dir = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!valid_dir_name)
|
|
||||||
continue;
|
|
||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -347,9 +383,11 @@ int unit_file_build_name_map(
|
|||||||
} else
|
} else
|
||||||
_filename_free = filename; /* Make sure we free the filename. */
|
_filename_free = filename; /* Make sure we free the filename. */
|
||||||
|
|
||||||
if (!IN_SET(de->d_type, DT_REG, DT_LNK))
|
if (de->d_type == DT_DIR || (de->d_type == DT_LNK && symlink_to_dir))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
assert(IN_SET(de->d_type, DT_REG, DT_LNK));
|
||||||
|
|
||||||
/* search_path is ordered by priority (highest first). If the name is already mapped
|
/* search_path is ordered by priority (highest first). If the name is already mapped
|
||||||
* to something (incl. itself), it means that we have already seen it, and we should
|
* to something (incl. itself), it means that we have already seen it, and we should
|
||||||
* ignore it here. */
|
* ignore it here. */
|
||||||
|
|||||||
@ -1728,9 +1728,10 @@ static void manager_ready(Manager *m) {
|
|||||||
manager_catchup(m);
|
manager_catchup(m);
|
||||||
|
|
||||||
/* Create a file which will indicate when the manager started loading units the last time. */
|
/* Create a file which will indicate when the manager started loading units the last time. */
|
||||||
(void) touch_file("/run/systemd/systemd-units-load", false,
|
if (MANAGER_IS_SYSTEM(m))
|
||||||
m->timestamps[MANAGER_TIMESTAMP_UNITS_LOAD].realtime ?: now(CLOCK_REALTIME),
|
(void) touch_file("/run/systemd/systemd-units-load", false,
|
||||||
UID_INVALID, GID_INVALID, 0444);
|
m->timestamps[MANAGER_TIMESTAMP_UNITS_LOAD].realtime ?: now(CLOCK_REALTIME),
|
||||||
|
UID_INVALID, GID_INVALID, 0444);
|
||||||
|
|
||||||
m->honor_device_enumeration = true;
|
m->honor_device_enumeration = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -612,6 +612,11 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Failed to get route prefix length: %m");
|
return log_link_error_errno(link, r, "Failed to get route prefix length: %m");
|
||||||
|
|
||||||
|
if (in6_addr_is_null(&dst) && prefixlen == 0) {
|
||||||
|
log_link_debug(link, "Route prefix is ::/0, ignoring");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (in6_prefix_is_filtered(&dst, prefixlen, link->network->ndisc_allow_listed_route_prefix, link->network->ndisc_deny_listed_route_prefix)) {
|
if (in6_prefix_is_filtered(&dst, prefixlen, link->network->ndisc_allow_listed_route_prefix, link->network->ndisc_deny_listed_route_prefix)) {
|
||||||
if (DEBUG_LOGGING) {
|
if (DEBUG_LOGGING) {
|
||||||
_cleanup_free_ char *buf = NULL;
|
_cleanup_free_ char *buf = NULL;
|
||||||
|
|||||||
@ -515,6 +515,25 @@ test_invalid_dropins () {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_symlink_dropin_directory () {
|
||||||
|
# For issue #21920.
|
||||||
|
echo "Testing symlink drop-in directory..."
|
||||||
|
create_services test15-a
|
||||||
|
rmdir /{etc,run,usr/lib}/systemd/system/test15-a.service.d
|
||||||
|
mkdir -p /tmp/testsuite-15-test15-a-dropin-directory
|
||||||
|
ln -s /tmp/testsuite-15-test15-a-dropin-directory /etc/systemd/system/test15-a.service.d
|
||||||
|
cat >/tmp/testsuite-15-test15-a-dropin-directory/override.conf <<EOF
|
||||||
|
[Unit]
|
||||||
|
Description=hogehoge
|
||||||
|
EOF
|
||||||
|
ln -s /tmp/testsuite-15-test15-a-dropin-directory-nonexistent /run/systemd/system/test15-a.service.d
|
||||||
|
touch /tmp/testsuite-15-test15-a-dropin-directory-regular
|
||||||
|
ln -s /tmp/testsuite-15-test15-a-dropin-directory-regular /usr/lib/systemd/system/test15-a.service.d
|
||||||
|
check_ok test15-a Description hogehoge
|
||||||
|
|
||||||
|
clear_services test15-a
|
||||||
|
}
|
||||||
|
|
||||||
test_basic_dropins
|
test_basic_dropins
|
||||||
test_linked_units
|
test_linked_units
|
||||||
test_template_alias
|
test_template_alias
|
||||||
@ -523,5 +542,6 @@ test_template_dropins
|
|||||||
test_alias_dropins
|
test_alias_dropins
|
||||||
test_masked_dropins
|
test_masked_dropins
|
||||||
test_invalid_dropins
|
test_invalid_dropins
|
||||||
|
test_symlink_dropin_directory
|
||||||
|
|
||||||
touch /testok
|
touch /testok
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user