mirror of
https://github.com/systemd/systemd.git
synced 2025-03-03 16:58:37 +03:00
udev: split on_ctrl_msg() into small pieces (#35736)
This commit is contained in:
commit
04b09924b2
@ -15,7 +15,6 @@
|
||||
#include "creds-util.h"
|
||||
#include "device-private.h"
|
||||
#include "device-util.h"
|
||||
#include "env-util.h"
|
||||
#include "escape.h"
|
||||
#include "ethtool-util.h"
|
||||
#include "fd-util.h"
|
||||
@ -1111,8 +1110,7 @@ int config_parse_udev_property(
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The restriction for udev property is not clear. Let's apply the one for environment variable here. */
|
||||
if (!env_assignment_is_valid(resolved)) {
|
||||
if (!udev_property_assignment_is_valid(resolved)) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid udev property, ignoring assignment: %s", word);
|
||||
continue;
|
||||
@ -1181,8 +1179,7 @@ int config_parse_udev_property_name(
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The restriction for udev property is not clear. Let's apply the one for environment variable here. */
|
||||
if (!env_name_is_valid(resolved)) {
|
||||
if (!udev_property_name_is_valid(resolved)) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid udev property name, ignoring assignment: %s", resolved);
|
||||
continue;
|
||||
|
@ -271,7 +271,7 @@ static void manager_merge_config(Manager *manager) {
|
||||
MERGE_BOOL(blockdev_read_only);
|
||||
}
|
||||
|
||||
void udev_config_set_default_children_max(UdevConfig *config) {
|
||||
static void udev_config_set_default_children_max(UdevConfig *config) {
|
||||
uint64_t cpu_limit, mem_limit, cpu_count = 1;
|
||||
int r;
|
||||
|
||||
@ -293,6 +293,30 @@ void udev_config_set_default_children_max(UdevConfig *config) {
|
||||
log_debug("Set children_max to %u", config->children_max);
|
||||
}
|
||||
|
||||
void manager_set_children_max(Manager *manager, unsigned n) {
|
||||
assert(manager);
|
||||
|
||||
manager->config_by_control.children_max = n;
|
||||
/* When 0 is specified, determine the maximum based on the system resources. */
|
||||
udev_config_set_default_children_max(&manager->config_by_control);
|
||||
manager->config.children_max = manager->config_by_control.children_max;
|
||||
|
||||
notify_ready(manager);
|
||||
}
|
||||
|
||||
void manager_set_log_level(Manager *manager, int log_level) {
|
||||
assert(manager);
|
||||
assert(LOG_PRI(log_level) == log_level);
|
||||
|
||||
int old = log_get_max_level();
|
||||
|
||||
log_set_max_level(log_level);
|
||||
manager->config.log_level = manager->config_by_control.log_level = log_level;
|
||||
|
||||
if (log_level != old)
|
||||
manager_kill_workers(manager, /* force = */ false);
|
||||
}
|
||||
|
||||
static void manager_adjust_config(UdevConfig *config) {
|
||||
assert(config);
|
||||
|
||||
@ -315,6 +339,58 @@ static void manager_adjust_config(UdevConfig *config) {
|
||||
udev_config_set_default_children_max(config);
|
||||
}
|
||||
|
||||
static int manager_set_environment_one(Manager *manager, const char *s) {
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
assert(s);
|
||||
|
||||
_cleanup_free_ char *key = NULL, *value = NULL;
|
||||
r = split_pair(s, "=", &key, &value);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (isempty(value)) {
|
||||
_cleanup_free_ char *old_key = NULL, *old_value = NULL;
|
||||
old_value = hashmap_remove2(manager->properties, key, (void**) &old_key);
|
||||
return !!old_value;
|
||||
}
|
||||
|
||||
if (streq_ptr(value, hashmap_get(manager->properties, key)))
|
||||
return 0;
|
||||
|
||||
_cleanup_free_ char *old_key = NULL, *old_value = NULL;
|
||||
old_value = hashmap_get2(manager->properties, key, (void**) &old_key);
|
||||
|
||||
r = hashmap_ensure_replace(&manager->properties, &string_hash_ops, key, value);
|
||||
if (r < 0) {
|
||||
assert(!old_key);
|
||||
assert(!old_value);
|
||||
return r;
|
||||
}
|
||||
|
||||
TAKE_PTR(key);
|
||||
TAKE_PTR(value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void manager_set_environment(Manager *manager, char * const *v) {
|
||||
bool changed = false;
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
|
||||
STRV_FOREACH(s, v) {
|
||||
r = manager_set_environment_one(manager, *s);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to update environment '%s', ignoring: %m", *s);
|
||||
changed = changed || r > 0;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
manager_kill_workers(manager, /* force = */ false);
|
||||
}
|
||||
|
||||
int manager_load(Manager *manager, int argc, char *argv[]) {
|
||||
int r;
|
||||
|
||||
|
@ -26,6 +26,9 @@ typedef struct UdevConfig {
|
||||
.resolve_name_timing = _RESOLVE_NAME_TIMING_INVALID, \
|
||||
}
|
||||
|
||||
void manager_set_children_max(Manager *manager, unsigned n);
|
||||
void manager_set_log_level(Manager *manager, int log_level);
|
||||
void manager_set_environment(Manager *manager, char * const *v);
|
||||
|
||||
int manager_load(Manager *manager, int argc, char *argv[]);
|
||||
UdevReloadFlags manager_reload_config(Manager *manager);
|
||||
void udev_config_set_default_children_max(UdevConfig *c);
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "env-util.h"
|
||||
|
||||
#define UDEV_NAME_SIZE 512
|
||||
#define UDEV_PATH_SIZE 1024
|
||||
#define UDEV_LINE_SIZE 16384
|
||||
@ -78,3 +80,9 @@ typedef enum UdevReloadFlags {
|
||||
UDEV_RELOAD_KILL_WORKERS = 1u << (_UDEV_BUILTIN_MAX + 0),
|
||||
UDEV_RELOAD_RULES = 1u << (_UDEV_BUILTIN_MAX + 1),
|
||||
} UdevReloadFlags;
|
||||
|
||||
/* udev properties are conceptually close to environment variables. Let's validate names, values, and
|
||||
* assignments in the same way. */
|
||||
#define udev_property_name_is_valid(x) env_name_is_valid(x)
|
||||
#define udev_property_value_is_valid(x) env_value_is_valid(x)
|
||||
#define udev_property_assignment_is_valid(x) env_assignment_is_valid(x)
|
||||
|
@ -194,7 +194,7 @@ static int worker_new(Worker **ret, Manager *manager, sd_device_monitor *worker_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void manager_kill_workers(Manager *manager, bool force) {
|
||||
void manager_kill_workers(Manager *manager, bool force) {
|
||||
Worker *worker;
|
||||
|
||||
assert(manager);
|
||||
@ -233,7 +233,7 @@ static void manager_exit(Manager *manager) {
|
||||
manager_kill_workers(manager, true);
|
||||
}
|
||||
|
||||
static void notify_ready(Manager *manager) {
|
||||
void notify_ready(Manager *manager) {
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
@ -844,7 +844,6 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
|
||||
/* receive the udevd message from userspace */
|
||||
static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrlMessageValue *value, void *userdata) {
|
||||
Manager *manager = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(value);
|
||||
|
||||
@ -857,13 +856,7 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl
|
||||
|
||||
log_debug("Received udev control message (SET_LOG_LEVEL), setting log_level=%i", value->intval);
|
||||
|
||||
r = log_get_max_level();
|
||||
if (r == value->intval)
|
||||
break;
|
||||
|
||||
log_set_max_level(value->intval);
|
||||
manager->config.log_level = manager->config_by_control.log_level = value->intval;
|
||||
manager_kill_workers(manager, false);
|
||||
manager_set_log_level(manager, value->intval);
|
||||
break;
|
||||
case UDEV_CTRL_STOP_EXEC_QUEUE:
|
||||
log_debug("Received udev control message (STOP_EXEC_QUEUE)");
|
||||
@ -878,54 +871,15 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl
|
||||
log_debug("Received udev control message (RELOAD)");
|
||||
manager_reload(manager, /* force = */ true);
|
||||
break;
|
||||
case UDEV_CTRL_SET_ENV: {
|
||||
_unused_ _cleanup_free_ char *old_val = NULL, *old_key = NULL;
|
||||
_cleanup_free_ char *key = NULL, *val = NULL;
|
||||
const char *eq;
|
||||
|
||||
eq = strchr(value->buf, '=');
|
||||
if (!eq) {
|
||||
log_error("Invalid key format '%s'", value->buf);
|
||||
return 1;
|
||||
case UDEV_CTRL_SET_ENV:
|
||||
if (!udev_property_assignment_is_valid(value->buf)) {
|
||||
log_debug("Received invalid udev control message(SET_ENV, %s), ignoring.", value->buf);
|
||||
break;
|
||||
}
|
||||
|
||||
key = strndup(value->buf, eq - value->buf);
|
||||
if (!key) {
|
||||
log_oom();
|
||||
return 1;
|
||||
}
|
||||
|
||||
old_val = hashmap_remove2(manager->properties, key, (void **) &old_key);
|
||||
|
||||
r = hashmap_ensure_allocated(&manager->properties, &string_hash_ops);
|
||||
if (r < 0) {
|
||||
log_oom();
|
||||
return 1;
|
||||
}
|
||||
|
||||
eq++;
|
||||
if (isempty(eq))
|
||||
log_debug("Received udev control message (ENV), unsetting '%s'", key);
|
||||
else {
|
||||
val = strdup(eq);
|
||||
if (!val) {
|
||||
log_oom();
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_debug("Received udev control message (ENV), setting '%s=%s'", key, val);
|
||||
|
||||
r = hashmap_put(manager->properties, key, val);
|
||||
if (r < 0) {
|
||||
log_oom();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
key = val = NULL;
|
||||
manager_kill_workers(manager, false);
|
||||
log_debug("Received udev control message(SET_ENV, %s)", value->buf);
|
||||
manager_set_environment(manager, STRV_MAKE(value->buf));
|
||||
break;
|
||||
}
|
||||
case UDEV_CTRL_SET_CHILDREN_MAX:
|
||||
if (value->intval < 0) {
|
||||
log_debug("Received invalid udev control message (SET_MAX_CHILDREN, %i), ignoring.", value->intval);
|
||||
@ -933,13 +887,8 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl
|
||||
}
|
||||
|
||||
log_debug("Received udev control message (SET_MAX_CHILDREN), setting children_max=%i", value->intval);
|
||||
manager->config_by_control.children_max = value->intval;
|
||||
|
||||
/* When 0 is specified, determine the maximum based on the system resources. */
|
||||
udev_config_set_default_children_max(&manager->config_by_control);
|
||||
manager->config.children_max = manager->config_by_control.children_max;
|
||||
|
||||
notify_ready(manager);
|
||||
manager_set_children_max(manager, value->intval);
|
||||
break;
|
||||
case UDEV_CTRL_PING:
|
||||
log_debug("Received udev control message (PING)");
|
||||
|
@ -55,4 +55,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
|
||||
int manager_init(Manager *manager);
|
||||
int manager_main(Manager *manager);
|
||||
|
||||
void notify_ready(Manager *manager);
|
||||
|
||||
void manager_kill_workers(Manager *manager, bool force);
|
||||
|
||||
bool devpath_conflict(const char *a, const char *b);
|
||||
|
Loading…
x
Reference in New Issue
Block a user