@@ -2,6 +2,7 @@
|
||||
|
||||
#include "bus-get-properties.h"
|
||||
#include "rlimit-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
int bus_property_get_bool(
|
||||
@@ -54,6 +55,23 @@ int bus_property_get_id128(
|
||||
return sd_bus_message_append_array(reply, 'y', id->bytes, 16);
|
||||
}
|
||||
|
||||
int bus_property_get_percent(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
char pstr[DECIMAL_STR_MAX(int) + 2];
|
||||
int p = *(int*) userdata;
|
||||
|
||||
xsprintf(pstr, "%d%%", p);
|
||||
|
||||
return sd_bus_message_append_basic(reply, 's', pstr);
|
||||
}
|
||||
|
||||
#if __SIZEOF_SIZE_T__ != 8
|
||||
int bus_property_get_size(
|
||||
sd_bus *bus,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
|
||||
int bus_property_set_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error);
|
||||
int bus_property_get_id128(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
|
||||
int bus_property_get_percent(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
|
||||
|
||||
#define bus_property_get_usec ((sd_bus_property_get_t) NULL)
|
||||
#define bus_property_set_usec ((sd_bus_property_set_t) NULL)
|
||||
|
||||
@@ -432,7 +432,11 @@ static int bus_append_ip_address_access(sd_bus_message *m, int family, const uni
|
||||
static int bus_append_cgroup_property(sd_bus_message *m, const char *field, const char *eq) {
|
||||
int r;
|
||||
|
||||
if (STR_IN_SET(field, "DevicePolicy", "Slice"))
|
||||
if (STR_IN_SET(field, "DevicePolicy",
|
||||
"Slice",
|
||||
"ManagedOOMSwap",
|
||||
"ManagedOOMMemoryPressure",
|
||||
"ManagedOOMMemoryPressureLimitPercent"))
|
||||
return bus_append_string(m, field, eq);
|
||||
|
||||
if (STR_IN_SET(field, "CPUAccounting",
|
||||
|
||||
@@ -1243,3 +1243,5 @@ int config_parse_vlanprotocol(const char* unit,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_CONFIG_PARSE(config_parse_percent, parse_percent, "Failed to parse percent value");
|
||||
|
||||
@@ -147,6 +147,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ip_port);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_mtu);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_rlimit);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_vlanprotocol);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_percent);
|
||||
|
||||
typedef enum Disabled {
|
||||
DISABLED_CONFIGURATION,
|
||||
|
||||
@@ -189,6 +189,8 @@ shared_sources = files('''
|
||||
pkcs11-util.h
|
||||
pretty-print.c
|
||||
pretty-print.h
|
||||
psi-util.c
|
||||
psi-util.h
|
||||
ptyfwd.c
|
||||
ptyfwd.h
|
||||
pwquality-util.c
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "extract-word.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "parse-util.h"
|
||||
#include "psi-util.h"
|
||||
#include "string-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
int read_resource_pressure(const char *path, PressureType type, ResourcePressure *ret) {
|
||||
_cleanup_free_ char *line = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
unsigned field_filled = 0;
|
||||
ResourcePressure rp = {};
|
||||
const char *t, *cline;
|
||||
char *word;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(IN_SET(type, PRESSURE_TYPE_SOME, PRESSURE_TYPE_FULL));
|
||||
assert(ret);
|
||||
|
||||
if (type == PRESSURE_TYPE_SOME)
|
||||
t = "some";
|
||||
else if (type == PRESSURE_TYPE_FULL)
|
||||
t = "full";
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
r = fopen_unlocked(path, "re", &f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *l = NULL;
|
||||
char *w;
|
||||
|
||||
r = read_line(f, LONG_LINE_MAX, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
w = first_word(l, t);
|
||||
if (w) {
|
||||
line = TAKE_PTR(l);
|
||||
cline = w;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!line)
|
||||
return -ENODATA;
|
||||
|
||||
/* extracts either avgX=Y.Z or total=X */
|
||||
while ((r = extract_first_word(&cline, &word, NULL, 0)) > 0) {
|
||||
_cleanup_free_ char *w = word;
|
||||
const char *v;
|
||||
|
||||
if ((v = startswith(w, "avg10="))) {
|
||||
if (field_filled & (1U << 0))
|
||||
return -EINVAL;
|
||||
|
||||
field_filled |= 1U << 0;
|
||||
r = parse_loadavg_fixed_point(v, &rp.avg10);
|
||||
} else if ((v = startswith(w, "avg60="))) {
|
||||
if (field_filled & (1U << 1))
|
||||
return -EINVAL;
|
||||
|
||||
field_filled |= 1U << 1;
|
||||
r = parse_loadavg_fixed_point(v, &rp.avg60);
|
||||
} else if ((v = startswith(w, "avg300="))) {
|
||||
if (field_filled & (1U << 2))
|
||||
return -EINVAL;
|
||||
|
||||
field_filled |= 1U << 2;
|
||||
r = parse_loadavg_fixed_point(v, &rp.avg300);
|
||||
} else if ((v = startswith(w, "total="))) {
|
||||
if (field_filled & (1U << 3))
|
||||
return -EINVAL;
|
||||
|
||||
field_filled |= 1U << 3;
|
||||
r = safe_atou64(v, &rp.total);
|
||||
} else
|
||||
continue;
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (field_filled != 15U)
|
||||
return -EINVAL;
|
||||
|
||||
*ret = rp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_pressure_supported(void) {
|
||||
const char *p;
|
||||
|
||||
FOREACH_STRING(p, "/proc/pressure/cpu", "/proc/pressure/io", "/proc/pressure/memory")
|
||||
if (access(p, F_OK) < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "parse-util.h"
|
||||
#include "time-util.h"
|
||||
|
||||
typedef enum PressureType {
|
||||
PRESSURE_TYPE_SOME,
|
||||
PRESSURE_TYPE_FULL,
|
||||
} PressureType;
|
||||
|
||||
/* Averages are stored in fixed-point with 11 bit fractions */
|
||||
typedef struct ResourcePressure {
|
||||
loadavg_t avg10;
|
||||
loadavg_t avg60;
|
||||
loadavg_t avg300;
|
||||
usec_t total;
|
||||
} ResourcePressure;
|
||||
|
||||
/** Upstream 4.20+ format
|
||||
*
|
||||
* some avg10=0.22 avg60=0.17 avg300=1.11 total=58761459
|
||||
* full avg10=0.23 avg60=0.16 avg300=1.08 total=58464525
|
||||
*/
|
||||
int read_resource_pressure(const char *path, PressureType type, ResourcePressure *ret);
|
||||
|
||||
/* Was the kernel compiled with CONFIG_PSI=y? 1 if yes, 0 if not, negative on error. */
|
||||
int is_pressure_supported(void);
|
||||
+16
-2
@@ -254,7 +254,7 @@ static int allocate_scope(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int enter_cgroup_subroot(char **ret_cgroup) {
|
||||
static int enter_cgroup(char **ret_cgroup, bool enter_subroot) {
|
||||
_cleanup_free_ char *cgroup_root = NULL, *cgroup_subroot = NULL;
|
||||
CGroupMask supported;
|
||||
int r;
|
||||
@@ -268,7 +268,13 @@ int enter_cgroup_subroot(char **ret_cgroup) {
|
||||
return log_warning_errno(r, "cg_pid_get_path(NULL, 0, ...) failed: %m");
|
||||
assert(r >= 0);
|
||||
|
||||
assert_se(asprintf(&cgroup_subroot, "%s/%" PRIx64, cgroup_root, random_u64()) >= 0);
|
||||
if (enter_subroot)
|
||||
assert_se(asprintf(&cgroup_subroot, "%s/%" PRIx64, cgroup_root, random_u64()) >= 0);
|
||||
else {
|
||||
cgroup_subroot = strdup(cgroup_root);
|
||||
assert_se(cgroup_subroot != NULL);
|
||||
}
|
||||
|
||||
assert_se(cg_mask_supported(&supported) >= 0);
|
||||
|
||||
/* If this fails, then we don't mind as the later cgroup operations will fail too, and it's fine if
|
||||
@@ -287,3 +293,11 @@ int enter_cgroup_subroot(char **ret_cgroup) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int enter_cgroup_subroot(char **ret_cgroup) {
|
||||
return enter_cgroup(ret_cgroup, true);
|
||||
}
|
||||
|
||||
int enter_cgroup_root(char **ret_cgroup) {
|
||||
return enter_cgroup(ret_cgroup, false);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ static inline bool manager_errno_skip_test(int r) {
|
||||
|
||||
char* setup_fake_runtime_dir(void);
|
||||
int enter_cgroup_subroot(char **ret_cgroup);
|
||||
int enter_cgroup_root(char **ret_cgroup);
|
||||
int get_testdata_dir(const char *suffix, char **ret);
|
||||
const char* get_catalog_dir(void);
|
||||
bool slow_tests_enabled(void);
|
||||
|
||||
@@ -418,6 +418,11 @@ static int varlink_test_disconnect(Varlink *v) {
|
||||
if (IN_SET(v->state, VARLINK_IDLE_CLIENT) && (v->write_disconnected || v->got_pollhup))
|
||||
goto disconnect;
|
||||
|
||||
/* The server is still expecting to write more, but its write end is disconnected and it got a POLLHUP
|
||||
* (i.e. from a disconnected client), so disconnect. */
|
||||
if (IN_SET(v->state, VARLINK_PENDING_METHOD, VARLINK_PENDING_METHOD_MORE) && v->write_disconnected && v->got_pollhup)
|
||||
goto disconnect;
|
||||
|
||||
return 0;
|
||||
|
||||
disconnect:
|
||||
|
||||
@@ -171,3 +171,4 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(VarlinkServer *, varlink_server_unref);
|
||||
#define VARLINK_ERROR_METHOD_NOT_FOUND "org.varlink.service.MethodNotFound"
|
||||
#define VARLINK_ERROR_METHOD_NOT_IMPLEMENTED "org.varlink.service.MethodNotImplemented"
|
||||
#define VARLINK_ERROR_INVALID_PARAMETER "org.varlink.service.InvalidParameter"
|
||||
#define VARLINK_ERROR_SUBSCRIPTION_TAKEN "org.varlink.service.SubscriptionTaken"
|
||||
|
||||
Reference in New Issue
Block a user