xref: /linux/tools/testing/selftests/ublk/kublk.c (revision 55ab7e14222e5f0b0fd9f7711ca391d2924b35e3)
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Description: uring_cmd based ublk
4  */
5 
6 #include <linux/fs.h>
7 #include <sys/un.h>
8 #include "kublk.h"
9 
10 #define MAX_NR_TGT_ARG 	64
11 #define KUBLK_PARAM_LOGICAL_BS_SHIFT		9
12 #define KUBLK_PARAM_PHYSICAL_BS_SHIFT		12
13 #define KUBLK_PARAM_ZONE_SECTORS		128
14 #define KUBLK_PARAM_NR_ZONES			16
15 #define KUBLK_PARAM_DEV_SECTORS			\
16 	(KUBLK_PARAM_ZONE_SECTORS * KUBLK_PARAM_NR_ZONES)
17 #define KUBLK_PARAM_ZONE_APPEND_SECTORS		8
18 
19 unsigned int ublk_dbg_mask = UBLK_LOG;
20 static const struct ublk_tgt_ops *tgt_ops_list[] = {
21 	&null_tgt_ops,
22 	&loop_tgt_ops,
23 	&stripe_tgt_ops,
24 	&fault_inject_tgt_ops,
25 };
26 
ublk_find_tgt(const char * name)27 static const struct ublk_tgt_ops *ublk_find_tgt(const char *name)
28 {
29 	int i;
30 
31 	if (name == NULL)
32 		return NULL;
33 
34 	for (i = 0; i < ARRAY_SIZE(tgt_ops_list); i++)
35 		if (strcmp(tgt_ops_list[i]->name, name) == 0)
36 			return tgt_ops_list[i];
37 	return NULL;
38 }
39 
ublk_setup_ring(struct io_uring * r,int depth,int cq_depth,unsigned flags)40 static inline int ublk_setup_ring(struct io_uring *r, int depth,
41 		int cq_depth, unsigned flags)
42 {
43 	struct io_uring_params p;
44 
45 	memset(&p, 0, sizeof(p));
46 	p.flags = flags | IORING_SETUP_CQSIZE;
47 	p.cq_entries = cq_depth;
48 
49 	return io_uring_queue_init_params(depth, r, &p);
50 }
51 
ublk_ctrl_init_cmd(struct ublk_dev * dev,struct io_uring_sqe * sqe,struct ublk_ctrl_cmd_data * data)52 static void ublk_ctrl_init_cmd(struct ublk_dev *dev,
53 		struct io_uring_sqe *sqe,
54 		struct ublk_ctrl_cmd_data *data)
55 {
56 	struct ublksrv_ctrl_dev_info *info = &dev->dev_info;
57 	struct ublksrv_ctrl_cmd *cmd = (struct ublksrv_ctrl_cmd *)ublk_get_sqe_cmd(sqe);
58 
59 	sqe->fd = dev->ctrl_fd;
60 	sqe->opcode = IORING_OP_URING_CMD;
61 	sqe->ioprio = 0;
62 
63 	if (data->flags & CTRL_CMD_HAS_BUF) {
64 		cmd->addr = data->addr;
65 		cmd->len = data->len;
66 	}
67 
68 	if (data->flags & CTRL_CMD_HAS_DATA)
69 		cmd->data[0] = data->data[0];
70 
71 	cmd->dev_id = info->dev_id;
72 	cmd->queue_id = -1;
73 
74 	ublk_set_sqe_cmd_op(sqe, data->cmd_op);
75 
76 	io_uring_sqe_set_data(sqe, cmd);
77 }
78 
__ublk_ctrl_cmd(struct ublk_dev * dev,struct ublk_ctrl_cmd_data * data)79 static int __ublk_ctrl_cmd(struct ublk_dev *dev,
80 		struct ublk_ctrl_cmd_data *data)
81 {
82 	struct io_uring_sqe *sqe;
83 	struct io_uring_cqe *cqe;
84 	int ret = -EINVAL;
85 
86 	sqe = io_uring_get_sqe(&dev->ring);
87 	if (!sqe) {
88 		ublk_err("%s: can't get sqe ret %d\n", __func__, ret);
89 		return ret;
90 	}
91 
92 	ublk_ctrl_init_cmd(dev, sqe, data);
93 
94 	ret = io_uring_submit(&dev->ring);
95 	if (ret < 0) {
96 		ublk_err("uring submit ret %d\n", ret);
97 		return ret;
98 	}
99 
100 	ret = io_uring_wait_cqe(&dev->ring, &cqe);
101 	if (ret < 0) {
102 		ublk_err("wait cqe: %s\n", strerror(-ret));
103 		return ret;
104 	}
105 	io_uring_cqe_seen(&dev->ring, cqe);
106 
107 	return cqe->res;
108 }
109 
ublk_ctrl_stop_dev(struct ublk_dev * dev)110 static int ublk_ctrl_stop_dev(struct ublk_dev *dev)
111 {
112 	struct ublk_ctrl_cmd_data data = {
113 		.cmd_op	= UBLK_U_CMD_STOP_DEV,
114 	};
115 
116 	return __ublk_ctrl_cmd(dev, &data);
117 }
118 
ublk_ctrl_try_stop_dev(struct ublk_dev * dev)119 static int ublk_ctrl_try_stop_dev(struct ublk_dev *dev)
120 {
121 	struct ublk_ctrl_cmd_data data = {
122 		.cmd_op	= UBLK_U_CMD_TRY_STOP_DEV,
123 	};
124 
125 	return __ublk_ctrl_cmd(dev, &data);
126 }
127 
ublk_ctrl_start_dev(struct ublk_dev * dev,int daemon_pid)128 static int ublk_ctrl_start_dev(struct ublk_dev *dev,
129 		int daemon_pid)
130 {
131 	struct ublk_ctrl_cmd_data data = {
132 		.cmd_op	= UBLK_U_CMD_START_DEV,
133 		.flags	= CTRL_CMD_HAS_DATA,
134 	};
135 
136 	dev->dev_info.ublksrv_pid = data.data[0] = daemon_pid;
137 
138 	return __ublk_ctrl_cmd(dev, &data);
139 }
140 
ublk_ctrl_start_user_recovery(struct ublk_dev * dev)141 static int ublk_ctrl_start_user_recovery(struct ublk_dev *dev)
142 {
143 	struct ublk_ctrl_cmd_data data = {
144 		.cmd_op	= UBLK_U_CMD_START_USER_RECOVERY,
145 	};
146 
147 	return __ublk_ctrl_cmd(dev, &data);
148 }
149 
ublk_ctrl_end_user_recovery(struct ublk_dev * dev,int daemon_pid)150 static int ublk_ctrl_end_user_recovery(struct ublk_dev *dev, int daemon_pid)
151 {
152 	struct ublk_ctrl_cmd_data data = {
153 		.cmd_op	= UBLK_U_CMD_END_USER_RECOVERY,
154 		.flags	= CTRL_CMD_HAS_DATA,
155 	};
156 
157 	dev->dev_info.ublksrv_pid = data.data[0] = daemon_pid;
158 
159 	return __ublk_ctrl_cmd(dev, &data);
160 }
161 
ublk_ctrl_add_dev(struct ublk_dev * dev)162 static int ublk_ctrl_add_dev(struct ublk_dev *dev)
163 {
164 	struct ublk_ctrl_cmd_data data = {
165 		.cmd_op	= UBLK_U_CMD_ADD_DEV,
166 		.flags	= CTRL_CMD_HAS_BUF,
167 		.addr = (__u64) (uintptr_t) &dev->dev_info,
168 		.len = sizeof(struct ublksrv_ctrl_dev_info),
169 	};
170 
171 	return __ublk_ctrl_cmd(dev, &data);
172 }
173 
ublk_ctrl_del_dev(struct ublk_dev * dev)174 static int ublk_ctrl_del_dev(struct ublk_dev *dev)
175 {
176 	struct ublk_ctrl_cmd_data data = {
177 		.cmd_op = UBLK_U_CMD_DEL_DEV,
178 		.flags = 0,
179 	};
180 
181 	return __ublk_ctrl_cmd(dev, &data);
182 }
183 
ublk_ctrl_get_info(struct ublk_dev * dev)184 static int ublk_ctrl_get_info(struct ublk_dev *dev)
185 {
186 	struct ublk_ctrl_cmd_data data = {
187 		.cmd_op	= UBLK_U_CMD_GET_DEV_INFO,
188 		.flags	= CTRL_CMD_HAS_BUF,
189 		.addr = (__u64) (uintptr_t) &dev->dev_info,
190 		.len = sizeof(struct ublksrv_ctrl_dev_info),
191 	};
192 
193 	return __ublk_ctrl_cmd(dev, &data);
194 }
195 
ublk_ctrl_set_params(struct ublk_dev * dev,struct ublk_params * params)196 static int ublk_ctrl_set_params(struct ublk_dev *dev,
197 		struct ublk_params *params)
198 {
199 	struct ublk_ctrl_cmd_data data = {
200 		.cmd_op	= UBLK_U_CMD_SET_PARAMS,
201 		.flags	= CTRL_CMD_HAS_BUF,
202 		.addr = (__u64) (uintptr_t) params,
203 		.len = sizeof(*params),
204 	};
205 	params->len = sizeof(*params);
206 	return __ublk_ctrl_cmd(dev, &data);
207 }
208 
ublk_ctrl_get_params(struct ublk_dev * dev,struct ublk_params * params)209 static int ublk_ctrl_get_params(struct ublk_dev *dev,
210 		struct ublk_params *params)
211 {
212 	struct ublk_ctrl_cmd_data data = {
213 		.cmd_op	= UBLK_U_CMD_GET_PARAMS,
214 		.flags	= CTRL_CMD_HAS_BUF,
215 		.addr = (__u64)params,
216 		.len = sizeof(*params),
217 	};
218 
219 	params->len = sizeof(*params);
220 
221 	return __ublk_ctrl_cmd(dev, &data);
222 }
223 
ublk_ctrl_get_features(struct ublk_dev * dev,__u64 * features)224 static int ublk_ctrl_get_features(struct ublk_dev *dev,
225 		__u64 *features)
226 {
227 	struct ublk_ctrl_cmd_data data = {
228 		.cmd_op	= UBLK_U_CMD_GET_FEATURES,
229 		.flags	= CTRL_CMD_HAS_BUF,
230 		.addr = (__u64) (uintptr_t) features,
231 		.len = sizeof(*features),
232 	};
233 
234 	return __ublk_ctrl_cmd(dev, &data);
235 }
236 
parse_param_types(const char * arg,__u32 * types)237 static int parse_param_types(const char *arg, __u32 *types)
238 {
239 	char buf[128], *save = NULL, *tok;
240 
241 	if (strlen(arg) >= sizeof(buf))
242 		return -EINVAL;
243 
244 	strcpy(buf, arg);
245 	*types = 0;
246 	tok = strtok_r(buf, ",", &save);
247 	while (tok) {
248 		if (!strcmp(tok, "none"))
249 			;
250 		else if (!strcmp(tok, "basic"))
251 			*types |= UBLK_PARAM_TYPE_BASIC;
252 		else if (!strcmp(tok, "zoned"))
253 			*types |= UBLK_PARAM_TYPE_ZONED;
254 		else
255 			return -EINVAL;
256 		tok = strtok_r(NULL, ",", &save);
257 	}
258 
259 	return 0;
260 }
261 
ublk_init_params_from_ctx(const struct dev_ctx * ctx,struct ublk_params * params)262 static void ublk_init_params_from_ctx(const struct dev_ctx *ctx,
263 				      struct ublk_params *params)
264 {
265 	const struct params_ctx *p = &ctx->params;
266 
267 	*params = (struct ublk_params) {
268 		.types = p->types,
269 		.basic = {
270 			.logical_bs_shift	= p->logical_bs_shift,
271 			.physical_bs_shift	= p->physical_bs_shift,
272 			.io_min_shift		= p->io_min_shift,
273 			.io_opt_shift		= p->io_opt_shift,
274 			.max_sectors		= p->max_sectors,
275 			.chunk_sectors		= p->chunk_sectors,
276 			.dev_sectors		= p->dev_sectors,
277 		},
278 		.zoned = {
279 			.max_open_zones		= p->max_open_zones,
280 			.max_active_zones	= p->max_active_zones,
281 			.max_zone_append_sectors = p->max_zone_append_sectors,
282 		},
283 	};
284 }
285 
ublk_ctrl_update_size(struct ublk_dev * dev,__u64 nr_sects)286 static int ublk_ctrl_update_size(struct ublk_dev *dev,
287 		__u64 nr_sects)
288 {
289 	struct ublk_ctrl_cmd_data data = {
290 		.cmd_op	= UBLK_U_CMD_UPDATE_SIZE,
291 		.flags	= CTRL_CMD_HAS_DATA,
292 	};
293 
294 	data.data[0] = nr_sects;
295 	return __ublk_ctrl_cmd(dev, &data);
296 }
297 
ublk_ctrl_quiesce_dev(struct ublk_dev * dev,unsigned int timeout_ms)298 static int ublk_ctrl_quiesce_dev(struct ublk_dev *dev,
299 				 unsigned int timeout_ms)
300 {
301 	struct ublk_ctrl_cmd_data data = {
302 		.cmd_op	= UBLK_U_CMD_QUIESCE_DEV,
303 		.flags	= CTRL_CMD_HAS_DATA,
304 	};
305 
306 	data.data[0] = timeout_ms;
307 	return __ublk_ctrl_cmd(dev, &data);
308 }
309 
ublk_dev_state_desc(struct ublk_dev * dev)310 static const char *ublk_dev_state_desc(struct ublk_dev *dev)
311 {
312 	switch (dev->dev_info.state) {
313 	case UBLK_S_DEV_DEAD:
314 		return "DEAD";
315 	case UBLK_S_DEV_LIVE:
316 		return "LIVE";
317 	case UBLK_S_DEV_QUIESCED:
318 		return "QUIESCED";
319 	default:
320 		return "UNKNOWN";
321 	};
322 }
323 
ublk_print_cpu_set(const cpu_set_t * set,char * buf,unsigned len)324 static void ublk_print_cpu_set(const cpu_set_t *set, char *buf, unsigned len)
325 {
326 	unsigned done = 0;
327 	int i;
328 
329 	for (i = 0; i < CPU_SETSIZE; i++) {
330 		if (CPU_ISSET(i, set))
331 			done += snprintf(&buf[done], len - done, "%d ", i);
332 	}
333 }
334 
ublk_adjust_affinity(cpu_set_t * set)335 static void ublk_adjust_affinity(cpu_set_t *set)
336 {
337 	int j, updated = 0;
338 
339 	/*
340 	 * Just keep the 1st CPU now.
341 	 *
342 	 * In future, auto affinity selection can be tried.
343 	 */
344 	for (j = 0; j < CPU_SETSIZE; j++) {
345 		if (CPU_ISSET(j, set)) {
346 			if (!updated) {
347 				updated = 1;
348 				continue;
349 			}
350 			CPU_CLR(j, set);
351 		}
352 	}
353 }
354 
355 /* Caller must free the allocated buffer */
ublk_ctrl_get_affinity(struct ublk_dev * ctrl_dev,cpu_set_t ** ptr_buf)356 static int ublk_ctrl_get_affinity(struct ublk_dev *ctrl_dev, cpu_set_t **ptr_buf)
357 {
358 	struct ublk_ctrl_cmd_data data = {
359 		.cmd_op	= UBLK_U_CMD_GET_QUEUE_AFFINITY,
360 		.flags	= CTRL_CMD_HAS_DATA | CTRL_CMD_HAS_BUF,
361 	};
362 	cpu_set_t *buf;
363 	int i, ret;
364 
365 	buf = malloc(sizeof(cpu_set_t) * ctrl_dev->dev_info.nr_hw_queues);
366 	if (!buf)
367 		return -ENOMEM;
368 
369 	for (i = 0; i < ctrl_dev->dev_info.nr_hw_queues; i++) {
370 		data.data[0] = i;
371 		data.len = sizeof(cpu_set_t);
372 		data.addr = (__u64)&buf[i];
373 
374 		ret = __ublk_ctrl_cmd(ctrl_dev, &data);
375 		if (ret < 0) {
376 			free(buf);
377 			return ret;
378 		}
379 		ublk_adjust_affinity(&buf[i]);
380 	}
381 
382 	*ptr_buf = buf;
383 	return 0;
384 }
385 
ublk_ctrl_dump(struct ublk_dev * dev)386 static void ublk_ctrl_dump(struct ublk_dev *dev)
387 {
388 	struct ublksrv_ctrl_dev_info *info = &dev->dev_info;
389 	struct ublk_params p;
390 	cpu_set_t *affinity;
391 	int ret;
392 
393 	ret = ublk_ctrl_get_params(dev, &p);
394 	if (ret < 0) {
395 		ublk_err("failed to get params %d %s\n", ret, strerror(-ret));
396 		return;
397 	}
398 
399 	ret = ublk_ctrl_get_affinity(dev, &affinity);
400 	if (ret < 0) {
401 		ublk_err("failed to get affinity %m\n");
402 		return;
403 	}
404 
405 	ublk_log("dev id %d: nr_hw_queues %d queue_depth %d block size %d dev_capacity %lld\n",
406 			info->dev_id, info->nr_hw_queues, info->queue_depth,
407 			1 << p.basic.logical_bs_shift, p.basic.dev_sectors);
408 	ublk_log("\tmax rq size %d daemon pid %d flags 0x%llx state %s\n",
409 			info->max_io_buf_bytes, info->ublksrv_pid, info->flags,
410 			ublk_dev_state_desc(dev));
411 	if (info->flags & UBLK_F_IO_DESC_SIZE)
412 		ublk_log("\tio_desc_size %u\n", info->io_desc_size);
413 
414 	if (affinity) {
415 		char buf[512];
416 		int i;
417 
418 		for (i = 0; i < info->nr_hw_queues; i++) {
419 			ublk_print_cpu_set(&affinity[i], buf, sizeof(buf));
420 			printf("\tqueue %u: affinity(%s)\n",
421 					i, buf);
422 		}
423 		free(affinity);
424 	}
425 
426 	fflush(stdout);
427 }
428 
ublk_ctrl_deinit(struct ublk_dev * dev)429 static void ublk_ctrl_deinit(struct ublk_dev *dev)
430 {
431 	close(dev->ctrl_fd);
432 	free(dev);
433 }
434 
ublk_ctrl_init(void)435 static struct ublk_dev *ublk_ctrl_init(void)
436 {
437 	struct ublk_dev *dev = (struct ublk_dev *)calloc(1, sizeof(*dev));
438 	struct ublksrv_ctrl_dev_info *info = &dev->dev_info;
439 	int ret;
440 
441 	dev->ctrl_fd = open(CTRL_DEV, O_RDWR);
442 	if (dev->ctrl_fd < 0) {
443 		free(dev);
444 		return NULL;
445 	}
446 
447 	info->max_io_buf_bytes = UBLK_IO_MAX_BYTES;
448 
449 	ret = ublk_setup_ring(&dev->ring, UBLK_CTRL_RING_DEPTH,
450 			UBLK_CTRL_RING_DEPTH, IORING_SETUP_SQE128);
451 	if (ret < 0) {
452 		ublk_err("queue_init: %s\n", strerror(-ret));
453 		free(dev);
454 		return NULL;
455 	}
456 	dev->nr_fds = 1;
457 
458 	return dev;
459 }
460 
__ublk_queue_cmd_buf_sz(const struct ublk_queue * q,__u16 depth)461 static size_t __ublk_queue_cmd_buf_sz(const struct ublk_queue *q, __u16 depth)
462 {
463 	size_t size = depth * (size_t)q->io_desc_size;
464 	size_t page_sz = getpagesize();
465 
466 	return round_up(size, page_sz);
467 }
468 
ublk_queue_max_cmd_buf_sz(const struct ublk_queue * q)469 static size_t ublk_queue_max_cmd_buf_sz(const struct ublk_queue *q)
470 {
471 	return __ublk_queue_cmd_buf_sz(q, UBLK_MAX_QUEUE_DEPTH);
472 }
473 
ublk_queue_cmd_buf_sz(const struct ublk_queue * q)474 static size_t ublk_queue_cmd_buf_sz(const struct ublk_queue *q)
475 {
476 	return __ublk_queue_cmd_buf_sz(q, q->q_depth);
477 }
478 
ublk_queue_deinit(struct ublk_queue * q)479 static void ublk_queue_deinit(struct ublk_queue *q)
480 {
481 	int i;
482 	int nr_ios = q->q_depth;
483 
484 	if (q->io_cmd_buf)
485 		munmap(q->io_cmd_buf, ublk_queue_cmd_buf_sz(q));
486 
487 	for (i = 0; i < nr_ios; i++) {
488 		free(q->ios[i].buf_addr);
489 		free(q->ios[i].integrity_buf);
490 	}
491 }
492 
ublk_thread_deinit(struct ublk_thread * t)493 static void ublk_thread_deinit(struct ublk_thread *t)
494 {
495 	io_uring_unregister_buffers(&t->ring);
496 
497 	ublk_batch_free_buf(t);
498 
499 	io_uring_unregister_ring_fd(&t->ring);
500 
501 	if (t->ring.ring_fd > 0) {
502 		io_uring_unregister_files(&t->ring);
503 		close(t->ring.ring_fd);
504 		t->ring.ring_fd = -1;
505 	}
506 }
507 
ublk_queue_init(struct ublk_queue * q,unsigned long long extra_flags,__u8 metadata_size)508 static int ublk_queue_init(struct ublk_queue *q, unsigned long long extra_flags,
509 			   __u8 metadata_size)
510 {
511 	struct ublk_dev *dev = q->dev;
512 	int depth = dev->dev_info.queue_depth;
513 	int i;
514 	size_t cmd_buf_size, io_buf_size, integrity_size;
515 	unsigned long off;
516 
517 	pthread_spin_init(&q->lock, PTHREAD_PROCESS_PRIVATE);
518 	q->tgt_ops = dev->tgt.ops;
519 	q->flags = 0;
520 	q->q_depth = depth;
521 	q->flags = dev->dev_info.flags;
522 	q->flags |= extra_flags;
523 	q->metadata_size = metadata_size;
524 	q->io_desc_size = dev->dev_info.io_desc_size;
525 
526 	/* Cache fd in queue for fast path access */
527 	q->ublk_fd = dev->fds[0];
528 
529 	cmd_buf_size = ublk_queue_cmd_buf_sz(q);
530 	off = UBLKSRV_CMD_BUF_OFFSET + q->q_id * ublk_queue_max_cmd_buf_sz(q);
531 	q->io_cmd_buf = mmap(0, cmd_buf_size, PROT_READ,
532 			MAP_SHARED | MAP_POPULATE, dev->fds[0], off);
533 	if (q->io_cmd_buf == MAP_FAILED) {
534 		ublk_err("ublk dev %d queue %d map io_cmd_buf failed %m\n",
535 				q->dev->dev_info.dev_id, q->q_id);
536 		goto fail;
537 	}
538 
539 	io_buf_size = dev->dev_info.max_io_buf_bytes;
540 	integrity_size = ublk_integrity_len(q, io_buf_size);
541 	for (i = 0; i < q->q_depth; i++) {
542 		q->ios[i].buf_addr = NULL;
543 		q->ios[i].flags = UBLKS_IO_NEED_FETCH_RQ | UBLKS_IO_FREE;
544 		q->ios[i].tag = i;
545 
546 		if (integrity_size) {
547 			q->ios[i].integrity_buf = malloc(integrity_size);
548 			if (!q->ios[i].integrity_buf) {
549 				ublk_err("ublk dev %d queue %d io %d malloc(%d) failed: %m\n",
550 					 dev->dev_info.dev_id, q->q_id, i,
551 					 integrity_size);
552 				goto fail;
553 			}
554 		}
555 
556 
557 		if (ublk_queue_no_buf(q))
558 			continue;
559 
560 		if (posix_memalign((void **)&q->ios[i].buf_addr,
561 					getpagesize(), io_buf_size)) {
562 			ublk_err("ublk dev %d queue %d io %d posix_memalign failed %m\n",
563 					dev->dev_info.dev_id, q->q_id, i);
564 			goto fail;
565 		}
566 	}
567 
568 	return 0;
569  fail:
570 	ublk_queue_deinit(q);
571 	ublk_err("ublk dev %d queue %d failed\n",
572 			dev->dev_info.dev_id, q->q_id);
573 	return -ENOMEM;
574 }
575 
ublk_thread_init(struct ublk_thread * t,unsigned long long extra_flags)576 static int ublk_thread_init(struct ublk_thread *t, unsigned long long extra_flags)
577 {
578 	struct ublk_dev *dev = t->dev;
579 	unsigned long long flags = dev->dev_info.flags | extra_flags;
580 	int ring_depth = dev->tgt.sq_depth, cq_depth = dev->tgt.cq_depth;
581 	int ret;
582 
583 	/* FETCH_IO_CMDS is multishot, so increase cq depth for BATCH_IO */
584 	if (ublk_dev_batch_io(dev))
585 		cq_depth += dev->dev_info.queue_depth * 2;
586 
587 	ret = ublk_setup_ring(&t->ring, ring_depth, cq_depth,
588 			IORING_SETUP_COOP_TASKRUN |
589 			IORING_SETUP_SINGLE_ISSUER |
590 			IORING_SETUP_DEFER_TASKRUN);
591 	if (ret < 0) {
592 		ublk_err("ublk dev %d thread %d setup io_uring failed %d\n",
593 				dev->dev_info.dev_id, t->idx, ret);
594 		goto fail;
595 	}
596 
597 	if (dev->dev_info.flags & (UBLK_F_SUPPORT_ZERO_COPY | UBLK_F_AUTO_BUF_REG)) {
598 		unsigned nr_ios = dev->dev_info.queue_depth * dev->dev_info.nr_hw_queues;
599 		unsigned max_nr_ios_per_thread = nr_ios / dev->nthreads;
600 		max_nr_ios_per_thread += !!(nr_ios % dev->nthreads);
601 
602 		t->auto_buf_stride = max_nr_ios_per_thread;
603 		t->nr_bufs = max_nr_ios_per_thread;
604 		if ((extra_flags & UBLKS_Q_ROTATE_AUTO_BUF) &&
605 		    (dev->dev_info.flags & UBLK_F_AUTO_BUF_REG))
606 			t->nr_bufs *= 2;
607 	} else {
608 		t->nr_bufs = 0;
609 		t->auto_buf_stride = 0;
610 	}
611 
612 	if (ublk_dev_batch_io(dev))
613 		 ublk_batch_prepare(t);
614 
615 	if (t->nr_bufs) {
616 		ret = io_uring_register_buffers_sparse(&t->ring, t->nr_bufs);
617 		if (ret) {
618 			ublk_err("ublk dev %d thread %d register spare buffers failed %d\n",
619 					dev->dev_info.dev_id, t->idx, ret);
620 			goto fail;
621 		}
622 	}
623 
624 	if (ublk_dev_batch_io(dev)) {
625 		ret = ublk_batch_alloc_buf(t);
626 		if (ret) {
627 			ublk_err("ublk dev %d thread %d alloc batch buf failed %d\n",
628 				dev->dev_info.dev_id, t->idx, ret);
629 			goto fail;
630 		}
631 	}
632 
633 	io_uring_register_ring_fd(&t->ring);
634 
635 	if (flags & UBLKS_Q_NO_UBLK_FIXED_FD) {
636 		/* Register only backing files starting from index 1, exclude ublk control device */
637 		if (dev->nr_fds > 1) {
638 			ret = io_uring_register_files(&t->ring, &dev->fds[1], dev->nr_fds - 1);
639 		} else {
640 			/* No backing files to register, skip file registration */
641 			ret = 0;
642 		}
643 	} else {
644 		ret = io_uring_register_files(&t->ring, dev->fds, dev->nr_fds);
645 	}
646 	if (ret) {
647 		ublk_err("ublk dev %d thread %d register files failed %d\n",
648 				t->dev->dev_info.dev_id, t->idx, ret);
649 		goto fail;
650 	}
651 
652 	return 0;
653 fail:
654 	ublk_thread_deinit(t);
655 	ublk_err("ublk dev %d thread %d init failed\n",
656 			dev->dev_info.dev_id, t->idx);
657 	return -ENOMEM;
658 }
659 
660 #define WAIT_USEC 	100000
661 #define MAX_WAIT_USEC 	(3 * 1000000)
ublk_dev_prep(const struct dev_ctx * ctx,struct ublk_dev * dev)662 static int ublk_dev_prep(const struct dev_ctx *ctx, struct ublk_dev *dev)
663 {
664 	int dev_id = dev->dev_info.dev_id;
665 	unsigned int wait_usec = 0;
666 	int ret = 0, fd = -1;
667 	char buf[64];
668 
669 	snprintf(buf, 64, "%s%d", UBLKC_DEV, dev_id);
670 
671 	while (wait_usec < MAX_WAIT_USEC) {
672 		fd = open(buf, O_RDWR);
673 		if (fd >= 0)
674 			break;
675 		usleep(WAIT_USEC);
676 		wait_usec += WAIT_USEC;
677 	}
678 	if (fd < 0) {
679 		ublk_err("can't open %s %s\n", buf, strerror(errno));
680 		return -1;
681 	}
682 
683 	dev->fds[0] = fd;
684 	if (dev->tgt.ops->init_tgt)
685 		ret = dev->tgt.ops->init_tgt(ctx, dev);
686 	if (ret)
687 		close(dev->fds[0]);
688 	return ret;
689 }
690 
ublk_dev_unprep(struct ublk_dev * dev)691 static void ublk_dev_unprep(struct ublk_dev *dev)
692 {
693 	if (dev->tgt.ops->deinit_tgt)
694 		dev->tgt.ops->deinit_tgt(dev);
695 	close(dev->fds[0]);
696 }
697 
ublk_set_auto_buf_reg(const struct ublk_thread * t,const struct ublk_queue * q,struct io_uring_sqe * sqe,unsigned short tag)698 static void ublk_set_auto_buf_reg(const struct ublk_thread *t,
699 				  const struct ublk_queue *q,
700 				  struct io_uring_sqe *sqe,
701 				  unsigned short tag)
702 {
703 	struct ublk_auto_buf_reg buf = {};
704 
705 	if (q->tgt_ops->buf_index)
706 		buf.index = q->tgt_ops->buf_index(t, q, tag);
707 	else
708 		buf.index = ublk_io_buf_idx(t, q, tag);
709 
710 	if (ublk_queue_auto_zc_fallback(q))
711 		buf.flags = UBLK_AUTO_BUF_REG_FALLBACK;
712 
713 	sqe->addr = ublk_auto_buf_reg_to_sqe_addr(&buf);
714 }
715 
716 /* Copy in pieces to test the buffer offset logic */
717 #define UBLK_USER_COPY_LEN 2048
718 
ublk_user_copy(const struct ublk_io * io,__u8 match_ublk_op)719 static void ublk_user_copy(const struct ublk_io *io, __u8 match_ublk_op)
720 {
721 	const struct ublk_queue *q = ublk_io_to_queue(io);
722 	const struct ublksrv_io_desc *iod = ublk_get_iod(q, io->tag);
723 	__u64 off = ublk_user_copy_offset(q->q_id, io->tag);
724 	__u8 ublk_op = ublksrv_get_op(iod);
725 	__u32 len = iod->nr_sectors << 9;
726 	void *addr = io->buf_addr;
727 	ssize_t copied;
728 
729 	if (ublk_op != match_ublk_op)
730 		return;
731 
732 	while (len) {
733 		__u32 copy_len = min(len, UBLK_USER_COPY_LEN);
734 
735 		if (ublk_op == UBLK_IO_OP_WRITE)
736 			copied = pread(q->ublk_fd, addr, copy_len, off);
737 		else if (ublk_op == UBLK_IO_OP_READ)
738 			copied = pwrite(q->ublk_fd, addr, copy_len, off);
739 		else
740 			assert(0);
741 		assert(copied == (ssize_t)copy_len);
742 		addr += copy_len;
743 		off += copy_len;
744 		len -= copy_len;
745 	}
746 
747 	if (!(iod->op_flags & UBLK_IO_F_INTEGRITY))
748 		return;
749 
750 	len = ublk_integrity_len(q, iod->nr_sectors << 9);
751 	off = ublk_user_copy_offset(q->q_id, io->tag);
752 	off |= UBLKSRV_IO_INTEGRITY_FLAG;
753 	if (ublk_op == UBLK_IO_OP_WRITE)
754 		copied = pread(q->ublk_fd, io->integrity_buf, len, off);
755 	else if (ublk_op == UBLK_IO_OP_READ)
756 		copied = pwrite(q->ublk_fd, io->integrity_buf, len, off);
757 	else
758 		assert(0);
759 	assert(copied == (ssize_t)len);
760 }
761 
ublk_queue_io_cmd(struct ublk_thread * t,struct ublk_io * io)762 int ublk_queue_io_cmd(struct ublk_thread *t, struct ublk_io *io)
763 {
764 	struct ublk_queue *q = ublk_io_to_queue(io);
765 	struct ublksrv_io_cmd *cmd;
766 	struct io_uring_sqe *sqe[1];
767 	unsigned int cmd_op = 0;
768 	__u64 user_data;
769 
770 	/* only freed io can be issued */
771 	if (!(io->flags & UBLKS_IO_FREE))
772 		return 0;
773 
774 	/*
775 	 * we issue because we need either fetching or committing or
776 	 * getting data
777 	 */
778 	if (!(io->flags &
779 		(UBLKS_IO_NEED_FETCH_RQ | UBLKS_IO_NEED_COMMIT_RQ_COMP | UBLKS_IO_NEED_GET_DATA)))
780 		return 0;
781 
782 	if (io->flags & UBLKS_IO_NEED_GET_DATA)
783 		cmd_op = UBLK_U_IO_NEED_GET_DATA;
784 	else if (io->flags & UBLKS_IO_NEED_COMMIT_RQ_COMP) {
785 		if (ublk_queue_use_user_copy(q))
786 			ublk_user_copy(io, UBLK_IO_OP_READ);
787 
788 		cmd_op = UBLK_U_IO_COMMIT_AND_FETCH_REQ;
789 	} else if (io->flags & UBLKS_IO_NEED_FETCH_RQ)
790 		cmd_op = UBLK_U_IO_FETCH_REQ;
791 
792 	if (io_uring_sq_space_left(&t->ring) < 1)
793 		io_uring_submit(&t->ring);
794 
795 	ublk_io_alloc_sqes(t, sqe, 1);
796 	if (!sqe[0]) {
797 		ublk_err("%s: run out of sqe. thread %u, tag %d\n",
798 				__func__, t->idx, io->tag);
799 		return -1;
800 	}
801 
802 	cmd = (struct ublksrv_io_cmd *)ublk_get_sqe_cmd(sqe[0]);
803 
804 	if (cmd_op == UBLK_U_IO_COMMIT_AND_FETCH_REQ)
805 		cmd->result = io->result;
806 
807 	/* These fields should be written once, never change */
808 	ublk_set_sqe_cmd_op(sqe[0], cmd_op);
809 	sqe[0]->fd	= ublk_get_registered_fd(q, 0);	/* dev->fds[0] */
810 	sqe[0]->opcode	= IORING_OP_URING_CMD;
811 	if (q->flags & UBLKS_Q_NO_UBLK_FIXED_FD)
812 		sqe[0]->flags	= 0;  /* Use raw FD, not fixed file */
813 	else
814 		sqe[0]->flags	= IOSQE_FIXED_FILE;
815 	sqe[0]->rw_flags	= 0;
816 	cmd->tag	= io->tag;
817 	cmd->q_id	= q->q_id;
818 	if (!ublk_queue_no_buf(q) && !ublk_queue_use_user_copy(q))
819 		cmd->addr	= (__u64) (uintptr_t) io->buf_addr;
820 	else
821 		cmd->addr	= 0;
822 
823 	if (ublk_queue_use_auto_zc(q))
824 		ublk_set_auto_buf_reg(t, q, sqe[0], io->tag);
825 
826 	user_data = build_user_data(io->tag, _IOC_NR(cmd_op), 0, q->q_id, 0);
827 	io_uring_sqe_set_data64(sqe[0], user_data);
828 
829 	io->flags = 0;
830 
831 	t->cmd_inflight += 1;
832 
833 	ublk_dbg(UBLK_DBG_IO_CMD, "%s: (thread %u qid %d tag %u cmd_op %u) iof %x stopping %d\n",
834 			__func__, t->idx, q->q_id, io->tag, cmd_op,
835 			io->flags, !!(t->state & UBLKS_T_STOPPING));
836 	return 1;
837 }
838 
ublk_submit_fetch_commands(struct ublk_thread * t)839 static void ublk_submit_fetch_commands(struct ublk_thread *t)
840 {
841 	struct ublk_queue *q;
842 	struct ublk_io *io;
843 	int i = 0, j = 0;
844 
845 	if (t->dev->per_io_tasks) {
846 		/*
847 		 * Lexicographically order all the (qid,tag) pairs, with
848 		 * qid taking priority (so (1,0) > (0,1)). Then make
849 		 * this thread the daemon for every Nth entry in this
850 		 * list (N is the number of threads), starting at this
851 		 * thread's index. This ensures that each queue is
852 		 * handled by as many ublk server threads as possible,
853 		 * so that load that is concentrated on one or a few
854 		 * queues can make use of all ublk server threads.
855 		 */
856 		const struct ublksrv_ctrl_dev_info *dinfo = &t->dev->dev_info;
857 		int nr_ios = dinfo->nr_hw_queues * dinfo->queue_depth;
858 		for (i = t->idx; i < nr_ios; i += t->dev->nthreads) {
859 			int q_id = i / dinfo->queue_depth;
860 			int tag = i % dinfo->queue_depth;
861 			q = &t->dev->q[q_id];
862 			io = &q->ios[tag];
863 			io->buf_index = j++;
864 			if (q->tgt_ops->pre_fetch_io)
865 				q->tgt_ops->pre_fetch_io(t, q, tag, false);
866 			ublk_queue_io_cmd(t, io);
867 		}
868 	} else {
869 		/*
870 		 * Service exclusively the queue whose q_id matches our
871 		 * thread index.
872 		 */
873 		struct ublk_queue *q = &t->dev->q[t->idx];
874 		for (i = 0; i < q->q_depth; i++) {
875 			io = &q->ios[i];
876 			io->buf_index = i;
877 			if (q->tgt_ops->pre_fetch_io)
878 				q->tgt_ops->pre_fetch_io(t, q, i, false);
879 			ublk_queue_io_cmd(t, io);
880 		}
881 	}
882 }
883 
ublk_thread_is_idle(struct ublk_thread * t)884 static int ublk_thread_is_idle(struct ublk_thread *t)
885 {
886 	return !io_uring_sq_ready(&t->ring) && !t->io_inflight;
887 }
888 
ublk_thread_is_done(struct ublk_thread * t)889 static int ublk_thread_is_done(struct ublk_thread *t)
890 {
891 	return (t->state & UBLKS_T_STOPPING) && ublk_thread_is_idle(t) && !t->cmd_inflight;
892 }
893 
ublksrv_handle_tgt_cqe(struct ublk_thread * t,struct ublk_queue * q,struct io_uring_cqe * cqe)894 static inline void ublksrv_handle_tgt_cqe(struct ublk_thread *t,
895 					  struct ublk_queue *q,
896 					  struct io_uring_cqe *cqe)
897 {
898 	if (cqe->res < 0 && cqe->res != -EAGAIN)
899 		ublk_err("%s: failed tgt io: res %d qid %u tag %u, cmd_op %u\n",
900 			__func__, cqe->res, q->q_id,
901 			user_data_to_tag(cqe->user_data),
902 			user_data_to_op(cqe->user_data));
903 
904 	if (q->tgt_ops->tgt_io_done)
905 		q->tgt_ops->tgt_io_done(t, q, cqe);
906 }
907 
ublk_handle_uring_cmd(struct ublk_thread * t,struct ublk_queue * q,const struct io_uring_cqe * cqe)908 static void ublk_handle_uring_cmd(struct ublk_thread *t,
909 				  struct ublk_queue *q,
910 				  const struct io_uring_cqe *cqe)
911 {
912 	int fetch = (cqe->res != UBLK_IO_RES_ABORT) &&
913 		!(t->state & UBLKS_T_STOPPING);
914 	unsigned tag = user_data_to_tag(cqe->user_data);
915 	struct ublk_io *io = &q->ios[tag];
916 
917 	t->cmd_inflight--;
918 
919 	if (!fetch) {
920 		t->state |= UBLKS_T_STOPPING;
921 		io->flags &= ~UBLKS_IO_NEED_FETCH_RQ;
922 	}
923 
924 	if (cqe->res == UBLK_IO_RES_OK) {
925 		ublk_assert(tag < q->q_depth);
926 
927 		if (ublk_queue_use_user_copy(q))
928 			ublk_user_copy(io, UBLK_IO_OP_WRITE);
929 
930 		if (q->tgt_ops->queue_io)
931 			q->tgt_ops->queue_io(t, q, tag);
932 	} else if (cqe->res == UBLK_IO_RES_NEED_GET_DATA) {
933 		io->flags |= UBLKS_IO_NEED_GET_DATA | UBLKS_IO_FREE;
934 		ublk_queue_io_cmd(t, io);
935 	} else {
936 		/*
937 		 * COMMIT_REQ will be completed immediately since no fetching
938 		 * piggyback is required.
939 		 *
940 		 * Marking IO_FREE only, then this io won't be issued since
941 		 * we only issue io with (UBLKS_IO_FREE | UBLKSRV_NEED_*)
942 		 *
943 		 * */
944 		io->flags = UBLKS_IO_FREE;
945 	}
946 }
947 
ublk_handle_cqe(struct ublk_thread * t,struct io_uring_cqe * cqe,void * data)948 static void ublk_handle_cqe(struct ublk_thread *t,
949 		struct io_uring_cqe *cqe, void *data)
950 {
951 	struct ublk_dev *dev = t->dev;
952 	unsigned q_id = user_data_to_q_id(cqe->user_data);
953 	unsigned cmd_op = user_data_to_op(cqe->user_data);
954 
955 	if (cqe->res < 0 && cqe->res != -ENODEV && cqe->res != -ENOBUFS)
956 		ublk_err("%s: res %d userdata %llx thread state %x\n", __func__,
957 				cqe->res, cqe->user_data, t->state);
958 
959 	ublk_dbg(UBLK_DBG_IO_CMD, "%s: res %d (thread %d qid %d tag %u cmd_op %x "
960 			"data %lx target %d/%d) stopping %d\n",
961 			__func__, cqe->res, t->idx, q_id,
962 			user_data_to_tag(cqe->user_data),
963 			cmd_op, cqe->user_data, is_target_io(cqe->user_data),
964 			user_data_to_tgt_data(cqe->user_data),
965 			(t->state & UBLKS_T_STOPPING));
966 
967 	/* Don't retrieve io in case of target io */
968 	if (is_target_io(cqe->user_data)) {
969 		ublksrv_handle_tgt_cqe(t, &dev->q[q_id], cqe);
970 		return;
971 	}
972 
973 	if (ublk_thread_batch_io(t))
974 		ublk_batch_compl_cmd(t, cqe);
975 	else
976 		ublk_handle_uring_cmd(t, &dev->q[q_id], cqe);
977 }
978 
ublk_reap_events_uring(struct ublk_thread * t)979 static int ublk_reap_events_uring(struct ublk_thread *t)
980 {
981 	struct io_uring_cqe *cqe;
982 	unsigned head;
983 	int count = 0;
984 
985 	io_uring_for_each_cqe(&t->ring, head, cqe) {
986 		ublk_handle_cqe(t, cqe, NULL);
987 		count += 1;
988 	}
989 	io_uring_cq_advance(&t->ring, count);
990 
991 	return count;
992 }
993 
ublk_process_io(struct ublk_thread * t)994 static int ublk_process_io(struct ublk_thread *t)
995 {
996 	int ret, reapped;
997 
998 	ublk_dbg(UBLK_DBG_THREAD, "dev%d-t%u: to_submit %d inflight cmd %u stopping %d\n",
999 				t->dev->dev_info.dev_id,
1000 				t->idx, io_uring_sq_ready(&t->ring),
1001 				t->cmd_inflight,
1002 				(t->state & UBLKS_T_STOPPING));
1003 
1004 	if (ublk_thread_is_done(t))
1005 		return -ENODEV;
1006 
1007 	ret = io_uring_submit_and_wait(&t->ring, 1);
1008 	if (ublk_thread_batch_io(t)) {
1009 		ublk_batch_prep_commit(t);
1010 		reapped = ublk_reap_events_uring(t);
1011 		ublk_batch_commit_io_cmds(t);
1012 	} else {
1013 		reapped = ublk_reap_events_uring(t);
1014 	}
1015 
1016 	ublk_dbg(UBLK_DBG_THREAD, "submit result %d, reapped %d stop %d idle %d\n",
1017 			ret, reapped, (t->state & UBLKS_T_STOPPING),
1018 			(t->state & UBLKS_T_IDLE));
1019 
1020 	return reapped;
1021 }
1022 
1023 struct ublk_thread_info {
1024 	struct ublk_dev 	*dev;
1025 	pthread_t		thread;
1026 	unsigned		idx;
1027 	sem_t 			*ready;
1028 	cpu_set_t 		*affinity;
1029 	unsigned long long	extra_flags;
1030 	unsigned char		(*q_thread_map)[UBLK_MAX_QUEUES];
1031 };
1032 
ublk_thread_set_sched_affinity(const struct ublk_thread_info * info)1033 static void ublk_thread_set_sched_affinity(const struct ublk_thread_info *info)
1034 {
1035 	if (pthread_setaffinity_np(pthread_self(), sizeof(*info->affinity), info->affinity) < 0)
1036 		ublk_err("ublk dev %u thread %u set affinity failed",
1037 				info->dev->dev_info.dev_id, info->idx);
1038 }
1039 
ublk_batch_setup_queues(struct ublk_thread * t)1040 static void ublk_batch_setup_queues(struct ublk_thread *t)
1041 {
1042 	int i;
1043 
1044 	for (i = 0; i < t->dev->dev_info.nr_hw_queues; i++) {
1045 		struct ublk_queue *q = &t->dev->q[i];
1046 		int ret;
1047 
1048 		/*
1049 		 * Only prepare io commands in the mapped thread context,
1050 		 * otherwise io command buffer index may not work as expected
1051 		 */
1052 		if (t->q_map[i] == 0)
1053 			continue;
1054 
1055 		if (q->tgt_ops->pre_fetch_io)
1056 			q->tgt_ops->pre_fetch_io(t, q, 0, true);
1057 
1058 		ret = ublk_batch_queue_prep_io_cmds(t, q);
1059 		ublk_assert(ret >= 0);
1060 	}
1061 }
1062 
__ublk_io_handler_fn(struct ublk_thread_info * info)1063 static __attribute__((noinline)) int __ublk_io_handler_fn(struct ublk_thread_info *info)
1064 {
1065 	struct ublk_thread t = {
1066 		.dev = info->dev,
1067 		.idx = info->idx,
1068 	};
1069 	int dev_id = info->dev->dev_info.dev_id;
1070 	int ret;
1071 
1072 	/* Copy per-thread queue mapping into thread-local variable */
1073 	if (info->q_thread_map)
1074 		memcpy(t.q_map, info->q_thread_map[info->idx], sizeof(t.q_map));
1075 
1076 	ret = ublk_thread_init(&t, info->extra_flags);
1077 	if (ret) {
1078 		ublk_err("ublk dev %d thread %u init failed\n",
1079 				dev_id, t.idx);
1080 		return ret;
1081 	}
1082 	sem_post(info->ready);
1083 
1084 	ublk_dbg(UBLK_DBG_THREAD, "tid %d: ublk dev %d thread %u started\n",
1085 			gettid(), dev_id, t.idx);
1086 
1087 	if (!ublk_thread_batch_io(&t)) {
1088 		/* submit all io commands to ublk driver */
1089 		ublk_submit_fetch_commands(&t);
1090 	} else {
1091 		ublk_batch_setup_queues(&t);
1092 		ublk_batch_start_fetch(&t);
1093 	}
1094 
1095 	do {
1096 		if (ublk_process_io(&t) < 0)
1097 			break;
1098 	} while (1);
1099 
1100 	ublk_dbg(UBLK_DBG_THREAD, "tid %d: ublk dev %d thread %d exiting\n",
1101 		 gettid(), dev_id, t.idx);
1102 	ublk_thread_deinit(&t);
1103 	return 0;
1104 }
1105 
ublk_io_handler_fn(void * data)1106 static void *ublk_io_handler_fn(void *data)
1107 {
1108 	struct ublk_thread_info *info = data;
1109 
1110 	/*
1111 	 * IO perf is sensitive with queue pthread affinity on NUMA machine
1112 	 *
1113 	 * Set sched_affinity at beginning, so following allocated memory/pages
1114 	 * could be CPU/NUMA aware.
1115 	 */
1116 	if (info->affinity)
1117 		ublk_thread_set_sched_affinity(info);
1118 
1119 	__ublk_io_handler_fn(info);
1120 
1121 	return NULL;
1122 }
1123 
ublk_set_parameters(struct ublk_dev * dev)1124 static void ublk_set_parameters(struct ublk_dev *dev)
1125 {
1126 	int ret;
1127 
1128 	ret = ublk_ctrl_set_params(dev, &dev->tgt.params);
1129 	if (ret)
1130 		ublk_err("dev %d set basic parameter failed %d\n",
1131 				dev->dev_info.dev_id, ret);
1132 }
1133 
ublk_send_dev_event(const struct dev_ctx * ctx,struct ublk_dev * dev,int dev_id)1134 static int ublk_send_dev_event(const struct dev_ctx *ctx, struct ublk_dev *dev, int dev_id)
1135 {
1136 	uint64_t id;
1137 	int evtfd = ctx->_evtfd;
1138 
1139 	if (evtfd < 0)
1140 		return -EBADF;
1141 
1142 	if (dev_id >= 0)
1143 		id = dev_id + 1;
1144 	else
1145 		id = ERROR_EVTFD_DEVID;
1146 
1147 	if (dev && ctx->shadow_dev)
1148 		memcpy(&ctx->shadow_dev->q, &dev->q, sizeof(dev->q));
1149 
1150 	if (write(evtfd, &id, sizeof(id)) != sizeof(id))
1151 		return -EINVAL;
1152 
1153 	close(evtfd);
1154 	shmdt(ctx->shadow_dev);
1155 
1156 	return 0;
1157 }
1158 
1159 
1160 /*
1161  * Shared memory registration socket listener.
1162  *
1163  * The parent daemon context listens on a per-device unix socket at
1164  * /run/ublk/ublkb<dev_id>.sock for shared memory registration requests
1165  * from clients. Clients send a memfd via SCM_RIGHTS; the server
1166  * registers it with the kernel, mmaps it, and returns the assigned index.
1167  */
1168 #define UBLK_SHMEM_SOCK_DIR	"/run/ublk"
1169 
1170 /* defined in kublk.h, shared with file_backed.c (loop target) */
1171 struct ublk_shmem_entry shmem_table[UBLK_BUF_MAX];
1172 int shmem_count;
1173 
ublk_shmem_sock_path(int dev_id,char * buf,size_t len)1174 static void ublk_shmem_sock_path(int dev_id, char *buf, size_t len)
1175 {
1176 	snprintf(buf, len, "%s/ublkb%d.sock", UBLK_SHMEM_SOCK_DIR, dev_id);
1177 }
1178 
ublk_shmem_sock_create(int dev_id)1179 static int ublk_shmem_sock_create(int dev_id)
1180 {
1181 	struct sockaddr_un addr = { .sun_family = AF_UNIX };
1182 	char path[108];
1183 	int fd;
1184 
1185 	mkdir(UBLK_SHMEM_SOCK_DIR, 0755);
1186 	ublk_shmem_sock_path(dev_id, path, sizeof(path));
1187 	unlink(path);
1188 
1189 	fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
1190 	if (fd < 0)
1191 		return -1;
1192 
1193 	snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path);
1194 	if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
1195 		close(fd);
1196 		return -1;
1197 	}
1198 
1199 	listen(fd, 4);
1200 	ublk_dbg(UBLK_DBG_DEV, "shmem socket created: %s\n", path);
1201 	return fd;
1202 }
1203 
ublk_shmem_sock_destroy(int dev_id,int sock_fd)1204 static void ublk_shmem_sock_destroy(int dev_id, int sock_fd)
1205 {
1206 	char path[108];
1207 
1208 	if (sock_fd >= 0)
1209 		close(sock_fd);
1210 	ublk_shmem_sock_path(dev_id, path, sizeof(path));
1211 	unlink(path);
1212 }
1213 
1214 /* Receive a memfd from a client via SCM_RIGHTS */
ublk_shmem_recv_fd(int client_fd)1215 static int ublk_shmem_recv_fd(int client_fd)
1216 {
1217 	char buf[1];
1218 	struct iovec iov = { .iov_base = buf, .iov_len = sizeof(buf) };
1219 	union {
1220 		char cmsg_buf[CMSG_SPACE(sizeof(int))];
1221 		struct cmsghdr align;
1222 	} u;
1223 	struct msghdr msg = {
1224 		.msg_iov = &iov,
1225 		.msg_iovlen = 1,
1226 		.msg_control = u.cmsg_buf,
1227 		.msg_controllen = sizeof(u.cmsg_buf),
1228 	};
1229 	struct cmsghdr *cmsg;
1230 
1231 	if (recvmsg(client_fd, &msg, 0) <= 0)
1232 		return -1;
1233 
1234 	cmsg = CMSG_FIRSTHDR(&msg);
1235 	if (!cmsg || cmsg->cmsg_level != SOL_SOCKET ||
1236 	    cmsg->cmsg_type != SCM_RIGHTS)
1237 		return -1;
1238 
1239 	return *(int *)CMSG_DATA(cmsg);
1240 }
1241 
1242 /* Register a shared memory buffer: store fd, mmap it, return index */
ublk_shmem_register(int shmem_fd)1243 static int ublk_shmem_register(int shmem_fd)
1244 {
1245 	off_t size;
1246 	void *base;
1247 	int idx;
1248 
1249 	if (shmem_count >= UBLK_BUF_MAX)
1250 		return -1;
1251 
1252 	size = lseek(shmem_fd, 0, SEEK_END);
1253 	if (size <= 0)
1254 		return -1;
1255 
1256 	base = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
1257 		    shmem_fd, 0);
1258 	if (base == MAP_FAILED)
1259 		return -1;
1260 
1261 	idx = shmem_count++;
1262 	shmem_table[idx].fd = shmem_fd;
1263 	shmem_table[idx].mmap_base = base;
1264 	shmem_table[idx].size = size;
1265 
1266 	ublk_dbg(UBLK_DBG_DEV, "shmem registered: index=%d fd=%d size=%zu\n",
1267 		 idx, shmem_fd, (size_t)size);
1268 	return idx;
1269 }
1270 
ublk_shmem_unregister_all(void)1271 static void ublk_shmem_unregister_all(void)
1272 {
1273 	int i;
1274 
1275 	for (i = 0; i < shmem_count; i++) {
1276 		if (shmem_table[i].mmap_base) {
1277 			munmap(shmem_table[i].mmap_base,
1278 			       shmem_table[i].size);
1279 			close(shmem_table[i].fd);
1280 			shmem_table[i].mmap_base = NULL;
1281 		}
1282 	}
1283 	shmem_count = 0;
1284 }
1285 
ublk_ctrl_reg_buf(struct ublk_dev * dev,void * addr,size_t size,__u32 flags)1286 static int ublk_ctrl_reg_buf(struct ublk_dev *dev, void *addr, size_t size,
1287 			     __u32 flags)
1288 {
1289 	struct ublk_shmem_buf_reg buf_reg = {
1290 		.addr = (unsigned long)addr,
1291 		.len = size,
1292 		.flags = flags,
1293 	};
1294 	struct ublk_ctrl_cmd_data data = {
1295 		.cmd_op = UBLK_U_CMD_REG_BUF,
1296 		.flags = CTRL_CMD_HAS_BUF,
1297 		.addr = (unsigned long)&buf_reg,
1298 		.len = sizeof(buf_reg),
1299 	};
1300 
1301 	return __ublk_ctrl_cmd(dev, &data);
1302 }
1303 
1304 /*
1305  * Handle one client connection: receive memfd, mmap it, register
1306  * the VA range with kernel, send back the assigned index.
1307  */
ublk_shmem_handle_client(int sock_fd,struct ublk_dev * dev)1308 static void ublk_shmem_handle_client(int sock_fd, struct ublk_dev *dev)
1309 {
1310 	int client_fd, memfd, idx, ret;
1311 	int32_t reply;
1312 	off_t size;
1313 	void *base;
1314 
1315 	client_fd = accept(sock_fd, NULL, NULL);
1316 	if (client_fd < 0)
1317 		return;
1318 
1319 	memfd = ublk_shmem_recv_fd(client_fd);
1320 	if (memfd < 0) {
1321 		reply = -1;
1322 		goto out;
1323 	}
1324 
1325 	/* mmap the memfd in server address space */
1326 	size = lseek(memfd, 0, SEEK_END);
1327 	if (size <= 0) {
1328 		reply = -1;
1329 		close(memfd);
1330 		goto out;
1331 	}
1332 	base = mmap(NULL, size, PROT_READ | PROT_WRITE,
1333 		    MAP_SHARED | MAP_POPULATE, memfd, 0);
1334 	if (base == MAP_FAILED) {
1335 		reply = -1;
1336 		close(memfd);
1337 		goto out;
1338 	}
1339 
1340 	/* Register server's VA range with kernel for PFN matching */
1341 	ret = ublk_ctrl_reg_buf(dev, base, size, 0);
1342 	if (ret < 0) {
1343 		ublk_dbg(UBLK_DBG_DEV,
1344 			 "shmem_zc: kernel reg failed %d\n", ret);
1345 		munmap(base, size);
1346 		close(memfd);
1347 		reply = ret;
1348 		goto out;
1349 	}
1350 
1351 	/* Store in table for I/O handling */
1352 	idx = ublk_shmem_register(memfd);
1353 	if (idx >= 0) {
1354 		shmem_table[idx].mmap_base = base;
1355 		shmem_table[idx].size = size;
1356 	}
1357 	reply = idx;
1358 out:
1359 	send(client_fd, &reply, sizeof(reply), 0);
1360 	close(client_fd);
1361 }
1362 
1363 struct shmem_listener_info {
1364 	int dev_id;
1365 	int stop_efd;		/* eventfd to signal listener to stop */
1366 	int sock_fd;		/* listener socket fd (output) */
1367 	struct ublk_dev *dev;
1368 };
1369 
1370 /*
1371  * Socket listener thread: runs in the parent daemon context alongside
1372  * the I/O threads. Accepts shared memory registration requests from
1373  * clients via SCM_RIGHTS. Exits when stop_efd is signaled.
1374  */
ublk_shmem_listener_fn(void * data)1375 static void *ublk_shmem_listener_fn(void *data)
1376 {
1377 	struct shmem_listener_info *info = data;
1378 	struct pollfd pfds[2];
1379 
1380 	info->sock_fd = ublk_shmem_sock_create(info->dev_id);
1381 	if (info->sock_fd < 0)
1382 		return NULL;
1383 
1384 	pfds[0].fd = info->sock_fd;
1385 	pfds[0].events = POLLIN;
1386 	pfds[1].fd = info->stop_efd;
1387 	pfds[1].events = POLLIN;
1388 
1389 	while (1) {
1390 		int ret = poll(pfds, 2, -1);
1391 
1392 		if (ret < 0)
1393 			break;
1394 
1395 		/* Stop signal from parent */
1396 		if (pfds[1].revents & POLLIN)
1397 			break;
1398 
1399 		/* Client connection */
1400 		if (pfds[0].revents & POLLIN)
1401 			ublk_shmem_handle_client(info->sock_fd, info->dev);
1402 	}
1403 
1404 	return NULL;
1405 }
1406 
ublk_shmem_htlb_setup(const struct dev_ctx * ctx,struct ublk_dev * dev)1407 static int ublk_shmem_htlb_setup(const struct dev_ctx *ctx,
1408 				 struct ublk_dev *dev)
1409 {
1410 	int fd, idx, ret;
1411 	struct stat st;
1412 	void *base;
1413 
1414 	fd = open(ctx->htlb_path, O_RDWR);
1415 	if (fd < 0) {
1416 		ublk_err("htlb: can't open %s\n", ctx->htlb_path);
1417 		return -errno;
1418 	}
1419 
1420 	if (fstat(fd, &st) < 0 || st.st_size <= 0) {
1421 		ublk_err("htlb: invalid file size\n");
1422 		close(fd);
1423 		return -EINVAL;
1424 	}
1425 
1426 	base = mmap(NULL, st.st_size,
1427 		    ctx->rdonly_shmem_buf ? PROT_READ : PROT_READ | PROT_WRITE,
1428 		    MAP_SHARED | MAP_POPULATE, fd, 0);
1429 	if (base == MAP_FAILED) {
1430 		ublk_err("htlb: mmap failed\n");
1431 		close(fd);
1432 		return -ENOMEM;
1433 	}
1434 
1435 	ret = ublk_ctrl_reg_buf(dev, base, st.st_size,
1436 			       ctx->rdonly_shmem_buf ? UBLK_SHMEM_BUF_READ_ONLY : 0);
1437 	if (ret < 0) {
1438 		ublk_err("htlb: reg_buf failed: %d\n", ret);
1439 		munmap(base, st.st_size);
1440 		close(fd);
1441 		return ret;
1442 	}
1443 
1444 	if (shmem_count >= UBLK_BUF_MAX) {
1445 		munmap(base, st.st_size);
1446 		close(fd);
1447 		return -ENOMEM;
1448 	}
1449 
1450 	idx = shmem_count++;
1451 	shmem_table[idx].fd = fd;
1452 	shmem_table[idx].mmap_base = base;
1453 	shmem_table[idx].size = st.st_size;
1454 
1455 	ublk_dbg(UBLK_DBG_DEV, "htlb registered: index=%d size=%zu\n",
1456 		 idx, (size_t)st.st_size);
1457 	return 0;
1458 }
1459 
ublk_start_daemon(const struct dev_ctx * ctx,struct ublk_dev * dev)1460 static int ublk_start_daemon(const struct dev_ctx *ctx, struct ublk_dev *dev)
1461 {
1462 	const struct ublksrv_ctrl_dev_info *dinfo = &dev->dev_info;
1463 	struct shmem_listener_info linfo = {};
1464 	struct ublk_thread_info *tinfo;
1465 	unsigned long long extra_flags = 0;
1466 	cpu_set_t *affinity_buf;
1467 	unsigned char (*q_thread_map)[UBLK_MAX_QUEUES] = NULL;
1468 	uint64_t stop_val = 1;
1469 	pthread_t listener;
1470 	void *thread_ret;
1471 	sem_t ready;
1472 	int ret, i;
1473 
1474 	ublk_dbg(UBLK_DBG_DEV, "%s enter\n", __func__);
1475 
1476 	tinfo = calloc(sizeof(struct ublk_thread_info), dev->nthreads);
1477 	if (!tinfo)
1478 		return -ENOMEM;
1479 
1480 	sem_init(&ready, 0, 0);
1481 	ret = ublk_dev_prep(ctx, dev);
1482 	if (ret)
1483 		return ret;
1484 
1485 	ret = ublk_ctrl_get_affinity(dev, &affinity_buf);
1486 	if (ret)
1487 		return ret;
1488 
1489 	if (ublk_dev_batch_io(dev)) {
1490 		q_thread_map = calloc(dev->nthreads, sizeof(*q_thread_map));
1491 		if (!q_thread_map) {
1492 			ret = -ENOMEM;
1493 			goto fail;
1494 		}
1495 		ublk_batch_setup_map(q_thread_map, dev->nthreads,
1496 				     dinfo->nr_hw_queues);
1497 	}
1498 
1499 	if (ctx->auto_zc_fallback)
1500 		extra_flags = UBLKS_Q_AUTO_BUF_REG_FALLBACK;
1501 	if (ctx->no_ublk_fixed_fd)
1502 		extra_flags |= UBLKS_Q_NO_UBLK_FIXED_FD;
1503 	if (ctx->rotate_auto_buf)
1504 		extra_flags |= UBLKS_Q_ROTATE_AUTO_BUF;
1505 
1506 	for (i = 0; i < dinfo->nr_hw_queues; i++) {
1507 		dev->q[i].dev = dev;
1508 		dev->q[i].q_id = i;
1509 
1510 		ret = ublk_queue_init(&dev->q[i], extra_flags,
1511 				      ctx->metadata_size);
1512 		if (ret) {
1513 			ublk_err("ublk dev %d queue %d init queue failed\n",
1514 				 dinfo->dev_id, i);
1515 			goto fail;
1516 		}
1517 	}
1518 
1519 	for (i = 0; i < dev->nthreads; i++) {
1520 		tinfo[i].dev = dev;
1521 		tinfo[i].idx = i;
1522 		tinfo[i].ready = &ready;
1523 		tinfo[i].extra_flags = extra_flags;
1524 		tinfo[i].q_thread_map = q_thread_map;
1525 
1526 		/*
1527 		 * If threads are not tied 1:1 to queues, setting thread
1528 		 * affinity based on queue affinity makes little sense.
1529 		 * However, thread CPU affinity has significant impact
1530 		 * on performance, so to compare fairly, we'll still set
1531 		 * thread CPU affinity based on queue affinity where
1532 		 * possible.
1533 		 */
1534 		if (dev->nthreads == dinfo->nr_hw_queues)
1535 			tinfo[i].affinity = &affinity_buf[i];
1536 		pthread_create(&tinfo[i].thread, NULL,
1537 				ublk_io_handler_fn,
1538 				&tinfo[i]);
1539 	}
1540 
1541 	for (i = 0; i < dev->nthreads; i++)
1542 		sem_wait(&ready);
1543 	free(affinity_buf);
1544 	free(q_thread_map);
1545 
1546 	/* everything is fine now, start us */
1547 	if (ctx->recovery)
1548 		ret = ublk_ctrl_end_user_recovery(dev, getpid());
1549 	else {
1550 		ublk_set_parameters(dev);
1551 		ret = ublk_ctrl_start_dev(dev, getpid());
1552 	}
1553 	if (ret < 0) {
1554 		ublk_err("%s: ublk_ctrl_start_dev failed: %d\n", __func__, ret);
1555 		/* stop device so that inflight uring_cmd can be cancelled */
1556 		ublk_ctrl_stop_dev(dev);
1557 		goto fail_start;
1558 	}
1559 
1560 	if (ctx->htlb_path) {
1561 		ret = ublk_shmem_htlb_setup(ctx, dev);
1562 		if (ret < 0) {
1563 			ublk_err("htlb setup failed: %d\n", ret);
1564 			ublk_ctrl_stop_dev(dev);
1565 			goto fail_start;
1566 		}
1567 	}
1568 
1569 	ublk_ctrl_get_info(dev);
1570 	if (ctx->fg)
1571 		ublk_ctrl_dump(dev);
1572 	else
1573 		ublk_send_dev_event(ctx, dev, dev->dev_info.dev_id);
1574 fail_start:
1575 	/*
1576 	 * Wait for I/O threads to exit. While waiting, a listener
1577 	 * thread accepts shared memory registration requests from
1578 	 * clients via a per-device unix socket (SCM_RIGHTS fd passing).
1579 	 */
1580 	linfo.dev_id = dinfo->dev_id;
1581 	linfo.dev = dev;
1582 	linfo.stop_efd = eventfd(0, 0);
1583 	if (linfo.stop_efd >= 0)
1584 		pthread_create(&listener, NULL,
1585 			       ublk_shmem_listener_fn, &linfo);
1586 
1587 	for (i = 0; i < (int)dev->nthreads; i++)
1588 		pthread_join(tinfo[i].thread, &thread_ret);
1589 
1590 	/* Signal listener thread to stop and wait for it */
1591 	if (linfo.stop_efd >= 0) {
1592 		write(linfo.stop_efd, &stop_val, sizeof(stop_val));
1593 		pthread_join(listener, NULL);
1594 		close(linfo.stop_efd);
1595 		ublk_shmem_sock_destroy(dinfo->dev_id, linfo.sock_fd);
1596 	}
1597 	ublk_shmem_unregister_all();
1598 	free(tinfo);
1599  fail:
1600 	for (i = 0; i < dinfo->nr_hw_queues; i++)
1601 		ublk_queue_deinit(&dev->q[i]);
1602 	ublk_dev_unprep(dev);
1603 	ublk_dbg(UBLK_DBG_DEV, "%s exit\n", __func__);
1604 
1605 	return ret;
1606 }
1607 
wait_ublk_dev(const char * path,int evt_mask,unsigned timeout)1608 static int wait_ublk_dev(const char *path, int evt_mask, unsigned timeout)
1609 {
1610 #define EV_SIZE (sizeof(struct inotify_event))
1611 #define EV_BUF_LEN (128 * (EV_SIZE + 16))
1612 	struct pollfd pfd;
1613 	int fd, wd;
1614 	int ret = -EINVAL;
1615 	const char *dev_name = basename(path);
1616 
1617 	fd = inotify_init();
1618 	if (fd < 0) {
1619 		ublk_dbg(UBLK_DBG_DEV, "%s: inotify init failed\n", __func__);
1620 		return fd;
1621 	}
1622 
1623 	wd = inotify_add_watch(fd, "/dev", evt_mask);
1624 	if (wd == -1) {
1625 		ublk_dbg(UBLK_DBG_DEV, "%s: add watch for /dev failed\n", __func__);
1626 		goto fail;
1627 	}
1628 
1629 	pfd.fd = fd;
1630 	pfd.events = POLL_IN;
1631 	while (1) {
1632 		int i = 0;
1633 		char buffer[EV_BUF_LEN];
1634 		ret = poll(&pfd, 1, 1000 * timeout);
1635 
1636 		if (ret == -1) {
1637 			ublk_err("%s: poll inotify failed: %d\n", __func__, ret);
1638 			goto rm_watch;
1639 		} else if (ret == 0) {
1640 			ublk_err("%s: poll inotify timeout\n", __func__);
1641 			ret = -ETIMEDOUT;
1642 			goto rm_watch;
1643 		}
1644 
1645 		ret = read(fd, buffer, EV_BUF_LEN);
1646 		if (ret < 0) {
1647 			ublk_err("%s: read inotify fd failed\n", __func__);
1648 			goto rm_watch;
1649 		}
1650 
1651 		while (i < ret) {
1652 			struct inotify_event *event = (struct inotify_event *)&buffer[i];
1653 
1654 			ublk_dbg(UBLK_DBG_DEV, "%s: inotify event %x %s\n",
1655 					__func__, event->mask, event->name);
1656 			if (event->mask & evt_mask) {
1657 				if (!strcmp(event->name, dev_name)) {
1658 					ret = 0;
1659 					goto rm_watch;
1660 				}
1661 			}
1662 			i += EV_SIZE + event->len;
1663 		}
1664 	}
1665 rm_watch:
1666 	inotify_rm_watch(fd, wd);
1667 fail:
1668 	close(fd);
1669 	return ret;
1670 }
1671 
ublk_stop_io_daemon(const struct ublk_dev * dev)1672 static int ublk_stop_io_daemon(const struct ublk_dev *dev)
1673 {
1674 	int daemon_pid = dev->dev_info.ublksrv_pid;
1675 	int dev_id = dev->dev_info.dev_id;
1676 	char ublkc[64];
1677 	int ret = 0;
1678 
1679 	if (daemon_pid < 0)
1680 		return 0;
1681 
1682 	/* daemon may be dead already */
1683 	if (kill(daemon_pid, 0) < 0)
1684 		goto wait;
1685 
1686 	snprintf(ublkc, sizeof(ublkc), "/dev/%s%d", "ublkc", dev_id);
1687 
1688 	/* ublk char device may be gone already */
1689 	if (access(ublkc, F_OK) != 0)
1690 		goto wait;
1691 
1692 	/* Wait until ublk char device is closed, when the daemon is shutdown */
1693 	ret = wait_ublk_dev(ublkc, IN_CLOSE, 10);
1694 	/* double check and since it may be closed before starting inotify */
1695 	if (ret == -ETIMEDOUT)
1696 		ret = kill(daemon_pid, 0) < 0;
1697 wait:
1698 	waitpid(daemon_pid, NULL, 0);
1699 	ublk_dbg(UBLK_DBG_DEV, "%s: pid %d dev_id %d ret %d\n",
1700 			__func__, daemon_pid, dev_id, ret);
1701 
1702 	return ret;
1703 }
1704 
__cmd_dev_add(const struct dev_ctx * ctx)1705 static int __cmd_dev_add(const struct dev_ctx *ctx)
1706 {
1707 	unsigned nthreads = ctx->nthreads;
1708 	unsigned nr_queues = ctx->nr_hw_queues;
1709 	const char *tgt_type = ctx->tgt_type;
1710 	unsigned depth = ctx->queue_depth;
1711 	__u64 features;
1712 	const struct ublk_tgt_ops *ops;
1713 	struct ublksrv_ctrl_dev_info *info;
1714 	struct ublk_dev *dev = NULL;
1715 	int dev_id = ctx->dev_id;
1716 	int ret, i;
1717 
1718 	ops = ublk_find_tgt(tgt_type);
1719 	if (!ops) {
1720 		ublk_err("%s: no such tgt type, type %s\n",
1721 				__func__, tgt_type);
1722 		ret = -ENODEV;
1723 		goto fail;
1724 	}
1725 
1726 	if (nr_queues > UBLK_MAX_QUEUES || depth > UBLK_QUEUE_DEPTH) {
1727 		ublk_err("%s: invalid nr_queues or depth queues %u depth %u\n",
1728 				__func__, nr_queues, depth);
1729 		ret = -EINVAL;
1730 		goto fail;
1731 	}
1732 
1733 	/* default to 1:1 threads:queues if nthreads is unspecified */
1734 	if (!nthreads)
1735 		nthreads = nr_queues;
1736 
1737 	if (nthreads > UBLK_MAX_THREADS) {
1738 		ublk_err("%s: %u is too many threads (max %u)\n",
1739 				__func__, nthreads, UBLK_MAX_THREADS);
1740 		ret = -EINVAL;
1741 		goto fail;
1742 	}
1743 
1744 	if (nthreads != nr_queues && (!ctx->per_io_tasks &&
1745 				!(ctx->flags & UBLK_F_BATCH_IO))) {
1746 		ublk_err("%s: threads %u must be same as queues %u if "
1747 			"not using per_io_tasks\n",
1748 			__func__, nthreads, nr_queues);
1749 		ret = -EINVAL;
1750 		goto fail;
1751 	}
1752 
1753 	dev = ublk_ctrl_init();
1754 	if (!dev) {
1755 		ublk_err("%s: can't alloc dev id %d, type %s\n",
1756 				__func__, dev_id, tgt_type);
1757 		ret = -ENOMEM;
1758 		goto fail;
1759 	}
1760 
1761 	/* kernel doesn't support get_features */
1762 	ret = ublk_ctrl_get_features(dev, &features);
1763 	if (ret < 0) {
1764 		ret = -EINVAL;
1765 		goto fail;
1766 	}
1767 
1768 	if (!(features & UBLK_F_CMD_IOCTL_ENCODE)) {
1769 		ret = -ENOTSUP;
1770 		goto fail;
1771 	}
1772 
1773 	info = &dev->dev_info;
1774 	info->dev_id = ctx->dev_id;
1775 	info->nr_hw_queues = nr_queues;
1776 	info->queue_depth = depth;
1777 	info->io_desc_size = ctx->io_desc_size;
1778 	info->flags = ctx->flags;
1779 	if ((features & UBLK_F_QUIESCE) &&
1780 			(info->flags & UBLK_F_USER_RECOVERY))
1781 		info->flags |= UBLK_F_QUIESCE;
1782 	dev->nthreads = nthreads;
1783 	dev->per_io_tasks = ctx->per_io_tasks;
1784 	dev->tgt.ops = ops;
1785 	dev->tgt.sq_depth = depth;
1786 	dev->tgt.cq_depth = depth;
1787 
1788 	for (i = 0; i < MAX_BACK_FILES; i++) {
1789 		if (ctx->files[i]) {
1790 			strcpy(dev->tgt.backing_file[i], ctx->files[i]);
1791 			dev->tgt.nr_backing_files++;
1792 		}
1793 	}
1794 
1795 	if (ctx->recovery)
1796 		ret = ublk_ctrl_start_user_recovery(dev);
1797 	else
1798 		ret = ublk_ctrl_add_dev(dev);
1799 	if (ret < 0) {
1800 		ublk_err("%s: can't add dev id %d, type %s ret %d\n",
1801 				__func__, dev_id, tgt_type, ret);
1802 		goto fail;
1803 	}
1804 
1805 	/*
1806 	 * The kernel may reduce nr_hw_queues (e.g. capped to nr_cpu_ids).
1807 	 * Cap nthreads to the actual queue count to avoid creating extra
1808 	 * handler threads that will hang during device removal.
1809 	 *
1810 	 * per_io_tasks mode is excluded: threads interleave across all
1811 	 * queues so nthreads > nr_hw_queues is valid and intentional.
1812 	 */
1813 	if (!ctx->per_io_tasks && dev->nthreads > info->nr_hw_queues)
1814 		dev->nthreads = info->nr_hw_queues;
1815 
1816 	ret = ublk_start_daemon(ctx, dev);
1817 	ublk_dbg(UBLK_DBG_DEV, "%s: daemon exit %d\n", __func__, ret);
1818 	if (ret < 0)
1819 		ublk_ctrl_del_dev(dev);
1820 
1821 fail:
1822 	if (ret < 0)
1823 		ublk_send_dev_event(ctx, dev, -1);
1824 	if (dev)
1825 		ublk_ctrl_deinit(dev);
1826 	return ret;
1827 }
1828 
1829 static int __cmd_dev_list(struct dev_ctx *ctx);
1830 
cmd_dev_set_params(struct dev_ctx * ctx)1831 static int cmd_dev_set_params(struct dev_ctx *ctx)
1832 {
1833 	struct ublksrv_ctrl_dev_info *info;
1834 	struct ublk_params params;
1835 	struct ublk_dev *dev;
1836 	__u64 features;
1837 	int ret, del_ret;
1838 
1839 	dev = ublk_ctrl_init();
1840 	if (!dev)
1841 		return -ENODEV;
1842 
1843 	ret = ublk_ctrl_get_features(dev, &features);
1844 	if (ret < 0)
1845 		goto out;
1846 
1847 	if (!(features & UBLK_F_CMD_IOCTL_ENCODE)) {
1848 		ret = -ENOTSUP;
1849 		goto out;
1850 	}
1851 
1852 	info = &dev->dev_info;
1853 	info->dev_id = ctx->dev_id;
1854 	info->nr_hw_queues = ctx->nr_hw_queues;
1855 	info->queue_depth = ctx->queue_depth;
1856 	info->io_desc_size = ctx->io_desc_size;
1857 	info->flags = ctx->flags;
1858 
1859 	ret = ublk_ctrl_add_dev(dev);
1860 	if (ret < 0)
1861 		goto out;
1862 
1863 	ublk_init_params_from_ctx(ctx, &params);
1864 
1865 	ret = ublk_ctrl_set_params(dev, &params);
1866 	printf("SET_PARAMS returned %d\n", ret);
1867 
1868 	del_ret = ublk_ctrl_del_dev(dev);
1869 	if (del_ret < 0 && ret == 0)
1870 		ret = del_ret;
1871 out:
1872 	ublk_ctrl_deinit(dev);
1873 	return ret < 0 ? ret : 0;
1874 }
1875 
cmd_dev_add(struct dev_ctx * ctx)1876 static int cmd_dev_add(struct dev_ctx *ctx)
1877 {
1878 	int res;
1879 
1880 	if (ctx->fg)
1881 		goto run;
1882 
1883 	ctx->_shmid = shmget(IPC_PRIVATE, sizeof(struct ublk_dev), IPC_CREAT | 0666);
1884 	if (ctx->_shmid < 0) {
1885 		ublk_err("%s: failed to shmget %s\n", __func__, strerror(errno));
1886 		exit(-1);
1887 	}
1888 	ctx->shadow_dev = (struct ublk_dev *)shmat(ctx->_shmid, NULL, 0);
1889 	if (ctx->shadow_dev == (struct ublk_dev *)-1) {
1890 		ublk_err("%s: failed to shmat %s\n", __func__, strerror(errno));
1891 		exit(-1);
1892 	}
1893 	ctx->_evtfd = eventfd(0, 0);
1894 	if (ctx->_evtfd < 0) {
1895 		ublk_err("%s: failed to create eventfd %s\n", __func__, strerror(errno));
1896 		exit(-1);
1897 	}
1898 
1899 	res = fork();
1900 	if (res == 0) {
1901 		int res2;
1902 
1903 		setsid();
1904 		res2 = fork();
1905 		if (res2 == 0) {
1906 			/* prepare for detaching */
1907 			close(STDIN_FILENO);
1908 			close(STDOUT_FILENO);
1909 			close(STDERR_FILENO);
1910 run:
1911 			res = __cmd_dev_add(ctx);
1912 			return res;
1913 		} else {
1914 			/* detached from the foreground task */
1915 			exit(EXIT_SUCCESS);
1916 		}
1917 	} else if (res > 0) {
1918 		uint64_t id;
1919 		int exit_code = EXIT_FAILURE;
1920 
1921 		res = read(ctx->_evtfd, &id, sizeof(id));
1922 		close(ctx->_evtfd);
1923 		if (res == sizeof(id) && id != ERROR_EVTFD_DEVID) {
1924 			ctx->dev_id = id - 1;
1925 			if (__cmd_dev_list(ctx) >= 0)
1926 				exit_code = EXIT_SUCCESS;
1927 		}
1928 		shmdt(ctx->shadow_dev);
1929 		shmctl(ctx->_shmid, IPC_RMID, NULL);
1930 		/* wait for child and detach from it */
1931 		wait(NULL);
1932 		if (exit_code == EXIT_FAILURE)
1933 			ublk_err("%s: command failed\n", __func__);
1934 		exit(exit_code);
1935 	} else {
1936 		exit(EXIT_FAILURE);
1937 	}
1938 }
1939 
__cmd_dev_del(struct dev_ctx * ctx)1940 static int __cmd_dev_del(struct dev_ctx *ctx)
1941 {
1942 	int number = ctx->dev_id;
1943 	struct ublk_dev *dev;
1944 	int ret;
1945 
1946 	dev = ublk_ctrl_init();
1947 	dev->dev_info.dev_id = number;
1948 
1949 	ret = ublk_ctrl_get_info(dev);
1950 	if (ret < 0)
1951 		goto fail;
1952 
1953 	ret = ublk_ctrl_stop_dev(dev);
1954 	if (ret < 0)
1955 		ublk_err("%s: stop dev %d failed ret %d\n", __func__, number, ret);
1956 
1957 	ret = ublk_stop_io_daemon(dev);
1958 	if (ret < 0)
1959 		ublk_err("%s: stop daemon id %d dev %d, ret %d\n",
1960 				__func__, dev->dev_info.ublksrv_pid, number, ret);
1961 	ublk_ctrl_del_dev(dev);
1962 fail:
1963 	ublk_ctrl_deinit(dev);
1964 
1965 	return (ret >= 0) ? 0 : ret;
1966 }
1967 
cmd_dev_del(struct dev_ctx * ctx)1968 static int cmd_dev_del(struct dev_ctx *ctx)
1969 {
1970 	int i;
1971 
1972 	if (ctx->dev_id >= 0 || !ctx->all)
1973 		return __cmd_dev_del(ctx);
1974 
1975 	for (i = 0; i < 255; i++) {
1976 		ctx->dev_id = i;
1977 		__cmd_dev_del(ctx);
1978 	}
1979 	return 0;
1980 }
1981 
cmd_dev_stop(struct dev_ctx * ctx)1982 static int cmd_dev_stop(struct dev_ctx *ctx)
1983 {
1984 	int number = ctx->dev_id;
1985 	struct ublk_dev *dev;
1986 	int ret;
1987 
1988 	if (number < 0) {
1989 		ublk_err("%s: device id is required\n", __func__);
1990 		return -EINVAL;
1991 	}
1992 
1993 	dev = ublk_ctrl_init();
1994 	dev->dev_info.dev_id = number;
1995 
1996 	ret = ublk_ctrl_get_info(dev);
1997 	if (ret < 0)
1998 		goto fail;
1999 
2000 	if (ctx->safe_stop) {
2001 		ret = ublk_ctrl_try_stop_dev(dev);
2002 		if (ret < 0)
2003 			ublk_err("%s: try_stop dev %d failed ret %d\n",
2004 					__func__, number, ret);
2005 	} else {
2006 		ret = ublk_ctrl_stop_dev(dev);
2007 		if (ret < 0)
2008 			ublk_err("%s: stop dev %d failed ret %d\n",
2009 					__func__, number, ret);
2010 	}
2011 
2012 fail:
2013 	ublk_ctrl_deinit(dev);
2014 
2015 	return ret;
2016 }
2017 
__cmd_dev_list(struct dev_ctx * ctx)2018 static int __cmd_dev_list(struct dev_ctx *ctx)
2019 {
2020 	struct ublk_dev *dev = ublk_ctrl_init();
2021 	int ret;
2022 
2023 	if (!dev)
2024 		return -ENODEV;
2025 
2026 	dev->dev_info.dev_id = ctx->dev_id;
2027 
2028 	ret = ublk_ctrl_get_info(dev);
2029 	if (ret < 0) {
2030 		if (ctx->logging)
2031 			ublk_err("%s: can't get dev info from %d: %d\n",
2032 					__func__, ctx->dev_id, ret);
2033 	} else {
2034 		if (ctx->shadow_dev)
2035 			memcpy(&dev->q, ctx->shadow_dev->q, sizeof(dev->q));
2036 
2037 		ublk_ctrl_dump(dev);
2038 	}
2039 
2040 	ublk_ctrl_deinit(dev);
2041 
2042 	return ret;
2043 }
2044 
cmd_dev_list(struct dev_ctx * ctx)2045 static int cmd_dev_list(struct dev_ctx *ctx)
2046 {
2047 	int i;
2048 
2049 	if (ctx->dev_id >= 0 || !ctx->all)
2050 		return __cmd_dev_list(ctx);
2051 
2052 	ctx->logging = false;
2053 	for (i = 0; i < 255; i++) {
2054 		ctx->dev_id = i;
2055 		__cmd_dev_list(ctx);
2056 	}
2057 	return 0;
2058 }
2059 
cmd_dev_get_features(void)2060 static int cmd_dev_get_features(void)
2061 {
2062 #define const_ilog2(x) (63 - __builtin_clzll(x))
2063 #define FEAT_NAME(f) [const_ilog2(f)] = #f
2064 	static const char *feat_map[] = {
2065 		FEAT_NAME(UBLK_F_SUPPORT_ZERO_COPY),
2066 		FEAT_NAME(UBLK_F_URING_CMD_COMP_IN_TASK),
2067 		FEAT_NAME(UBLK_F_NEED_GET_DATA),
2068 		FEAT_NAME(UBLK_F_USER_RECOVERY),
2069 		FEAT_NAME(UBLK_F_USER_RECOVERY_REISSUE),
2070 		FEAT_NAME(UBLK_F_UNPRIVILEGED_DEV),
2071 		FEAT_NAME(UBLK_F_CMD_IOCTL_ENCODE),
2072 		FEAT_NAME(UBLK_F_USER_COPY),
2073 		FEAT_NAME(UBLK_F_ZONED),
2074 		FEAT_NAME(UBLK_F_USER_RECOVERY_FAIL_IO),
2075 		FEAT_NAME(UBLK_F_UPDATE_SIZE),
2076 		FEAT_NAME(UBLK_F_AUTO_BUF_REG),
2077 		FEAT_NAME(UBLK_F_QUIESCE),
2078 		FEAT_NAME(UBLK_F_PER_IO_DAEMON),
2079 		FEAT_NAME(UBLK_F_BUF_REG_OFF_DAEMON),
2080 		FEAT_NAME(UBLK_F_INTEGRITY),
2081 		FEAT_NAME(UBLK_F_SAFE_STOP_DEV),
2082 		FEAT_NAME(UBLK_F_BATCH_IO),
2083 		FEAT_NAME(UBLK_F_NO_AUTO_PART_SCAN),
2084 		FEAT_NAME(UBLK_F_SHMEM_ZC),
2085 		FEAT_NAME(UBLK_F_IO_DESC_SIZE),
2086 	};
2087 	struct ublk_dev *dev;
2088 	__u64 features = 0;
2089 	int ret;
2090 
2091 	dev = ublk_ctrl_init();
2092 	if (!dev) {
2093 		fprintf(stderr, "ublksrv_ctrl_init failed id\n");
2094 		return -EOPNOTSUPP;
2095 	}
2096 
2097 	ret = ublk_ctrl_get_features(dev, &features);
2098 	if (!ret) {
2099 		int i;
2100 
2101 		printf("ublk_drv features: 0x%llx\n", features);
2102 
2103 		for (i = 0; i < sizeof(features) * 8; i++) {
2104 			const char *feat;
2105 
2106 			if (!((1ULL << i)  & features))
2107 				continue;
2108 			if (i < ARRAY_SIZE(feat_map))
2109 				feat = feat_map[i];
2110 			else
2111 				feat = "unknown";
2112 			printf("0x%-16llx: %s\n", 1ULL << i, feat);
2113 		}
2114 	}
2115 
2116 	return ret;
2117 }
2118 
cmd_dev_update_size(struct dev_ctx * ctx)2119 static int cmd_dev_update_size(struct dev_ctx *ctx)
2120 {
2121 	struct ublk_dev *dev = ublk_ctrl_init();
2122 	struct ublk_params p;
2123 	int ret = -EINVAL;
2124 
2125 	if (!dev)
2126 		return -ENODEV;
2127 
2128 	if (ctx->dev_id < 0) {
2129 		fprintf(stderr, "device id isn't provided\n");
2130 		goto out;
2131 	}
2132 
2133 	dev->dev_info.dev_id = ctx->dev_id;
2134 	ret = ublk_ctrl_get_params(dev, &p);
2135 	if (ret < 0) {
2136 		ublk_err("failed to get params %d %s\n", ret, strerror(-ret));
2137 		goto out;
2138 	}
2139 
2140 	if (ctx->size & ((1 << p.basic.logical_bs_shift) - 1)) {
2141 		ublk_err("size isn't aligned with logical block size\n");
2142 		ret = -EINVAL;
2143 		goto out;
2144 	}
2145 
2146 	ret = ublk_ctrl_update_size(dev, ctx->size >> 9);
2147 out:
2148 	ublk_ctrl_deinit(dev);
2149 	return ret;
2150 }
2151 
cmd_dev_quiesce(struct dev_ctx * ctx)2152 static int cmd_dev_quiesce(struct dev_ctx *ctx)
2153 {
2154 	struct ublk_dev *dev = ublk_ctrl_init();
2155 	int ret = -EINVAL;
2156 
2157 	if (!dev)
2158 		return -ENODEV;
2159 
2160 	if (ctx->dev_id < 0) {
2161 		fprintf(stderr, "device id isn't provided for quiesce\n");
2162 		goto out;
2163 	}
2164 	dev->dev_info.dev_id = ctx->dev_id;
2165 	ret = ublk_ctrl_quiesce_dev(dev, 10000);
2166 
2167 out:
2168 	ublk_ctrl_deinit(dev);
2169 	return ret;
2170 }
2171 
__cmd_create_help(char * exe,bool recovery)2172 static void __cmd_create_help(char *exe, bool recovery)
2173 {
2174 	int i;
2175 
2176 	printf("%s %s -t [null|loop|stripe|fault_inject] [-q nr_queues] [-d depth] [-n dev_id]\n",
2177 			exe, recovery ? "recover" : "add");
2178 	printf("\t[--foreground] [--quiet] [-z] [--auto_zc] [--auto_zc_fallback] [--debug_mask mask] [-r 0|1] [-g] [-u]\n");
2179 	printf("\t[-e 0|1 ] [-i 0|1] [--no_ublk_fixed_fd]\n");
2180 	printf("\t[--nthreads threads] [--per_io_tasks]\n");
2181 	printf("\t[--integrity_capable] [--integrity_reftag] [--metadata_size SIZE] "
2182 		 "[--pi_offset OFFSET] [--csum_type ip|t10dif|nvme] [--tag_size SIZE]\n");
2183 	printf("\t[--batch|-b] [--rotate_auto_buf] [--no_auto_part_scan]\n");
2184 	printf("\t[--io_desc_size SIZE]\n");
2185 	printf("\t[target options] [backfile1] [backfile2] ...\n");
2186 	printf("\tdefault: nr_queues=2(max 32), depth=128(max 1024), dev_id=-1(auto allocation)\n");
2187 	printf("\tdefault: nthreads=nr_queues");
2188 
2189 	for (i = 0; i < ARRAY_SIZE(tgt_ops_list); i++) {
2190 		const struct ublk_tgt_ops *ops = tgt_ops_list[i];
2191 
2192 		if (ops->usage)
2193 			ops->usage(ops);
2194 	}
2195 }
2196 
cmd_add_help(char * exe)2197 static void cmd_add_help(char *exe)
2198 {
2199 	__cmd_create_help(exe, false);
2200 	printf("\n");
2201 }
2202 
cmd_recover_help(char * exe)2203 static void cmd_recover_help(char *exe)
2204 {
2205 	__cmd_create_help(exe, true);
2206 	printf("\tPlease provide exact command line for creating this device with real dev_id\n");
2207 	printf("\n");
2208 }
2209 
cmd_dev_help(char * exe)2210 static int cmd_dev_help(char *exe)
2211 {
2212 	cmd_add_help(exe);
2213 	cmd_recover_help(exe);
2214 
2215 	printf("%s del [-n dev_id] -a \n", exe);
2216 	printf("\t -a delete all devices -n delete specified device\n\n");
2217 	printf("%s stop -n dev_id [--safe]\n", exe);
2218 	printf("\t --safe only stop if device has no active openers\n\n");
2219 	printf("%s list [-n dev_id] -a \n", exe);
2220 	printf("\t -a list all devices, -n list specified device, default -a \n\n");
2221 	printf("%s set_params [-n dev_id] [-q nr_queues] [-d depth] [-u] [--zoned]\n", exe);
2222 	printf("\t[--param_types basic[,zoned]|none]\n");
2223 	printf("\t issue ADD_DEV, SET_PARAMS and DEL_DEV without START_DEV\n\n");
2224 	printf("%s features\n", exe);
2225 	printf("%s update_size -n dev_id -s|--size size_in_bytes \n", exe);
2226 	printf("%s quiesce -n dev_id\n", exe);
2227 	return 0;
2228 }
2229 
main(int argc,char * argv[])2230 int main(int argc, char *argv[])
2231 {
2232 	static const struct option longopts[] = {
2233 		{ "all",		0,	NULL, 'a' },
2234 		{ "type",		1,	NULL, 't' },
2235 		{ "number",		1,	NULL, 'n' },
2236 		{ "queues",		1,	NULL, 'q' },
2237 		{ "depth",		1,	NULL, 'd' },
2238 		{ "debug_mask",		1,	NULL,  0  },
2239 		{ "quiet",		0,	NULL,  0  },
2240 		{ "zero_copy",          0,      NULL, 'z' },
2241 		{ "foreground",		0,	NULL,  0  },
2242 		{ "recovery", 		1,      NULL, 'r' },
2243 		{ "recovery_fail_io",	1,	NULL, 'e'},
2244 		{ "recovery_reissue",	1,	NULL, 'i'},
2245 		{ "get_data",		1,	NULL, 'g'},
2246 		{ "auto_zc",		0,	NULL,  0 },
2247 		{ "auto_zc_fallback", 	0,	NULL,  0 },
2248 		{ "user_copy",		0,	NULL, 'u'},
2249 		{ "size",		1,	NULL, 's'},
2250 		{ "nthreads",		1,	NULL,  0 },
2251 		{ "per_io_tasks",	0,	NULL,  0 },
2252 		{ "no_ublk_fixed_fd",	0,	NULL,  0 },
2253 		{ "integrity_capable",	0,	NULL,  0 },
2254 		{ "integrity_reftag",	0,	NULL,  0 },
2255 		{ "metadata_size",	1,	NULL,  0 },
2256 		{ "pi_offset",		1,	NULL,  0 },
2257 		{ "csum_type",		1,	NULL,  0 },
2258 		{ "tag_size",		1,	NULL,  0 },
2259 		{ "safe",		0,	NULL,  0 },
2260 		{ "batch",              0,      NULL, 'b'},
2261 		{ "rotate_auto_buf",	0,	NULL,  0 },
2262 		{ "no_auto_part_scan",	0,	NULL,  0 },
2263 		{ "shmem_zc",		0,	NULL,  0  },
2264 		{ "htlb",		1,	NULL,  0  },
2265 		{ "rdonly_shmem_buf",	0,	NULL,  0  },
2266 		{ "io_desc_size",	1,	NULL,  0  },
2267 		{ "zoned",		0,	NULL,  0  },
2268 		{ "param_types",	1,	NULL,  0  },
2269 		{ "logical_bs_shift",	1,	NULL,  0  },
2270 		{ "physical_bs_shift",	1,	NULL,  0  },
2271 		{ "io_min_shift",	1,	NULL,  0  },
2272 		{ "io_opt_shift",	1,	NULL,  0  },
2273 		{ "max_sectors",	1,	NULL,  0  },
2274 		{ "chunk_sectors",	1,	NULL,  0  },
2275 		{ "dev_sectors",	1,	NULL,  0  },
2276 		{ "max_zone_append_sectors", 1, NULL,  0  },
2277 		{ "max_open_zones",	1,	NULL,  0  },
2278 		{ "max_active_zones",	1,	NULL,  0  },
2279 		{ 0, 0, 0, 0 }
2280 	};
2281 	const struct ublk_tgt_ops *ops = NULL;
2282 	int option_idx, opt;
2283 	const char *cmd = argv[1];
2284 	struct dev_ctx ctx = {
2285 		._evtfd         =       -1,
2286 		.queue_depth	=	128,
2287 		.nr_hw_queues	=	2,
2288 		.dev_id		=	-1,
2289 		.tgt_type	=	"unknown",
2290 		.csum_type	=	LBMD_PI_CSUM_NONE,
2291 		.io_desc_size	=	sizeof(struct ublksrv_io_desc),
2292 		.params = {
2293 			.types			= UBLK_PARAM_TYPE_BASIC,
2294 			.logical_bs_shift	= KUBLK_PARAM_LOGICAL_BS_SHIFT,
2295 			.physical_bs_shift	= KUBLK_PARAM_PHYSICAL_BS_SHIFT,
2296 			.io_min_shift		= KUBLK_PARAM_LOGICAL_BS_SHIFT,
2297 			.io_opt_shift		= KUBLK_PARAM_PHYSICAL_BS_SHIFT,
2298 			.max_sectors		=
2299 				UBLK_IO_MAX_BYTES >> KUBLK_PARAM_LOGICAL_BS_SHIFT,
2300 			.chunk_sectors		= KUBLK_PARAM_ZONE_SECTORS,
2301 			.dev_sectors		= KUBLK_PARAM_DEV_SECTORS,
2302 			.max_zone_append_sectors =
2303 				KUBLK_PARAM_ZONE_APPEND_SECTORS,
2304 		},
2305 	};
2306 	int ret = -EINVAL, i;
2307 	int tgt_argc = 1;
2308 	char *tgt_argv[MAX_NR_TGT_ARG] = { NULL };
2309 	int value;
2310 
2311 	if (argc == 1)
2312 		return ret;
2313 
2314 	opterr = 0;
2315 	optind = 2;
2316 	while ((opt = getopt_long(argc, argv, "t:n:d:q:r:e:i:s:gazub",
2317 				  longopts, &option_idx)) != -1) {
2318 		switch (opt) {
2319 		case 'a':
2320 			ctx.all = 1;
2321 			break;
2322 		case 'b':
2323 			ctx.flags |= UBLK_F_BATCH_IO;
2324 			break;
2325 		case 'n':
2326 			ctx.dev_id = strtol(optarg, NULL, 10);
2327 			break;
2328 		case 't':
2329 			if (strlen(optarg) < sizeof(ctx.tgt_type))
2330 				strcpy(ctx.tgt_type, optarg);
2331 			break;
2332 		case 'q':
2333 			ctx.nr_hw_queues = strtol(optarg, NULL, 10);
2334 			break;
2335 		case 'd':
2336 			ctx.queue_depth = strtol(optarg, NULL, 10);
2337 			break;
2338 		case 'z':
2339 			ctx.flags |= UBLK_F_SUPPORT_ZERO_COPY;
2340 			break;
2341 		case 'r':
2342 			value = strtol(optarg, NULL, 10);
2343 			if (value)
2344 				ctx.flags |= UBLK_F_USER_RECOVERY;
2345 			break;
2346 		case 'e':
2347 			value = strtol(optarg, NULL, 10);
2348 			if (value)
2349 				ctx.flags |= UBLK_F_USER_RECOVERY | UBLK_F_USER_RECOVERY_FAIL_IO;
2350 			break;
2351 		case 'i':
2352 			value = strtol(optarg, NULL, 10);
2353 			if (value)
2354 				ctx.flags |= UBLK_F_USER_RECOVERY | UBLK_F_USER_RECOVERY_REISSUE;
2355 			break;
2356 		case 'g':
2357 			ctx.flags |= UBLK_F_NEED_GET_DATA;
2358 			break;
2359 		case 'u':
2360 			ctx.flags |= UBLK_F_USER_COPY;
2361 			break;
2362 		case 's':
2363 			ctx.size = strtoull(optarg, NULL, 10);
2364 			break;
2365 		case 0:
2366 			if (!strcmp(longopts[option_idx].name, "debug_mask"))
2367 				ublk_dbg_mask = strtol(optarg, NULL, 16);
2368 			if (!strcmp(longopts[option_idx].name, "quiet"))
2369 				ublk_dbg_mask = 0;
2370 			if (!strcmp(longopts[option_idx].name, "foreground"))
2371 				ctx.fg = 1;
2372 			if (!strcmp(longopts[option_idx].name, "auto_zc"))
2373 				ctx.flags |= UBLK_F_AUTO_BUF_REG;
2374 			if (!strcmp(longopts[option_idx].name, "auto_zc_fallback"))
2375 				ctx.auto_zc_fallback = 1;
2376 			if (!strcmp(longopts[option_idx].name, "rotate_auto_buf"))
2377 				ctx.rotate_auto_buf = 1;
2378 			if (!strcmp(longopts[option_idx].name, "nthreads"))
2379 				ctx.nthreads = strtol(optarg, NULL, 10);
2380 			if (!strcmp(longopts[option_idx].name, "per_io_tasks"))
2381 				ctx.per_io_tasks = 1;
2382 			if (!strcmp(longopts[option_idx].name, "no_ublk_fixed_fd"))
2383 				ctx.no_ublk_fixed_fd = 1;
2384 			if (!strcmp(longopts[option_idx].name, "integrity_capable"))
2385 				ctx.integrity_flags |= LBMD_PI_CAP_INTEGRITY;
2386 			if (!strcmp(longopts[option_idx].name, "integrity_reftag"))
2387 				ctx.integrity_flags |= LBMD_PI_CAP_REFTAG;
2388 			if (!strcmp(longopts[option_idx].name, "metadata_size"))
2389 				ctx.metadata_size = strtoul(optarg, NULL, 0);
2390 			if (!strcmp(longopts[option_idx].name, "pi_offset"))
2391 				ctx.pi_offset = strtoul(optarg, NULL, 0);
2392 			if (!strcmp(longopts[option_idx].name, "csum_type")) {
2393 				if (!strcmp(optarg, "ip")) {
2394 					ctx.csum_type = LBMD_PI_CSUM_IP;
2395 				} else if (!strcmp(optarg, "t10dif")) {
2396 					ctx.csum_type = LBMD_PI_CSUM_CRC16_T10DIF;
2397 				} else if (!strcmp(optarg, "nvme")) {
2398 					ctx.csum_type = LBMD_PI_CSUM_CRC64_NVME;
2399 				} else {
2400 					ublk_err("invalid csum_type: %s\n", optarg);
2401 					return -EINVAL;
2402 				}
2403 			}
2404 			if (!strcmp(longopts[option_idx].name, "tag_size"))
2405 				ctx.tag_size = strtoul(optarg, NULL, 0);
2406 			if (!strcmp(longopts[option_idx].name, "safe"))
2407 				ctx.safe_stop = 1;
2408 			if (!strcmp(longopts[option_idx].name, "no_auto_part_scan"))
2409 				ctx.flags |= UBLK_F_NO_AUTO_PART_SCAN;
2410 			if (!strcmp(longopts[option_idx].name, "shmem_zc"))
2411 				ctx.flags |= UBLK_F_SHMEM_ZC;
2412 			if (!strcmp(longopts[option_idx].name, "htlb"))
2413 				ctx.htlb_path = strdup(optarg);
2414 			if (!strcmp(longopts[option_idx].name, "rdonly_shmem_buf"))
2415 				ctx.rdonly_shmem_buf = 1;
2416 			if (!strcmp(longopts[option_idx].name, "io_desc_size")) {
2417 				ctx.flags |= UBLK_F_IO_DESC_SIZE;
2418 				ctx.io_desc_size = strtoul(optarg, NULL, 0);
2419 			}
2420 			if (!strcmp(longopts[option_idx].name, "zoned"))
2421 				ctx.flags |= UBLK_F_ZONED;
2422 			if (!strcmp(longopts[option_idx].name, "param_types")) {
2423 				ret = parse_param_types(optarg, &ctx.params.types);
2424 				if (ret)
2425 					return ret;
2426 			}
2427 			if (!strcmp(longopts[option_idx].name, "logical_bs_shift"))
2428 				ctx.params.logical_bs_shift = strtoul(optarg, NULL, 0);
2429 			if (!strcmp(longopts[option_idx].name, "physical_bs_shift"))
2430 				ctx.params.physical_bs_shift = strtoul(optarg, NULL, 0);
2431 			if (!strcmp(longopts[option_idx].name, "io_min_shift"))
2432 				ctx.params.io_min_shift = strtoul(optarg, NULL, 0);
2433 			if (!strcmp(longopts[option_idx].name, "io_opt_shift"))
2434 				ctx.params.io_opt_shift = strtoul(optarg, NULL, 0);
2435 			if (!strcmp(longopts[option_idx].name, "max_sectors"))
2436 				ctx.params.max_sectors = strtoul(optarg, NULL, 0);
2437 			if (!strcmp(longopts[option_idx].name, "chunk_sectors"))
2438 				ctx.params.chunk_sectors = strtoul(optarg, NULL, 0);
2439 			if (!strcmp(longopts[option_idx].name, "dev_sectors"))
2440 				ctx.params.dev_sectors = strtoull(optarg, NULL, 0);
2441 			if (!strcmp(longopts[option_idx].name, "max_zone_append_sectors"))
2442 				ctx.params.max_zone_append_sectors =
2443 					strtoul(optarg, NULL, 0);
2444 			if (!strcmp(longopts[option_idx].name, "max_open_zones"))
2445 				ctx.params.max_open_zones = strtoul(optarg, NULL, 0);
2446 			if (!strcmp(longopts[option_idx].name, "max_active_zones"))
2447 				ctx.params.max_active_zones = strtoul(optarg, NULL, 0);
2448 			break;
2449 		case '?':
2450 			/*
2451 			 * target requires every option must have argument
2452 			 */
2453 			if (argv[optind][0] == '-' || argv[optind - 1][0] != '-') {
2454 				fprintf(stderr, "every target option requires argument: %s %s\n",
2455 						argv[optind - 1], argv[optind]);
2456 				exit(EXIT_FAILURE);
2457 			}
2458 
2459 			if (tgt_argc < (MAX_NR_TGT_ARG - 1) / 2) {
2460 				tgt_argv[tgt_argc++] = argv[optind - 1];
2461 				tgt_argv[tgt_argc++] = argv[optind];
2462 			} else {
2463 				fprintf(stderr, "too many target options\n");
2464 				exit(EXIT_FAILURE);
2465 			}
2466 			optind += 1;
2467 			break;
2468 		}
2469 	}
2470 
2471 	if (ctx.per_io_tasks && (ctx.flags & UBLK_F_BATCH_IO)) {
2472 		ublk_err("per_io_task and F_BATCH_IO conflict\n");
2473 		return -EINVAL;
2474 	}
2475 
2476 	/* auto_zc_fallback depends on F_AUTO_BUF_REG & F_SUPPORT_ZERO_COPY */
2477 	if (ctx.auto_zc_fallback &&
2478 	    !((ctx.flags & UBLK_F_AUTO_BUF_REG) &&
2479 		    (ctx.flags & UBLK_F_SUPPORT_ZERO_COPY))) {
2480 		ublk_err("%s: auto_zc_fallback is set but neither "
2481 				"F_AUTO_BUF_REG nor F_SUPPORT_ZERO_COPY is enabled\n",
2482 					__func__);
2483 		return -EINVAL;
2484 	}
2485 
2486 	if (!!(ctx.flags & UBLK_F_NEED_GET_DATA) +
2487 	    !!(ctx.flags & UBLK_F_USER_COPY) +
2488 	    (ctx.flags & UBLK_F_SUPPORT_ZERO_COPY && !ctx.auto_zc_fallback) +
2489 	    (ctx.flags & UBLK_F_AUTO_BUF_REG && !ctx.auto_zc_fallback) +
2490 	    ctx.auto_zc_fallback > 1) {
2491 		fprintf(stderr, "too many data copy modes specified\n");
2492 		return -EINVAL;
2493 	}
2494 
2495 	if (ctx.metadata_size) {
2496 		if (!(ctx.flags & UBLK_F_USER_COPY)) {
2497 			ublk_err("integrity requires user_copy\n");
2498 			return -EINVAL;
2499 		}
2500 
2501 		ctx.flags |= UBLK_F_INTEGRITY;
2502 	} else if (ctx.integrity_flags ||
2503 		   ctx.pi_offset ||
2504 		   ctx.csum_type != LBMD_PI_CSUM_NONE ||
2505 		   ctx.tag_size) {
2506 		ublk_err("integrity parameters require metadata_size\n");
2507 		return -EINVAL;
2508 	}
2509 
2510 	if ((ctx.flags & UBLK_F_AUTO_BUF_REG) &&
2511 			(ctx.flags & UBLK_F_BATCH_IO) &&
2512 			(ctx.nthreads > ctx.nr_hw_queues)) {
2513 		ublk_err("too many threads for F_AUTO_BUF_REG & F_BATCH_IO\n");
2514 		return -EINVAL;
2515 	}
2516 
2517 	if (ctx.rotate_auto_buf &&
2518 	    !((ctx.flags & UBLK_F_AUTO_BUF_REG) &&
2519 	      (ctx.flags & UBLK_F_BATCH_IO))) {
2520 		ublk_err("rotate_auto_buf requires --auto_zc and --batch\n");
2521 		return -EINVAL;
2522 	}
2523 
2524 	i = optind;
2525 	while (i < argc && ctx.nr_files < MAX_BACK_FILES) {
2526 		ctx.files[ctx.nr_files++] = argv[i++];
2527 	}
2528 
2529 	ops = ublk_find_tgt(ctx.tgt_type);
2530 	if (ops && ops->parse_cmd_line) {
2531 		optind = 0;
2532 
2533 		tgt_argv[0] = ctx.tgt_type;
2534 		ops->parse_cmd_line(&ctx, tgt_argc, tgt_argv);
2535 	}
2536 
2537 	if (!strcmp(cmd, "set_params"))
2538 		ret = cmd_dev_set_params(&ctx);
2539 	else if (!strcmp(cmd, "add"))
2540 		ret = cmd_dev_add(&ctx);
2541 	else if (!strcmp(cmd, "recover")) {
2542 		if (ctx.dev_id < 0) {
2543 			fprintf(stderr, "device id isn't provided for recovering\n");
2544 			ret = -EINVAL;
2545 		} else {
2546 			ctx.recovery = 1;
2547 			ret = cmd_dev_add(&ctx);
2548 		}
2549 	} else if (!strcmp(cmd, "del"))
2550 		ret = cmd_dev_del(&ctx);
2551 	else if (!strcmp(cmd, "stop"))
2552 		ret = cmd_dev_stop(&ctx);
2553 	else if (!strcmp(cmd, "list")) {
2554 		ctx.all = 1;
2555 		ret = cmd_dev_list(&ctx);
2556 	} else if (!strcmp(cmd, "help"))
2557 		ret = cmd_dev_help(argv[0]);
2558 	else if (!strcmp(cmd, "features"))
2559 		ret = cmd_dev_get_features();
2560 	else if (!strcmp(cmd, "update_size"))
2561 		ret = cmd_dev_update_size(&ctx);
2562 	else if (!strcmp(cmd, "quiesce"))
2563 		ret = cmd_dev_quiesce(&ctx);
2564 	else
2565 		cmd_dev_help(argv[0]);
2566 
2567 	return ret;
2568 }
2569