10#include "ublk/detail/retry.hpp"
15#include <system_error>
20struct control_get_dev_info_t {
21 template <
typename Sched,
typename Alloc>
22 ex::task<void, TaskEnv<Sched, Alloc>> invoke(
int fd, uint32_t dev_id,
23 ublksrv_ctrl_dev_info *info) {
24 DevPathBuf<ublksrv_ctrl_dev_info> buf(dev_id);
25 bool ok =
co_await retry<Sched, Alloc>(
26 [&]() -> ex::task<
bool, TaskEnv<Sched, Alloc>> {
30 ex::upon_error([](std::error_code ec)
noexcept {
40 if (r == -EOPNOTSUPP) {
44 throw std::system_error(-r, std::generic_category(),
49 throw std::system_error(EACCES, std::generic_category(),
55template <
typename Sched,
typename Alloc>
56inline ex::task<void, TaskEnv<Sched, Alloc>>
57cached_get_dev_info(
int fd, uint32_t dev_id, ublksrv_ctrl_dev_info *info) {
59 if (dev_info && dev_info->dev_id == dev_id) {
63 co_await control_get_dev_info_t{}.invoke<Sched, Alloc>(fd, dev_id, info);
66struct control_get_queue_affinity_t {
67 template <
typename Sched,
typename Alloc>
68 ex::task<void, TaskEnv<Sched, Alloc>>
69 invoke(
int control_fd, uint32_t dev_id, uint16_t q_id, cpu_set_t *cpuset) {
70 ublksrv_ctrl_dev_info info;
71 co_await cached_get_dev_info<Sched, Alloc>(control_fd, dev_id, &info);
72 if (info.flags & UBLK_F_UNPRIVILEGED_DEV) {
73 DevPathBuf<cpu_set_t> buf(dev_id);
75 sizeof(buf), DEV_PATH_LEN);
76 *cpuset = buf.payload;
83template <
typename Sched,
typename Alloc,
typename Fn>
84inline ex::task<void, TaskEnv<Sched, Alloc>>
85with_dev_path(
int control_fd, uint32_t dev_id, Fn fn) {
86 ublksrv_ctrl_dev_info info;
87 char path[DEV_PATH_LEN];
88 fill_dev_path(path,
sizeof(path), dev_id);
89 auto s = cached_get_dev_info<Sched, Alloc>(control_fd, dev_id, &info) |
90 ex::let_value([&, fn = std::move(fn)]()
noexcept(
91 noexcept(std::move(fn)(path, DEV_PATH_LEN))) {
92 if (info.flags & UBLK_F_UNPRIVILEGED_DEV) {
93 return std::move(fn)(path, DEV_PATH_LEN);
95 return std::move(fn)(
nullptr, 0);
98 co_await std::move(s);
101struct control_del_dev_t {
102 template <
typename Sched,
typename Alloc>
103 auto invoke(
int control_fd, uint32_t dev_id) {
104 return with_dev_path<Sched, Alloc>(
105 control_fd, dev_id, [=](
char *path, uint16_t len)
noexcept {
111struct control_start_dev_t {
112 template <
typename Sched,
typename Alloc>
113 auto invoke(
int control_fd, uint32_t dev_id, int32_t daemon_pid) {
114 return with_dev_path<Sched, Alloc>(
115 control_fd, dev_id, [=](
char *path, uint16_t len)
noexcept {
122struct control_stop_dev_t {
123 template <
typename Sched,
typename Alloc>
124 auto invoke(
int control_fd, uint32_t dev_id) {
125 return with_dev_path<Sched, Alloc>(
126 control_fd, dev_id, [=](
char *path, uint16_t len)
noexcept {
132struct control_set_params_t {
133 template <
typename Sched,
typename Alloc>
134 ex::task<void, TaskEnv<Sched, Alloc>>
135 invoke(
int control_fd, uint32_t dev_id,
const ublk_params *params) {
136 ublksrv_ctrl_dev_info info;
137 co_await cached_get_dev_info<Sched, Alloc>(control_fd, dev_id, &info);
138 ublk_params full = *params;
139 full.len =
sizeof(full);
140 if (info.flags & UBLK_F_UNPRIVILEGED_DEV) {
141 DevPathBuf<ublk_params> buf(dev_id);
151struct control_get_params_t {
152 template <
typename Sched,
typename Alloc>
153 ex::task<void, TaskEnv<Sched, Alloc>>
154 invoke(
int control_fd, uint32_t dev_id, ublk_params *params) {
155 ublksrv_ctrl_dev_info info;
156 co_await cached_get_dev_info<Sched, Alloc>(control_fd, dev_id, &info);
157 params->len =
sizeof(*params);
158 if (info.flags & UBLK_F_UNPRIVILEGED_DEV) {
159 DevPathBuf<ublk_params> buf(dev_id);
160 buf.payload.len =
sizeof(buf.payload);
163 *params = buf.payload;
170struct control_start_user_recovery_t {
171 template <
typename Sched,
typename Alloc>
172 auto invoke(
int control_fd, uint32_t dev_id) {
173 return with_dev_path<Sched, Alloc>(
174 control_fd, dev_id, [=](
char *path, uint16_t len)
noexcept {
180struct control_end_user_recovery_t {
181 template <
typename Sched,
typename Alloc>
182 auto invoke(
int control_fd, uint32_t dev_id, int32_t daemon_pid) {
183 return with_dev_path<Sched, Alloc>(
184 control_fd, dev_id, [=](
char *path, uint16_t len)
noexcept {
191struct control_del_dev_async_t {
192 template <
typename Sched,
typename Alloc>
193 auto invoke(
int control_fd, uint32_t dev_id) {
194 return with_dev_path<Sched, Alloc>(
195 control_fd, dev_id, [=](
char *path, uint16_t len)
noexcept {
201struct control_update_size_t {
202 template <
typename Sched,
typename Alloc>
203 auto invoke(
int control_fd, uint32_t dev_id, uint64_t sectors) {
204 return with_dev_path<Sched, Alloc>(
205 control_fd, dev_id, [=](
char *path, uint16_t len)
noexcept {
211struct control_quiesce_dev_t {
212 template <
typename Sched,
typename Alloc>
213 auto invoke(
int control_fd, uint32_t dev_id, uint64_t timeout_ms) {
214 return with_dev_path<Sched, Alloc>(
215 control_fd, dev_id, [=](
char *path, uint16_t len)
noexcept {
222struct control_try_stop_dev_t {
223 template <
typename Sched,
typename Alloc>
224 auto invoke(
int control_fd, uint32_t dev_id) {
225 return with_dev_path<Sched, Alloc>(
226 control_fd, dev_id, [=](
char *path, uint16_t len)
noexcept {
232struct control_register_shm_buf_t {
233 template <
typename Sched,
typename Alloc>
234 ex::task<int32_t, TaskEnv<Sched, Alloc>>
235 invoke(
int control_fd, uint32_t dev_id,
const ublk_shmem_buf_reg *reg) {
236 ublksrv_ctrl_dev_info info;
237 co_await cached_get_dev_info<Sched, Alloc>(control_fd, dev_id, &info);
238 if (info.flags & UBLK_F_UNPRIVILEGED_DEV) {
239 DevPathBuf<ublk_shmem_buf_reg> buf(dev_id);
242 sizeof(buf), DEV_PATH_LEN);
249struct control_unregister_shm_buf_t {
250 template <
typename Sched,
typename Alloc>
251 auto invoke(
int control_fd, uint32_t dev_id, uint64_t buf_index) {
252 return with_dev_path<Sched, Alloc>(
253 control_fd, dev_id, [=](
char *path, uint16_t len)
noexcept {
The std::execution backend namespace used by ublk-cpp.
auto start_user_recovery(Fd fd, uint32_t dev_id, const char *dev_path, uint16_t dev_path_len) noexcept
Unprivileged version of start_user_recovery().
auto update_size(Fd fd, uint32_t dev_id, uint64_t sectors, const char *dev_path, uint16_t dev_path_len) noexcept
Unprivileged version of update_size().
auto end_user_recovery(Fd fd, uint32_t dev_id, int32_t daemon_pid, const char *dev_path, uint16_t dev_path_len) noexcept
Unprivileged version of end_user_recovery().
auto set_params(Fd fd, uint32_t dev_id, const void *data, uint16_t size, uint16_t dev_path_len) noexcept
Unprivileged version of set_params().
auto quiesce_dev(Fd fd, uint32_t dev_id, uint64_t timeout_ms, const char *dev_path, uint16_t dev_path_len) noexcept
Unprivileged version of quiesce_dev().
auto start_dev(Fd fd, uint32_t dev_id, int32_t daemon_pid, const char *dev_path, uint16_t dev_path_len) noexcept
Unprivileged version of start_dev().
auto register_shm_buf(Fd fd, uint32_t dev_id, const void *data, uint16_t size, uint16_t dev_path_len) noexcept
Unprivileged version of register_shm_buf().
auto try_stop_dev(Fd fd, uint32_t dev_id, const char *dev_path, uint16_t dev_path_len) noexcept
Unprivileged version of try_stop_dev().
auto del_dev_async(Fd fd, uint32_t dev_id, const char *dev_path, uint16_t dev_path_len) noexcept
Unprivileged version of del_dev_async().
auto unregister_shm_buf(Fd fd, uint32_t dev_id, uint64_t buf_index, const char *dev_path, uint16_t dev_path_len) noexcept
Unprivileged version of unregister_shm_buf().
auto get_dev_info(Fd fd, uint32_t dev_id, void *data, uint16_t size, uint16_t dev_path_len) noexcept
Unprivileged version of get_dev_info().
auto stop_dev(Fd fd, uint32_t dev_id, const char *dev_path, uint16_t dev_path_len) noexcept
Unprivileged version of stop_dev().
auto get_dev_info2(Fd fd, uint32_t dev_id, void *data, uint16_t size, uint16_t dev_path_len) noexcept
Get the device information of a ublk device, works both for privileged and unprivileged modes.
auto del_dev(Fd fd, uint32_t dev_id, const char *dev_path, uint16_t dev_path_len) noexcept
Unprivileged version of del_dev().
auto get_params(Fd fd, uint32_t dev_id, void *data, uint16_t size, uint16_t dev_path_len) noexcept
Unprivileged version of get_params().
auto get_queue_affinity(Fd fd, uint32_t dev_id, uint16_t q_id, void *data, uint16_t size, uint16_t dev_path_len) noexcept
Unprivileged version of get_queue_affinity().
The main namespace of the ublk-cpp library.
constexpr fetch_dev_info_t fetch_dev_info
Query object instance of fetch_dev_info_t.
Low-level io_uring command senders for ublk control and I/O commands.