mirror of
https://github.com/systemd/systemd
synced 2024-07-22 18:55:10 +00:00
Merge pull request #29630 from DaanDeMeyer/manager-json
Various refactoring in preparation for adding JSON dump to pid 1
This commit is contained in:
commit
26204e1a4a
|
@ -234,16 +234,17 @@ QEMU.
|
|||
To allow VSCode's debugger to attach to systemd running in a mkosi image, we have to make sure it can access
|
||||
the virtual machine spawned by mkosi where systemd is running. mkosi makes this possible via a handy SSH
|
||||
option that makes the generated image accessible via SSH when booted. Thus you must build the image with
|
||||
`mkosi --ssh`. The easiest way to set the option is to create a file 20-local.conf in mkosi.conf.d/ (in the
|
||||
directory you ran mkosi in) and add the following contents:
|
||||
`mkosi --ssh`. The easiest way to set the option is to create a file `mkosi.conf` in the root of the
|
||||
repository and add the following contents:
|
||||
|
||||
```
|
||||
[Host]
|
||||
Ssh=yes
|
||||
RuntimeTrees=.
|
||||
```
|
||||
|
||||
Also make sure that the SSH agent is running on your system and that you've added your SSH key to it with
|
||||
`ssh-add`.
|
||||
`ssh-add`. Also make sure that `virtiofsd` is installed.
|
||||
|
||||
After rebuilding the image and booting it with `mkosi qemu`, you should now be able to connect to it by
|
||||
running `mkosi ssh` from the same directory in another terminal window.
|
||||
|
@ -284,14 +285,10 @@ the directory, and add the following contents:
|
|||
},
|
||||
"MIMode": "gdb",
|
||||
"sourceFileMap": {
|
||||
"/work/build/../src": {
|
||||
"/root/src/systemd": {
|
||||
"editorPath": "${workspaceFolder}",
|
||||
"useForBreakpoints": false
|
||||
},
|
||||
"/work/build/*": {
|
||||
"editorPath": "${workspaceFolder}/mkosi.builddir",
|
||||
"useForBreakpoints": false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -7,7 +7,6 @@ Dependencies=base
|
|||
Autologin=yes
|
||||
BaseTrees=../../mkosi.output/base
|
||||
ExtraTrees=../../mkosi.output/base-systemd
|
||||
ExtraTrees=../../src:/usr/src/src
|
||||
Packages=
|
||||
acl
|
||||
bash-completion
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
set debuginfod enabled off
|
||||
set build-id-verbose 0
|
||||
set substitute-path ../src /usr/src
|
||||
set substitute-path ../src /root/src/systemd
|
||||
|
|
|
@ -2135,7 +2135,9 @@ int _hashmap_dump_sorted(HashmapBase *h, void ***ret, size_t *ret_n) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
entries = new(struct hashmap_base_entry*, _hashmap_size(h));
|
||||
/* We append one more element than needed so that the resulting array can be used as a strv. We
|
||||
* don't count this entry in the returned size. */
|
||||
entries = new(struct hashmap_base_entry*, _hashmap_size(h) + 1);
|
||||
if (!entries)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -2143,6 +2145,7 @@ int _hashmap_dump_sorted(HashmapBase *h, void ***ret, size_t *ret_n) {
|
|||
entries[n++] = bucket_at(h, idx);
|
||||
|
||||
assert(n == _hashmap_size(h));
|
||||
entries[n] = NULL;
|
||||
|
||||
typesafe_qsort_r(entries, n, hashmap_entry_compare, h->hash_ops->compare);
|
||||
|
||||
|
|
|
@ -68,6 +68,14 @@ const char *unit_dbus_interface_from_name(const char *name) {
|
|||
return unit_dbus_interface_from_type(t);
|
||||
}
|
||||
|
||||
const char* unit_type_to_capitalized_string(UnitType t) {
|
||||
const char *di = unit_dbus_interface_from_type(t);
|
||||
if (!di)
|
||||
return NULL;
|
||||
|
||||
return ASSERT_PTR(startswith(di, "org.freedesktop.systemd1."));
|
||||
}
|
||||
|
||||
static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
|
||||
[UNIT_SERVICE] = "service",
|
||||
[UNIT_SOCKET] = "socket",
|
||||
|
|
|
@ -287,6 +287,8 @@ const char *unit_dbus_interface_from_name(const char *name);
|
|||
const char *unit_type_to_string(UnitType i) _const_;
|
||||
UnitType unit_type_from_string(const char *s) _pure_;
|
||||
|
||||
const char* unit_type_to_capitalized_string(UnitType t);
|
||||
|
||||
const char *unit_load_state_to_string(UnitLoadState i) _const_;
|
||||
UnitLoadState unit_load_state_from_string(const char *s) _pure_;
|
||||
|
||||
|
|
|
@ -4543,3 +4543,21 @@ static const char* const cgroup_pressure_watch_table[_CGROUP_PRESSURE_WATCH_MAX]
|
|||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(cgroup_pressure_watch, CGroupPressureWatch, CGROUP_PRESSURE_WATCH_ON);
|
||||
|
||||
static const char* const cgroup_ip_accounting_metric_table[_CGROUP_IP_ACCOUNTING_METRIC_MAX] = {
|
||||
[CGROUP_IP_INGRESS_BYTES] = "IPIngressBytes",
|
||||
[CGROUP_IP_EGRESS_BYTES] = "IPEgressBytes",
|
||||
[CGROUP_IP_INGRESS_PACKETS] = "IPIngressPackets",
|
||||
[CGROUP_IP_EGRESS_PACKETS] = "IPEgressPackets",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(cgroup_ip_accounting_metric, CGroupIPAccountingMetric);
|
||||
|
||||
static const char* const cgroup_io_accounting_metric_table[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {
|
||||
[CGROUP_IO_READ_BYTES] = "IOReadBytes",
|
||||
[CGROUP_IO_WRITE_BYTES] = "IOWriteBytes",
|
||||
[CGROUP_IO_READ_OPERATIONS] = "IOReadOperations",
|
||||
[CGROUP_IO_WRITE_OPERATIONS] = "IOWriteOperations",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(cgroup_io_accounting_metric, CGroupIOAccountingMetric);
|
||||
|
|
|
@ -399,3 +399,9 @@ CGroupPressureWatch cgroup_pressure_watch_from_string(const char *s) _pure_;
|
|||
|
||||
const char *cgroup_device_permissions_to_string(CGroupDevicePermissions p) _const_;
|
||||
CGroupDevicePermissions cgroup_device_permissions_from_string(const char *s) _pure_;
|
||||
|
||||
const char* cgroup_ip_accounting_metric_to_string(CGroupIPAccountingMetric m) _const_;
|
||||
CGroupIPAccountingMetric cgroup_ip_accounting_metric_from_string(const char *s) _pure_;
|
||||
|
||||
const char* cgroup_io_accounting_metric_to_string(CGroupIOAccountingMetric m) _const_;
|
||||
CGroupIOAccountingMetric cgroup_io_accounting_metric_from_string(const char *s) _pure_;
|
||||
|
|
|
@ -61,6 +61,12 @@ static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_string, "s", NULL);
|
|||
static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_level, "i", int, LOG_PRI);
|
||||
static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_facility, "i", int, LOG_FAC);
|
||||
static BUS_DEFINE_PROPERTY_GET(property_get_cpu_affinity_from_numa, "b", ExecContext, exec_context_get_cpu_affinity_from_numa);
|
||||
static BUS_DEFINE_PROPERTY_GET(property_get_oom_score_adjust, "i", ExecContext, exec_context_get_oom_score_adjust);
|
||||
static BUS_DEFINE_PROPERTY_GET(property_get_nice, "i", ExecContext, exec_context_get_nice);
|
||||
static BUS_DEFINE_PROPERTY_GET(property_get_cpu_sched_policy, "i", ExecContext, exec_context_get_cpu_sched_policy);
|
||||
static BUS_DEFINE_PROPERTY_GET(property_get_cpu_sched_priority, "i", ExecContext, exec_context_get_cpu_sched_priority);
|
||||
static BUS_DEFINE_PROPERTY_GET(property_get_coredump_filter, "t", ExecContext, exec_context_get_coredump_filter);
|
||||
static BUS_DEFINE_PROPERTY_GET(property_get_timer_slack_nsec, "t", ExecContext, exec_context_get_timer_slack_nsec);
|
||||
|
||||
static int property_get_environment_files(
|
||||
sd_bus *bus,
|
||||
|
@ -92,150 +98,6 @@ static int property_get_environment_files(
|
|||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
static int property_get_oom_score_adjust(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
ExecContext *c = ASSERT_PTR(userdata);
|
||||
int r, n;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
if (c->oom_score_adjust_set)
|
||||
n = c->oom_score_adjust;
|
||||
else {
|
||||
n = 0;
|
||||
r = get_oom_score_adjust(&n);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to read /proc/self/oom_score_adj, ignoring: %m");
|
||||
}
|
||||
|
||||
return sd_bus_message_append(reply, "i", n);
|
||||
}
|
||||
|
||||
static int property_get_coredump_filter(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
ExecContext *c = ASSERT_PTR(userdata);
|
||||
uint64_t n;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
if (c->coredump_filter_set)
|
||||
n = c->coredump_filter;
|
||||
else {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
|
||||
n = COREDUMP_FILTER_MASK_DEFAULT;
|
||||
r = read_one_line_file("/proc/self/coredump_filter", &t);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to read /proc/self/coredump_filter, ignoring: %m");
|
||||
else {
|
||||
r = safe_atoux64(t, &n);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse \"%s\" from /proc/self/coredump_filter, ignoring: %m", t);
|
||||
}
|
||||
}
|
||||
|
||||
return sd_bus_message_append(reply, "t", n);
|
||||
}
|
||||
|
||||
static int property_get_nice(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
ExecContext *c = ASSERT_PTR(userdata);
|
||||
int32_t n;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
if (c->nice_set)
|
||||
n = c->nice;
|
||||
else {
|
||||
errno = 0;
|
||||
n = getpriority(PRIO_PROCESS, 0);
|
||||
if (errno > 0)
|
||||
n = 0;
|
||||
}
|
||||
|
||||
return sd_bus_message_append(reply, "i", n);
|
||||
}
|
||||
|
||||
static int property_get_cpu_sched_policy(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
ExecContext *c = ASSERT_PTR(userdata);
|
||||
int32_t n;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
if (c->cpu_sched_set)
|
||||
n = c->cpu_sched_policy;
|
||||
else {
|
||||
n = sched_getscheduler(0);
|
||||
if (n < 0)
|
||||
n = SCHED_OTHER;
|
||||
}
|
||||
|
||||
return sd_bus_message_append(reply, "i", n);
|
||||
}
|
||||
|
||||
static int property_get_cpu_sched_priority(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
ExecContext *c = ASSERT_PTR(userdata);
|
||||
int32_t n;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
if (c->cpu_sched_set)
|
||||
n = c->cpu_sched_priority;
|
||||
else {
|
||||
struct sched_param p = {};
|
||||
|
||||
if (sched_getparam(0, &p) >= 0)
|
||||
n = p.sched_priority;
|
||||
else
|
||||
n = 0;
|
||||
}
|
||||
|
||||
return sd_bus_message_append(reply, "i", n);
|
||||
}
|
||||
|
||||
static int property_get_cpu_affinity(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
|
@ -306,29 +168,6 @@ static int property_get_numa_policy(
|
|||
return sd_bus_message_append_basic(reply, 'i', &policy);
|
||||
}
|
||||
|
||||
static int property_get_timer_slack_nsec(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
ExecContext *c = ASSERT_PTR(userdata);
|
||||
uint64_t u;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
if (c->timer_slack_nsec != NSEC_INFINITY)
|
||||
u = (uint64_t) c->timer_slack_nsec;
|
||||
else
|
||||
u = (uint64_t) prctl(PR_GET_TIMERSLACK);
|
||||
|
||||
return sd_bus_message_append(reply, "t", u);
|
||||
}
|
||||
|
||||
static int property_get_syscall_filter(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
|
@ -353,43 +192,9 @@ static int property_get_syscall_filter(
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
void *id, *val;
|
||||
HASHMAP_FOREACH_KEY(val, id, c->syscall_filter) {
|
||||
_cleanup_free_ char *name = NULL;
|
||||
const char *e = NULL;
|
||||
char *s;
|
||||
int num = PTR_TO_INT(val);
|
||||
|
||||
if (c->syscall_allow_list && num >= 0)
|
||||
/* syscall with num >= 0 in allow-list is denied. */
|
||||
continue;
|
||||
|
||||
name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
if (num >= 0) {
|
||||
e = seccomp_errno_or_action_to_string(num);
|
||||
if (e) {
|
||||
s = strjoin(name, ":", e);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
r = asprintf(&s, "%s:%d", name, num);
|
||||
if (r < 0)
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else
|
||||
s = TAKE_PTR(name);
|
||||
|
||||
r = strv_consume(&l, s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
strv_sort(l);
|
||||
l = exec_context_get_syscall_filter(c);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
r = sd_bus_message_append_strv(reply, l);
|
||||
if (r < 0)
|
||||
|
@ -422,22 +227,9 @@ static int property_get_syscall_log(
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
void *id, *val;
|
||||
HASHMAP_FOREACH_KEY(val, id, c->syscall_log) {
|
||||
char *name = NULL;
|
||||
|
||||
name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
r = strv_consume(&l, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
strv_sort(l);
|
||||
l = exec_context_get_syscall_log(c);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
r = sd_bus_message_append_strv(reply, l);
|
||||
if (r < 0)
|
||||
|
@ -455,28 +247,16 @@ static int property_get_syscall_archs(
|
|||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
ExecContext *c = ASSERT_PTR(userdata);
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
void *id;
|
||||
SET_FOREACH(id, ASSERT_PTR((ExecContext*) userdata)->syscall_archs) {
|
||||
const char *name;
|
||||
|
||||
name = seccomp_arch_to_string(PTR_TO_UINT32(id) - 1);
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
r = strv_extend(&l, name);
|
||||
if (r < 0)
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
strv_sort(l);
|
||||
l = exec_context_get_syscall_archs(c);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
r = sd_bus_message_append_strv(reply, l);
|
||||
if (r < 0)
|
||||
|
@ -547,7 +327,6 @@ static int property_get_address_families(
|
|||
|
||||
ExecContext *c = ASSERT_PTR(userdata);
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
void *af;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
|
@ -561,19 +340,9 @@ static int property_get_address_families(
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
SET_FOREACH(af, c->address_families) {
|
||||
const char *name;
|
||||
|
||||
name = af_to_name(PTR_TO_INT(af));
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
r = strv_extend(&l, name);
|
||||
if (r < 0)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
strv_sort(l);
|
||||
l = exec_context_get_address_families(c);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
r = sd_bus_message_append_strv(reply, l);
|
||||
if (r < 0)
|
||||
|
@ -678,13 +447,9 @@ static int property_get_restrict_filesystems(
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
#if HAVE_LIBBPF
|
||||
l = set_get_strv(c->restrict_filesystems);
|
||||
l = exec_context_get_restrict_filesystems(c);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
#endif
|
||||
|
||||
strv_sort(l);
|
||||
|
||||
r = sd_bus_message_append_strv(reply, l);
|
||||
if (r < 0)
|
||||
|
|
|
@ -67,6 +67,7 @@ static BUS_DEFINE_PROPERTY_GET(property_get_default_timeout_abort_usec, "t", Man
|
|||
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_watchdog_device, "s", watchdog_get_device());
|
||||
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_watchdog_last_ping_realtime, "t", watchdog_get_last_ping(CLOCK_REALTIME));
|
||||
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_watchdog_last_ping_monotonic, "t", watchdog_get_last_ping(CLOCK_MONOTONIC));
|
||||
static BUS_DEFINE_PROPERTY_GET(property_get_progress, "d", Manager, manager_get_progress);
|
||||
|
||||
static int property_get_virtualization(
|
||||
sd_bus *bus,
|
||||
|
@ -207,29 +208,6 @@ static int property_set_log_level(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int property_get_progress(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
double d;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
if (MANAGER_IS_FINISHED(m))
|
||||
d = 1.0;
|
||||
else
|
||||
d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
|
||||
|
||||
return sd_bus_message_append(reply, "d", d);
|
||||
}
|
||||
|
||||
static int property_get_environment(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
|
|
|
@ -22,21 +22,13 @@ static int property_get_what(
|
|||
|
||||
_cleanup_free_ char *escaped = NULL;
|
||||
Mount *m = ASSERT_PTR(userdata);
|
||||
const char *s = NULL;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
|
||||
s = m->parameters_proc_self_mountinfo.what;
|
||||
else if (m->from_fragment && m->parameters_fragment.what)
|
||||
s = m->parameters_fragment.what;
|
||||
|
||||
if (s) {
|
||||
escaped = utf8_escape_invalid(s);
|
||||
if (!escaped)
|
||||
return -ENOMEM;
|
||||
}
|
||||
escaped = mount_get_what_escaped(m);
|
||||
if (!escaped)
|
||||
return -ENOMEM;
|
||||
|
||||
return sd_bus_message_append_basic(reply, 's', escaped);
|
||||
}
|
||||
|
@ -52,33 +44,17 @@ static int property_get_options(
|
|||
|
||||
_cleanup_free_ char *escaped = NULL;
|
||||
Mount *m = ASSERT_PTR(userdata);
|
||||
const char *s = NULL;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options)
|
||||
s = m->parameters_proc_self_mountinfo.options;
|
||||
else if (m->from_fragment && m->parameters_fragment.options)
|
||||
s = m->parameters_fragment.options;
|
||||
|
||||
if (s) {
|
||||
escaped = utf8_escape_invalid(s);
|
||||
if (!escaped)
|
||||
return -ENOMEM;
|
||||
}
|
||||
escaped = mount_get_options_escaped(m);
|
||||
if (!escaped)
|
||||
return -ENOMEM;
|
||||
|
||||
return sd_bus_message_append_basic(reply, 's', escaped);
|
||||
}
|
||||
|
||||
static const char *mount_get_fstype(const Mount *m) {
|
||||
if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype)
|
||||
return m->parameters_proc_self_mountinfo.fstype;
|
||||
else if (m->from_fragment && m->parameters_fragment.fstype)
|
||||
return m->parameters_fragment.fstype;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BUS_DEFINE_PROPERTY_GET(property_get_type, "s", Mount, mount_get_fstype);
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, mount_result, MountResult);
|
||||
|
||||
|
|
|
@ -44,30 +44,12 @@ static int property_get_listen(
|
|||
|
||||
LIST_FOREACH(port, p, s->ports) {
|
||||
_cleanup_free_ char *address = NULL;
|
||||
const char *a;
|
||||
|
||||
switch (p->type) {
|
||||
case SOCKET_SOCKET: {
|
||||
r = socket_address_print(&p->address, &address);
|
||||
if (r)
|
||||
return r;
|
||||
r = socket_port_to_address(p, &address);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
a = address;
|
||||
break;
|
||||
}
|
||||
|
||||
case SOCKET_SPECIAL:
|
||||
case SOCKET_MQUEUE:
|
||||
case SOCKET_FIFO:
|
||||
case SOCKET_USB_FUNCTION:
|
||||
a = p->path;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
r = sd_bus_message_append(reply, "(ss)", socket_port_type_to_string(p), a);
|
||||
r = sd_bus_message_append(reply, "(ss)", socket_port_type_to_string(p), address);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -11,27 +11,6 @@
|
|||
#include "swap.h"
|
||||
#include "unit.h"
|
||||
|
||||
static int swap_get_priority(Swap *s) {
|
||||
assert(s);
|
||||
|
||||
if (s->from_proc_swaps && s->parameters_proc_swaps.priority_set)
|
||||
return s->parameters_proc_swaps.priority;
|
||||
|
||||
if (s->from_fragment && s->parameters_fragment.priority_set)
|
||||
return s->parameters_fragment.priority;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char *swap_get_options(Swap *s) {
|
||||
assert(s);
|
||||
|
||||
if (s->from_fragment)
|
||||
return s->parameters_fragment.options;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BUS_DEFINE_PROPERTY_GET(property_get_priority, "i", Swap, swap_get_priority);
|
||||
static BUS_DEFINE_PROPERTY_GET(property_get_options, "s", Swap, swap_get_options);
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, swap_result, SwapResult);
|
||||
|
|
|
@ -30,26 +30,16 @@ static int property_get_monotonic_timers(
|
|||
return r;
|
||||
|
||||
LIST_FOREACH(value, v, t->values) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
const char *s;
|
||||
size_t l;
|
||||
_cleanup_free_ char *usec = NULL;
|
||||
|
||||
if (v->base == TIMER_CALENDAR)
|
||||
continue;
|
||||
|
||||
s = timer_base_to_string(v->base);
|
||||
assert(endswith(s, "Sec"));
|
||||
|
||||
/* s/Sec/USec/ */
|
||||
l = strlen(s);
|
||||
buf = new(char, l+2);
|
||||
if (!buf)
|
||||
usec = timer_base_to_usec_string(v->base);
|
||||
if (!usec)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(buf, s, l-3);
|
||||
memcpy(buf+l-3, "USec", 5);
|
||||
|
||||
r = sd_bus_message_append(reply, "(stt)", buf, v->value, v->next_elapse);
|
||||
r = sd_bus_message_append(reply, "(stt)", usec, v->value, v->next_elapse);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
@ -108,9 +98,7 @@ static int property_get_next_elapse_monotonic(
|
|||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
return sd_bus_message_append(reply, "t",
|
||||
(uint64_t) usec_shift_clock(t->next_elapse_monotonic_or_boottime,
|
||||
TIMER_MONOTONIC_CLOCK(t), CLOCK_MONOTONIC));
|
||||
return sd_bus_message_append(reply, "t", timer_next_elapse_monotonic(t));
|
||||
}
|
||||
|
||||
const sd_bus_vtable bus_timer_vtable[] = {
|
||||
|
|
|
@ -30,18 +30,6 @@
|
|||
#include "user-util.h"
|
||||
#include "web-util.h"
|
||||
|
||||
static bool unit_can_start_refuse_manual(Unit *u) {
|
||||
return unit_can_start(u) && !u->refuse_manual_start;
|
||||
}
|
||||
|
||||
static bool unit_can_stop_refuse_manual(Unit *u) {
|
||||
return unit_can_stop(u) && !u->refuse_manual_stop;
|
||||
}
|
||||
|
||||
static bool unit_can_isolate_refuse_manual(Unit *u) {
|
||||
return unit_can_isolate(u) && !u->refuse_manual_start;
|
||||
}
|
||||
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_collect_mode, collect_mode, CollectMode);
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState);
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_job_mode, job_mode, JobMode);
|
||||
|
@ -1397,22 +1385,15 @@ static int property_get_ip_counter(
|
|||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
static const char *const table[_CGROUP_IP_ACCOUNTING_METRIC_MAX] = {
|
||||
[CGROUP_IP_INGRESS_BYTES] = "IPIngressBytes",
|
||||
[CGROUP_IP_EGRESS_BYTES] = "IPEgressBytes",
|
||||
[CGROUP_IP_INGRESS_PACKETS] = "IPIngressPackets",
|
||||
[CGROUP_IP_EGRESS_PACKETS] = "IPEgressPackets",
|
||||
};
|
||||
|
||||
uint64_t value = UINT64_MAX;
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
ssize_t metric;
|
||||
CGroupIPAccountingMetric metric;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
assert(property);
|
||||
|
||||
assert_se((metric = string_table_lookup(table, ELEMENTSOF(table), property)) >= 0);
|
||||
assert_se((metric = cgroup_ip_accounting_metric_from_string(property)) >= 0);
|
||||
(void) unit_get_ip_accounting(u, metric, &value);
|
||||
return sd_bus_message_append(reply, "t", value);
|
||||
}
|
||||
|
@ -1426,13 +1407,6 @@ static int property_get_io_counter(
|
|||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
static const char *const table[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {
|
||||
[CGROUP_IO_READ_BYTES] = "IOReadBytes",
|
||||
[CGROUP_IO_WRITE_BYTES] = "IOWriteBytes",
|
||||
[CGROUP_IO_READ_OPERATIONS] = "IOReadOperations",
|
||||
[CGROUP_IO_WRITE_OPERATIONS] = "IOWriteOperations",
|
||||
};
|
||||
|
||||
uint64_t value = UINT64_MAX;
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
ssize_t metric;
|
||||
|
@ -1441,8 +1415,8 @@ static int property_get_io_counter(
|
|||
assert(reply);
|
||||
assert(property);
|
||||
|
||||
assert_se((metric = string_table_lookup(table, ELEMENTSOF(table), property)) >= 0);
|
||||
(void) unit_get_io_accounting(u, metric, false, &value);
|
||||
assert_se((metric = cgroup_io_accounting_metric_from_string(property)) >= 0);
|
||||
(void) unit_get_io_accounting(u, metric, /* allow_cache= */ false, &value);
|
||||
return sd_bus_message_append(reply, "t", value);
|
||||
}
|
||||
|
||||
|
|
|
@ -1542,6 +1542,237 @@ int exec_context_get_clean_mask(ExecContext *c, ExecCleanMask *ret) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int exec_context_get_oom_score_adjust(const ExecContext *c) {
|
||||
int n = 0, r;
|
||||
|
||||
assert(c);
|
||||
|
||||
if (c->oom_score_adjust_set)
|
||||
return c->oom_score_adjust;
|
||||
|
||||
r = get_oom_score_adjust(&n);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to read /proc/self/oom_score_adj, ignoring: %m");
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
uint64_t exec_context_get_coredump_filter(const ExecContext *c) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
uint64_t n = COREDUMP_FILTER_MASK_DEFAULT;
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
|
||||
if (c->coredump_filter_set)
|
||||
return c->coredump_filter;
|
||||
|
||||
r = read_one_line_file("/proc/self/coredump_filter", &t);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to read /proc/self/coredump_filter, ignoring: %m");
|
||||
else {
|
||||
r = safe_atoux64(t, &n);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse \"%s\" from /proc/self/coredump_filter, ignoring: %m", t);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int exec_context_get_nice(const ExecContext *c) {
|
||||
int n;
|
||||
|
||||
assert(c);
|
||||
|
||||
if (c->nice_set)
|
||||
return c->nice;
|
||||
|
||||
errno = 0;
|
||||
n = getpriority(PRIO_PROCESS, 0);
|
||||
if (errno > 0) {
|
||||
log_debug_errno(errno, "Failed to get process nice value, ignoring: %m");
|
||||
n = 0;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int exec_context_get_cpu_sched_policy(const ExecContext *c) {
|
||||
int n;
|
||||
|
||||
assert(c);
|
||||
|
||||
if (c->cpu_sched_set)
|
||||
return c->cpu_sched_policy;
|
||||
|
||||
n = sched_getscheduler(0);
|
||||
if (n < 0)
|
||||
log_debug_errno(errno, "Failed to get scheduler policy, ignoring: %m");
|
||||
|
||||
return n < 0 ? SCHED_OTHER : n;
|
||||
}
|
||||
|
||||
int exec_context_get_cpu_sched_priority(const ExecContext *c) {
|
||||
struct sched_param p = {};
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
|
||||
if (c->cpu_sched_set)
|
||||
return c->cpu_sched_priority;
|
||||
|
||||
r = sched_getparam(0, &p);
|
||||
if (r < 0)
|
||||
log_debug_errno(errno, "Failed to get scheduler priority, ignoring: %m");
|
||||
|
||||
return r >= 0 ? p.sched_priority : 0;
|
||||
}
|
||||
|
||||
uint64_t exec_context_get_timer_slack_nsec(const ExecContext *c) {
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
|
||||
if (c->timer_slack_nsec != NSEC_INFINITY)
|
||||
return c->timer_slack_nsec;
|
||||
|
||||
r = prctl(PR_GET_TIMERSLACK);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to get timer slack, ignoring: %m");
|
||||
|
||||
return (uint64_t) MAX(r, 0);
|
||||
}
|
||||
|
||||
char** exec_context_get_syscall_filter(const ExecContext *c) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
|
||||
assert(c);
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
void *id, *val;
|
||||
HASHMAP_FOREACH_KEY(val, id, c->syscall_filter) {
|
||||
_cleanup_free_ char *name = NULL;
|
||||
const char *e = NULL;
|
||||
char *s;
|
||||
int num = PTR_TO_INT(val);
|
||||
|
||||
if (c->syscall_allow_list && num >= 0)
|
||||
/* syscall with num >= 0 in allow-list is denied. */
|
||||
continue;
|
||||
|
||||
name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
if (num >= 0) {
|
||||
e = seccomp_errno_or_action_to_string(num);
|
||||
if (e) {
|
||||
s = strjoin(name, ":", e);
|
||||
if (!s)
|
||||
return NULL;
|
||||
} else {
|
||||
if (asprintf(&s, "%s:%d", name, num) < 0)
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
s = TAKE_PTR(name);
|
||||
|
||||
if (strv_consume(&l, s) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strv_sort(l);
|
||||
#endif
|
||||
|
||||
return l ? TAKE_PTR(l) : strv_new(NULL);
|
||||
}
|
||||
|
||||
char** exec_context_get_syscall_archs(const ExecContext *c) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
|
||||
assert(c);
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
void *id;
|
||||
SET_FOREACH(id, c->syscall_archs) {
|
||||
const char *name;
|
||||
|
||||
name = seccomp_arch_to_string(PTR_TO_UINT32(id) - 1);
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
if (strv_extend(&l, name) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strv_sort(l);
|
||||
#endif
|
||||
|
||||
return l ? TAKE_PTR(l) : strv_new(NULL);
|
||||
}
|
||||
|
||||
char** exec_context_get_syscall_log(const ExecContext *c) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
|
||||
assert(c);
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
void *id, *val;
|
||||
HASHMAP_FOREACH_KEY(val, id, c->syscall_log) {
|
||||
char *name = NULL;
|
||||
|
||||
name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
if (strv_consume(&l, name) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strv_sort(l);
|
||||
#endif
|
||||
|
||||
return l ? TAKE_PTR(l) : strv_new(NULL);
|
||||
}
|
||||
|
||||
char** exec_context_get_address_families(const ExecContext *c) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
void *af;
|
||||
|
||||
assert(c);
|
||||
|
||||
SET_FOREACH(af, c->address_families) {
|
||||
const char *name;
|
||||
|
||||
name = af_to_name(PTR_TO_INT(af));
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
if (strv_extend(&l, name) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strv_sort(l);
|
||||
|
||||
return l ? TAKE_PTR(l) : strv_new(NULL);
|
||||
}
|
||||
|
||||
char** exec_context_get_restrict_filesystems(const ExecContext *c) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
|
||||
assert(c);
|
||||
|
||||
#if HAVE_LIBBPF
|
||||
l = set_get_strv(c->restrict_filesystems);
|
||||
if (!l)
|
||||
return NULL;
|
||||
|
||||
strv_sort(l);
|
||||
#endif
|
||||
|
||||
return l ? TAKE_PTR(l) : strv_new(NULL);
|
||||
}
|
||||
|
||||
void exec_status_start(ExecStatus *s, pid_t pid) {
|
||||
assert(s);
|
||||
|
||||
|
@ -2460,6 +2691,16 @@ static const char* const exec_directory_type_symlink_table[_EXEC_DIRECTORY_TYPE_
|
|||
|
||||
DEFINE_STRING_TABLE_LOOKUP(exec_directory_type_symlink, ExecDirectoryType);
|
||||
|
||||
static const char* const exec_directory_type_mode_table[_EXEC_DIRECTORY_TYPE_MAX] = {
|
||||
[EXEC_DIRECTORY_RUNTIME] = "RuntimeDirectoryMode",
|
||||
[EXEC_DIRECTORY_STATE] = "StateDirectoryMode",
|
||||
[EXEC_DIRECTORY_CACHE] = "CacheDirectoryMode",
|
||||
[EXEC_DIRECTORY_LOGS] = "LogsDirectoryMode",
|
||||
[EXEC_DIRECTORY_CONFIGURATION] = "ConfigurationDirectoryMode",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(exec_directory_type_mode, ExecDirectoryType);
|
||||
|
||||
/* And this table maps ExecDirectoryType too, but to a generic term identifying the type of resource. This
|
||||
* one is supposed to be generic enough to be used for unit types that don't use ExecContext and per-unit
|
||||
* directories, specifically .timer units with their timestamp touch file. */
|
||||
|
|
|
@ -516,6 +516,19 @@ const char *exec_context_tty_path(const ExecContext *context);
|
|||
int exec_context_tty_size(const ExecContext *context, unsigned *ret_rows, unsigned *ret_cols);
|
||||
void exec_context_tty_reset(const ExecContext *context, const ExecParameters *p);
|
||||
|
||||
uint64_t exec_context_get_rlimit(const ExecContext *c, const char *name);
|
||||
int exec_context_get_oom_score_adjust(const ExecContext *c);
|
||||
uint64_t exec_context_get_coredump_filter(const ExecContext *c);
|
||||
int exec_context_get_nice(const ExecContext *c);
|
||||
int exec_context_get_cpu_sched_policy(const ExecContext *c);
|
||||
int exec_context_get_cpu_sched_priority(const ExecContext *c);
|
||||
uint64_t exec_context_get_timer_slack_nsec(const ExecContext *c);
|
||||
char** exec_context_get_syscall_filter(const ExecContext *c);
|
||||
char** exec_context_get_syscall_archs(const ExecContext *c);
|
||||
char** exec_context_get_syscall_log(const ExecContext *c);
|
||||
char** exec_context_get_address_families(const ExecContext *c);
|
||||
char** exec_context_get_restrict_filesystems(const ExecContext *c);
|
||||
|
||||
void exec_status_start(ExecStatus *s, pid_t pid);
|
||||
void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int code, int status);
|
||||
void exec_status_dump(const ExecStatus *s, FILE *f, const char *prefix);
|
||||
|
@ -573,6 +586,9 @@ ExecDirectoryType exec_directory_type_from_string(const char *s) _pure_;
|
|||
const char* exec_directory_type_symlink_to_string(ExecDirectoryType i) _const_;
|
||||
ExecDirectoryType exec_directory_type_symlink_from_string(const char *s) _pure_;
|
||||
|
||||
const char* exec_directory_type_mode_to_string(ExecDirectoryType i) _const_;
|
||||
ExecDirectoryType exec_directory_type_mode_from_string(const char *s) _pure_;
|
||||
|
||||
const char* exec_resource_type_to_string(ExecDirectoryType i) _const_;
|
||||
ExecDirectoryType exec_resource_type_from_string(const char *s) _pure_;
|
||||
|
||||
|
|
|
@ -866,6 +866,15 @@ void manager_set_switching_root(Manager *m, bool switching_root) {
|
|||
m->switching_root = MANAGER_IS_SYSTEM(m) && switching_root;
|
||||
}
|
||||
|
||||
double manager_get_progress(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
if (MANAGER_IS_FINISHED(m) || m->n_installed_jobs == 0)
|
||||
return 1.0;
|
||||
|
||||
return 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
|
||||
}
|
||||
|
||||
static int compare_job_priority(const void *a, const void *b) {
|
||||
const Job *x = a, *y = b;
|
||||
|
||||
|
|
|
@ -592,6 +592,8 @@ void manager_override_show_status(Manager *m, ShowStatus mode, const char *reaso
|
|||
void manager_set_first_boot(Manager *m, bool b);
|
||||
void manager_set_switching_root(Manager *m, bool switching_root);
|
||||
|
||||
double manager_get_progress(Manager *m);
|
||||
|
||||
void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5);
|
||||
|
||||
Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "strv.h"
|
||||
#include "unit-name.h"
|
||||
#include "unit.h"
|
||||
#include "utf8.h"
|
||||
|
||||
#define RETRY_UMOUNT_MAX 32
|
||||
|
||||
|
@ -2345,6 +2346,58 @@ static int mount_subsystem_ratelimited(Manager *m) {
|
|||
return sd_event_source_is_ratelimited(m->mount_event_source);
|
||||
}
|
||||
|
||||
char* mount_get_what_escaped(const Mount *m) {
|
||||
_cleanup_free_ char *escaped = NULL;
|
||||
const char *s = NULL;
|
||||
|
||||
assert(m);
|
||||
|
||||
if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
|
||||
s = m->parameters_proc_self_mountinfo.what;
|
||||
else if (m->from_fragment && m->parameters_fragment.what)
|
||||
s = m->parameters_fragment.what;
|
||||
|
||||
if (s) {
|
||||
escaped = utf8_escape_invalid(s);
|
||||
if (!escaped)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return escaped ? TAKE_PTR(escaped) : strdup("");
|
||||
}
|
||||
|
||||
char* mount_get_options_escaped(const Mount *m) {
|
||||
_cleanup_free_ char *escaped = NULL;
|
||||
const char *s = NULL;
|
||||
|
||||
assert(m);
|
||||
|
||||
if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options)
|
||||
s = m->parameters_proc_self_mountinfo.options;
|
||||
else if (m->from_fragment && m->parameters_fragment.options)
|
||||
s = m->parameters_fragment.options;
|
||||
|
||||
if (s) {
|
||||
escaped = utf8_escape_invalid(s);
|
||||
if (!escaped)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return escaped ? TAKE_PTR(escaped) : strdup("");
|
||||
}
|
||||
|
||||
const char* mount_get_fstype(const Mount *m) {
|
||||
assert(m);
|
||||
|
||||
if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype)
|
||||
return m->parameters_proc_self_mountinfo.fstype;
|
||||
|
||||
if (m->from_fragment && m->parameters_fragment.fstype)
|
||||
return m->parameters_fragment.fstype;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
|
||||
[MOUNT_EXEC_MOUNT] = "ExecMount",
|
||||
[MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
|
||||
|
|
|
@ -97,6 +97,10 @@ void mount_fd_event(Manager *m, int events);
|
|||
|
||||
int mount_invalidate_state_by_path(Manager *manager, const char *path);
|
||||
|
||||
char* mount_get_what_escaped(const Mount *m);
|
||||
char* mount_get_options_escaped(const Mount *m);
|
||||
const char* mount_get_fstype(const Mount *m);
|
||||
|
||||
const char* mount_exec_command_to_string(MountExecCommand i) _const_;
|
||||
MountExecCommand mount_exec_command_from_string(const char *s) _pure_;
|
||||
|
||||
|
|
|
@ -2866,6 +2866,40 @@ static const char *socket_sub_state_to_string(Unit *u) {
|
|||
return socket_state_to_string(SOCKET(u)->state);
|
||||
}
|
||||
|
||||
int socket_port_to_address(const SocketPort *p, char **ret) {
|
||||
_cleanup_free_ char *address = NULL;
|
||||
int r;
|
||||
|
||||
assert(p);
|
||||
assert(ret);
|
||||
|
||||
switch (p->type) {
|
||||
case SOCKET_SOCKET: {
|
||||
r = socket_address_print(&p->address, &address);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SOCKET_SPECIAL:
|
||||
case SOCKET_MQUEUE:
|
||||
case SOCKET_FIFO:
|
||||
case SOCKET_USB_FUNCTION:
|
||||
address = strdup(p->path);
|
||||
if (!address)
|
||||
return -ENOMEM;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(address);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* socket_port_type_to_string(SocketPort *p) {
|
||||
|
||||
assert(p);
|
||||
|
|
|
@ -180,6 +180,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(SocketPort*, socket_port_free);
|
|||
|
||||
void socket_free_ports(Socket *s);
|
||||
|
||||
int socket_port_to_address(const SocketPort *s, char **ret);
|
||||
|
||||
int socket_load_service_unit(Socket *s, int cfd, Unit **ret);
|
||||
|
||||
char *socket_fdname(Socket *s);
|
||||
|
|
|
@ -1559,6 +1559,27 @@ static int swap_can_start(Unit *u) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int swap_get_priority(const Swap *s) {
|
||||
assert(s);
|
||||
|
||||
if (s->from_proc_swaps && s->parameters_proc_swaps.priority_set)
|
||||
return s->parameters_proc_swaps.priority;
|
||||
|
||||
if (s->from_fragment && s->parameters_fragment.priority_set)
|
||||
return s->parameters_fragment.priority;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* swap_get_options(const Swap *s) {
|
||||
assert(s);
|
||||
|
||||
if (s->from_fragment)
|
||||
return s->parameters_fragment.options;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
|
||||
[SWAP_EXEC_ACTIVATE] = "ExecActivate",
|
||||
[SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
|
||||
|
|
|
@ -91,6 +91,9 @@ extern const UnitVTable swap_vtable;
|
|||
int swap_process_device_new(Manager *m, sd_device *dev);
|
||||
int swap_process_device_remove(Manager *m, sd_device *dev);
|
||||
|
||||
int swap_get_priority(const Swap *s);
|
||||
const char* swap_get_options(const Swap *s);
|
||||
|
||||
const char* swap_exec_command_to_string(SwapExecCommand i) _const_;
|
||||
SwapExecCommand swap_exec_command_from_string(const char *s) _pure_;
|
||||
|
||||
|
|
|
@ -1001,6 +1001,13 @@ static int activation_details_timer_append_pair(ActivationDetails *details, char
|
|||
return 2; /* Return the number of pairs added to the env block */
|
||||
}
|
||||
|
||||
uint64_t timer_next_elapse_monotonic(const Timer *t) {
|
||||
assert(t);
|
||||
|
||||
return (uint64_t) usec_shift_clock(t->next_elapse_monotonic_or_boottime,
|
||||
TIMER_MONOTONIC_CLOCK(t), CLOCK_MONOTONIC);
|
||||
}
|
||||
|
||||
static const char* const timer_base_table[_TIMER_BASE_MAX] = {
|
||||
[TIMER_ACTIVE] = "OnActiveSec",
|
||||
[TIMER_BOOT] = "OnBootSec",
|
||||
|
@ -1012,6 +1019,31 @@ static const char* const timer_base_table[_TIMER_BASE_MAX] = {
|
|||
|
||||
DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase);
|
||||
|
||||
char* timer_base_to_usec_string(TimerBase i) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
const char *s;
|
||||
size_t l;
|
||||
|
||||
s = timer_base_to_string(i);
|
||||
|
||||
if (endswith(s, "Sec")) {
|
||||
/* s/Sec/USec/ */
|
||||
l = strlen(s);
|
||||
buf = new(char, l+2);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
memcpy(buf, s, l-3);
|
||||
memcpy(buf+l-3, "USec", 5);
|
||||
} else {
|
||||
buf = strdup(s);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return TAKE_PTR(buf);
|
||||
}
|
||||
|
||||
static const char* const timer_result_table[_TIMER_RESULT_MAX] = {
|
||||
[TIMER_SUCCESS] = "success",
|
||||
[TIMER_FAILURE_RESOURCES] = "resources",
|
||||
|
|
|
@ -72,6 +72,8 @@ struct ActivationDetailsTimer {
|
|||
|
||||
#define TIMER_MONOTONIC_CLOCK(t) ((t)->wake_system ? CLOCK_BOOTTIME_ALARM : CLOCK_MONOTONIC)
|
||||
|
||||
uint64_t timer_next_elapse_monotonic(const Timer *t);
|
||||
|
||||
void timer_free_values(Timer *t);
|
||||
|
||||
extern const UnitVTable timer_vtable;
|
||||
|
@ -80,6 +82,8 @@ extern const ActivationDetailsVTable activation_details_timer_vtable;
|
|||
const char *timer_base_to_string(TimerBase i) _const_;
|
||||
TimerBase timer_base_from_string(const char *s) _pure_;
|
||||
|
||||
char* timer_base_to_usec_string(TimerBase i);
|
||||
|
||||
const char* timer_result_to_string(TimerResult i) _const_;
|
||||
TimerResult timer_result_from_string(const char *s) _pure_;
|
||||
|
||||
|
|
|
@ -6167,6 +6167,18 @@ int unit_can_clean(Unit *u, ExecCleanMask *ret) {
|
|||
return UNIT_VTABLE(u)->can_clean(u, ret);
|
||||
}
|
||||
|
||||
bool unit_can_start_refuse_manual(Unit *u) {
|
||||
return unit_can_start(u) && !u->refuse_manual_start;
|
||||
}
|
||||
|
||||
bool unit_can_stop_refuse_manual(Unit *u) {
|
||||
return unit_can_stop(u) && !u->refuse_manual_stop;
|
||||
}
|
||||
|
||||
bool unit_can_isolate_refuse_manual(Unit *u) {
|
||||
return unit_can_isolate(u) && !u->refuse_manual_start;
|
||||
}
|
||||
|
||||
bool unit_can_freeze(Unit *u) {
|
||||
assert(u);
|
||||
|
||||
|
|
|
@ -1078,6 +1078,10 @@ void unit_destroy_runtime_data(Unit *u, const ExecContext *context);
|
|||
int unit_clean(Unit *u, ExecCleanMask mask);
|
||||
int unit_can_clean(Unit *u, ExecCleanMask *ret_mask);
|
||||
|
||||
bool unit_can_start_refuse_manual(Unit *u);
|
||||
bool unit_can_stop_refuse_manual(Unit *u);
|
||||
bool unit_can_isolate_refuse_manual(Unit *u);
|
||||
|
||||
bool unit_can_freeze(Unit *u);
|
||||
int unit_freeze(Unit *u);
|
||||
void unit_frozen(Unit *u);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "math-util.h"
|
||||
#include "memory-util.h"
|
||||
#include "memstream-util.h"
|
||||
#include "set.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
|
@ -3350,6 +3351,7 @@ int json_parse_file_at(
|
|||
int json_buildv(JsonVariant **ret, va_list ap) {
|
||||
JsonStack *stack = NULL;
|
||||
size_t n_stack = 1;
|
||||
const char *name = NULL;
|
||||
int r;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
@ -3877,6 +3879,77 @@ int json_buildv(JsonVariant **ret, va_list ap) {
|
|||
break;
|
||||
}
|
||||
|
||||
case _JSON_BUILD_STRING_SET: {
|
||||
Set *set;
|
||||
|
||||
if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
|
||||
r = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
set = va_arg(ap, Set*);
|
||||
|
||||
if (current->n_suppress == 0) {
|
||||
_cleanup_free_ char **sorted = NULL;
|
||||
|
||||
r = set_dump_sorted(set, (void ***) &sorted, NULL);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
r = json_variant_new_array_strv(&add, sorted);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
n_subtract = 1;
|
||||
|
||||
if (current->expect == EXPECT_TOPLEVEL)
|
||||
current->expect = EXPECT_END;
|
||||
else if (current->expect == EXPECT_OBJECT_VALUE)
|
||||
current->expect = EXPECT_OBJECT_KEY;
|
||||
else
|
||||
assert(current->expect == EXPECT_ARRAY_ELEMENT);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case _JSON_BUILD_CALLBACK: {
|
||||
JsonBuildCallback cb;
|
||||
void *userdata;
|
||||
|
||||
if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
|
||||
r = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
cb = va_arg(ap, JsonBuildCallback);
|
||||
userdata = va_arg(ap, void *);
|
||||
|
||||
if (current->n_suppress == 0) {
|
||||
if (cb) {
|
||||
r = cb(&add, name, userdata);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!add)
|
||||
add = JSON_VARIANT_MAGIC_NULL;
|
||||
|
||||
name = NULL;
|
||||
}
|
||||
|
||||
n_subtract = 1;
|
||||
|
||||
if (current->expect == EXPECT_TOPLEVEL)
|
||||
current->expect = EXPECT_END;
|
||||
else if (current->expect == EXPECT_OBJECT_VALUE)
|
||||
current->expect = EXPECT_OBJECT_KEY;
|
||||
else
|
||||
assert(current->expect == EXPECT_ARRAY_ELEMENT);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case _JSON_BUILD_OBJECT_BEGIN:
|
||||
|
||||
if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
|
||||
|
@ -3930,17 +4003,16 @@ int json_buildv(JsonVariant **ret, va_list ap) {
|
|||
break;
|
||||
|
||||
case _JSON_BUILD_PAIR: {
|
||||
const char *n;
|
||||
|
||||
if (current->expect != EXPECT_OBJECT_KEY) {
|
||||
r = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
n = va_arg(ap, const char *);
|
||||
name = va_arg(ap, const char *);
|
||||
|
||||
if (current->n_suppress == 0) {
|
||||
r = json_variant_new_string(&add, n);
|
||||
r = json_variant_new_string(&add, name);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
}
|
||||
|
@ -3952,7 +4024,6 @@ int json_buildv(JsonVariant **ret, va_list ap) {
|
|||
}
|
||||
|
||||
case _JSON_BUILD_PAIR_CONDITION: {
|
||||
const char *n;
|
||||
bool b;
|
||||
|
||||
if (current->expect != EXPECT_OBJECT_KEY) {
|
||||
|
@ -3961,10 +4032,10 @@ int json_buildv(JsonVariant **ret, va_list ap) {
|
|||
}
|
||||
|
||||
b = va_arg(ap, int);
|
||||
n = va_arg(ap, const char *);
|
||||
name = va_arg(ap, const char *);
|
||||
|
||||
if (b && current->n_suppress == 0) {
|
||||
r = json_variant_new_string(&add, n);
|
||||
r = json_variant_new_string(&add, name);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
}
|
||||
|
|
|
@ -275,6 +275,8 @@ enum {
|
|||
_JSON_BUILD_UUID,
|
||||
_JSON_BUILD_BYTE_ARRAY,
|
||||
_JSON_BUILD_HW_ADDR,
|
||||
_JSON_BUILD_STRING_SET,
|
||||
_JSON_BUILD_CALLBACK,
|
||||
_JSON_BUILD_PAIR_UNSIGNED_NON_ZERO,
|
||||
_JSON_BUILD_PAIR_FINITE_USEC,
|
||||
_JSON_BUILD_PAIR_STRING_NON_EMPTY,
|
||||
|
@ -289,6 +291,8 @@ enum {
|
|||
_JSON_BUILD_MAX,
|
||||
};
|
||||
|
||||
typedef int (*JsonBuildCallback)(JsonVariant **ret, const char *name, void *userdata);
|
||||
|
||||
#define JSON_BUILD_STRING(s) _JSON_BUILD_STRING, (const char*) { s }
|
||||
#define JSON_BUILD_INTEGER(i) _JSON_BUILD_INTEGER, (int64_t) { i }
|
||||
#define JSON_BUILD_UNSIGNED(u) _JSON_BUILD_UNSIGNED, (uint64_t) { u }
|
||||
|
@ -319,6 +323,8 @@ enum {
|
|||
#define JSON_BUILD_IN_ADDR(v, f) JSON_BUILD_BYTE_ARRAY(((const union in_addr_union*) { v })->bytes, FAMILY_ADDRESS_SIZE_SAFE(f))
|
||||
#define JSON_BUILD_ETHER_ADDR(v) JSON_BUILD_BYTE_ARRAY(((const struct ether_addr*) { v })->ether_addr_octet, sizeof(struct ether_addr))
|
||||
#define JSON_BUILD_HW_ADDR(v) _JSON_BUILD_HW_ADDR, (const struct hw_addr_data*) { v }
|
||||
#define JSON_BUILD_STRING_SET(s) _JSON_BUILD_STRING_SET, (Set *) { s }
|
||||
#define JSON_BUILD_CALLBACK(c, u) _JSON_BUILD_CALLBACK, (JsonBuildCallback) { c }, (void*) { u }
|
||||
|
||||
#define JSON_BUILD_PAIR_STRING(name, s) JSON_BUILD_PAIR(name, JSON_BUILD_STRING(s))
|
||||
#define JSON_BUILD_PAIR_INTEGER(name, i) JSON_BUILD_PAIR(name, JSON_BUILD_INTEGER(i))
|
||||
|
@ -344,6 +350,8 @@ enum {
|
|||
#define JSON_BUILD_PAIR_IN_ADDR(name, v, f) JSON_BUILD_PAIR(name, JSON_BUILD_IN_ADDR(v, f))
|
||||
#define JSON_BUILD_PAIR_ETHER_ADDR(name, v) JSON_BUILD_PAIR(name, JSON_BUILD_ETHER_ADDR(v))
|
||||
#define JSON_BUILD_PAIR_HW_ADDR(name, v) JSON_BUILD_PAIR(name, JSON_BUILD_HW_ADDR(v))
|
||||
#define JSON_BUILD_PAIR_STRING_SET(name, s) JSON_BUILD_PAIR(name, JSON_BUILD_STRING_SET(s))
|
||||
#define JSON_BUILD_PAIR_CALLBACK(name, c, u) JSON_BUILD_PAIR(name, JSON_BUILD_CALLBACK(c, u))
|
||||
|
||||
#define JSON_BUILD_PAIR_UNSIGNED_NON_ZERO(name, u) _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO, (const char*) { name }, (uint64_t) { u }
|
||||
#define JSON_BUILD_PAIR_FINITE_USEC(name, u) _JSON_BUILD_PAIR_FINITE_USEC, (const char*) { name }, (usec_t) { u }
|
||||
|
|
Loading…
Reference in a new issue