aboutsummaryrefslogtreecommitdiff
path: root/test/file-register.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/file-register.c')
-rw-r--r--test/file-register.c117
1 files changed, 114 insertions, 3 deletions
diff --git a/test/file-register.c b/test/file-register.c
index c5c5507..6889dbf 100644
--- a/test/file-register.c
+++ b/test/file-register.c
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
+#include <sys/resource.h>
#include "helpers.h"
#include "liburing.h"
@@ -351,8 +352,9 @@ static int test_basic(struct io_uring *ring, int fail)
{
int *files;
int ret;
+ int nr_files = fail ? 10 : 100;
- files = open_files(fail ? 10 : 100, 0, 0);
+ files = open_files(nr_files, 0, 0);
ret = io_uring_register_files(ring, files, 100);
if (ret) {
if (fail) {
@@ -371,10 +373,10 @@ static int test_basic(struct io_uring *ring, int fail)
fprintf(stderr, "%s: unregister %d\n", __FUNCTION__, ret);
goto err;
}
- close_files(files, 100, 0);
+ close_files(files, nr_files, 0);
return 0;
err:
- close_files(files, 100, 0);
+ close_files(files, nr_files, 0);
return 1;
}
@@ -493,6 +495,18 @@ static int test_fixed_read_write(struct io_uring *ring, int index)
return 0;
}
+static void adjust_nfiles(int want_files)
+{
+ struct rlimit rlim;
+
+ if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
+ return;
+ if (rlim.rlim_cur >= want_files)
+ return;
+ rlim.rlim_cur = want_files;
+ setrlimit(RLIMIT_NOFILE, &rlim);
+}
+
/*
* Register 8K of sparse files, update one at a random spot, then do some
* file IO to verify it works.
@@ -502,6 +516,8 @@ static int test_huge(struct io_uring *ring)
int *files;
int ret;
+ adjust_nfiles(16384);
+
files = open_files(0, 8192, 0);
ret = io_uring_register_files(ring, files, 8192);
if (ret) {
@@ -729,7 +745,90 @@ static int test_fixed_removal_ordering(void)
return 0;
}
+/* mix files requiring SCM-accounting and not in a single register */
+static int test_mixed_af_unix(void)
+{
+ struct io_uring ring;
+ int i, ret, fds[2];
+ int reg_fds[32];
+ int sp[2];
+ ret = io_uring_queue_init(8, &ring, 0);
+ if (ret < 0) {
+ fprintf(stderr, "failed to init io_uring: %s\n", strerror(-ret));
+ return ret;
+ }
+ if (pipe(fds)) {
+ perror("pipe");
+ return -1;
+ }
+ if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sp) != 0) {
+ perror("Failed to create Unix-domain socket pair\n");
+ return 1;
+ }
+
+ for (i = 0; i < 16; i++) {
+ reg_fds[i * 2] = fds[0];
+ reg_fds[i * 2 + 1] = sp[0];
+ }
+
+ ret = io_uring_register_files(&ring, reg_fds, 32);
+ if (ret) {
+ fprintf(stderr, "file_register: %d\n", ret);
+ return ret;
+ }
+
+ close(fds[0]);
+ close(fds[1]);
+ close(sp[0]);
+ close(sp[1]);
+ io_uring_queue_exit(&ring);
+ return 0;
+}
+
+static int test_partial_register_fail(void)
+{
+ char buffer[128];
+ struct io_uring ring;
+ int ret, fds[2];
+ int reg_fds[5];
+
+ ret = io_uring_queue_init(8, &ring, 0);
+ if (ret < 0) {
+ fprintf(stderr, "failed to init io_uring: %s\n", strerror(-ret));
+ return ret;
+ }
+ if (pipe(fds)) {
+ perror("pipe");
+ return -1;
+ }
+
+ /*
+ * Expect register to fail as it doesn't support io_uring fds, shouldn't
+ * leave any fds referenced afterwards.
+ */
+ reg_fds[0] = fds[0];
+ reg_fds[1] = fds[1];
+ reg_fds[2] = -1;
+ reg_fds[3] = ring.ring_fd;
+ reg_fds[4] = -1;
+ ret = io_uring_register_files(&ring, reg_fds, 5);
+ if (!ret) {
+ fprintf(stderr, "file_register unexpectedly succeeded\n");
+ return 1;
+ }
+
+ /* ring should have fds referenced, can close them */
+ close(fds[1]);
+
+ /* confirm that fds[1] is actually close and to ref'ed by io_uring */
+ ret = read(fds[0], buffer, 10);
+ if (ret < 0)
+ perror("read");
+ close(fds[0]);
+ io_uring_queue_exit(&ring);
+ return 0;
+}
int main(int argc, char *argv[])
{
@@ -838,5 +937,17 @@ int main(int argc, char *argv[])
return 1;
}
+ ret = test_mixed_af_unix();
+ if (ret) {
+ printf("test_mixed_af_unix failed\n");
+ return 1;
+ }
+
+ ret = test_partial_register_fail();
+ if (ret) {
+ printf("test_partial_register_fail failed\n");
+ return ret;
+ }
+
return 0;
}