123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- #include "../config-host.h"
- /* SPDX-License-Identifier: MIT */
- /*
- * Description: run various file registration tests
- *
- */
- #include <errno.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <fcntl.h>
- #include "helpers.h"
- #include "liburing.h"
- static void close_files(int *files, int nr_files, int add)
- {
- char fname[32];
- int i;
- for (i = 0; i < nr_files; i++) {
- if (files)
- close(files[i]);
- if (!add)
- sprintf(fname, ".reg.%d", i);
- else
- sprintf(fname, ".add.%d", i + add);
- unlink(fname);
- }
- if (files)
- free(files);
- }
- static int *open_files(int nr_files, int extra, int add)
- {
- char fname[32];
- int *files;
- int i;
- files = t_calloc(nr_files + extra, sizeof(int));
- for (i = 0; i < nr_files; i++) {
- if (!add)
- sprintf(fname, ".reg.%d", i);
- else
- sprintf(fname, ".add.%d", i + add);
- files[i] = open(fname, O_RDWR | O_CREAT, 0644);
- if (files[i] < 0) {
- perror("open");
- free(files);
- files = NULL;
- break;
- }
- }
- if (extra) {
- for (i = nr_files; i < nr_files + extra; i++)
- files[i] = -1;
- }
- return files;
- }
- static int test_update_multiring(struct io_uring *r1, struct io_uring *r2,
- struct io_uring *r3, int do_unreg)
- {
- int *fds, *newfds;
- fds = open_files(10, 0, 0);
- newfds = open_files(10, 0, 1);
- if (io_uring_register_files(r1, fds, 10) ||
- io_uring_register_files(r2, fds, 10) ||
- io_uring_register_files(r3, fds, 10)) {
- fprintf(stderr, "%s: register files failed\n", __FUNCTION__);
- goto err;
- }
- if (io_uring_register_files_update(r1, 0, newfds, 10) != 10 ||
- io_uring_register_files_update(r2, 0, newfds, 10) != 10 ||
- io_uring_register_files_update(r3, 0, newfds, 10) != 10) {
- fprintf(stderr, "%s: update files failed\n", __FUNCTION__);
- goto err;
- }
- if (!do_unreg)
- goto done;
- if (io_uring_unregister_files(r1) ||
- io_uring_unregister_files(r2) ||
- io_uring_unregister_files(r3)) {
- fprintf(stderr, "%s: unregister files failed\n", __FUNCTION__);
- goto err;
- }
- done:
- close_files(fds, 10, 0);
- close_files(newfds, 10, 1);
- return 0;
- err:
- close_files(fds, 10, 0);
- close_files(newfds, 10, 1);
- return 1;
- }
- static int test_sqe_update(struct io_uring *ring)
- {
- struct io_uring_sqe *sqe;
- struct io_uring_cqe *cqe;
- int *fds, i, ret;
- fds = t_malloc(sizeof(int) * 10);
- for (i = 0; i < 10; i++)
- fds[i] = -1;
- sqe = io_uring_get_sqe(ring);
- io_uring_prep_files_update(sqe, fds, 10, 0);
- ret = io_uring_submit(ring);
- if (ret != 1) {
- fprintf(stderr, "submit: %d\n", ret);
- return 1;
- }
- ret = io_uring_wait_cqe(ring, &cqe);
- if (ret) {
- fprintf(stderr, "wait: %d\n", ret);
- return 1;
- }
- ret = cqe->res;
- io_uring_cqe_seen(ring, cqe);
- free(fds);
- if (ret == -EINVAL) {
- fprintf(stdout, "IORING_OP_FILES_UPDATE not supported, skipping\n");
- return T_EXIT_SKIP;
- }
- return ret != 10;
- }
- static int test_update_no_table(void)
- {
- int up_fd, fds[4] = {-1, 0, 1, 4};
- struct io_uring_sqe *sqe;
- struct io_uring_cqe *cqe;
- struct io_uring ring;
- int ret;
- ret = t_create_ring(2, &ring, 0);
- if (ret == T_SETUP_SKIP)
- return T_EXIT_SKIP;
- else if (ret != T_SETUP_OK)
- return ret;
- ret = io_uring_register_files(&ring, fds, 4);
- /* ignore other failures */
- if (ret && ret != -EBADF) {
- fprintf(stderr, "Failed registering file table: %d\n", ret);
- goto fail;
- }
- sqe = io_uring_get_sqe(&ring);
- up_fd = ring.ring_fd;
- io_uring_prep_files_update(sqe, &up_fd, 1, -1); //offset = -1
- ret = io_uring_submit(&ring);
- if (ret != 1) {
- fprintf(stderr, "Failed submit: %d\n", ret);
- goto fail;
- }
- ret = io_uring_wait_cqe(&ring, &cqe);
- if (ret) {
- fprintf(stderr, "Failed wait: %d\n", ret);
- goto fail;
- }
- ret = cqe->res;
- io_uring_cqe_seen(&ring, cqe);
- if (ret != -EMFILE && ret != -EINVAL && ret != -EOVERFLOW &&
- ret != -ENXIO && ret != -EBADF) {
- fprintf(stderr, "Bad cqe res: %d\n", ret);
- goto fail;
- }
- io_uring_queue_exit(&ring);
- return T_EXIT_PASS;
- fail:
- io_uring_queue_exit(&ring);
- return T_EXIT_FAIL;
- }
- int main(int argc, char *argv[])
- {
- struct io_uring r1, r2, r3;
- int ret;
- if (argc > 1)
- return T_EXIT_SKIP;
- if (io_uring_queue_init(8, &r1, 0) ||
- io_uring_queue_init(8, &r2, 0) ||
- io_uring_queue_init(8, &r3, 0)) {
- fprintf(stderr, "ring setup failed\n");
- return 1;
- }
- ret = test_update_multiring(&r1, &r2, &r3, 1);
- if (ret) {
- fprintf(stderr, "test_update_multiring w/unreg\n");
- return ret;
- }
- ret = test_update_multiring(&r1, &r2, &r3, 0);
- if (ret) {
- fprintf(stderr, "test_update_multiring wo/unreg\n");
- return ret;
- }
- ret = test_sqe_update(&r1);
- if (ret) {
- if (ret != T_EXIT_SKIP)
- fprintf(stderr, "test_sqe_update failed\n");
- return ret;
- }
- ret = test_update_no_table();
- if (ret) {
- if (ret != T_EXIT_SKIP)
- fprintf(stderr, "test_sqe_update failed\n");
- return ret;
- }
- return T_EXIT_PASS;
- }
|