export system memory and number of cpus in basic metrics (#42076)
This commit is contained in:
@@ -136,6 +136,8 @@ SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
"nothing"/"invalid"/"zero"/"please-suppress". Then use that to reduce noise
|
||||
in systemd-report output.
|
||||
|
||||
- cgroup-metrics: add per-cgroup PSI metrics
|
||||
|
||||
- sysupdate: offer reading transfer files/components/features optionally from
|
||||
some JSON fragment rather than transfer files, so that we can update it
|
||||
independently from any DDI, and it needs no activation cycle. Why? so that
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "build.h"
|
||||
#include "conf-files.h"
|
||||
#include "constants.h"
|
||||
#include "cpu-set-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
@@ -314,13 +315,13 @@ static unsigned determine_num_worker_threads(unsigned n_modules) {
|
||||
if (n_threads == UINT_MAX) {
|
||||
/* By default, use a number of worker threads equal the number of online CPUs,
|
||||
* but clamp it to avoid a probing storm on machines with many CPUs. */
|
||||
long ncpus = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (ncpus < 0) {
|
||||
log_warning_errno(errno, "Failed to get number of online CPUs, ignoring: %m");
|
||||
ncpus = 1;
|
||||
}
|
||||
|
||||
n_threads = CLAMP((unsigned)ncpus, 1U, 16U);
|
||||
unsigned n_cpus;
|
||||
r = cpus_online(&n_cpus);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to get number of online CPUs, ignoring: %m");
|
||||
n_threads = 1;
|
||||
} else
|
||||
n_threads = CLAMP(n_cpus, 1U, 16U);
|
||||
}
|
||||
|
||||
/* There's no reason to spawn more threads than the modules that need to be loaded */
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "architecture.h"
|
||||
#include "cpu-set-util.h"
|
||||
#include "hostname-setup.h"
|
||||
#include "limits-util.h"
|
||||
#include "log.h"
|
||||
#include "metrics.h"
|
||||
#include "os-util.h"
|
||||
@@ -100,6 +102,37 @@ static int machine_id_generate(const MetricFamily *mf, sd_varlink *link, void *u
|
||||
/* fields= */ NULL);
|
||||
}
|
||||
|
||||
static int physical_memory_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
|
||||
assert(mf && mf->name);
|
||||
assert(link);
|
||||
|
||||
return metric_build_send_unsigned(
|
||||
mf,
|
||||
link,
|
||||
/* object= */ NULL,
|
||||
physical_memory(),
|
||||
/* fields= */ NULL);
|
||||
}
|
||||
|
||||
static int cpus_online_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
|
||||
int r;
|
||||
|
||||
assert(mf && mf->name);
|
||||
assert(link);
|
||||
|
||||
unsigned n_cpus;
|
||||
r = cpus_online(&n_cpus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return metric_build_send_unsigned(
|
||||
mf,
|
||||
link,
|
||||
/* object= */ NULL,
|
||||
n_cpus,
|
||||
/* fields= */ NULL);
|
||||
}
|
||||
|
||||
enum {
|
||||
FIELD_PRETTY_NAME,
|
||||
FIELD_NAME,
|
||||
@@ -203,6 +236,12 @@ static const MetricFamily metric_family_table[] = {
|
||||
METRIC_FAMILY_TYPE_STRING,
|
||||
.generate = boot_id_generate,
|
||||
},
|
||||
{
|
||||
METRIC_IO_SYSTEMD_BASIC_PREFIX "CPUsOnline",
|
||||
"Number of CPUs currently online",
|
||||
METRIC_FAMILY_TYPE_GAUGE,
|
||||
.generate = cpus_online_generate,
|
||||
},
|
||||
{
|
||||
METRIC_IO_SYSTEMD_BASIC_PREFIX "Hostname",
|
||||
"System hostname",
|
||||
@@ -239,6 +278,12 @@ static const MetricFamily metric_family_table[] = {
|
||||
OS_RELEASE_STANDARD_FIELD("SYSEXT_LEVEL"),
|
||||
OS_RELEASE_STANDARD_FIELD("CONFEXT_LEVEL"),
|
||||
/* Keep those ↑ in sync with os_release_generate(). */
|
||||
{
|
||||
METRIC_IO_SYSTEMD_BASIC_PREFIX "PhysicalMemoryBytes",
|
||||
"Installed physical memory in bytes",
|
||||
METRIC_FAMILY_TYPE_GAUGE,
|
||||
.generate = physical_memory_generate,
|
||||
},
|
||||
{
|
||||
METRIC_IO_SYSTEMD_BASIC_PREFIX "Virtualization",
|
||||
"Virtualization type",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "bitfield.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "cpu-set-util.h"
|
||||
#include "extract-word.h"
|
||||
#include "log.h"
|
||||
@@ -400,3 +401,50 @@ int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *ret) {
|
||||
*ret = TAKE_STRUCT(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cgroup_cpus_effective(unsigned *ret) {
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
_cleanup_free_ char *root = NULL;
|
||||
r = cg_get_root_path(&root);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to determine root cgroup: %m");
|
||||
|
||||
_cleanup_free_ char *value = NULL;
|
||||
r = cg_get_attribute(root, "cpuset.cpus.effective", &value);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to read cpuset.cpus.effective cgroup attribute: %m");
|
||||
|
||||
_cleanup_(cpu_set_done) CPUSet cpus = {};
|
||||
r = parse_cpu_set(value, &cpus);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to parse cpuset.cpus.effective cgroup attribute: %m");
|
||||
|
||||
*ret = (unsigned) MIN(cpu_set_count(&cpus), UINT_MAX);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpus_online(unsigned *ret) {
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
/* In order to support containers nicely that have a configured cpuset we'll take the minimum of the
|
||||
* physically reported amount of CPUs and the limit configured for the root cgroup, if there is
|
||||
* any. */
|
||||
|
||||
long sc = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (sc < 0)
|
||||
return log_debug_errno(errno, "sysconf(_SC_NPROCESSORS_ONLN) failed: %m");
|
||||
|
||||
unsigned cg, lc = (unsigned) CLAMP((unsigned long) sc, 1U, UINT_MAX);
|
||||
r = cgroup_cpus_effective(&cg);
|
||||
if (r < 0)
|
||||
*ret = lc;
|
||||
else
|
||||
*ret = CLAMP(cg, 1U, lc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,3 +38,13 @@ int cpu_set_to_dbus(const CPUSet *c, uint8_t **ret, size_t *ret_size);
|
||||
int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *ret);
|
||||
|
||||
int cpus_in_affinity_mask(void);
|
||||
|
||||
static inline size_t cpu_set_count(const CPUSet *c) {
|
||||
if (!c)
|
||||
return 0;
|
||||
if (c->allocated <= 0)
|
||||
return 0;
|
||||
return CPU_COUNT_S(c->allocated, c->set);
|
||||
}
|
||||
|
||||
int cpus_online(unsigned *ret);
|
||||
|
||||
@@ -26,7 +26,7 @@ bool numa_policy_is_valid(const NUMAPolicy *policy) {
|
||||
|
||||
if (policy->nodes.set &&
|
||||
numa_policy_get_type(policy) == MPOL_PREFERRED &&
|
||||
CPU_COUNT_S(policy->nodes.allocated, policy->nodes.set) != 1)
|
||||
cpu_set_count(&policy->nodes) != 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
#define ASSERT_CPUSET_COUNT(c, n) \
|
||||
ASSERT_NOT_NULL(c.set); \
|
||||
ASSERT_GE(c.allocated, CPU_ALLOC_SIZE(n)); \
|
||||
ASSERT_EQ(CPU_COUNT_S(c.allocated, c.set), (n))
|
||||
ASSERT_EQ(CPU_COUNT_S(c.allocated, c.set), (n)); \
|
||||
ASSERT_EQ(cpu_set_count(&c), (size_t) (n))
|
||||
|
||||
#define ASSERT_CPUSET_ISSET(c, i) \
|
||||
ASSERT_TRUE(CPU_ISSET_S(i, c.allocated, c.set));
|
||||
@@ -283,4 +284,11 @@ TEST(cpu_set_add_range) {
|
||||
ASSERT_OK(cpu_set_add_range(&c, 0, 8191));
|
||||
}
|
||||
|
||||
TEST(cpus_online) {
|
||||
unsigned n_cpus = 0;
|
||||
ASSERT_OK(cpus_online(&n_cpus));
|
||||
ASSERT_GE(n_cpus, 1U);
|
||||
log_info("Number of CPUs currently online: %u", n_cpus);
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_DEBUG);
|
||||
|
||||
Reference in New Issue
Block a user