mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 08:56:15 +09:00
Merge pull request #33823 from YHNdnzj/varlink-deserialize-again
core: reliably check if varlink socket has been deserialized; switch varlink server to pidref
This commit is contained in:
@@ -7,8 +7,10 @@
|
||||
#include "mkdir-label.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
#include "varlink-internal.h"
|
||||
#include "varlink-io.systemd.UserDatabase.h"
|
||||
#include "varlink-io.systemd.ManagedOOM.h"
|
||||
#include "varlink-util.h"
|
||||
|
||||
typedef struct LookupParameters {
|
||||
const char *user_name;
|
||||
@@ -217,19 +219,18 @@ static int vl_method_subscribe_managed_oom_cgroups(
|
||||
sd_varlink_method_flags_t flags,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
pid_t pid;
|
||||
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
|
||||
Unit *u;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
r = sd_varlink_get_peer_pid(link, &pid);
|
||||
r = varlink_get_peer_pidref(link, &pidref);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
u = manager_get_unit_by_pid(m, pid);
|
||||
u = manager_get_unit_by_pidref(m, &pidref);
|
||||
if (!u)
|
||||
return sd_varlink_error(link, SD_VARLINK_ERROR_PERMISSION_DENIED, NULL);
|
||||
|
||||
@@ -246,6 +247,8 @@ static int vl_method_subscribe_managed_oom_cgroups(
|
||||
if (FLAGS_SET(flags, SD_VARLINK_METHOD_MORE) && m->managed_oom_varlink)
|
||||
return sd_varlink_error(link, "io.systemd.ManagedOOM.SubscriptionTaken", NULL);
|
||||
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
|
||||
r = build_managed_oom_cgroups_json(m, &v);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -500,12 +503,17 @@ static void vl_disconnect(sd_varlink_server *s, sd_varlink *link, void *userdata
|
||||
m->managed_oom_varlink = sd_varlink_unref(link);
|
||||
}
|
||||
|
||||
static int manager_setup_varlink_server(Manager *m, sd_varlink_server **ret) {
|
||||
int manager_setup_varlink_server(Manager *m) {
|
||||
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *s = NULL;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(ret);
|
||||
|
||||
if (m->varlink_server)
|
||||
return 0;
|
||||
|
||||
if (!MANAGER_IS_SYSTEM(m))
|
||||
return -EINVAL;
|
||||
|
||||
r = sd_varlink_server_new(&s, SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA);
|
||||
if (r < 0)
|
||||
@@ -533,51 +541,51 @@ static int manager_setup_varlink_server(Manager *m, sd_varlink_server **ret) {
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to register varlink disconnect handler: %m");
|
||||
|
||||
*ret = TAKE_PTR(s);
|
||||
return 0;
|
||||
r = sd_varlink_server_attach_event(s, m->event, EVENT_PRIORITY_IPC);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to attach varlink connection to event loop: %m");
|
||||
|
||||
m->varlink_server = TAKE_PTR(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int manager_varlink_init_system(Manager *m) {
|
||||
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *s = NULL;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
if (m->varlink_server)
|
||||
return 1;
|
||||
|
||||
if (!MANAGER_IS_SYSTEM(m))
|
||||
return 0;
|
||||
|
||||
r = manager_setup_varlink_server(m, &s);
|
||||
r = manager_setup_varlink_server(m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set up varlink server: %m");
|
||||
bool fresh = r > 0;
|
||||
|
||||
if (!MANAGER_IS_TEST_RUN(m)) {
|
||||
(void) mkdir_p_label("/run/systemd/userdb", 0755);
|
||||
|
||||
FOREACH_STRING(address, "/run/systemd/userdb/io.systemd.DynamicUser", VARLINK_ADDR_PATH_MANAGED_OOM_SYSTEM) {
|
||||
if (MANAGER_IS_RELOADING(m)) {
|
||||
/* If manager is reloading, we skip listening on existing addresses, since
|
||||
* the fd should be acquired later through deserialization. */
|
||||
if (access(address, F_OK) >= 0)
|
||||
if (!fresh) {
|
||||
/* We might have got sockets through deserialization. Do not bind to them twice. */
|
||||
|
||||
bool found = false;
|
||||
LIST_FOREACH(sockets, ss, m->varlink_server->sockets)
|
||||
if (path_equal(ss->address, address)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (found)
|
||||
continue;
|
||||
if (errno != ENOENT)
|
||||
return log_error_errno(errno,
|
||||
"Failed to check if varlink socket '%s' exists: %m", address);
|
||||
}
|
||||
|
||||
r = sd_varlink_server_listen_address(s, address, 0666);
|
||||
r = sd_varlink_server_listen_address(m->varlink_server, address, 0666);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind to varlink socket '%s': %m", address);
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_varlink_server_attach_event(s, m->event, EVENT_PRIORITY_IPC);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
|
||||
|
||||
m->varlink_server = TAKE_PTR(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -613,17 +621,21 @@ static int manager_varlink_init_user(Manager *m) {
|
||||
if (m->managed_oom_varlink)
|
||||
return 1;
|
||||
|
||||
if (!MANAGER_IS_USER(m))
|
||||
return 0;
|
||||
|
||||
if (MANAGER_IS_TEST_RUN(m))
|
||||
return 0;
|
||||
|
||||
r = sd_varlink_connect_address(&link, VARLINK_ADDR_PATH_MANAGED_OOM_USER);
|
||||
if (r < 0) {
|
||||
if (r == -ENOENT || ERRNO_IS_DISCONNECT(r)) {
|
||||
log_debug("systemd-oomd varlink unix socket not found, skipping user manager varlink setup");
|
||||
return 0;
|
||||
}
|
||||
return log_error_errno(r, "Failed to connect to %s: %m", VARLINK_ADDR_PATH_MANAGED_OOM_USER);
|
||||
if (r == -ENOENT)
|
||||
return 0;
|
||||
if (ERRNO_IS_NEG_DISCONNECT(r)) {
|
||||
log_debug_errno(r, "systemd-oomd varlink socket isn't available, skipping user manager varlink setup: %m");
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to '%s': %m", VARLINK_ADDR_PATH_MANAGED_OOM_USER);
|
||||
|
||||
sd_varlink_set_userdata(link, m);
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "manager.h"
|
||||
|
||||
int manager_setup_varlink_server(Manager *m);
|
||||
|
||||
int manager_varlink_init(Manager *m);
|
||||
void manager_varlink_done(Manager *m);
|
||||
|
||||
|
||||
@@ -508,7 +508,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||
return r;
|
||||
} else if ((val = startswith(l, "varlink-server-socket-address="))) {
|
||||
if (!m->varlink_server && MANAGER_IS_SYSTEM(m)) {
|
||||
r = manager_varlink_init(m);
|
||||
r = manager_setup_varlink_server(m);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to setup varlink server, ignoring: %m");
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user