Add helpers for talking to /dev/liveupdate
This character device is the main kernel interface to deal with the Live Update Orchestrator (LUO) feature. Add some basic wrappers for the ioctls. https://docs.kernel.org/userspace-api/liveupdate.html
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <linux/liveupdate.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "luo-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
/* Kernel API defined at https://docs.kernel.org/userspace-api/liveupdate.html The /dev/liveupdate is a
|
||||
* single-owner singleton, only a single process at any given time can open it. Callers can create named
|
||||
* "sessions", and then add FDs to them. The session name can be used to retrieve the session after reboot.
|
||||
* To identify an FD, a 64bit token (what we would call an 'index' in our codebase) is passed in, and the
|
||||
* caller is responsible for coming up with the token and tracking them. */
|
||||
|
||||
int luo_open_device(void) {
|
||||
return RET_NERRNO(open("/dev/liveupdate", O_RDWR|O_CLOEXEC));
|
||||
}
|
||||
|
||||
int luo_create_session(int device_fd, const char *name) {
|
||||
struct liveupdate_ioctl_create_session args = {
|
||||
.size = sizeof(args),
|
||||
.fd = -EBADF,
|
||||
};
|
||||
|
||||
assert(device_fd >= 0);
|
||||
assert(name);
|
||||
|
||||
if (strlen(name) >= sizeof(args.name))
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
strncpy_exact((char *) args.name, name, sizeof(args.name));
|
||||
|
||||
if (ioctl(device_fd, LIVEUPDATE_IOCTL_CREATE_SESSION, &args) < 0)
|
||||
return -errno;
|
||||
|
||||
return args.fd;
|
||||
}
|
||||
|
||||
int luo_retrieve_session(int device_fd, const char *name) {
|
||||
struct liveupdate_ioctl_retrieve_session args = {
|
||||
.size = sizeof(args),
|
||||
.fd = -EBADF,
|
||||
};
|
||||
|
||||
assert(device_fd >= 0);
|
||||
assert(name);
|
||||
|
||||
if (strlen(name) >= sizeof(args.name))
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
strncpy_exact((char *) args.name, name, sizeof(args.name));
|
||||
|
||||
if (ioctl(device_fd, LIVEUPDATE_IOCTL_RETRIEVE_SESSION, &args) < 0)
|
||||
return -errno;
|
||||
|
||||
return args.fd;
|
||||
}
|
||||
|
||||
int luo_session_preserve_fd(int session_fd, int fd, uint64_t token) {
|
||||
struct liveupdate_session_preserve_fd args = {
|
||||
.size = sizeof(args),
|
||||
.fd = fd,
|
||||
.token = token,
|
||||
};
|
||||
|
||||
assert(session_fd >= 0);
|
||||
assert(fd >= 0);
|
||||
|
||||
return RET_NERRNO(ioctl(session_fd, LIVEUPDATE_SESSION_PRESERVE_FD, &args));
|
||||
}
|
||||
|
||||
int luo_session_retrieve_fd(int session_fd, uint64_t token) {
|
||||
struct liveupdate_session_retrieve_fd args = {
|
||||
.size = sizeof(args),
|
||||
.fd = -EBADF,
|
||||
.token = token,
|
||||
};
|
||||
int r;
|
||||
|
||||
assert(session_fd >= 0);
|
||||
|
||||
if (ioctl(session_fd, LIVEUPDATE_SESSION_RETRIEVE_FD, &args) < 0)
|
||||
return -errno;
|
||||
|
||||
r = fd_cloexec(args.fd, true);
|
||||
if (r < 0) {
|
||||
safe_close(args.fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
return args.fd;
|
||||
}
|
||||
|
||||
int luo_session_finish(int session_fd) {
|
||||
struct liveupdate_session_finish args = {
|
||||
.size = sizeof(args),
|
||||
};
|
||||
|
||||
assert(session_fd >= 0);
|
||||
|
||||
return RET_NERRNO(ioctl(session_fd, LIVEUPDATE_SESSION_FINISH, &args));
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "basic-forward.h"
|
||||
|
||||
int luo_open_device(void);
|
||||
int luo_create_session(int device_fd, const char *name);
|
||||
int luo_retrieve_session(int device_fd, const char *name);
|
||||
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);
|
||||
@@ -129,6 +129,7 @@ shared_sources = files(
|
||||
'loop-util.c',
|
||||
'loopback-setup.c',
|
||||
'lsm-util.c',
|
||||
'luo-util.c',
|
||||
'machine-bind-user.c',
|
||||
'machine-credential.c',
|
||||
'machine-id-setup.c',
|
||||
|
||||
Reference in New Issue
Block a user