Compare commits
14 Commits
c9fdaed079
...
b014a6161a
Author | SHA1 | Date |
---|---|---|
Zbigniew Jędrzejewski-Szmek | b014a6161a | |
Zbigniew Jędrzejewski-Szmek | 3049e6a233 | |
Zbigniew Jędrzejewski-Szmek | fe67137895 | |
Yu Watanabe | 0e96961d62 | |
Yu Watanabe | 461dbb2fa9 | |
Yu Watanabe | d8b736bd0c | |
Zbigniew Jędrzejewski-Szmek | d7cf8c24d4 | |
Zbigniew Jędrzejewski-Szmek | 7a16cd4b05 | |
Zbigniew Jędrzejewski-Szmek | 6906ac9a69 | |
Zbigniew Jędrzejewski-Szmek | 9161113652 | |
Zbigniew Jędrzejewski-Szmek | 0877d4e0cf | |
Zbigniew Jędrzejewski-Szmek | e617e2ccd7 | |
Zbigniew Jędrzejewski-Szmek | 1454ab403e | |
Zbigniew Jędrzejewski-Szmek | 3a0f06c41a |
|
@ -1643,14 +1643,13 @@
|
||||||
<term><varname>SendOption=</varname></term>
|
<term><varname>SendOption=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Send an arbitrary option in the DHCPv4 request. Takes a DHCP option number, data type
|
<para>Send an arbitrary option in the DHCPv4 request. Takes a DHCP option number, data type
|
||||||
and data separated with a colon (<literal><replaceable>option</replaceable>:
|
and data separated with a colon
|
||||||
<replaceable>type</replaceable>:<replaceable>value</replaceable></literal>). The option
|
(<literal><replaceable>option</replaceable>:<replaceable>type</replaceable>:<replaceable>value</replaceable></literal>).
|
||||||
number must be an interger in the range 1..254. The type takes one of
|
The option number must be an interger in the range 1..254. The type takes one of <literal>uint8</literal>,
|
||||||
<literal>uint8</literal>, <literal>uint16</literal>, <literal>uint32</literal>,
|
<literal>uint16</literal>, <literal>uint32</literal>, <literal>ipv4address</literal>, or
|
||||||
<literal>ipv4address</literal>, or <literal>string</literal>.
|
<literal>string</literal>. Special characters in the data string may be escaped using
|
||||||
Special characters in the data string may be escaped using
|
|
||||||
<ulink url="https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences">C-style
|
<ulink url="https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences">C-style
|
||||||
escapes</ulink>. This option can be specified multiple times. If an empty string is specified,
|
escapes</ulink>. This setting can be specified multiple times. If an empty string is specified,
|
||||||
then all options specified earlier are cleared. Defaults to unset.</para>
|
then all options specified earlier are cleared. Defaults to unset.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -1905,16 +1904,17 @@
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>SendRawOption=</varname></term>
|
<term><varname>SendOption=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Send a raw option with value via DHCPv4 server. Takes a DHCP option, data type and data
|
<para>Send a raw option with value via DHCPv4 server. Takes a DHCP option number, data type
|
||||||
(option:type:value). The option ranges [1-254]. The type takes one of <literal>uint8</literal>,
|
and data (<literal><replaceable>option</replaceable>:<replaceable>type</replaceable>:<replaceable>value</replaceable></literal>).
|
||||||
<literal>uint16</literal>, <literal>uint32</literal>, <literal>ipv4address</literal>, or <literal>string</literal>.
|
The option number is an integer in the range 1..254. The type takes one of <literal>uint8</literal>,
|
||||||
Special characters in the data string may be escaped using
|
<literal>uint16</literal>, <literal>uint32</literal>, <literal>ipv4address</literal>, or
|
||||||
<ulink url="https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences">C-style
|
<literal>string</literal>. Special characters in the data string may be escaped using
|
||||||
escapes</ulink>. This option can be specified multiple times. If an empty string is specified, then all
|
<ulink url="https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences">C-style
|
||||||
options specified earlier are cleared. Defaults to unset.</para>
|
escapes</ulink>. This setting can be specified multiple times. If an empty string is specified,
|
||||||
</listitem>
|
then all options specified earlier are cleared. Defaults to unset.</para>
|
||||||
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
|
@ -129,10 +129,6 @@ static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) {
|
||||||
(x >= CGROUP_BLKIO_WEIGHT_MIN && x <= CGROUP_BLKIO_WEIGHT_MAX);
|
(x >= CGROUP_BLKIO_WEIGHT_MIN && x <= CGROUP_BLKIO_WEIGHT_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default resource limits */
|
|
||||||
#define DEFAULT_TASKS_MAX_PERCENTAGE 15U /* 15% of PIDs, 4915 on default settings */
|
|
||||||
#define DEFAULT_USER_TASKS_MAX_PERCENTAGE 33U /* 33% of PIDs, 10813 on default settings */
|
|
||||||
|
|
||||||
typedef enum CGroupUnified {
|
typedef enum CGroupUnified {
|
||||||
CGROUP_UNIFIED_UNKNOWN = -1,
|
CGROUP_UNIFIED_UNKNOWN = -1,
|
||||||
CGROUP_UNIFIED_NONE = 0, /* Both systemd and controllers on legacy */
|
CGROUP_UNIFIED_NONE = 0, /* Both systemd and controllers on legacy */
|
||||||
|
|
|
@ -52,11 +52,7 @@ void path_hash_func(const char *q, struct siphash *state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int path_compare_func(const char *a, const char *b) {
|
DEFINE_HASH_OPS(path_hash_ops, char, path_hash_func, path_compare);
|
||||||
return path_compare(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_HASH_OPS(path_hash_ops, char, path_hash_func, path_compare_func);
|
|
||||||
|
|
||||||
void trivial_hash_func(const void *p, struct siphash *state) {
|
void trivial_hash_func(const void *p, struct siphash *state) {
|
||||||
siphash24_compress(&p, sizeof(p), state);
|
siphash24_compress(&p, sizeof(p), state);
|
||||||
|
|
|
@ -79,7 +79,6 @@ extern const struct hash_ops string_hash_ops;
|
||||||
extern const struct hash_ops string_hash_ops_free_free;
|
extern const struct hash_ops string_hash_ops_free_free;
|
||||||
|
|
||||||
void path_hash_func(const char *p, struct siphash *state);
|
void path_hash_func(const char *p, struct siphash *state);
|
||||||
int path_compare_func(const char *a, const char *b) _pure_;
|
|
||||||
extern const struct hash_ops path_hash_ops;
|
extern const struct hash_ops path_hash_ops;
|
||||||
|
|
||||||
/* This will compare the passed pointers directly, and will not dereference them. This is hence not useful for strings
|
/* This will compare the passed pointers directly, and will not dereference them. This is hence not useful for strings
|
||||||
|
|
|
@ -99,7 +99,6 @@ uint64_t physical_memory_scale(uint64_t v, uint64_t max) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t system_tasks_max(void) {
|
uint64_t system_tasks_max(void) {
|
||||||
|
|
||||||
uint64_t a = TASKS_MAX, b = TASKS_MAX;
|
uint64_t a = TASKS_MAX, b = TASKS_MAX;
|
||||||
_cleanup_free_ char *root = NULL;
|
_cleanup_free_ char *root = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
|
@ -897,7 +897,7 @@ static const char* counting_what(void) {
|
||||||
return "userspace processes (excl. kernel)";
|
return "userspace processes (excl. kernel)";
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(group_hash_ops, char, path_hash_func, path_compare_func, Group, group_free);
|
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(group_hash_ops, char, path_hash_func, path_compare, Group, group_free);
|
||||||
|
|
||||||
static int run(int argc, char *argv[]) {
|
static int run(int argc, char *argv[]) {
|
||||||
_cleanup_hashmap_free_ Hashmap *a = NULL, *b = NULL;
|
_cleanup_hashmap_free_ Hashmap *a = NULL, *b = NULL;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
|
#include "limits-util.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "process-util.h"
|
#include "process-util.h"
|
||||||
|
@ -34,6 +35,13 @@
|
||||||
* out specific attributes from us. */
|
* out specific attributes from us. */
|
||||||
#define LOG_LEVEL_CGROUP_WRITE(r) (IN_SET(abs(r), ENOENT, EROFS, EACCES, EPERM) ? LOG_DEBUG : LOG_WARNING)
|
#define LOG_LEVEL_CGROUP_WRITE(r) (IN_SET(abs(r), ENOENT, EROFS, EACCES, EPERM) ? LOG_DEBUG : LOG_WARNING)
|
||||||
|
|
||||||
|
uint64_t tasks_max_resolve(const TasksMax *tasks_max) {
|
||||||
|
if (tasks_max->scale == 0)
|
||||||
|
return tasks_max->value;
|
||||||
|
|
||||||
|
return system_tasks_max_scale(tasks_max->value, tasks_max->scale);
|
||||||
|
}
|
||||||
|
|
||||||
bool manager_owns_host_root_cgroup(Manager *m) {
|
bool manager_owns_host_root_cgroup(Manager *m) {
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
|
@ -117,7 +125,7 @@ void cgroup_context_init(CGroupContext *c) {
|
||||||
.blockio_weight = CGROUP_BLKIO_WEIGHT_INVALID,
|
.blockio_weight = CGROUP_BLKIO_WEIGHT_INVALID,
|
||||||
.startup_blockio_weight = CGROUP_BLKIO_WEIGHT_INVALID,
|
.startup_blockio_weight = CGROUP_BLKIO_WEIGHT_INVALID,
|
||||||
|
|
||||||
.tasks_max = CGROUP_LIMIT_MAX,
|
.tasks_max = TASKS_MAX_UNSET,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,7 +455,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||||||
prefix, c->memory_max, format_cgroup_memory_limit_comparison(cdd, sizeof(cdd), u, "MemoryMax"),
|
prefix, c->memory_max, format_cgroup_memory_limit_comparison(cdd, sizeof(cdd), u, "MemoryMax"),
|
||||||
prefix, c->memory_swap_max, format_cgroup_memory_limit_comparison(cde, sizeof(cde), u, "MemorySwapMax"),
|
prefix, c->memory_swap_max, format_cgroup_memory_limit_comparison(cde, sizeof(cde), u, "MemorySwapMax"),
|
||||||
prefix, c->memory_limit,
|
prefix, c->memory_limit,
|
||||||
prefix, c->tasks_max,
|
prefix, tasks_max_resolve(&c->tasks_max),
|
||||||
prefix, cgroup_device_policy_to_string(c->device_policy),
|
prefix, cgroup_device_policy_to_string(c->device_policy),
|
||||||
prefix, strempty(disable_controllers_str),
|
prefix, strempty(disable_controllers_str),
|
||||||
prefix, yes_no(c->delegate));
|
prefix, yes_no(c->delegate));
|
||||||
|
@ -1339,9 +1347,9 @@ static void cgroup_context_apply(
|
||||||
* which is desirable so that there's an official way to release control of the sysctl from
|
* which is desirable so that there's an official way to release control of the sysctl from
|
||||||
* systemd: set the limit to unbounded and reload. */
|
* systemd: set the limit to unbounded and reload. */
|
||||||
|
|
||||||
if (c->tasks_max != CGROUP_LIMIT_MAX) {
|
if (tasks_max_isset(&c->tasks_max)) {
|
||||||
u->manager->sysctl_pid_max_changed = true;
|
u->manager->sysctl_pid_max_changed = true;
|
||||||
r = procfs_tasks_set_limit(c->tasks_max);
|
r = procfs_tasks_set_limit(tasks_max_resolve(&c->tasks_max));
|
||||||
} else if (u->manager->sysctl_pid_max_changed)
|
} else if (u->manager->sysctl_pid_max_changed)
|
||||||
r = procfs_tasks_set_limit(TASKS_MAX);
|
r = procfs_tasks_set_limit(TASKS_MAX);
|
||||||
else
|
else
|
||||||
|
@ -1354,10 +1362,10 @@ static void cgroup_context_apply(
|
||||||
/* The attribute itself is not available on the host root cgroup, and in the container case we want to
|
/* The attribute itself is not available on the host root cgroup, and in the container case we want to
|
||||||
* leave it for the container manager. */
|
* leave it for the container manager. */
|
||||||
if (!is_local_root) {
|
if (!is_local_root) {
|
||||||
if (c->tasks_max != CGROUP_LIMIT_MAX) {
|
if (tasks_max_isset(&c->tasks_max)) {
|
||||||
char buf[DECIMAL_STR_MAX(uint64_t) + 2];
|
char buf[DECIMAL_STR_MAX(uint64_t) + 1];
|
||||||
|
|
||||||
sprintf(buf, "%" PRIu64 "\n", c->tasks_max);
|
xsprintf(buf, "%" PRIu64 "\n", tasks_max_resolve(&c->tasks_max));
|
||||||
(void) set_attribute_and_warn(u, "pids", "pids.max", buf);
|
(void) set_attribute_and_warn(u, "pids", "pids.max", buf);
|
||||||
} else
|
} else
|
||||||
(void) set_attribute_and_warn(u, "pids", "pids.max", "max\n");
|
(void) set_attribute_and_warn(u, "pids", "pids.max", "max\n");
|
||||||
|
@ -1434,7 +1442,7 @@ static CGroupMask unit_get_cgroup_mask(Unit *u) {
|
||||||
mask |= CGROUP_MASK_DEVICES | CGROUP_MASK_BPF_DEVICES;
|
mask |= CGROUP_MASK_DEVICES | CGROUP_MASK_BPF_DEVICES;
|
||||||
|
|
||||||
if (c->tasks_accounting ||
|
if (c->tasks_accounting ||
|
||||||
c->tasks_max != CGROUP_LIMIT_MAX)
|
tasks_max_isset(&c->tasks_max))
|
||||||
mask |= CGROUP_MASK_PIDS;
|
mask |= CGROUP_MASK_PIDS;
|
||||||
|
|
||||||
return CGROUP_MASK_EXTEND_JOINED(mask);
|
return CGROUP_MASK_EXTEND_JOINED(mask);
|
||||||
|
|
|
@ -9,6 +9,21 @@
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
|
|
||||||
|
typedef struct TasksMax {
|
||||||
|
/* If scale == 0, just use value; otherwise, value / scale.
|
||||||
|
* See tasks_max_resolve(). */
|
||||||
|
uint64_t value;
|
||||||
|
uint64_t scale;
|
||||||
|
} TasksMax;
|
||||||
|
|
||||||
|
#define TASKS_MAX_UNSET ((TasksMax) { .value = UINT64_MAX, .scale = 0 })
|
||||||
|
|
||||||
|
static inline bool tasks_max_isset(const TasksMax *tasks_max) {
|
||||||
|
return tasks_max->value != UINT64_MAX || tasks_max->scale != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t tasks_max_resolve(const TasksMax *tasks_max);
|
||||||
|
|
||||||
typedef struct CGroupContext CGroupContext;
|
typedef struct CGroupContext CGroupContext;
|
||||||
typedef struct CGroupDeviceAllow CGroupDeviceAllow;
|
typedef struct CGroupDeviceAllow CGroupDeviceAllow;
|
||||||
typedef struct CGroupIODeviceWeight CGroupIODeviceWeight;
|
typedef struct CGroupIODeviceWeight CGroupIODeviceWeight;
|
||||||
|
@ -135,7 +150,7 @@ struct CGroupContext {
|
||||||
LIST_HEAD(CGroupDeviceAllow, device_allow);
|
LIST_HEAD(CGroupDeviceAllow, device_allow);
|
||||||
|
|
||||||
/* Common */
|
/* Common */
|
||||||
uint64_t tasks_max;
|
TasksMax tasks_max;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Used when querying IP accounting data */
|
/* Used when querying IP accounting data */
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#include "limits-util.h"
|
#include "limits-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
|
|
||||||
|
BUS_DEFINE_PROPERTY_GET(bus_property_get_tasks_max, "t", TasksMax, tasks_max_resolve);
|
||||||
|
|
||||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy);
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy);
|
||||||
|
|
||||||
static int property_get_cgroup_mask(
|
static int property_get_cgroup_mask(
|
||||||
|
@ -382,7 +384,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
|
||||||
SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy, offsetof(CGroupContext, device_policy), 0),
|
SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy, offsetof(CGroupContext, device_policy), 0),
|
||||||
SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow, 0, 0),
|
SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow, 0, 0),
|
||||||
SD_BUS_PROPERTY("TasksAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, tasks_accounting), 0),
|
SD_BUS_PROPERTY("TasksAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, tasks_accounting), 0),
|
||||||
SD_BUS_PROPERTY("TasksMax", "t", NULL, offsetof(CGroupContext, tasks_max), 0),
|
SD_BUS_PROPERTY("TasksMax", "t", bus_property_get_tasks_max, offsetof(CGroupContext, tasks_max), 0),
|
||||||
SD_BUS_PROPERTY("IPAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, ip_accounting), 0),
|
SD_BUS_PROPERTY("IPAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, ip_accounting), 0),
|
||||||
SD_BUS_PROPERTY("IPAddressAllow", "a(iayu)", property_get_ip_address_access, offsetof(CGroupContext, ip_address_allow), 0),
|
SD_BUS_PROPERTY("IPAddressAllow", "a(iayu)", property_get_ip_address_access, offsetof(CGroupContext, ip_address_allow), 0),
|
||||||
SD_BUS_PROPERTY("IPAddressDeny", "a(iayu)", property_get_ip_address_access, offsetof(CGroupContext, ip_address_deny), 0),
|
SD_BUS_PROPERTY("IPAddressDeny", "a(iayu)", property_get_ip_address_access, offsetof(CGroupContext, ip_address_deny), 0),
|
||||||
|
@ -617,7 +619,7 @@ static int bus_cgroup_set_boolean(
|
||||||
\
|
\
|
||||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
||||||
*p = v; \
|
*p = v; \
|
||||||
unit_invalidate_cgroup(u, (mask)); \
|
unit_invalidate_cgroup(u, mask); \
|
||||||
\
|
\
|
||||||
if (v == (val)) \
|
if (v == (val)) \
|
||||||
unit_write_settingf(u, flags, name, \
|
unit_write_settingf(u, flags, name, \
|
||||||
|
@ -654,7 +656,7 @@ static int bus_cgroup_set_boolean(
|
||||||
\
|
\
|
||||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
||||||
*p = v; \
|
*p = v; \
|
||||||
unit_invalidate_cgroup(u, (mask)); \
|
unit_invalidate_cgroup(u, mask); \
|
||||||
\
|
\
|
||||||
if (v == CGROUP_LIMIT_MAX) \
|
if (v == CGROUP_LIMIT_MAX) \
|
||||||
unit_write_settingf(u, flags, name, \
|
unit_write_settingf(u, flags, name, \
|
||||||
|
@ -690,17 +692,16 @@ static int bus_cgroup_set_boolean(
|
||||||
"Value specified in %s is out of range", name); \
|
"Value specified in %s is out of range", name); \
|
||||||
\
|
\
|
||||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
||||||
const char *e; \
|
|
||||||
\
|
|
||||||
*p = v; \
|
*p = v; \
|
||||||
unit_invalidate_cgroup(u, (mask)); \
|
unit_invalidate_cgroup(u, mask); \
|
||||||
\
|
\
|
||||||
/* Chop off suffix */ \
|
/* Prepare to chop off suffix */ \
|
||||||
assert_se(e = endswith(name, "Scale")); \
|
assert_se(endswith(name, "Scale")); \
|
||||||
name = strndupa(name, e - name); \
|
|
||||||
\
|
\
|
||||||
unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name, \
|
uint32_t scaled = DIV_ROUND_UP((uint64_t) raw * 1000, (uint64_t) UINT32_MAX); \
|
||||||
(uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); \
|
unit_write_settingf(u, flags, name, "%.*s=%" PRIu32 ".%" PRIu32 "%%", \
|
||||||
|
(int)(strlen(name) - strlen("Scale")), name, \
|
||||||
|
scaled / 10, scaled % 10); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
return 1; \
|
return 1; \
|
||||||
|
@ -715,9 +716,77 @@ BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight, CGROUP_MASK_BLKIO, CGROUP_BLKIO_WEI
|
||||||
BUS_DEFINE_SET_CGROUP_LIMIT(memory, CGROUP_MASK_MEMORY, physical_memory_scale, 1);
|
BUS_DEFINE_SET_CGROUP_LIMIT(memory, CGROUP_MASK_MEMORY, physical_memory_scale, 1);
|
||||||
BUS_DEFINE_SET_CGROUP_LIMIT(memory_protection, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
|
BUS_DEFINE_SET_CGROUP_LIMIT(memory_protection, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
|
||||||
BUS_DEFINE_SET_CGROUP_LIMIT(swap, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
|
BUS_DEFINE_SET_CGROUP_LIMIT(swap, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
|
||||||
BUS_DEFINE_SET_CGROUP_LIMIT(tasks_max, CGROUP_MASK_PIDS, system_tasks_max_scale, 1);
|
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
static int bus_cgroup_set_tasks_max(
|
||||||
|
Unit *u,
|
||||||
|
const char *name,
|
||||||
|
TasksMax *p,
|
||||||
|
sd_bus_message *message,
|
||||||
|
UnitWriteFlags flags,
|
||||||
|
sd_bus_error *error) {
|
||||||
|
|
||||||
|
uint64_t v;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(p);
|
||||||
|
|
||||||
|
r = sd_bus_message_read(message, "t", &v);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (v < 1)
|
||||||
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||||
|
"Value specified in %s is out of range", name);
|
||||||
|
|
||||||
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||||
|
*p = (TasksMax) { .value = v, .scale = 0 }; /* When .scale==0, .value is the absolute value */
|
||||||
|
unit_invalidate_cgroup(u, CGROUP_MASK_PIDS);
|
||||||
|
|
||||||
|
if (v == CGROUP_LIMIT_MAX)
|
||||||
|
unit_write_settingf(u, flags, name,
|
||||||
|
"%s=infinity", name);
|
||||||
|
else
|
||||||
|
unit_write_settingf(u, flags, name,
|
||||||
|
"%s=%" PRIu64, name, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bus_cgroup_set_tasks_max_scale(
|
||||||
|
Unit *u,
|
||||||
|
const char *name,
|
||||||
|
TasksMax *p,
|
||||||
|
sd_bus_message *message,
|
||||||
|
UnitWriteFlags flags,
|
||||||
|
sd_bus_error *error) {
|
||||||
|
|
||||||
|
uint32_t v;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(p);
|
||||||
|
|
||||||
|
r = sd_bus_message_read(message, "u", &v);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (v < 1 || v >= UINT32_MAX)
|
||||||
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||||
|
"Value specified in %s is out of range", name);
|
||||||
|
|
||||||
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||||
|
*p = (TasksMax) { v, UINT32_MAX }; /* .scale is not 0, so this is interpreted as v/UINT32_MAX. */
|
||||||
|
unit_invalidate_cgroup(u, CGROUP_MASK_PIDS);
|
||||||
|
|
||||||
|
uint32_t scaled = DIV_ROUND_UP((uint64_t) v * 100U, (uint64_t) UINT32_MAX);
|
||||||
|
unit_write_settingf(u, flags, name, "%s=%" PRIu32 ".%" PRIu32 "%%", "TasksMax",
|
||||||
|
scaled / 10, scaled % 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int bus_cgroup_set_property(
|
int bus_cgroup_set_property(
|
||||||
Unit *u,
|
Unit *u,
|
||||||
CGroupContext *c,
|
CGroupContext *c,
|
||||||
|
|
|
@ -9,4 +9,6 @@
|
||||||
|
|
||||||
extern const sd_bus_vtable bus_cgroup_vtable[];
|
extern const sd_bus_vtable bus_cgroup_vtable[];
|
||||||
|
|
||||||
|
int bus_property_get_tasks_max(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error);
|
||||||
|
|
||||||
int bus_cgroup_set_property(Unit *u, CGroupContext *c, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
int bus_cgroup_set_property(Unit *u, CGroupContext *c, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "architecture.h"
|
#include "architecture.h"
|
||||||
#include "build.h"
|
#include "build.h"
|
||||||
#include "bus-common-errors.h"
|
#include "bus-common-errors.h"
|
||||||
|
#include "dbus-cgroup.h"
|
||||||
#include "dbus-execute.h"
|
#include "dbus-execute.h"
|
||||||
#include "dbus-job.h"
|
#include "dbus-job.h"
|
||||||
#include "dbus-manager.h"
|
#include "dbus-manager.h"
|
||||||
|
@ -2465,7 +2466,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
|
||||||
SD_BUS_PROPERTY("DefaultLimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("DefaultLimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("DefaultLimitRTTIME", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("DefaultLimitRTTIME", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("DefaultLimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("DefaultLimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("DefaultTasksMax", "t", NULL, offsetof(Manager, default_tasks_max), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("DefaultTasksMax", "t", bus_property_get_tasks_max, offsetof(Manager, default_tasks_max), 0),
|
||||||
SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("DefaultOOMPolicy", "s", bus_property_get_oom_policy, offsetof(Manager, default_oom_policy), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("DefaultOOMPolicy", "s", bus_property_get_oom_policy, offsetof(Manager, default_oom_policy), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
|
||||||
|
|
|
@ -3263,36 +3263,39 @@ int config_parse_tasks_max(
|
||||||
void *data,
|
void *data,
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
|
|
||||||
uint64_t *tasks_max = data, v;
|
|
||||||
const Unit *u = userdata;
|
const Unit *u = userdata;
|
||||||
|
TasksMax *tasks_max = data;
|
||||||
|
uint64_t v;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (isempty(rvalue)) {
|
if (isempty(rvalue)) {
|
||||||
*tasks_max = u ? u->manager->default_tasks_max : UINT64_MAX;
|
*tasks_max = u ? u->manager->default_tasks_max : TASKS_MAX_UNSET;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (streq(rvalue, "infinity")) {
|
if (streq(rvalue, "infinity")) {
|
||||||
*tasks_max = CGROUP_LIMIT_MAX;
|
*tasks_max = TASKS_MAX_UNSET;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = parse_permille(rvalue);
|
r = parse_permille(rvalue);
|
||||||
if (r < 0) {
|
if (r >= 0)
|
||||||
|
*tasks_max = (TasksMax) { r, 1000U }; /* r‰ */
|
||||||
|
else {
|
||||||
r = safe_atou64(rvalue, &v);
|
r = safe_atou64(rvalue, &v);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid maximum tasks value '%s', ignoring: %m", rvalue);
|
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid maximum tasks value '%s', ignoring: %m", rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else
|
|
||||||
v = system_tasks_max_scale(r, 1000U);
|
|
||||||
|
|
||||||
if (v <= 0 || v >= UINT64_MAX) {
|
if (v <= 0 || v >= UINT64_MAX) {
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Maximum tasks value '%s' out of range, ignoring.", rvalue);
|
log_syntax(unit, LOG_ERR, filename, line, 0, "Maximum tasks value '%s' out of range, ignoring.", rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*tasks_max = (TasksMax) { v };
|
||||||
}
|
}
|
||||||
|
|
||||||
*tasks_max = v;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,8 @@
|
||||||
#include <sanitizer/lsan_interface.h>
|
#include <sanitizer/lsan_interface.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define DEFAULT_TASKS_MAX ((TasksMax) { 15U, 100U }) /* 15% */
|
||||||
|
|
||||||
static enum {
|
static enum {
|
||||||
ACTION_RUN,
|
ACTION_RUN,
|
||||||
ACTION_HELP,
|
ACTION_HELP,
|
||||||
|
@ -135,7 +137,7 @@ static bool arg_default_ip_accounting;
|
||||||
static bool arg_default_blockio_accounting;
|
static bool arg_default_blockio_accounting;
|
||||||
static bool arg_default_memory_accounting;
|
static bool arg_default_memory_accounting;
|
||||||
static bool arg_default_tasks_accounting;
|
static bool arg_default_tasks_accounting;
|
||||||
static uint64_t arg_default_tasks_max;
|
static TasksMax arg_default_tasks_max;
|
||||||
static sd_id128_t arg_machine_id;
|
static sd_id128_t arg_machine_id;
|
||||||
static EmergencyAction arg_cad_burst_action;
|
static EmergencyAction arg_cad_burst_action;
|
||||||
static OOMPolicy arg_default_oom_policy;
|
static OOMPolicy arg_default_oom_policy;
|
||||||
|
@ -2131,7 +2133,7 @@ static void reset_arguments(void) {
|
||||||
arg_default_blockio_accounting = false;
|
arg_default_blockio_accounting = false;
|
||||||
arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT;
|
arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT;
|
||||||
arg_default_tasks_accounting = true;
|
arg_default_tasks_accounting = true;
|
||||||
arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
|
arg_default_tasks_max = DEFAULT_TASKS_MAX;
|
||||||
arg_machine_id = (sd_id128_t) {};
|
arg_machine_id = (sd_id128_t) {};
|
||||||
arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
|
arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
|
||||||
arg_default_oom_policy = OOM_STOP;
|
arg_default_oom_policy = OOM_STOP;
|
||||||
|
|
|
@ -762,7 +762,7 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
|
||||||
.default_timer_accuracy_usec = USEC_PER_MINUTE,
|
.default_timer_accuracy_usec = USEC_PER_MINUTE,
|
||||||
.default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT,
|
.default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT,
|
||||||
.default_tasks_accounting = true,
|
.default_tasks_accounting = true,
|
||||||
.default_tasks_max = UINT64_MAX,
|
.default_tasks_max = TASKS_MAX_UNSET,
|
||||||
.default_timeout_start_usec = DEFAULT_TIMEOUT_USEC,
|
.default_timeout_start_usec = DEFAULT_TIMEOUT_USEC,
|
||||||
.default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC,
|
.default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC,
|
||||||
.default_restart_usec = DEFAULT_RESTART_USEC,
|
.default_restart_usec = DEFAULT_RESTART_USEC,
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "sd-event.h"
|
#include "sd-event.h"
|
||||||
|
|
||||||
#include "cgroup-util.h"
|
#include "cgroup-util.h"
|
||||||
|
#include "cgroup.h"
|
||||||
#include "fdset.h"
|
#include "fdset.h"
|
||||||
#include "hashmap.h"
|
#include "hashmap.h"
|
||||||
#include "ip-address-access.h"
|
#include "ip-address-access.h"
|
||||||
|
@ -349,7 +350,7 @@ struct Manager {
|
||||||
bool default_tasks_accounting;
|
bool default_tasks_accounting;
|
||||||
bool default_ip_accounting;
|
bool default_ip_accounting;
|
||||||
|
|
||||||
uint64_t default_tasks_max;
|
TasksMax default_tasks_max;
|
||||||
usec_t default_timer_accuracy_usec;
|
usec_t default_timer_accuracy_usec;
|
||||||
|
|
||||||
OOMPolicy default_oom_policy;
|
OOMPolicy default_oom_policy;
|
||||||
|
|
|
@ -9,12 +9,14 @@
|
||||||
#include "bus-util.h"
|
#include "bus-util.h"
|
||||||
#include "dbus-path.h"
|
#include "dbus-path.h"
|
||||||
#include "dbus-unit.h"
|
#include "dbus-unit.h"
|
||||||
|
#include "escape.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
#include "glob-util.h"
|
#include "glob-util.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "mkdir.h"
|
#include "mkdir.h"
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
#include "path-util.h"
|
||||||
#include "serialize.h"
|
#include "serialize.h"
|
||||||
#include "special.h"
|
#include "special.h"
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
|
@ -27,19 +29,18 @@ static const UnitActiveState state_translation_table[_PATH_STATE_MAX] = {
|
||||||
[PATH_DEAD] = UNIT_INACTIVE,
|
[PATH_DEAD] = UNIT_INACTIVE,
|
||||||
[PATH_WAITING] = UNIT_ACTIVE,
|
[PATH_WAITING] = UNIT_ACTIVE,
|
||||||
[PATH_RUNNING] = UNIT_ACTIVE,
|
[PATH_RUNNING] = UNIT_ACTIVE,
|
||||||
[PATH_FAILED] = UNIT_FAILED
|
[PATH_FAILED] = UNIT_FAILED,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int path_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
|
static int path_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
|
||||||
|
|
||||||
int path_spec_watch(PathSpec *s, sd_event_io_handler_t handler) {
|
int path_spec_watch(PathSpec *s, sd_event_io_handler_t handler) {
|
||||||
|
|
||||||
static const int flags_table[_PATH_TYPE_MAX] = {
|
static const int flags_table[_PATH_TYPE_MAX] = {
|
||||||
[PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
|
[PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
|
||||||
[PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
|
[PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
|
||||||
[PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO,
|
[PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO,
|
||||||
[PATH_MODIFIED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO|IN_MODIFY,
|
[PATH_MODIFIED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO|IN_MODIFY,
|
||||||
[PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO
|
[PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
|
@ -174,12 +175,14 @@ int path_spec_fd_event(PathSpec *s, uint32_t revents) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool path_spec_check_good(PathSpec *s, bool initial) {
|
static bool path_spec_check_good(PathSpec *s, bool initial) {
|
||||||
bool good = false;
|
bool b, good = false;
|
||||||
|
|
||||||
switch (s->type) {
|
switch (s->type) {
|
||||||
|
|
||||||
case PATH_EXISTS:
|
case PATH_EXISTS:
|
||||||
good = access(s->path, F_OK) >= 0;
|
b = access(s->path, F_OK) >= 0;
|
||||||
|
good = b && !s->previous_exists;
|
||||||
|
s->previous_exists = b;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATH_EXISTS_GLOB:
|
case PATH_EXISTS_GLOB:
|
||||||
|
@ -195,14 +198,11 @@ static bool path_spec_check_good(PathSpec *s, bool initial) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case PATH_CHANGED:
|
case PATH_CHANGED:
|
||||||
case PATH_MODIFIED: {
|
case PATH_MODIFIED:
|
||||||
bool b;
|
|
||||||
|
|
||||||
b = access(s->path, F_OK) >= 0;
|
b = access(s->path, F_OK) >= 0;
|
||||||
good = !initial && b != s->previous_exists;
|
good = !initial && b != s->previous_exists;
|
||||||
s->previous_exists = b;
|
s->previous_exists = b;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
|
@ -601,6 +601,7 @@ static int path_stop(Unit *u) {
|
||||||
|
|
||||||
static int path_serialize(Unit *u, FILE *f, FDSet *fds) {
|
static int path_serialize(Unit *u, FILE *f, FDSet *fds) {
|
||||||
Path *p = PATH(u);
|
Path *p = PATH(u);
|
||||||
|
PathSpec *s;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
assert(f);
|
assert(f);
|
||||||
|
@ -609,6 +610,19 @@ static int path_serialize(Unit *u, FILE *f, FDSet *fds) {
|
||||||
(void) serialize_item(f, "state", path_state_to_string(p->state));
|
(void) serialize_item(f, "state", path_state_to_string(p->state));
|
||||||
(void) serialize_item(f, "result", path_result_to_string(p->result));
|
(void) serialize_item(f, "result", path_result_to_string(p->result));
|
||||||
|
|
||||||
|
LIST_FOREACH(spec, s, p->specs) {
|
||||||
|
_cleanup_free_ char *escaped = NULL;
|
||||||
|
|
||||||
|
escaped = cescape(s->path);
|
||||||
|
if (!escaped)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
(void) serialize_item_format(f, "path-spec", "%s %i %s",
|
||||||
|
path_type_to_string(s->type),
|
||||||
|
s->previous_exists,
|
||||||
|
s->path);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,6 +652,38 @@ static int path_deserialize_item(Unit *u, const char *key, const char *value, FD
|
||||||
else if (f != PATH_SUCCESS)
|
else if (f != PATH_SUCCESS)
|
||||||
p->result = f;
|
p->result = f;
|
||||||
|
|
||||||
|
} else if (streq(key, "path-spec")) {
|
||||||
|
int previous_exists, skip = 0, r;
|
||||||
|
_cleanup_free_ char *type_str = NULL;
|
||||||
|
|
||||||
|
if (sscanf(value, "%ms %i %n", &type_str, &previous_exists, &skip) < 2)
|
||||||
|
log_unit_debug(u, "Failed to parse path-spec value: %s", value);
|
||||||
|
else {
|
||||||
|
_cleanup_free_ char *unescaped = NULL;
|
||||||
|
PathType type;
|
||||||
|
PathSpec *s;
|
||||||
|
|
||||||
|
type = path_type_from_string(type_str);
|
||||||
|
if (type < 0) {
|
||||||
|
log_unit_warning(u, "Unknown path type \"%s\", ignoring.", type_str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = cunescape(value+skip, 0, &unescaped);
|
||||||
|
if (r < 0) {
|
||||||
|
log_unit_warning_errno(u, r, "Failed to unescape serialize path: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIST_FOREACH(spec, s, p->specs)
|
||||||
|
if (s->type == type &&
|
||||||
|
path_equal(s->path, unescaped)) {
|
||||||
|
|
||||||
|
s->previous_exists = previous_exists;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else
|
} else
|
||||||
log_unit_debug(u, "Unknown serialization key: %s", key);
|
log_unit_debug(u, "Unknown serialization key: %s", key);
|
||||||
|
|
||||||
|
@ -670,7 +716,7 @@ static int path_dispatch_io(sd_event_source *source, int fd, uint32_t revents, v
|
||||||
if (!IN_SET(p->state, PATH_WAITING, PATH_RUNNING))
|
if (!IN_SET(p->state, PATH_WAITING, PATH_RUNNING))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* log_debug("inotify wakeup on %s.", u->id); */
|
/* log_debug("inotify wakeup on %s.", UNIT(p)->id); */
|
||||||
|
|
||||||
LIST_FOREACH(spec, s, p->specs)
|
LIST_FOREACH(spec, s, p->specs)
|
||||||
if (path_spec_owns_inotify_fd(s, fd))
|
if (path_spec_owns_inotify_fd(s, fd))
|
||||||
|
|
|
@ -15,6 +15,16 @@
|
||||||
#include "dhcp-protocol.h"
|
#include "dhcp-protocol.h"
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
|
|
||||||
|
typedef struct sd_dhcp_option {
|
||||||
|
unsigned n_ref;
|
||||||
|
|
||||||
|
uint8_t option;
|
||||||
|
void *data;
|
||||||
|
size_t length;
|
||||||
|
} sd_dhcp_option;
|
||||||
|
|
||||||
|
extern const struct hash_ops dhcp_option_hash_ops;
|
||||||
|
|
||||||
int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
|
int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
|
||||||
uint32_t xid, const uint8_t *mac_addr,
|
uint32_t xid, const uint8_t *mac_addr,
|
||||||
size_t mac_addr_len, uint16_t arp_type,
|
size_t mac_addr_len, uint16_t arp_type,
|
||||||
|
|
|
@ -79,7 +79,7 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
||||||
break;
|
break;
|
||||||
case SD_DHCP_OPTION_VENDOR_SPECIFIC: {
|
case SD_DHCP_OPTION_VENDOR_SPECIFIC: {
|
||||||
OrderedHashmap *s = (OrderedHashmap *) optval;
|
OrderedHashmap *s = (OrderedHashmap *) optval;
|
||||||
struct sd_dhcp_raw_option *p;
|
struct sd_dhcp_option *p;
|
||||||
size_t l = 0;
|
size_t l = 0;
|
||||||
Iterator i;
|
Iterator i;
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
||||||
*offset += 2;
|
*offset += 2;
|
||||||
|
|
||||||
ORDERED_HASHMAP_FOREACH(p, s, i) {
|
ORDERED_HASHMAP_FOREACH(p, s, i) {
|
||||||
options[*offset] = p->type;
|
options[*offset] = p->option;
|
||||||
options[*offset + 1] = p->length;
|
options[*offset + 1] = p->length;
|
||||||
memcpy(&options[*offset + 2], p->data, p->length);
|
memcpy(&options[*offset + 2], p->data, p->length);
|
||||||
*offset += 2 + p->length;
|
*offset += 2 + p->length;
|
||||||
|
@ -315,3 +315,43 @@ int dhcp_option_parse(DHCPMessage *message, size_t len, dhcp_option_callback_t c
|
||||||
|
|
||||||
return message_type;
|
return message_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static sd_dhcp_option* dhcp_option_free(sd_dhcp_option *i) {
|
||||||
|
if (!i)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
free(i->data);
|
||||||
|
return mfree(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_dhcp_option_new(uint8_t option, const void *data, size_t length, sd_dhcp_option **ret) {
|
||||||
|
assert_return(ret, -EINVAL);
|
||||||
|
assert_return(length == 0 || data, -EINVAL);
|
||||||
|
|
||||||
|
_cleanup_free_ void *q = memdup(data, length);
|
||||||
|
if (!q)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
sd_dhcp_option *p = new(sd_dhcp_option, 1);
|
||||||
|
if (!p)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
*p = (sd_dhcp_option) {
|
||||||
|
.n_ref = 1,
|
||||||
|
.option = option,
|
||||||
|
.length = length,
|
||||||
|
.data = TAKE_PTR(q),
|
||||||
|
};
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_option, sd_dhcp_option, dhcp_option_free);
|
||||||
|
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||||
|
dhcp_option_hash_ops,
|
||||||
|
void,
|
||||||
|
trivial_hash_func,
|
||||||
|
trivial_compare_func,
|
||||||
|
sd_dhcp_option,
|
||||||
|
sd_dhcp_option_unref);
|
||||||
|
|
|
@ -37,15 +37,6 @@ typedef struct DHCPLease {
|
||||||
usec_t expiration;
|
usec_t expiration;
|
||||||
} DHCPLease;
|
} DHCPLease;
|
||||||
|
|
||||||
struct sd_dhcp_raw_option {
|
|
||||||
unsigned n_ref;
|
|
||||||
|
|
||||||
uint8_t type;
|
|
||||||
uint8_t length;
|
|
||||||
|
|
||||||
void *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sd_dhcp_server {
|
struct sd_dhcp_server {
|
||||||
unsigned n_ref;
|
unsigned n_ref;
|
||||||
|
|
||||||
|
|
|
@ -34,14 +34,6 @@
|
||||||
#define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
|
#define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
|
||||||
#define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
|
#define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
|
||||||
|
|
||||||
struct sd_dhcp_option {
|
|
||||||
unsigned n_ref;
|
|
||||||
|
|
||||||
uint8_t option;
|
|
||||||
void *data;
|
|
||||||
size_t length;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sd_dhcp_client {
|
struct sd_dhcp_client {
|
||||||
unsigned n_ref;
|
unsigned n_ref;
|
||||||
|
|
||||||
|
@ -548,46 +540,6 @@ int sd_dhcp_client_set_max_attempts(sd_dhcp_client *client, uint64_t max_attempt
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sd_dhcp_option* dhcp_option_free(sd_dhcp_option *i) {
|
|
||||||
if (!i)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
free(i->data);
|
|
||||||
return mfree(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sd_dhcp_option_new(uint8_t option, void *data, size_t length, sd_dhcp_option **ret) {
|
|
||||||
assert_return(ret, -EINVAL);
|
|
||||||
assert_return(length == 0 || data, -EINVAL);
|
|
||||||
|
|
||||||
_cleanup_free_ void *q = memdup(data, length);
|
|
||||||
if (!q)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
sd_dhcp_option *p = new(sd_dhcp_option, 1);
|
|
||||||
if (!p)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
*p = (sd_dhcp_option) {
|
|
||||||
.n_ref = 1,
|
|
||||||
.option = option,
|
|
||||||
.length = length,
|
|
||||||
.data = TAKE_PTR(q),
|
|
||||||
};
|
|
||||||
|
|
||||||
*ret = TAKE_PTR(p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_option, sd_dhcp_option, dhcp_option_free);
|
|
||||||
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
|
||||||
dhcp_option_hash_ops,
|
|
||||||
void,
|
|
||||||
trivial_hash_func,
|
|
||||||
trivial_compare_func,
|
|
||||||
sd_dhcp_option,
|
|
||||||
sd_dhcp_option_unref);
|
|
||||||
|
|
||||||
int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v) {
|
int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
|
|
@ -127,46 +127,6 @@ int client_id_compare_func(const DHCPClientId *a, const DHCPClientId *b) {
|
||||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(dhcp_lease_hash_ops, DHCPClientId, client_id_hash_func, client_id_compare_func,
|
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(dhcp_lease_hash_ops, DHCPClientId, client_id_hash_func, client_id_compare_func,
|
||||||
DHCPLease, dhcp_lease_free);
|
DHCPLease, dhcp_lease_free);
|
||||||
|
|
||||||
static sd_dhcp_raw_option* raw_option_free(sd_dhcp_raw_option *i) {
|
|
||||||
if (!i)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
free(i->data);
|
|
||||||
return mfree(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
_public_ int sd_dhcp_raw_option_new(uint8_t type, char *data, size_t length, sd_dhcp_raw_option **ret) {
|
|
||||||
_cleanup_(sd_dhcp_raw_option_unrefp) sd_dhcp_raw_option *p = NULL;
|
|
||||||
|
|
||||||
assert_return(ret, -EINVAL);
|
|
||||||
|
|
||||||
p = new(sd_dhcp_raw_option, 1);
|
|
||||||
if (!p)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
*p = (sd_dhcp_raw_option) {
|
|
||||||
.n_ref = 1,
|
|
||||||
.data = memdup(data, length),
|
|
||||||
.length = length,
|
|
||||||
.type = type,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!p->data)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
*ret = TAKE_PTR(p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_raw_option, sd_dhcp_raw_option, raw_option_free);
|
|
||||||
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
|
||||||
dhcp_raw_options_hash_ops,
|
|
||||||
void,
|
|
||||||
trivial_hash_func,
|
|
||||||
trivial_compare_func,
|
|
||||||
sd_dhcp_raw_option,
|
|
||||||
sd_dhcp_raw_option_unref);
|
|
||||||
|
|
||||||
static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
|
static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
|
||||||
assert(server);
|
assert(server);
|
||||||
|
|
||||||
|
@ -1222,13 +1182,13 @@ int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_dhcp_server_add_raw_option(sd_dhcp_server *server, sd_dhcp_raw_option *v) {
|
int sd_dhcp_server_add_option(sd_dhcp_server *server, sd_dhcp_option *v) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert_return(server, -EINVAL);
|
assert_return(server, -EINVAL);
|
||||||
assert_return(v, -EINVAL);
|
assert_return(v, -EINVAL);
|
||||||
|
|
||||||
r = ordered_hashmap_ensure_allocated(&server->raw_option, &dhcp_raw_options_hash_ops);
|
r = ordered_hashmap_ensure_allocated(&server->raw_option, &dhcp_option_hash_ops);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -1236,7 +1196,7 @@ int sd_dhcp_server_add_raw_option(sd_dhcp_server *server, sd_dhcp_raw_option *v)
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
sd_dhcp_raw_option_ref(v);
|
sd_dhcp_option_ref(v);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,6 @@ void manager_reset_config(Manager *m) {
|
||||||
m->idle_action = HANDLE_IGNORE;
|
m->idle_action = HANDLE_IGNORE;
|
||||||
|
|
||||||
m->runtime_dir_size = physical_memory_scale(10U, 100U); /* 10% */
|
m->runtime_dir_size = physical_memory_scale(10U, 100U); /* 10% */
|
||||||
m->user_tasks_max = system_tasks_max_scale(DEFAULT_USER_TASKS_MAX_PERCENTAGE, 100U); /* 33% */
|
|
||||||
m->sessions_max = 8192;
|
m->sessions_max = 8192;
|
||||||
m->inhibitors_max = 8192;
|
m->inhibitors_max = 8192;
|
||||||
|
|
||||||
|
|
|
@ -41,4 +41,4 @@ Login.RuntimeDirectorySize, config_parse_tmpfs_size, 0, offse
|
||||||
Login.RemoveIPC, config_parse_bool, 0, offsetof(Manager, remove_ipc)
|
Login.RemoveIPC, config_parse_bool, 0, offsetof(Manager, remove_ipc)
|
||||||
Login.InhibitorsMax, config_parse_uint64, 0, offsetof(Manager, inhibitors_max)
|
Login.InhibitorsMax, config_parse_uint64, 0, offsetof(Manager, inhibitors_max)
|
||||||
Login.SessionsMax, config_parse_uint64, 0, offsetof(Manager, sessions_max)
|
Login.SessionsMax, config_parse_uint64, 0, offsetof(Manager, sessions_max)
|
||||||
Login.UserTasksMax, config_parse_compat_user_tasks_max, 0, offsetof(Manager, user_tasks_max)
|
Login.UserTasksMax, config_parse_compat_user_tasks_max, 0, 0
|
||||||
|
|
|
@ -849,7 +849,6 @@ int config_parse_compat_user_tasks_max(
|
||||||
assert(filename);
|
assert(filename);
|
||||||
assert(lvalue);
|
assert(lvalue);
|
||||||
assert(rvalue);
|
assert(rvalue);
|
||||||
assert(data);
|
|
||||||
|
|
||||||
log_syntax(unit, LOG_NOTICE, filename, line, 0,
|
log_syntax(unit, LOG_NOTICE, filename, line, 0,
|
||||||
"Support for option %s= has been removed.",
|
"Support for option %s= has been removed.",
|
||||||
|
|
|
@ -119,7 +119,6 @@ struct Manager {
|
||||||
sd_event_source *lid_switch_ignore_event_source;
|
sd_event_source *lid_switch_ignore_event_source;
|
||||||
|
|
||||||
uint64_t runtime_dir_size;
|
uint64_t runtime_dir_size;
|
||||||
uint64_t user_tasks_max;
|
|
||||||
uint64_t sessions_max;
|
uint64_t sessions_max;
|
||||||
uint64_t inhibitors_max;
|
uint64_t inhibitors_max;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
|
||||||
|
#include "dhcp-internal.h"
|
||||||
|
#include "escape.h"
|
||||||
#include "in-addr-util.h"
|
#include "in-addr-util.h"
|
||||||
#include "networkd-dhcp-common.h"
|
#include "networkd-dhcp-common.h"
|
||||||
#include "networkd-network.h"
|
#include "networkd-network.h"
|
||||||
|
@ -263,6 +265,167 @@ int config_parse_dhcp6_pd_hint(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_parse_dhcp_send_option(
|
||||||
|
const char *unit,
|
||||||
|
const char *filename,
|
||||||
|
unsigned line,
|
||||||
|
const char *section,
|
||||||
|
unsigned section_line,
|
||||||
|
const char *lvalue,
|
||||||
|
int ltype,
|
||||||
|
const char *rvalue,
|
||||||
|
void *data,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
_cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt = NULL, *old = NULL;
|
||||||
|
_cleanup_free_ char *word = NULL, *q = NULL;
|
||||||
|
OrderedHashmap **options = userdata;
|
||||||
|
union in_addr_union addr;
|
||||||
|
DHCPOptionDataType type;
|
||||||
|
uint8_t u, uint8_data;
|
||||||
|
uint16_t uint16_data;
|
||||||
|
uint32_t uint32_data;
|
||||||
|
const void *udata;
|
||||||
|
const char *p;
|
||||||
|
ssize_t sz;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(filename);
|
||||||
|
assert(lvalue);
|
||||||
|
assert(rvalue);
|
||||||
|
assert(data);
|
||||||
|
|
||||||
|
if (isempty(rvalue)) {
|
||||||
|
*options = ordered_hashmap_free(*options);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = rvalue;
|
||||||
|
r = extract_first_word(&p, &word, ":", 0);
|
||||||
|
if (r == -ENOMEM)
|
||||||
|
return log_oom();
|
||||||
|
if (r <= 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Invalid DHCP option, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = safe_atou8(word, &u);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Invalid DHCP option, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (u < 1 || u >= 255) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||||
|
"Invalid DHCP option, valid range is 1-254, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(word);
|
||||||
|
r = extract_first_word(&p, &word, ":", 0);
|
||||||
|
if (r == -ENOMEM)
|
||||||
|
return log_oom();
|
||||||
|
if (r <= 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Invalid DHCP option, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = dhcp_option_data_type_from_string(word);
|
||||||
|
if (type < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||||
|
"Invalid DHCP option data type, ignoring assignment: %s", p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case DHCP_OPTION_DATA_UINT8:{
|
||||||
|
r = safe_atou8(p, &uint8_data);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to parse DHCPv4 uint8 data, ignoring assignment: %s", p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
udata = &uint8_data;
|
||||||
|
sz = sizeof(uint8_t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DHCP_OPTION_DATA_UINT16:{
|
||||||
|
r = safe_atou16(p, &uint16_data);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to parse DHCPv4 uint16 data, ignoring assignment: %s", p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
udata = &uint16_data;
|
||||||
|
sz = sizeof(uint16_t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DHCP_OPTION_DATA_UINT32: {
|
||||||
|
r = safe_atou32(p, &uint32_data);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to parse DHCPv4 uint32 data, ignoring assignment: %s", p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
udata = &uint32_data;
|
||||||
|
sz = sizeof(uint32_t);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DHCP_OPTION_DATA_IPV4ADDRESS: {
|
||||||
|
r = in_addr_from_string(AF_INET, p, &addr);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to parse DHCPv4 ipv4address data, ignoring assignment: %s", p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
udata = &addr.in;
|
||||||
|
sz = sizeof(addr.in.s_addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DHCP_OPTION_DATA_STRING:
|
||||||
|
sz = cunescape(p, 0, &q);
|
||||||
|
if (sz < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, sz,
|
||||||
|
"Failed to decode DHCPv4 option data, ignoring assignment: %s", p);
|
||||||
|
}
|
||||||
|
|
||||||
|
udata = q;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_dhcp_option_new(u, udata, sz, &opt);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to store DHCPv4 option '%s', ignoring assignment: %m", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = ordered_hashmap_ensure_allocated(options, &dhcp_option_hash_ops);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
/* Overwrite existing option */
|
||||||
|
old = ordered_hashmap_remove(*options, UINT_TO_PTR(u));
|
||||||
|
r = ordered_hashmap_put(*options, UINT_TO_PTR(u), opt);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to store DHCPv4 option '%s', ignoring assignment: %m", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAKE_PTR(opt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains, dhcp_use_domains, DHCPUseDomains,
|
DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains, dhcp_use_domains, DHCPUseDomains,
|
||||||
"Failed to parse DHCP use domains setting");
|
"Failed to parse DHCP use domains setting");
|
||||||
|
|
||||||
|
|
|
@ -48,3 +48,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_sip);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
|
CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table);
|
CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_pd_hint);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_pd_hint);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option);
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include "sd-dhcp-server.h"
|
#include "sd-dhcp-server.h"
|
||||||
|
|
||||||
#include "escape.h"
|
|
||||||
#include "networkd-dhcp-server.h"
|
#include "networkd-dhcp-server.h"
|
||||||
#include "networkd-link.h"
|
#include "networkd-link.h"
|
||||||
#include "networkd-manager.h"
|
#include "networkd-manager.h"
|
||||||
|
@ -192,7 +191,7 @@ static int link_push_uplink_sip_to_dhcp_server(Link *link, sd_dhcp_server *s) {
|
||||||
|
|
||||||
int dhcp4_server_configure(Link *link) {
|
int dhcp4_server_configure(Link *link) {
|
||||||
bool acquired_uplink = false;
|
bool acquired_uplink = false;
|
||||||
sd_dhcp_raw_option *p;
|
sd_dhcp_option *p;
|
||||||
Link *uplink = NULL;
|
Link *uplink = NULL;
|
||||||
Address *address;
|
Address *address;
|
||||||
Iterator i;
|
Iterator i;
|
||||||
|
@ -305,8 +304,8 @@ int dhcp4_server_configure(Link *link) {
|
||||||
return log_link_error_errno(link, r, "Failed to set timezone for DHCP server: %m");
|
return log_link_error_errno(link, r, "Failed to set timezone for DHCP server: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
ORDERED_HASHMAP_FOREACH(p, link->network->dhcp_server_raw_options, i) {
|
ORDERED_HASHMAP_FOREACH(p, link->network->dhcp_server_send_options, i) {
|
||||||
r = sd_dhcp_server_add_raw_option(link->dhcp_server, p);
|
r = sd_dhcp_server_add_option(link->dhcp_server, p);
|
||||||
if (r == -EEXIST)
|
if (r == -EEXIST)
|
||||||
continue;
|
continue;
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -479,167 +478,3 @@ int config_parse_dhcp_server_sip(
|
||||||
n->dhcp_server_sip = m;
|
n->dhcp_server_sip = m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int config_parse_dhcp_server_raw_option_data(
|
|
||||||
const char *unit,
|
|
||||||
const char *filename,
|
|
||||||
unsigned line,
|
|
||||||
const char *section,
|
|
||||||
unsigned section_line,
|
|
||||||
const char *lvalue,
|
|
||||||
int ltype,
|
|
||||||
const char *rvalue,
|
|
||||||
void *data,
|
|
||||||
void *userdata) {
|
|
||||||
|
|
||||||
_cleanup_(sd_dhcp_raw_option_unrefp) sd_dhcp_raw_option *opt = NULL, *old = NULL;
|
|
||||||
_cleanup_free_ char *word = NULL, *q = NULL;
|
|
||||||
union in_addr_union addr;
|
|
||||||
DHCPOptionDataType type;
|
|
||||||
Network *network = data;
|
|
||||||
uint16_t uint16_data;
|
|
||||||
uint32_t uint32_data;
|
|
||||||
uint8_t uint8_data;
|
|
||||||
const char *p;
|
|
||||||
void *udata;
|
|
||||||
ssize_t sz;
|
|
||||||
uint8_t u;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(filename);
|
|
||||||
assert(lvalue);
|
|
||||||
assert(rvalue);
|
|
||||||
assert(data);
|
|
||||||
|
|
||||||
if (isempty(rvalue)) {
|
|
||||||
network->dhcp_server_raw_options = ordered_hashmap_free(network->dhcp_server_raw_options);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = rvalue;
|
|
||||||
r = extract_first_word(&p, &word, ":", 0);
|
|
||||||
if (r == -ENOMEM)
|
|
||||||
return log_oom();
|
|
||||||
if (r <= 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Invalid DHCP server send raw option, ignoring assignment: %s", rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = safe_atou8(word, &u);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Failed to parse DHCP server send raw option type, ignoring assignment: %s", rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (u < 1 || u >= 255) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
|
||||||
"Invalid DHCP server send raw option, valid range is 1-254, ignoring assignment: %s", rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(word);
|
|
||||||
|
|
||||||
r = extract_first_word(&p, &word, ":", 0);
|
|
||||||
if (r == -ENOMEM)
|
|
||||||
return log_oom();
|
|
||||||
if (r <= 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Invalid DHCP server send raw option, ignoring assignment: %s", rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = dhcp_option_data_type_from_string(word);
|
|
||||||
if (type < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
|
||||||
"Invalid DHCP server send data type, ignoring assignment: %s", p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(type) {
|
|
||||||
case DHCP_OPTION_DATA_UINT8:{
|
|
||||||
r = safe_atou8(p, &uint8_data);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Failed to parse DHCPv4 vendor specific uint8 data, ignoring assignment: %s", p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
udata = &uint8_data;
|
|
||||||
sz = sizeof(uint8_t);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DHCP_OPTION_DATA_UINT16:{
|
|
||||||
r = safe_atou16(p, &uint16_data);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Failed to parse DHCPv4 vendor specific uint16 data, ignoring assignment: %s", p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
udata = &uint16_data;
|
|
||||||
sz = sizeof(uint16_t);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DHCP_OPTION_DATA_UINT32: {
|
|
||||||
r = safe_atou32(p, &uint32_data);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Failed to parse DHCPv4 vendor specific uint32 data, ignoring assignment: %s", p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
udata = &uint32_data;
|
|
||||||
sz = sizeof(uint32_t);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DHCP_OPTION_DATA_IPV4ADDRESS: {
|
|
||||||
r = in_addr_from_string(AF_INET, p, &addr);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Failed to parse DHCPv4 vendor specific ipv4address data, ignoring assignment: %s", p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
udata = &addr.in;
|
|
||||||
sz = sizeof(addr.in.s_addr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DHCP_OPTION_DATA_STRING:
|
|
||||||
sz = cunescape(p, 0, &q);
|
|
||||||
if (sz < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, sz,
|
|
||||||
"Failed to decode option data, ignoring assignment: %s", p);
|
|
||||||
}
|
|
||||||
|
|
||||||
udata = q;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sd_dhcp_raw_option_new(u, udata, sz, &opt);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Failed to store DHCP send raw option '%s', ignoring assignment: %m", rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = ordered_hashmap_ensure_allocated(&network->dhcp_server_raw_options, &dhcp_raw_options_hash_ops);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
/* Overwrite existing option */
|
|
||||||
old = ordered_hashmap_remove(network->dhcp_server_raw_options, UINT_TO_PTR(u));
|
|
||||||
r = ordered_hashmap_put(network->dhcp_server_raw_options, UINT_TO_PTR(u), opt);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Failed to store DHCP server send raw option '%s'", rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TAKE_PTR(opt);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,4 +12,3 @@ int dhcp4_server_configure(Link *link);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_dns);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_dns);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_sip);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_sip);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_raw_option_data);
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "dhcp-client-internal.h"
|
#include "dhcp-client-internal.h"
|
||||||
#include "escape.h"
|
|
||||||
#include "hostname-util.h"
|
#include "hostname-util.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "network-internal.h"
|
#include "network-internal.h"
|
||||||
|
@ -1295,7 +1294,7 @@ int dhcp4_configure(Link *link) {
|
||||||
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for '%u': %m", option);
|
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for '%u': %m", option);
|
||||||
}
|
}
|
||||||
|
|
||||||
ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_send_options, i) {
|
ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_client_send_options, i) {
|
||||||
r = sd_dhcp_client_set_dhcp_option(link->dhcp_client, send_option);
|
r = sd_dhcp_client_set_dhcp_option(link->dhcp_client, send_option);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set send option: %m");
|
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set send option: %m");
|
||||||
|
@ -1566,167 +1565,6 @@ int config_parse_dhcp_request_options(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int config_parse_dhcp_send_option(
|
|
||||||
const char *unit,
|
|
||||||
const char *filename,
|
|
||||||
unsigned line,
|
|
||||||
const char *section,
|
|
||||||
unsigned section_line,
|
|
||||||
const char *lvalue,
|
|
||||||
int ltype,
|
|
||||||
const char *rvalue,
|
|
||||||
void *data,
|
|
||||||
void *userdata) {
|
|
||||||
|
|
||||||
_cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt = NULL, *old = NULL;
|
|
||||||
_cleanup_free_ char *word = NULL, *q = NULL;
|
|
||||||
union in_addr_union addr;
|
|
||||||
DHCPOptionDataType type;
|
|
||||||
Network *network = data;
|
|
||||||
uint8_t u, uint8_data;
|
|
||||||
uint16_t uint16_data;
|
|
||||||
uint32_t uint32_data;
|
|
||||||
const char *p;
|
|
||||||
void *udata;
|
|
||||||
ssize_t sz;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(filename);
|
|
||||||
assert(lvalue);
|
|
||||||
assert(rvalue);
|
|
||||||
assert(data);
|
|
||||||
|
|
||||||
if (isempty(rvalue)) {
|
|
||||||
network->dhcp_send_options = ordered_hashmap_free(network->dhcp_send_options);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = rvalue;
|
|
||||||
r = extract_first_word(&p, &word, ":", 0);
|
|
||||||
if (r == -ENOMEM)
|
|
||||||
return log_oom();
|
|
||||||
if (r <= 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Invalid DHCP send option, ignoring assignment: %s", rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = safe_atou8(word, &u);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Invalid DHCP send option, ignoring assignment: %s", rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (u < 1 || u >= 255) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
|
||||||
"Invalid DHCP send option, valid range is 1-254, ignoring assignment: %s", rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(word);
|
|
||||||
r = extract_first_word(&p, &word, ":", 0);
|
|
||||||
if (r == -ENOMEM)
|
|
||||||
return log_oom();
|
|
||||||
if (r <= 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Invalid DHCP send option, ignoring assignment: %s", rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = dhcp_option_data_type_from_string(word);
|
|
||||||
if (type < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
|
||||||
"Invalid DHCP send data type, ignoring assignment: %s", p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(type) {
|
|
||||||
case DHCP_OPTION_DATA_UINT8:{
|
|
||||||
r = safe_atou8(p, &uint8_data);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Failed to parse DHCPv4 uint8 data, ignoring assignment: %s", p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
udata = &uint8_data;
|
|
||||||
sz = sizeof(uint8_t);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DHCP_OPTION_DATA_UINT16:{
|
|
||||||
r = safe_atou16(p, &uint16_data);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Failed to parse DHCPv4 uint16 data, ignoring assignment: %s", p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
udata = &uint16_data;
|
|
||||||
sz = sizeof(uint16_t);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DHCP_OPTION_DATA_UINT32: {
|
|
||||||
r = safe_atou32(p, &uint32_data);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Failed to parse DHCPv4 uint32 data, ignoring assignment: %s", p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
udata = &uint32_data;
|
|
||||||
sz = sizeof(uint32_t);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DHCP_OPTION_DATA_IPV4ADDRESS: {
|
|
||||||
r = in_addr_from_string(AF_INET, p, &addr);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Failed to parse DHCPv4 ipv4address data, ignoring assignment: %s", p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
udata = &addr.in;
|
|
||||||
sz = sizeof(addr.in.s_addr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DHCP_OPTION_DATA_STRING:
|
|
||||||
sz = cunescape(p, 0, &q);
|
|
||||||
if (sz < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, sz,
|
|
||||||
"Failed to decode option data, ignoring assignment: %s", p);
|
|
||||||
}
|
|
||||||
|
|
||||||
udata = q;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sd_dhcp_option_new(u, udata, sz, &opt);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Failed to store DHCP send option '%s', ignoring assignment: %m", rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = ordered_hashmap_ensure_allocated(&network->dhcp_send_options, &dhcp_option_hash_ops);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
/* Overwrite existing option */
|
|
||||||
old = ordered_hashmap_remove(network->dhcp_send_options, UINT_TO_PTR(u));
|
|
||||||
r = ordered_hashmap_put(network->dhcp_send_options, UINT_TO_PTR(u), opt);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Failed to store DHCP send option '%s'", rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TAKE_PTR(opt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = {
|
static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = {
|
||||||
[DHCP_CLIENT_ID_MAC] = "mac",
|
[DHCP_CLIENT_ID_MAC] = "mac",
|
||||||
[DHCP_CLIENT_ID_DUID] = "duid",
|
[DHCP_CLIENT_ID_DUID] = "duid",
|
||||||
|
|
|
@ -27,4 +27,3 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_black_listed_ip_address);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option);
|
|
||||||
|
|
|
@ -175,7 +175,7 @@ DHCPv4.ListenPort, config_parse_uint16,
|
||||||
DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release)
|
DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release)
|
||||||
DHCPv4.BlackList, config_parse_dhcp_black_listed_ip_address, 0, 0
|
DHCPv4.BlackList, config_parse_dhcp_black_listed_ip_address, 0, 0
|
||||||
DHCPv4.IPServiceType, config_parse_ip_service_type, 0, offsetof(Network, ip_service_type)
|
DHCPv4.IPServiceType, config_parse_ip_service_type, 0, offsetof(Network, ip_service_type)
|
||||||
DHCPv4.SendOption, config_parse_dhcp_send_option, 0, 0
|
DHCPv4.SendOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_client_send_options)
|
||||||
DHCPv6.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp6_use_dns)
|
DHCPv6.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp6_use_dns)
|
||||||
DHCPv6.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp6_use_ntp)
|
DHCPv6.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp6_use_ntp)
|
||||||
DHCPv6.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit)
|
DHCPv6.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit)
|
||||||
|
@ -200,7 +200,7 @@ DHCPServer.EmitTimezone, config_parse_bool,
|
||||||
DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone)
|
DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone)
|
||||||
DHCPServer.PoolOffset, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_offset)
|
DHCPServer.PoolOffset, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_offset)
|
||||||
DHCPServer.PoolSize, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_size)
|
DHCPServer.PoolSize, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_size)
|
||||||
DHCPServer.SendRawOption, config_parse_dhcp_server_raw_option_data, 0, 0
|
DHCPServer.SendOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_server_send_options)
|
||||||
Bridge.Cost, config_parse_uint32, 0, offsetof(Network, cost)
|
Bridge.Cost, config_parse_uint32, 0, offsetof(Network, cost)
|
||||||
Bridge.UseBPDU, config_parse_tristate, 0, offsetof(Network, use_bpdu)
|
Bridge.UseBPDU, config_parse_tristate, 0, offsetof(Network, use_bpdu)
|
||||||
Bridge.HairPin, config_parse_tristate, 0, offsetof(Network, hairpin)
|
Bridge.HairPin, config_parse_tristate, 0, offsetof(Network, hairpin)
|
||||||
|
|
|
@ -686,8 +686,8 @@ static Network *network_free(Network *network) {
|
||||||
|
|
||||||
set_free_free(network->dnssec_negative_trust_anchors);
|
set_free_free(network->dnssec_negative_trust_anchors);
|
||||||
|
|
||||||
ordered_hashmap_free(network->dhcp_send_options);
|
ordered_hashmap_free(network->dhcp_client_send_options);
|
||||||
ordered_hashmap_free(network->dhcp_server_raw_options);
|
ordered_hashmap_free(network->dhcp_server_send_options);
|
||||||
|
|
||||||
return mfree(network);
|
return mfree(network);
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,8 +114,8 @@ struct Network {
|
||||||
DHCPUseDomains dhcp_use_domains;
|
DHCPUseDomains dhcp_use_domains;
|
||||||
Set *dhcp_black_listed_ip;
|
Set *dhcp_black_listed_ip;
|
||||||
Set *dhcp_request_options;
|
Set *dhcp_request_options;
|
||||||
OrderedHashmap *dhcp_send_options;
|
OrderedHashmap *dhcp_client_send_options;
|
||||||
OrderedHashmap *dhcp_server_raw_options;
|
OrderedHashmap *dhcp_server_send_options;
|
||||||
|
|
||||||
/* DHCPv6 Client support*/
|
/* DHCPv6 Client support*/
|
||||||
bool dhcp6_use_dns;
|
bool dhcp6_use_dns;
|
||||||
|
|
|
@ -22,6 +22,7 @@ _not_installed_headers = '''
|
||||||
sd-dhcp6-lease.h
|
sd-dhcp6-lease.h
|
||||||
sd-dhcp-client.h
|
sd-dhcp-client.h
|
||||||
sd-dhcp-lease.h
|
sd-dhcp-lease.h
|
||||||
|
sd-dhcp-option.h
|
||||||
sd-dhcp-server.h
|
sd-dhcp-server.h
|
||||||
sd-ipv4acd.h
|
sd-ipv4acd.h
|
||||||
sd-ipv4ll.h
|
sd-ipv4ll.h
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "sd-dhcp-lease.h"
|
#include "sd-dhcp-lease.h"
|
||||||
|
#include "sd-dhcp-option.h"
|
||||||
#include "sd-event.h"
|
#include "sd-event.h"
|
||||||
|
|
||||||
#include "_sd-common.h"
|
#include "_sd-common.h"
|
||||||
|
@ -99,7 +100,6 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct sd_dhcp_client sd_dhcp_client;
|
typedef struct sd_dhcp_client sd_dhcp_client;
|
||||||
typedef struct sd_dhcp_option sd_dhcp_option;
|
|
||||||
|
|
||||||
typedef int (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event, void *userdata);
|
typedef int (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event, void *userdata);
|
||||||
int sd_dhcp_client_set_callback(
|
int sd_dhcp_client_set_callback(
|
||||||
|
@ -179,9 +179,6 @@ int sd_dhcp_client_set_service_type(
|
||||||
sd_dhcp_client *client,
|
sd_dhcp_client *client,
|
||||||
int type);
|
int type);
|
||||||
|
|
||||||
int sd_dhcp_option_new(uint8_t option, void *data, size_t length, sd_dhcp_option **ret);
|
|
||||||
sd_dhcp_option* sd_dhcp_option_ref(sd_dhcp_option *i);
|
|
||||||
sd_dhcp_option* sd_dhcp_option_unref(sd_dhcp_option *i);
|
|
||||||
int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v);
|
int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v);
|
||||||
|
|
||||||
int sd_dhcp_client_stop(sd_dhcp_client *client);
|
int sd_dhcp_client_stop(sd_dhcp_client *client);
|
||||||
|
@ -204,7 +201,6 @@ int sd_dhcp_client_detach_event(sd_dhcp_client *client);
|
||||||
sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client);
|
sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client);
|
||||||
|
|
||||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_client, sd_dhcp_client_unref);
|
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_client, sd_dhcp_client_unref);
|
||||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_option, sd_dhcp_option_unref);
|
|
||||||
|
|
||||||
_SD_END_DECLARATIONS;
|
_SD_END_DECLARATIONS;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
#ifndef foosddhcpoptionhfoo
|
||||||
|
#define foosddhcpoptionhfoo
|
||||||
|
|
||||||
|
/***
|
||||||
|
Copyright © 2013 Intel Corporation. All rights reserved.
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "_sd-common.h"
|
||||||
|
|
||||||
|
_SD_BEGIN_DECLARATIONS;
|
||||||
|
|
||||||
|
typedef struct sd_dhcp_option sd_dhcp_option;
|
||||||
|
|
||||||
|
int sd_dhcp_option_new(uint8_t option, const void *data, size_t length, sd_dhcp_option **ret);
|
||||||
|
sd_dhcp_option *sd_dhcp_option_ref(sd_dhcp_option *ra);
|
||||||
|
sd_dhcp_option *sd_dhcp_option_unref(sd_dhcp_option *ra);
|
||||||
|
|
||||||
|
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_option, sd_dhcp_option_unref);
|
||||||
|
|
||||||
|
_SD_END_DECLARATIONS;
|
||||||
|
|
||||||
|
#endif
|
|
@ -21,26 +21,20 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include "sd-dhcp-option.h"
|
||||||
#include "sd-event.h"
|
#include "sd-event.h"
|
||||||
|
|
||||||
#include "_sd-common.h"
|
#include "_sd-common.h"
|
||||||
|
|
||||||
_SD_BEGIN_DECLARATIONS;
|
_SD_BEGIN_DECLARATIONS;
|
||||||
|
|
||||||
extern const struct hash_ops dhcp_raw_options_hash_ops;
|
|
||||||
|
|
||||||
typedef struct sd_dhcp_server sd_dhcp_server;
|
typedef struct sd_dhcp_server sd_dhcp_server;
|
||||||
typedef struct sd_dhcp_raw_option sd_dhcp_raw_option;
|
|
||||||
|
|
||||||
int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex);
|
int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex);
|
||||||
|
|
||||||
sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server);
|
sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server);
|
||||||
sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server);
|
sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server);
|
||||||
|
|
||||||
int sd_dhcp_raw_option_new(uint8_t type, char *data, size_t lengt, sd_dhcp_raw_option **ret);
|
|
||||||
sd_dhcp_raw_option *sd_dhcp_raw_option_ref(sd_dhcp_raw_option *ra);
|
|
||||||
sd_dhcp_raw_option *sd_dhcp_raw_option_unref(sd_dhcp_raw_option *ra);
|
|
||||||
|
|
||||||
int sd_dhcp_server_attach_event(sd_dhcp_server *client, sd_event *event, int64_t priority);
|
int sd_dhcp_server_attach_event(sd_dhcp_server *client, sd_event *event, int64_t priority);
|
||||||
int sd_dhcp_server_detach_event(sd_dhcp_server *client);
|
int sd_dhcp_server_detach_event(sd_dhcp_server *client);
|
||||||
sd_event *sd_dhcp_server_get_event(sd_dhcp_server *client);
|
sd_event *sd_dhcp_server_get_event(sd_dhcp_server *client);
|
||||||
|
@ -58,7 +52,7 @@ int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], u
|
||||||
int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n);
|
int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n);
|
||||||
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled);
|
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled);
|
||||||
|
|
||||||
int sd_dhcp_server_add_raw_option(sd_dhcp_server *server, sd_dhcp_raw_option *v);
|
int sd_dhcp_server_add_option(sd_dhcp_server *server, sd_dhcp_option *v);
|
||||||
|
|
||||||
int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t);
|
int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t);
|
||||||
int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t);
|
int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t);
|
||||||
|
@ -66,7 +60,6 @@ int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t);
|
||||||
int sd_dhcp_server_forcerenew(sd_dhcp_server *server);
|
int sd_dhcp_server_forcerenew(sd_dhcp_server *server);
|
||||||
|
|
||||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_server, sd_dhcp_server_unref);
|
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_server, sd_dhcp_server_unref);
|
||||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_raw_option, sd_dhcp_raw_option_unref);
|
|
||||||
|
|
||||||
_SD_END_DECLARATIONS;
|
_SD_END_DECLARATIONS;
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ static int test_cgroup_mask(void) {
|
||||||
m->default_blockio_accounting =
|
m->default_blockio_accounting =
|
||||||
m->default_io_accounting =
|
m->default_io_accounting =
|
||||||
m->default_tasks_accounting = false;
|
m->default_tasks_accounting = false;
|
||||||
m->default_tasks_max = (uint64_t) -1;
|
m->default_tasks_max = TASKS_MAX_UNSET;
|
||||||
|
|
||||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||||
|
|
||||||
|
|
|
@ -259,7 +259,7 @@ MaxLeaseTimeSec=
|
||||||
DefaultLeaseTimeSec=
|
DefaultLeaseTimeSec=
|
||||||
EmitTimezone=
|
EmitTimezone=
|
||||||
DNS=
|
DNS=
|
||||||
SendRawOption=
|
SendOption=
|
||||||
[NextHop]
|
[NextHop]
|
||||||
Id=
|
Id=
|
||||||
Gateway=
|
Gateway=
|
||||||
|
|
Loading…
Reference in New Issue