mirror of
https://git.proxmox.com/git/systemd
synced 2025-06-03 22:56:27 +00:00
New upstream version 245.4
This commit is contained in:
parent
cb695f0e25
commit
7d4b9ad6f6
@ -68,16 +68,14 @@
|
||||
#define SD_INFO "<6>" /* informational */
|
||||
#define SD_DEBUG "<7>" /* debug-level messages */</programlisting>
|
||||
|
||||
<para>These prefixes are intended to be used in conjunction with
|
||||
stderr-based logging as implemented by systemd. If a systemd
|
||||
service definition file is configured with
|
||||
<varname>StandardError=journal</varname>,
|
||||
<varname>StandardError=syslog</varname> or
|
||||
<varname>StandardError=kmsg</varname>, these prefixes can be used
|
||||
to encode a log level in lines printed. This is similar to the
|
||||
kernel <function>printk()</function>-style logging. See
|
||||
<citerefentry><refentrytitle>klogctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||
for more information.</para>
|
||||
<para>These prefixes are intended to be used in conjunction with stderr-based logging (or stdout-based
|
||||
logging) as implemented by systemd. If a systemd service definition file is configured with
|
||||
<varname>StandardError=journal</varname>, <varname>StandardError=syslog</varname> or
|
||||
<varname>StandardError=kmsg</varname> (and similar with <varname>StandardOutput=</varname>), these
|
||||
prefixes can be used to encode a log level in lines printed. This is similar to the kernel
|
||||
<function>printk()</function>-style logging. See
|
||||
<citerefentry><refentrytitle>klogctl</refentrytitle><manvolnum>2</manvolnum></citerefentry> for more
|
||||
information.</para>
|
||||
|
||||
<para>The log levels are identical to
|
||||
<citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>'s
|
||||
|
@ -774,10 +774,11 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
|
||||
<term><varname>CPUAffinity=</varname></term>
|
||||
|
||||
<listitem><para>Controls the CPU affinity of the executed processes. Takes a list of CPU indices or ranges
|
||||
separated by either whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated
|
||||
by a dash. This option may be specified more than once, in which case the specified CPU affinity masks are
|
||||
merged. If the empty string is assigned, the mask is reset, all assignments prior to this will have no
|
||||
effect. See
|
||||
separated by either whitespace or commas. Alternatively, takes a special "numa" value in which case systemd
|
||||
automatically derives allowed CPU range based on the value of <varname>NUMAMask=</varname> option. CPU ranges
|
||||
are specified by the lower and upper CPU indices separated by a dash. This option may be specified more than
|
||||
once, in which case the specified CPU affinity masks are merged. If the empty string is assigned, the mask
|
||||
is reset, all assignments prior to this will have no effect. See
|
||||
<citerefentry><refentrytitle>sched_setaffinity</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
||||
details.</para></listitem>
|
||||
</varlistentry>
|
||||
|
@ -217,8 +217,7 @@
|
||||
this notification message has been sent. If this option is used, <varname>NotifyAccess=</varname> (see
|
||||
below) should be set to open access to the notification socket provided by systemd. If
|
||||
<varname>NotifyAccess=</varname> is missing or set to <option>none</option>, it will be forcibly set to
|
||||
<option>main</option>. Note that currently <varname>Type=</varname><option>notify</option> will not work if
|
||||
used in combination with <varname>PrivateNetwork=</varname><option>yes</option>.</para></listitem>
|
||||
<option>main</option></para></listitem>.
|
||||
|
||||
<listitem><para>Behavior of <option>idle</option> is very similar to <option>simple</option>; however,
|
||||
actual execution of the service program is delayed until all active jobs are dispatched. This may be used
|
||||
|
@ -28,6 +28,7 @@
|
||||
"start:Start container as a service"
|
||||
"stop:Stop container (equal to poweroff)"
|
||||
"login:Get a login prompt on a VM/container"
|
||||
"shell:Invoke a shell (or other command) in a container"
|
||||
"enable:Enable automatic container start at boot"
|
||||
"disable:Disable automatic container start at boot"
|
||||
"poweroff:Power off one or more VMs/containers"
|
||||
|
@ -107,6 +107,10 @@ int capability_ambient_set_apply(uint64_t set, bool also_inherit) {
|
||||
unsigned long i;
|
||||
int r;
|
||||
|
||||
/* Check that we can use PR_CAP_AMBIENT or quit early. */
|
||||
if (!ambient_capabilities_supported())
|
||||
return 0;
|
||||
|
||||
/* Add the capabilities to the ambient set. */
|
||||
|
||||
if (also_inherit) {
|
||||
|
@ -74,7 +74,7 @@ int log_get_max_level_realm(LogRealm realm) _pure_;
|
||||
*/
|
||||
|
||||
assert_cc(STRLEN(__FILE__) > STRLEN(RELATIVE_SOURCE_PATH) + 1);
|
||||
#define PROJECT_FILE (__FILE__ + STRLEN(RELATIVE_SOURCE_PATH) + 1)
|
||||
#define PROJECT_FILE (&__FILE__[STRLEN(RELATIVE_SOURCE_PATH) + 1])
|
||||
|
||||
int log_open(void);
|
||||
void log_close(void);
|
||||
|
@ -310,7 +310,8 @@ bool fstype_is_network(const char *fstype) {
|
||||
"glusterfs",
|
||||
"pvfs2", /* OrangeFS */
|
||||
"ocfs2",
|
||||
"lustre");
|
||||
"lustre",
|
||||
"davfs");
|
||||
}
|
||||
|
||||
bool fstype_is_api_vfs(const char *fstype) {
|
||||
|
@ -701,16 +701,18 @@ int take_etc_passwd_lock(const char *root) {
|
||||
bool valid_user_group_name_full(const char *u, bool strict) {
|
||||
const char *i;
|
||||
long sz;
|
||||
bool warned = false;
|
||||
|
||||
/* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition,
|
||||
* 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules:
|
||||
*
|
||||
* - We require that names fit into the appropriate utmp field
|
||||
* - We don't allow empty user names
|
||||
* - No dots or digits in the first character
|
||||
* - No dots in the first character
|
||||
*
|
||||
* If strict==true, additionally:
|
||||
* - We don't allow any dots (this conflicts with chown syntax which permits dots as user/group name separator)
|
||||
* - We don't allow a digit as the first character
|
||||
*
|
||||
* Note that other systems are even more restrictive, and don't permit underscores or uppercase characters.
|
||||
*/
|
||||
@ -720,17 +722,26 @@ bool valid_user_group_name_full(const char *u, bool strict) {
|
||||
|
||||
if (!(u[0] >= 'a' && u[0] <= 'z') &&
|
||||
!(u[0] >= 'A' && u[0] <= 'Z') &&
|
||||
!(u[0] >= '0' && u[0] <= '9' && !strict) &&
|
||||
u[0] != '_')
|
||||
return false;
|
||||
|
||||
bool warned = false;
|
||||
bool only_digits_seen = u[0] >= '0' && u[0] <= '9';
|
||||
|
||||
if (only_digits_seen) {
|
||||
log_warning("User or group name \"%s\" starts with a digit, accepting for compatibility.", u);
|
||||
warned = true;
|
||||
}
|
||||
|
||||
for (i = u+1; *i; i++) {
|
||||
if (((*i >= 'a' && *i <= 'z') ||
|
||||
(*i >= 'A' && *i <= 'Z') ||
|
||||
(*i >= '0' && *i <= '9') ||
|
||||
IN_SET(*i, '_', '-')))
|
||||
IN_SET(*i, '_', '-'))) {
|
||||
if (!(*i >= '0' && *i <= '9'))
|
||||
only_digits_seen = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*i == '.' && !strict) {
|
||||
if (!warned) {
|
||||
@ -744,6 +755,9 @@ bool valid_user_group_name_full(const char *u, bool strict) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (only_digits_seen)
|
||||
return false;
|
||||
|
||||
sz = sysconf(_SC_LOGIN_NAME_MAX);
|
||||
assert_se(sz > 0);
|
||||
|
||||
@ -764,10 +778,10 @@ bool valid_user_group_name_or_id_full(const char *u, bool strict) {
|
||||
if (isempty(u))
|
||||
return false;
|
||||
|
||||
if (valid_user_group_name_full(u, strict))
|
||||
if (parse_uid(u, NULL) >= 0)
|
||||
return true;
|
||||
|
||||
return parse_uid(u, NULL) >= 0;
|
||||
return valid_user_group_name_full(u, strict);
|
||||
}
|
||||
|
||||
bool valid_gecos(const char *d) {
|
||||
|
@ -56,6 +56,8 @@ static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_priority, "i", ExecContext,
|
||||
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 int property_get_environment_files(
|
||||
sd_bus *bus,
|
||||
@ -213,6 +215,7 @@ static int property_get_cpu_affinity(
|
||||
sd_bus_error *error) {
|
||||
|
||||
ExecContext *c = userdata;
|
||||
_cleanup_(cpu_set_reset) CPUSet s = {};
|
||||
_cleanup_free_ uint8_t *array = NULL;
|
||||
size_t allocated;
|
||||
|
||||
@ -220,7 +223,16 @@ static int property_get_cpu_affinity(
|
||||
assert(reply);
|
||||
assert(c);
|
||||
|
||||
(void) cpu_set_to_dbus(&c->cpu_set, &array, &allocated);
|
||||
if (c->cpu_affinity_from_numa) {
|
||||
int r;
|
||||
|
||||
r = numa_to_cpu_set(&c->numa_policy, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
(void) cpu_set_to_dbus(c->cpu_affinity_from_numa ? &s : &c->cpu_set, &array, &allocated);
|
||||
|
||||
return sd_bus_message_append_array(reply, 'y', array, allocated);
|
||||
}
|
||||
|
||||
@ -741,6 +753,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
|
||||
SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CPUAffinityFromNUMA", "b", property_get_cpu_affinity_from_numa, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("NUMAPolicy", "i", property_get_numa_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("NUMAMask", "ay", property_get_numa_mask, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
@ -1770,6 +1783,20 @@ int bus_exec_context_set_transient_property(
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "CPUAffinityFromNUMA")) {
|
||||
int q;
|
||||
|
||||
r = sd_bus_message_read_basic(message, 'b', &q);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->cpu_affinity_from_numa = q;
|
||||
unit_write_settingf(u, flags, name, "%s=%s", "CPUAffinity", "numa");
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "NUMAPolicy")) {
|
||||
int32_t type;
|
||||
|
||||
@ -1784,6 +1811,7 @@ int bus_exec_context_set_transient_property(
|
||||
c->numa_policy.type = type;
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "Nice")) {
|
||||
int32_t q;
|
||||
|
||||
|
@ -3021,6 +3021,33 @@ static int exec_parameters_get_cgroup_path(const ExecParameters *params, char **
|
||||
return using_subcgroup;
|
||||
}
|
||||
|
||||
static int exec_context_cpu_affinity_from_numa(const ExecContext *c, CPUSet *ret) {
|
||||
_cleanup_(cpu_set_reset) CPUSet s = {};
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
assert(ret);
|
||||
|
||||
if (!c->numa_policy.nodes.set) {
|
||||
log_debug("Can't derive CPU affinity mask from NUMA mask because NUMA mask is not set, ignoring");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = numa_to_cpu_set(&c->numa_policy, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
cpu_set_reset(ret);
|
||||
|
||||
return cpu_set_add_all(ret, &s);
|
||||
}
|
||||
|
||||
bool exec_context_get_cpu_affinity_from_numa(const ExecContext *c) {
|
||||
assert(c);
|
||||
|
||||
return c->cpu_affinity_from_numa;
|
||||
}
|
||||
|
||||
static int exec_child(
|
||||
Unit *unit,
|
||||
const ExecCommand *command,
|
||||
@ -3318,11 +3345,26 @@ static int exec_child(
|
||||
}
|
||||
}
|
||||
|
||||
if (context->cpu_set.set)
|
||||
if (sched_setaffinity(0, context->cpu_set.allocated, context->cpu_set.set) < 0) {
|
||||
if (context->cpu_affinity_from_numa || context->cpu_set.set) {
|
||||
_cleanup_(cpu_set_reset) CPUSet converted_cpu_set = {};
|
||||
const CPUSet *cpu_set;
|
||||
|
||||
if (context->cpu_affinity_from_numa) {
|
||||
r = exec_context_cpu_affinity_from_numa(context, &converted_cpu_set);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_CPUAFFINITY;
|
||||
return log_unit_error_errno(unit, r, "Failed to derive CPU affinity mask from NUMA mask: %m");
|
||||
}
|
||||
|
||||
cpu_set = &converted_cpu_set;
|
||||
} else
|
||||
cpu_set = &context->cpu_set;
|
||||
|
||||
if (sched_setaffinity(0, cpu_set->allocated, cpu_set->set) < 0) {
|
||||
*exit_status = EXIT_CPUAFFINITY;
|
||||
return log_unit_error_errno(unit, errno, "Failed to set up CPU affinity: %m");
|
||||
}
|
||||
}
|
||||
|
||||
if (mpol_is_valid(numa_policy_get_type(&context->numa_policy))) {
|
||||
r = apply_numa_policy(&context->numa_policy);
|
||||
|
@ -21,6 +21,7 @@ typedef struct Manager Manager;
|
||||
#include "missing_resource.h"
|
||||
#include "namespace.h"
|
||||
#include "nsflags.h"
|
||||
#include "numa-util.h"
|
||||
#include "time-util.h"
|
||||
|
||||
#define EXEC_STDIN_DATA_MAX (64U*1024U*1024U)
|
||||
@ -181,6 +182,7 @@ struct ExecContext {
|
||||
|
||||
CPUSet cpu_set;
|
||||
NUMAPolicy numa_policy;
|
||||
bool cpu_affinity_from_numa;
|
||||
|
||||
ExecInput std_input;
|
||||
ExecOutput std_output;
|
||||
@ -405,6 +407,8 @@ void exec_runtime_vacuum(Manager *m);
|
||||
|
||||
void exec_params_clear(ExecParameters *p);
|
||||
|
||||
bool exec_context_get_cpu_affinity_from_numa(const ExecContext *c);
|
||||
|
||||
const char* exec_output_to_string(ExecOutput i) _const_;
|
||||
ExecOutput exec_output_from_string(const char *s) _pure_;
|
||||
|
||||
|
@ -1330,13 +1330,25 @@ int config_parse_exec_cpu_affinity(const char *unit,
|
||||
void *userdata) {
|
||||
|
||||
ExecContext *c = data;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
return parse_cpu_set_extend(rvalue, &c->cpu_set, true, unit, filename, line, lvalue);
|
||||
if (streq(rvalue, "numa")) {
|
||||
c->cpu_affinity_from_numa = true;
|
||||
cpu_set_reset(&c->cpu_set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_cpu_set_extend(rvalue, &c->cpu_set, true, unit, filename, line, lvalue);
|
||||
if (r >= 0)
|
||||
c->cpu_affinity_from_numa = false;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int config_parse_capability_set(
|
||||
|
@ -207,7 +207,7 @@ static int swap_add_device_dependencies(Swap *s) {
|
||||
return 0;
|
||||
|
||||
p = swap_get_parameters(s);
|
||||
if (!p)
|
||||
if (!p || !p->what)
|
||||
return 0;
|
||||
|
||||
mask = s->from_proc_swaps ? UNIT_DEPENDENCY_PROC_SWAP : UNIT_DEPENDENCY_FILE;
|
||||
|
@ -295,7 +295,7 @@ static int handle_generic_user_record_error(
|
||||
|
||||
if (sd_bus_error_has_name(error, BUS_ERROR_HOME_ABSENT))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EREMOTE),
|
||||
"Home of user %s is currently absent, please plug in the necessary stroage device or backing file system.", user_name);
|
||||
"Home of user %s is currently absent, please plug in the necessary storage device or backing file system.", user_name);
|
||||
|
||||
else if (sd_bus_error_has_name(error, BUS_ERROR_AUTHENTICATION_LIMIT_HIT))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ETOOMANYREFS),
|
||||
@ -1207,7 +1207,7 @@ static int add_pkcs11_key_data(JsonVariant **v, const char *uri) {
|
||||
|
||||
pkey = X509_get0_pubkey(cert);
|
||||
if (!pkey)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to exract public key from X.509 certificate.");
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to extract public key from X.509 certificate.");
|
||||
|
||||
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "X.509 certificate does not refer to RSA key.");
|
||||
@ -1338,7 +1338,7 @@ static int acquire_new_password(
|
||||
string_erase(e);
|
||||
|
||||
if (unsetenv("NEWPASSWORD") < 0)
|
||||
return log_error_errno(errno, "Failed to unse $NEWPASSWORD: %m");
|
||||
return log_error_errno(errno, "Failed to unset $NEWPASSWORD: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1376,7 +1376,7 @@ static int acquire_new_password(
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_error("Password didn't mach, try again.");
|
||||
log_error("Password didn't match, try again.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -3148,7 +3148,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
r = read_line(f, LONG_LINE_MAX, &line);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Faile dto read from '%s': %m", optarg+1);
|
||||
return log_error_errno(r, "Failed to read from '%s': %m", optarg+1);
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
|
@ -630,7 +630,7 @@ int bus_home_method_acquire(
|
||||
/* This operation might not be something we can executed immediately, hence queue it */
|
||||
fd = home_create_fifo(h, please_suspend);
|
||||
if (fd < 0)
|
||||
return sd_bus_reply_method_errnof(message, fd, "Failed to allocate fifo for %s: %m", h->user_name);
|
||||
return sd_bus_reply_method_errnof(message, fd, "Failed to allocate FIFO for %s: %m", h->user_name);
|
||||
|
||||
o = operation_new(OPERATION_ACQUIRE, message);
|
||||
if (!o)
|
||||
@ -681,7 +681,7 @@ int bus_home_method_ref(
|
||||
|
||||
fd = home_create_fifo(h, please_suspend);
|
||||
if (fd < 0)
|
||||
return sd_bus_reply_method_errnof(message, fd, "Failed to allocate fifo for %s: %m", h->user_name);
|
||||
return sd_bus_reply_method_errnof(message, fd, "Failed to allocate FIFO for %s: %m", h->user_name);
|
||||
|
||||
return sd_bus_reply_method_return(message, "h", fd);
|
||||
}
|
||||
|
@ -424,7 +424,7 @@ static int home_verify_user_record(Home *h, UserRecord *hr, bool *ret_signed_loc
|
||||
|
||||
case -ENOKEY:
|
||||
sd_bus_error_setf(ret_error, BUS_ERROR_BAD_SIGNATURE, "User record %s is not signed by any known key, refusing.", hr->user_name);
|
||||
return log_error_errno(is_signed, "Home %s contians user record that is not signed by any known key, refusing.", hr->user_name);
|
||||
return log_error_errno(is_signed, "Home %s contains user record that is not signed by any known key, refusing.", hr->user_name);
|
||||
|
||||
default:
|
||||
assert(is_signed < 0);
|
||||
@ -438,7 +438,7 @@ static int convert_worker_errno(Home *h, int e, sd_bus_error *error) {
|
||||
switch (e) {
|
||||
|
||||
case -EMSGSIZE:
|
||||
return sd_bus_error_setf(error, BUS_ERROR_BAD_HOME_SIZE, "File systems of this type cannot shrinked");
|
||||
return sd_bus_error_setf(error, BUS_ERROR_BAD_HOME_SIZE, "File systems of this type cannot be shrinked");
|
||||
case -ETXTBSY:
|
||||
return sd_bus_error_setf(error, BUS_ERROR_BAD_HOME_SIZE, "File systems of this type can only be shrinked offline");
|
||||
case -ERANGE:
|
||||
@ -1472,7 +1472,7 @@ int home_resize(Home *h, uint64_t disk_size, UserRecord *secret, sd_bus_error *e
|
||||
|
||||
if (disk_size == UINT64_MAX || disk_size == h->record->disk_size) {
|
||||
if (h->record->disk_size == UINT64_MAX)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Not disk size to resize to specified.");
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "No disk size to resize to specified.");
|
||||
|
||||
c = user_record_ref(h->record); /* Shortcut if size is unspecified or matches the record */
|
||||
} else {
|
||||
@ -1904,7 +1904,7 @@ static int home_get_disk_status_luks(
|
||||
goto finish;
|
||||
|
||||
if (statfs(hd, &sfs) < 0) {
|
||||
log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", hd);
|
||||
log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", hd);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -584,7 +584,7 @@ static int method_lock_all_homes(sd_bus_message *message, void *userdata, sd_bus
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
log_info("Automatically locking of home of user %s.", h->user_name);
|
||||
log_info("Automatically locking home of user %s.", h->user_name);
|
||||
|
||||
r = home_schedule_operation(h, o, error);
|
||||
if (r < 0)
|
||||
|
@ -631,7 +631,7 @@ static int manager_add_home_by_image(
|
||||
}
|
||||
|
||||
if (!same) {
|
||||
log_debug("Found a multiple images for a user '%s', ignoring image '%s'.", user_name, image_path);
|
||||
log_debug("Found multiple images for user '%s', ignoring image '%s'.", user_name, image_path);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
@ -768,7 +768,7 @@ static int manager_assess_image(
|
||||
r = stat(path, &st);
|
||||
if (r < 0)
|
||||
return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
|
||||
"Failed to stat directory entry '%s', ignoring: %m", dentry_name);
|
||||
"Failed to stat() directory entry '%s', ignoring: %m", dentry_name);
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
_cleanup_free_ char *n = NULL, *user_name = NULL, *realm = NULL;
|
||||
@ -833,7 +833,7 @@ static int manager_assess_image(
|
||||
if (errno == ENODATA)
|
||||
log_debug_errno(errno, "Determined %s is not fscrypt encrypted.", path);
|
||||
else if (ERRNO_IS_NOT_SUPPORTED(errno))
|
||||
log_debug_errno(errno, "Determined %s is not fscrypt encrypted because kernel or file system don't support it.", path);
|
||||
log_debug_errno(errno, "Determined %s is not fscrypt encrypted because kernel or file system doesn't support it.", path);
|
||||
else
|
||||
log_debug_errno(errno, "FS_IOC_GET_ENCRYPTION_POLICY failed with unexpected error code on %s, ignoring: %m", path);
|
||||
|
||||
@ -1307,7 +1307,7 @@ static int manager_generate_key_pair(Manager *m) {
|
||||
/* Write out public key (note that we only do that as a help to the user, we don't make use of this ever */
|
||||
r = fopen_temporary("/var/lib/systemd/home/local.public", &fpublic, &temp_public);
|
||||
if (r < 0)
|
||||
return log_error_errno(errno, "Failed ot open key file for writing: %m");
|
||||
return log_error_errno(errno, "Failed to open key file for writing: %m");
|
||||
|
||||
if (PEM_write_PUBKEY(fpublic, m->private_key) <= 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key.");
|
||||
@ -1321,7 +1321,7 @@ static int manager_generate_key_pair(Manager *m) {
|
||||
/* Write out the private key (this actually writes out both private and public, OpenSSL is confusing) */
|
||||
r = fopen_temporary("/var/lib/systemd/home/local.private", &fprivate, &temp_private);
|
||||
if (r < 0)
|
||||
return log_error_errno(errno, "Failed ot open key file for writing: %m");
|
||||
return log_error_errno(errno, "Failed to open key file for writing: %m");
|
||||
|
||||
if (PEM_write_PrivateKey(fprivate, m->private_key, NULL, NULL, 0, NULL, 0) <= 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write private key pair.");
|
||||
@ -1660,7 +1660,7 @@ int manager_enqueue_gc(Manager *m, Home *focus) {
|
||||
|
||||
r = sd_event_add_defer(m->event, &m->deferred_gc_event_source, on_deferred_gc, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate gc event source: %m");
|
||||
return log_error_errno(r, "Failed to allocate GC event source: %m");
|
||||
|
||||
r = sd_event_source_set_priority(m->deferred_gc_event_source, SD_EVENT_PRIORITY_IDLE);
|
||||
if (r < 0)
|
||||
|
@ -47,7 +47,7 @@ static Operation *operation_free(Operation *o) {
|
||||
r = sd_bus_reply_method_errnof(o->message, o->ret, "Failed to execute operation: %m");
|
||||
}
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed ot reply to %s method call, ignoring: %m", sd_bus_message_get_member(o->message));
|
||||
log_warning_errno(r, "Failed to reply to %s method call, ignoring: %m", sd_bus_message_get_member(o->message));
|
||||
}
|
||||
|
||||
sd_bus_message_unref(o->message);
|
||||
|
@ -616,7 +616,7 @@ static int crypt_device_to_evp_cipher(struct crypt_device *cd, const EVP_CIPHER
|
||||
/* Verify that our key length calculations match what OpenSSL thinks */
|
||||
r = EVP_CIPHER_key_length(cc);
|
||||
if (r < 0 || (uint64_t) r != key_size)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Key size of selected cipher doesn't meet out expectations.");
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Key size of selected cipher doesn't meet our expectations.");
|
||||
|
||||
*ret = cc;
|
||||
return 0;
|
||||
@ -787,7 +787,7 @@ static int format_luks_token_text(
|
||||
|
||||
r = json_variant_format(hr->json, 0, &text);
|
||||
if (r < 0)
|
||||
return log_error_errno(r,"Failed to format user record for LUKS: %m");
|
||||
return log_error_errno(r, "Failed to format user record for LUKS: %m");
|
||||
|
||||
text_length = strlen(text);
|
||||
encrypted_size = text_length + 2*key_size - 1;
|
||||
@ -1263,7 +1263,7 @@ int home_activate_luks(
|
||||
|
||||
r = dm_deferred_remove(setup.dm_name);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to relinquish dm device, ignoring: %m");
|
||||
log_warning_errno(r, "Failed to relinquish DM device, ignoring: %m");
|
||||
|
||||
setup.undo_dm = false;
|
||||
|
||||
@ -1328,7 +1328,7 @@ static int run_mkfs(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to check if mkfs for file system %s exists: %m", fstype);
|
||||
if (r == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EPROTONOSUPPORT), "Nt mkfs for file system %s installed.", fstype);
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EPROTONOSUPPORT), "No mkfs for file system %s installed.", fstype);
|
||||
|
||||
r = safe_fork("(mkfs)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR, NULL);
|
||||
if (r < 0)
|
||||
@ -1584,7 +1584,7 @@ static int make_partition_table(
|
||||
|
||||
r = fdisk_create_disklabel(c, "gpt");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create gpt disk label: %m");
|
||||
return log_error_errno(r, "Failed to create GPT disk label: %m");
|
||||
|
||||
p = fdisk_new_partition();
|
||||
if (!p)
|
||||
@ -2212,7 +2212,7 @@ static int ext4_offline_resize_fs(HomeSetup *setup, uint64_t new_size, bool disc
|
||||
re_mount = true;
|
||||
}
|
||||
|
||||
log_info("Temporarary unmounting of file system completed.");
|
||||
log_info("Temporary unmounting of file system completed.");
|
||||
|
||||
/* resize2fs requires that the file system is force checked first, do so. */
|
||||
r = safe_fork("(e2fsck)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_STDOUT_TO_STDERR, &fsck_pid);
|
||||
@ -2426,7 +2426,7 @@ static int apply_resize_partition(int fd, sd_id128_t disk_uuids, struct fdisk_ta
|
||||
if (n < 0)
|
||||
return log_error_errno(errno, "Failed to wipe partition table: %m");
|
||||
if (n != 1024)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short write while whiping partition table.");
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short write while wiping partition table.");
|
||||
|
||||
c = fdisk_new_context();
|
||||
if (!c)
|
||||
@ -2536,7 +2536,7 @@ int home_resize_luks(
|
||||
} else {
|
||||
r = stat_verify_regular(&st);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Image file %s is not a block device nor regular: %m", ip);
|
||||
return log_error_errno(r, "Image %s is not a block device nor regular file: %m", ip);
|
||||
|
||||
old_image_size = st.st_size;
|
||||
|
||||
|
@ -53,7 +53,7 @@ int pkcs11_callback(
|
||||
if (rv != CKR_OK)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to log into security token '%s': %s", token_label, p11_kit_strerror(rv));
|
||||
|
||||
log_info("Successully logged into security token '%s' via protected authentication path.", token_label);
|
||||
log_info("Successfully logged into security token '%s' via protected authentication path.", token_label);
|
||||
goto decrypt;
|
||||
}
|
||||
|
||||
|
@ -383,7 +383,7 @@ int home_load_embedded_identity(
|
||||
return r;
|
||||
|
||||
if (!user_record_compatible(h, embedded_home))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EREMCHG), "Hmbedded home record not compatible with host record, refusing.");
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EREMCHG), "Embedded home record not compatible with host record, refusing.");
|
||||
|
||||
/* Insist that credentials the user supplies also unlocks any embedded records. */
|
||||
r = user_record_authenticate(embedded_home, h, pkcs11_decrypted_passwords);
|
||||
@ -986,7 +986,7 @@ static int home_remove(UserRecord *h) {
|
||||
|
||||
if (stat(ip, &st) < 0) {
|
||||
if (errno != -ENOENT)
|
||||
return log_error_errno(errno, "Failed to stat %s: %m", ip);
|
||||
return log_error_errno(errno, "Failed to stat() %s: %m", ip);
|
||||
|
||||
} else {
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
|
@ -41,7 +41,7 @@ static int parse_argv(
|
||||
|
||||
k = parse_boolean(v);
|
||||
if (k < 0)
|
||||
pam_syslog(handle, LOG_WARNING, "Failed to parse suspend-please= argument, ignoring: %s", v);
|
||||
pam_syslog(handle, LOG_WARNING, "Failed to parse suspend= argument, ignoring: %s", v);
|
||||
else if (please_suspend)
|
||||
*please_suspend = k;
|
||||
|
||||
@ -95,7 +95,7 @@ static int acquire_user_record(
|
||||
r = pam_get_data(handle, "systemd-user-record-is-homed", &b);
|
||||
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA)) {
|
||||
/* Failure */
|
||||
pam_syslog(handle, LOG_ERR, "Failed to get PAM user record is homed flag: %s", pam_strerror(handle, r));
|
||||
pam_syslog(handle, LOG_ERR, "Failed to get PAM user-record-is-homed flag: %s", pam_strerror(handle, r));
|
||||
return r;
|
||||
} else if (b == NULL)
|
||||
/* Nothing cached yet, need to acquire fresh */
|
||||
@ -200,7 +200,7 @@ user_unknown:
|
||||
/* Cache this, so that we don't check again */
|
||||
r = pam_set_data(handle, "systemd-user-record-is-homed", USER_RECORD_IS_OTHER, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
pam_syslog(handle, LOG_ERR, "Failed to set PAM user record is homed flag, ignoring: %s", pam_strerror(handle, r));
|
||||
pam_syslog(handle, LOG_ERR, "Failed to set PAM user-record-is-homed flag, ignoring: %s", pam_strerror(handle, r));
|
||||
|
||||
return PAM_USER_UNKNOWN;
|
||||
}
|
||||
@ -214,7 +214,7 @@ static int release_user_record(pam_handle_t *handle) {
|
||||
|
||||
k = pam_set_data(handle, "systemd-user-record-is-homed", NULL, NULL);
|
||||
if (k != PAM_SUCCESS)
|
||||
pam_syslog(handle, LOG_ERR, "Failed to release PAM user record is homed flag: %s", pam_strerror(handle, k));
|
||||
pam_syslog(handle, LOG_ERR, "Failed to release PAM user-record-is-homed flag: %s", pam_strerror(handle, k));
|
||||
|
||||
return IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA) ? k : r;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ int quality_check_password(
|
||||
|
||||
r = pwquality_read_config(pwq, NULL, &auxerror);
|
||||
if (r < 0)
|
||||
log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to read libpwquality configuation, ignoring: %s",
|
||||
log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to read libpwquality configuration, ignoring: %s",
|
||||
pwquality_strerror(buf, sizeof(buf), r, auxerror));
|
||||
|
||||
pwquality_maybe_disable_dictionary(pwq);
|
||||
@ -143,7 +143,7 @@ int suggest_passwords(void) {
|
||||
|
||||
r = pwquality_read_config(pwq, NULL, &auxerror);
|
||||
if (r < 0)
|
||||
log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to read libpwquality configuation, ignoring: %s",
|
||||
log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to read libpwquality configuration, ignoring: %s",
|
||||
pwquality_strerror(buf, sizeof(buf), r, auxerror));
|
||||
|
||||
pwquality_maybe_disable_dictionary(pwq);
|
||||
|
@ -509,14 +509,17 @@ static void raw_pull_job_on_finished(PullJob *j) {
|
||||
|
||||
raw_pull_report_progress(i, RAW_FINALIZING);
|
||||
|
||||
r = import_make_read_only_fd(i->raw_job->disk_fd);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
if (i->raw_job->etag) {
|
||||
/* Only make a read-only copy if ETag header is set. */
|
||||
r = import_make_read_only_fd(i->raw_job->disk_fd);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to rename raw file to %s: %m", i->final_path);
|
||||
goto finish;
|
||||
r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to rename raw file to %s: %m", i->final_path);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
i->temp_path = mfree(i->temp_path);
|
||||
|
@ -2675,13 +2675,12 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) {
|
||||
Get rid of the deleted files now so they don't stay around indefinitely. */
|
||||
ORDERED_HASHMAP_FOREACH(f, j->files, i) {
|
||||
r = journal_file_fstat(f);
|
||||
if (r < 0) {
|
||||
if (r == -EIDRM)
|
||||
remove_file_real(j, f);
|
||||
else if (r < 0) {
|
||||
log_debug_errno(r,"Failed to fstat() journal file '%s' : %m", f->path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (f->last_stat.st_nlink <= 0)
|
||||
remove_file_real(j, f);
|
||||
}
|
||||
|
||||
/* The journal might have changed since the context
|
||||
|
@ -1175,7 +1175,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to deserialize SIP servers %s, ignoring: %m", sip);
|
||||
else
|
||||
lease->ntp_size = r;
|
||||
lease->sip_size = r;
|
||||
}
|
||||
|
||||
if (mtu) {
|
||||
|
@ -3424,7 +3424,7 @@ const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
static int session_jobs_reply(Session *s, const char *unit, const char *result) {
|
||||
static int session_jobs_reply(Session *s, uint32_t jid, const char *unit, const char *result) {
|
||||
assert(s);
|
||||
assert(unit);
|
||||
|
||||
@ -3435,7 +3435,7 @@ static int session_jobs_reply(Session *s, const char *unit, const char *result)
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
|
||||
|
||||
sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED,
|
||||
"Start job for unit '%s' failed with '%s'", unit, result);
|
||||
"Job %u for unit '%s' failed with '%s'", jid, unit, result);
|
||||
return session_send_create_reply(s, &e);
|
||||
}
|
||||
|
||||
@ -3475,7 +3475,7 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
|
||||
if (session) {
|
||||
if (streq_ptr(path, session->scope_job)) {
|
||||
session->scope_job = mfree(session->scope_job);
|
||||
(void) session_jobs_reply(session, unit, result);
|
||||
(void) session_jobs_reply(session, id, unit, result);
|
||||
|
||||
session_save(session);
|
||||
user_save(session->user);
|
||||
@ -3490,7 +3490,7 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
|
||||
user->service_job = mfree(user->service_job);
|
||||
|
||||
LIST_FOREACH(sessions_by_user, session, user->sessions)
|
||||
(void) session_jobs_reply(session, unit, NULL /* don't propagate user service failures to the client */);
|
||||
(void) session_jobs_reply(session, id, unit, NULL /* don't propagate user service failures to the client */);
|
||||
|
||||
user_save(user);
|
||||
}
|
||||
|
@ -396,7 +396,7 @@
|
||||
<message gettext-domain="systemd">Authentication is required to change the virtual terminal.</message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin_keep</allow_any>
|
||||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_inactive>yes</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
@ -432,7 +432,7 @@ enum nss_status _nss_systemd_getgrent_r(
|
||||
if (!getgrent_data.by_membership) {
|
||||
r = groupdb_iterator_get(getgrent_data.iterator, &gr);
|
||||
if (r == -ESRCH) {
|
||||
/* So we finished iterating native groups now. let's now continue with iterating
|
||||
/* So we finished iterating native groups now. Let's now continue with iterating
|
||||
* native memberships, and generate additional group entries for any groups
|
||||
* referenced there that are defined in NSS only. This means for those groups there
|
||||
* will be two or more entries generated during iteration, but this is apparently how
|
||||
@ -511,7 +511,8 @@ enum nss_status _nss_systemd_getgrent_r(
|
||||
if (!members) {
|
||||
UNPROTECT_ERRNO;
|
||||
*errnop = ENOMEM;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
ret = NSS_STATUS_TRYAGAIN;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Note that we currently generate one group entry per user that is part of a
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "missing_fs.h"
|
||||
#include "mountpoint-util.h"
|
||||
#include "nsflags.h"
|
||||
#include "numa-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "process-util.h"
|
||||
#include "rlimit-util.h"
|
||||
@ -28,6 +29,7 @@
|
||||
#include "signal-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "sort-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "string-util.h"
|
||||
#include "syslog-util.h"
|
||||
#include "terminal-util.h"
|
||||
@ -1102,6 +1104,13 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||
_cleanup_free_ uint8_t *array = NULL;
|
||||
size_t allocated;
|
||||
|
||||
if (eq && streq(eq, "numa")) {
|
||||
r = sd_bus_message_append(m, "(sv)", "CPUAffinityFromNUMA", "b", true);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = parse_cpu_set(eq, &cpuset);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
|
||||
|
@ -14,11 +14,9 @@
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "memory-util.h"
|
||||
#include "missing_syscall.h"
|
||||
#include "parse-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "string-util.h"
|
||||
#include "string-table.h"
|
||||
#include "strv.h"
|
||||
#include "util.h"
|
||||
|
||||
@ -133,7 +131,7 @@ int cpu_set_add_all(CPUSet *a, const CPUSet *b) {
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parse_cpu_set_full(
|
||||
@ -218,7 +216,7 @@ int parse_cpu_set_extend(
|
||||
if (!old->set) {
|
||||
*old = cpuset;
|
||||
cpuset = (CPUSet) {};
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return cpu_set_add_all(old, &cpuset);
|
||||
@ -295,88 +293,3 @@ int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set) {
|
||||
s = (CPUSet) {};
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool numa_policy_is_valid(const NUMAPolicy *policy) {
|
||||
assert(policy);
|
||||
|
||||
if (!mpol_is_valid(numa_policy_get_type(policy)))
|
||||
return false;
|
||||
|
||||
if (!policy->nodes.set &&
|
||||
!IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL, MPOL_PREFERRED))
|
||||
return false;
|
||||
|
||||
if (policy->nodes.set &&
|
||||
numa_policy_get_type(policy) == MPOL_PREFERRED &&
|
||||
CPU_COUNT_S(policy->nodes.allocated, policy->nodes.set) != 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int numa_policy_to_mempolicy(const NUMAPolicy *policy, unsigned long *ret_maxnode, unsigned long **ret_nodes) {
|
||||
unsigned node, bits = 0, ulong_bits;
|
||||
_cleanup_free_ unsigned long *out = NULL;
|
||||
|
||||
assert(policy);
|
||||
assert(ret_maxnode);
|
||||
assert(ret_nodes);
|
||||
|
||||
if (IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL) ||
|
||||
(numa_policy_get_type(policy) == MPOL_PREFERRED && !policy->nodes.set)) {
|
||||
*ret_nodes = NULL;
|
||||
*ret_maxnode = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bits = policy->nodes.allocated * 8;
|
||||
ulong_bits = sizeof(unsigned long) * 8;
|
||||
|
||||
out = new0(unsigned long, DIV_ROUND_UP(policy->nodes.allocated, sizeof(unsigned long)));
|
||||
if (!out)
|
||||
return -ENOMEM;
|
||||
|
||||
/* We don't make any assumptions about internal type libc is using to store NUMA node mask.
|
||||
Hence we need to convert the node mask to the representation expected by set_mempolicy() */
|
||||
for (node = 0; node < bits; node++)
|
||||
if (CPU_ISSET_S(node, policy->nodes.allocated, policy->nodes.set))
|
||||
out[node / ulong_bits] |= 1ul << (node % ulong_bits);
|
||||
|
||||
*ret_nodes = TAKE_PTR(out);
|
||||
*ret_maxnode = bits + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int apply_numa_policy(const NUMAPolicy *policy) {
|
||||
int r;
|
||||
_cleanup_free_ unsigned long *nodes = NULL;
|
||||
unsigned long maxnode;
|
||||
|
||||
assert(policy);
|
||||
|
||||
if (get_mempolicy(NULL, NULL, 0, 0, 0) < 0 && errno == ENOSYS)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!numa_policy_is_valid(policy))
|
||||
return -EINVAL;
|
||||
|
||||
r = numa_policy_to_mempolicy(policy, &maxnode, &nodes);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = set_mempolicy(numa_policy_get_type(policy), nodes, maxnode);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* const mpol_table[] = {
|
||||
[MPOL_DEFAULT] = "default",
|
||||
[MPOL_PREFERRED] = "preferred",
|
||||
[MPOL_BIND] = "bind",
|
||||
[MPOL_INTERLEAVE] = "interleave",
|
||||
[MPOL_LOCAL] = "local",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(mpol, int);
|
||||
|
@ -49,30 +49,3 @@ int cpu_set_to_dbus(const CPUSet *set, uint8_t **ret, size_t *allocated);
|
||||
int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set);
|
||||
|
||||
int cpus_in_affinity_mask(void);
|
||||
|
||||
static inline bool mpol_is_valid(int t) {
|
||||
return t >= MPOL_DEFAULT && t <= MPOL_LOCAL;
|
||||
}
|
||||
|
||||
typedef struct NUMAPolicy {
|
||||
/* Always use numa_policy_get_type() to read the value */
|
||||
int type;
|
||||
CPUSet nodes;
|
||||
} NUMAPolicy;
|
||||
|
||||
bool numa_policy_is_valid(const NUMAPolicy *p);
|
||||
|
||||
static inline int numa_policy_get_type(const NUMAPolicy *p) {
|
||||
return p->type < 0 ? (p->nodes.set ? MPOL_PREFERRED : -1) : p->type;
|
||||
}
|
||||
|
||||
static inline void numa_policy_reset(NUMAPolicy *p) {
|
||||
assert(p);
|
||||
cpu_set_reset(&p->nodes);
|
||||
p->type = -1;
|
||||
}
|
||||
|
||||
int apply_numa_policy(const NUMAPolicy *policy);
|
||||
|
||||
const char* mpol_to_string(int i) _const_;
|
||||
int mpol_from_string(const char *s) _pure_;
|
||||
|
@ -147,6 +147,8 @@ shared_sources = files('''
|
||||
nscd-flush.h
|
||||
nsflags.c
|
||||
nsflags.h
|
||||
numa-util.c
|
||||
numa-util.h
|
||||
openssl-util.h
|
||||
os-util.c
|
||||
os-util.h
|
||||
|
135
src/shared/numa-util.c
Normal file
135
src/shared/numa-util.c
Normal file
@ -0,0 +1,135 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "cpu-set-util.h"
|
||||
#include "fileio.h"
|
||||
#include "macro.h"
|
||||
#include "missing_syscall.h"
|
||||
#include "numa-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "string-table.h"
|
||||
|
||||
bool numa_policy_is_valid(const NUMAPolicy *policy) {
|
||||
assert(policy);
|
||||
|
||||
if (!mpol_is_valid(numa_policy_get_type(policy)))
|
||||
return false;
|
||||
|
||||
if (!policy->nodes.set &&
|
||||
!IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL, MPOL_PREFERRED))
|
||||
return false;
|
||||
|
||||
if (policy->nodes.set &&
|
||||
numa_policy_get_type(policy) == MPOL_PREFERRED &&
|
||||
CPU_COUNT_S(policy->nodes.allocated, policy->nodes.set) != 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int numa_policy_to_mempolicy(const NUMAPolicy *policy, unsigned long *ret_maxnode, unsigned long **ret_nodes) {
|
||||
unsigned node, bits = 0, ulong_bits;
|
||||
_cleanup_free_ unsigned long *out = NULL;
|
||||
|
||||
assert(policy);
|
||||
assert(ret_maxnode);
|
||||
assert(ret_nodes);
|
||||
|
||||
if (IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL) ||
|
||||
(numa_policy_get_type(policy) == MPOL_PREFERRED && !policy->nodes.set)) {
|
||||
*ret_nodes = NULL;
|
||||
*ret_maxnode = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bits = policy->nodes.allocated * 8;
|
||||
ulong_bits = sizeof(unsigned long) * 8;
|
||||
|
||||
out = new0(unsigned long, DIV_ROUND_UP(policy->nodes.allocated, sizeof(unsigned long)));
|
||||
if (!out)
|
||||
return -ENOMEM;
|
||||
|
||||
/* We don't make any assumptions about internal type libc is using to store NUMA node mask.
|
||||
Hence we need to convert the node mask to the representation expected by set_mempolicy() */
|
||||
for (node = 0; node < bits; node++)
|
||||
if (CPU_ISSET_S(node, policy->nodes.allocated, policy->nodes.set))
|
||||
out[node / ulong_bits] |= 1ul << (node % ulong_bits);
|
||||
|
||||
*ret_nodes = TAKE_PTR(out);
|
||||
*ret_maxnode = bits + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int apply_numa_policy(const NUMAPolicy *policy) {
|
||||
int r;
|
||||
_cleanup_free_ unsigned long *nodes = NULL;
|
||||
unsigned long maxnode;
|
||||
|
||||
assert(policy);
|
||||
|
||||
if (get_mempolicy(NULL, NULL, 0, 0, 0) < 0 && errno == ENOSYS)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!numa_policy_is_valid(policy))
|
||||
return -EINVAL;
|
||||
|
||||
r = numa_policy_to_mempolicy(policy, &maxnode, &nodes);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = set_mempolicy(numa_policy_get_type(policy), nodes, maxnode);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int numa_to_cpu_set(const NUMAPolicy *policy, CPUSet *ret) {
|
||||
int r;
|
||||
size_t i;
|
||||
_cleanup_(cpu_set_reset) CPUSet s = {};
|
||||
|
||||
assert(policy);
|
||||
assert(ret);
|
||||
|
||||
for (i = 0; i < policy->nodes.allocated * 8; i++) {
|
||||
_cleanup_free_ char *l = NULL;
|
||||
char p[STRLEN("/sys/devices/system/node/node//cpulist") + DECIMAL_STR_MAX(size_t) + 1];
|
||||
_cleanup_(cpu_set_reset) CPUSet part = {};
|
||||
|
||||
if (!CPU_ISSET_S(i, policy->nodes.allocated, policy->nodes.set))
|
||||
continue;
|
||||
|
||||
xsprintf(p, "/sys/devices/system/node/node%zu/cpulist", i);
|
||||
|
||||
r = read_one_line_file(p, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = parse_cpu_set(l, &part);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = cpu_set_add_all(&s, &part);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = s;
|
||||
s = (CPUSet) {};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* const mpol_table[] = {
|
||||
[MPOL_DEFAULT] = "default",
|
||||
[MPOL_PREFERRED] = "preferred",
|
||||
[MPOL_BIND] = "bind",
|
||||
[MPOL_INTERLEAVE] = "interleave",
|
||||
[MPOL_LOCAL] = "local",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(mpol, int);
|
33
src/shared/numa-util.h
Normal file
33
src/shared/numa-util.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include "cpu-set-util.h"
|
||||
#include "missing_syscall.h"
|
||||
|
||||
static inline bool mpol_is_valid(int t) {
|
||||
return t >= MPOL_DEFAULT && t <= MPOL_LOCAL;
|
||||
}
|
||||
|
||||
typedef struct NUMAPolicy {
|
||||
/* Always use numa_policy_get_type() to read the value */
|
||||
int type;
|
||||
CPUSet nodes;
|
||||
} NUMAPolicy;
|
||||
|
||||
bool numa_policy_is_valid(const NUMAPolicy *p);
|
||||
|
||||
static inline int numa_policy_get_type(const NUMAPolicy *p) {
|
||||
return p->type < 0 ? (p->nodes.set ? MPOL_PREFERRED : -1) : p->type;
|
||||
}
|
||||
|
||||
static inline void numa_policy_reset(NUMAPolicy *p) {
|
||||
assert(p);
|
||||
cpu_set_reset(&p->nodes);
|
||||
p->type = -1;
|
||||
}
|
||||
|
||||
int apply_numa_policy(const NUMAPolicy *policy);
|
||||
int numa_to_cpu_set(const NUMAPolicy *policy, CPUSet *set);
|
||||
|
||||
const char* mpol_to_string(int i) _const_;
|
||||
int mpol_from_string(const char *s) _pure_;
|
@ -125,11 +125,12 @@ int xdg_user_dirs(char ***ret_config_dirs, char ***ret_data_dirs) {
|
||||
_cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
|
||||
|
||||
e = getenv("XDG_CONFIG_DIRS");
|
||||
if (e) {
|
||||
if (e)
|
||||
config_dirs = strv_split(e, ":");
|
||||
if (!config_dirs)
|
||||
return -ENOMEM;
|
||||
}
|
||||
else
|
||||
config_dirs = strv_new("/etc/xdg");
|
||||
if (!config_dirs)
|
||||
return -ENOMEM;
|
||||
|
||||
e = getenv("XDG_DATA_DIRS");
|
||||
if (e)
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include "main-func.h"
|
||||
#include "memory-util.h"
|
||||
#include "mkdir.h"
|
||||
#include "numa-util.h"
|
||||
#include "pager.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-lookup.h"
|
||||
|
@ -216,12 +216,12 @@ static void test_parse_cpu_set_extend(void) {
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(parse_cpu_set_extend("1 3", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
|
||||
assert_se(parse_cpu_set_extend("1 3", &c, true, NULL, "fake", 1, "CPUAffinity") == 1);
|
||||
assert_se(CPU_COUNT_S(c.allocated, c.set) == 2);
|
||||
assert_se(s1 = cpu_set_to_string(&c));
|
||||
log_info("cpu_set_to_string: %s", s1);
|
||||
|
||||
assert_se(parse_cpu_set_extend("4", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
|
||||
assert_se(parse_cpu_set_extend("4", &c, true, NULL, "fake", 1, "CPUAffinity") == 1);
|
||||
assert_se(CPU_COUNT_S(c.allocated, c.set) == 3);
|
||||
assert_se(s2 = cpu_set_to_string(&c));
|
||||
log_info("cpu_set_to_string: %s", s2);
|
||||
@ -238,7 +238,7 @@ static void test_cpu_set_to_from_dbus(void) {
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(parse_cpu_set_extend("1 3 8 100-200", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
|
||||
assert_se(parse_cpu_set_extend("1 3 8 100-200", &c, true, NULL, "fake", 1, "CPUAffinity") == 1);
|
||||
assert_se(s = cpu_set_to_string(&c));
|
||||
log_info("cpu_set_to_string: %s", s);
|
||||
assert_se(CPU_COUNT_S(c.allocated, c.set) == 104);
|
||||
|
@ -96,7 +96,7 @@ static void test_valid_user_group_name_compat(void) {
|
||||
assert_se(valid_user_group_name_compat("eff."));
|
||||
|
||||
assert_se(valid_user_group_name_compat("some5"));
|
||||
assert_se(!valid_user_group_name_compat("5some"));
|
||||
assert_se(valid_user_group_name_compat("5some"));
|
||||
assert_se(valid_user_group_name_compat("INNER5NUMBER"));
|
||||
}
|
||||
|
||||
@ -166,7 +166,7 @@ static void test_valid_user_group_name_or_id_compat(void) {
|
||||
assert_se(valid_user_group_name_or_id_compat("kk-k"));
|
||||
|
||||
assert_se(valid_user_group_name_or_id_compat("some5"));
|
||||
assert_se(!valid_user_group_name_or_id_compat("5some"));
|
||||
assert_se(valid_user_group_name_or_id_compat("5some"));
|
||||
assert_se(valid_user_group_name_or_id_compat("INNER5NUMBER"));
|
||||
}
|
||||
|
||||
|
@ -763,7 +763,7 @@ static int run(int argc, char *argv[]) {
|
||||
if (parent <= 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Parent already died?");
|
||||
|
||||
if (kill(parent, SIGUSR1) < 0)
|
||||
if (kill(parent, SIGUSR2) < 0)
|
||||
return log_error_errno(errno, "Failed to kill our own parent.");
|
||||
}
|
||||
}
|
||||
|
@ -279,6 +279,18 @@ else
|
||||
# Maks must be ignored
|
||||
grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
|
||||
|
||||
echo "Unit file CPUAffinity=NUMA support"
|
||||
writeTestUnitNUMAPolicy "bind" "0"
|
||||
echo "CPUAffinity=numa" >> $testUnitNUMAConf
|
||||
systemctl daemon-reload
|
||||
systemctl start $testUnit
|
||||
systemctlCheckNUMAProperties $testUnit "bind" "0"
|
||||
pid=$(systemctl show --value -p MainPID $testUnit)
|
||||
cpulist=$(cat /sys/devices/system/node/node0/cpulist)
|
||||
affinity_systemd=$(systemctl show --value -p CPUAffinity $testUnit)
|
||||
[ $cpulist = $affinity_systemd ]
|
||||
pid1StopUnit $testUnit
|
||||
|
||||
echo "systemd-run NUMAPolicy support"
|
||||
runUnit='numa-systemd-run-test.service'
|
||||
|
||||
@ -309,6 +321,12 @@ else
|
||||
systemd-run -p NUMAPolicy=local -p NUMAMask=0 --unit $runUnit sleep 1000
|
||||
systemctlCheckNUMAProperties $runUnit "local" ""
|
||||
pid1StopUnit $runUnit
|
||||
|
||||
systemd-run -p NUMAPolicy=local -p NUMAMask=0 -p CPUAffinity=numa --unit $runUnit sleep 1000
|
||||
systemctlCheckNUMAProperties $runUnit "local" ""
|
||||
systemctl cat $runUnit | grep -q 'CPUAffinity=numa'
|
||||
pid1StopUnit $runUnit
|
||||
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
|
@ -12,6 +12,7 @@ Description=Kernel Trace File System
|
||||
Documentation=https://www.kernel.org/doc/Documentation/trace/ftrace.txt
|
||||
Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
|
||||
DefaultDependencies=no
|
||||
ConditionVirtualization=!lxc
|
||||
ConditionPathExists=/sys/kernel/tracing
|
||||
ConditionCapability=CAP_SYS_RAWIO
|
||||
Before=sysinit.target
|
||||
|
@ -10,7 +10,7 @@
|
||||
[Unit]
|
||||
Description=Home Area Manager
|
||||
Documentation=man:systemd-homed.service(8)
|
||||
RequiresMountsFor=/home
|
||||
After=home.mount
|
||||
|
||||
[Service]
|
||||
BusName=org.freedesktop.home1
|
||||
|
Loading…
Reference in New Issue
Block a user