core: add LUOSession= unit setting

Acquiring a LUO session from /dev/liveupdate requires privileges,
and also the device is a single-owner driver so only a single
process can open it at any given time.

Add a LUOSession= service settings that allows units running
without privileges to get a session assigned to them.

The kernel imposes a 64 chars limit on session names, which is
too short to avoid clashes, so derive a hash from joining the
unit name with the parameter name, that way two units using
the same setting don't clash.
This commit is contained in:
Luca Boccassi
2026-06-17 13:11:15 +01:00
parent 9404fa70df
commit 82b8615463
13 changed files with 344 additions and 3 deletions
+1
View File
@@ -2688,6 +2688,7 @@ static const BusProperty service_properties[] = {
{ "TimeoutStartFailureMode", bus_append_string },
{ "TimeoutStopFailureMode", bus_append_string },
{ "FileDescriptorStorePreserve", bus_append_string },
{ "LUOSession", bus_append_strv },
{ "PermissionsStartOnly", bus_append_parse_boolean },
{ "RootDirectoryStartOnly", bus_append_parse_boolean },
{ "RemainAfterExit", bus_append_parse_boolean },
+5
View File
@@ -115,6 +115,11 @@ int luo_session_finish(int session_fd) {
return RET_NERRNO(ioctl(session_fd, LIVEUPDATE_SESSION_FINISH, &args));
}
bool luo_session_name_is_valid(const char *name) {
/* Used for FDNAME: no whitespace, no ":", no control characters, etc. */
return fdname_is_valid(name) && string_is_safe(name, STRING_DISALLOW_WHITESPACE);
}
int luo_parse_serialization(sd_json_variant **ret, int **ret_fds, size_t *ret_n_fds) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *root = NULL;
_cleanup_free_ int *fd_list = NULL;
+2
View File
@@ -36,6 +36,8 @@ int luo_session_preserve_fd(int session_fd, int fd, uint64_t token);
int luo_session_retrieve_fd(int session_fd, uint64_t token);
int luo_session_finish(int session_fd);
bool luo_session_name_is_valid(const char *name);
int luo_parse_serialization(sd_json_variant **ret, int **ret_fds, size_t *ret_n_fds);
int luo_preserve_fd_stores(sd_json_variant *serialization, int *ret_session_fd);