# HG changeset patch # User Paul Boddie # Date 1634079100 -7200 # Node ID b8bbb7ab64fefac4da924fd8ae15bd8a4f8f3faa # Parent 5bb0970d9eb6ef3a1916eb42ec3d9998d9f6bd07 Added a test of concurrent operations during directory reading. diff -r 5bb0970d9eb6 -r b8bbb7ab64fe conf/dstest_file_readdir_concurrent.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/dstest_file_readdir_concurrent.cfg Wed Oct 13 00:51:40 2021 +0200 @@ -0,0 +1,51 @@ +-- vim:set ft=lua: + +local L4 = require("L4"); + +local l = L4.default_loader; + +local pipe_server = l:new_channel(); + +l:startv({ + caps = { + server = pipe_server:svr(), + }, + log = { "pipes", "r" }, + }, + "rom/dstest_pipe_server", "10"); + +local block_server = l:new_channel(); + +l:startv({ + caps = { + server = block_server:svr(), + }, + log = { "blocksvr", "r" }, + }, + "rom/dstest_block_server", "10"); + +local ext2svr = l:new_channel(); + +l:startv({ + caps = { + blocksvr = block_server, + pipes = pipe_server, + ext2svr = ext2svr:svr(), + }, + log = { "ext2svr", "y" }, + }, + "rom/dstest_ext2_server", "blocksvr", "rom/e2test.fs", "10", "ext2svr"); + +-- Obtain user filesystems with umask 0022 (18). + +local open_for_user = 6; +local ext2svr_paulb = L4.cast(L4.Proto.Factory, ext2svr):create(open_for_user, 1000, 1000, 18); + +l:startv({ + caps = { + server = ext2svr_paulb, + }, + log = { "client", "g" }, + }, + -- program, directory to read + "rom/dstest_file_readdir_concurrent", "home/paulb/many"); diff -r 5bb0970d9eb6 -r b8bbb7ab64fe conf/dstest_file_readdir_concurrent.list --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/dstest_file_readdir_concurrent.list Wed Oct 13 00:51:40 2021 +0200 @@ -0,0 +1,28 @@ +entry dstest_file_readdir_concurrent +roottask moe rom/dstest_file_readdir_concurrent.cfg +module dstest_file_readdir_concurrent.cfg +module e2test.fs +module l4re +module ned +module dstest_file_readdir_concurrent +module dstest_ext2_server +module dstest_block_server +module dstest_pipe_server +module lib4re-c.so +module lib4re-c-util.so +module lib4re.so +module lib4re-util.so +module libc_be_l4refile.so +module libc_be_l4re.so +module libc_be_socket_noop.so +module libc_support_misc.so +module libdl.so +module libipc.so +module libl4sys-direct.so +module libl4sys.so +module libl4util.so +module libld-l4.so +module libpthread.so +module libstdc++.so +module libsupc++.so +module libuc_c.so diff -r 5bb0970d9eb6 -r b8bbb7ab64fe tests/Makefile --- a/tests/Makefile Wed Oct 13 00:50:33 2021 +0200 +++ b/tests/Makefile Wed Oct 13 00:51:40 2021 +0200 @@ -7,6 +7,7 @@ dstest_file_client \ dstest_file_monitor \ dstest_file_readdir \ + dstest_file_readdir_concurrent \ dstest_host_client \ dstest_pipe_client \ dstest_test_client @@ -25,6 +26,8 @@ SRC_CC_dstest_file_readdir = dstest_file_readdir.cc +SRC_CC_dstest_file_readdir_concurrent = dstest_file_readdir_concurrent.cc + SRC_CC_dstest_host_client = dstest_host_client.cc SRC_CC_dstest_pipe_client = dstest_pipe_client.cc diff -r 5bb0970d9eb6 -r b8bbb7ab64fe tests/dstest_file_readdir_concurrent.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/dstest_file_readdir_concurrent.cc Wed Oct 13 00:51:40 2021 +0200 @@ -0,0 +1,161 @@ +/* + * Test directory reading operations, exploring concurrency issues. + * + * Copyright (C) 2020, 2021 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include +#include + +#include +#include +#include + +#include +#include + + + +static file_t *open_directory(char *filename, bool have_uid, sys_uid_t uid) +{ + /* With a user, open a user-specific file opener. */ + + if (have_uid) + { + l4_cap_idx_t opener = client_open_for_user((user_t) {uid, uid, 0022}); + + if (l4_is_invalid_cap(opener)) + { + printf("Could not obtain opener for file.\n"); + return NULL; + } + + /* Invoke the open method to receive the file reference. */ + + return client_opendir_using(filename, opener); + } + else + { + return client_opendir(filename); + } +} + +static file_t *open_file(char *filename, bool have_uid, sys_uid_t uid) +{ + /* With a user, open a user-specific file opener. */ + + if (have_uid) + { + l4_cap_idx_t opener = client_open_for_user((user_t) {uid, uid, 0022}); + + if (l4_is_invalid_cap(opener)) + { + printf("Could not obtain opener for file.\n"); + return NULL; + } + + /* Invoke the open method to receive the file reference. */ + + return client_open_using(filename, O_RDWR | O_CREAT, opener); + } + else + { + return client_open(filename, O_RDWR | O_CREAT); + } +} + + + +int main(int argc, char *argv[]) +{ + if (argc < 2) + { + printf("Need a directory name and an optional user identifier (if used with a filesystem).\n"); + return 1; + } + + char *filename = argv[1]; + bool have_uid = (argc > 2) && strlen(argv[2]); + sys_uid_t uid = have_uid ? atoi(argv[2]) : 0; + + printf("Opening %s...\n", filename); + + file_t *reader = open_directory(filename, have_uid, uid); + + if (reader == NULL) + { + printf("Could not read from directory.\n"); + return 1; + } + + printf("Reading...\n"); + + struct dirent *dirent; + int filenum = 1000, remaining = 100; + char buffer[strlen(filename) + strlen("/file-XXXX.txt") + 10]; + int found = 0; + + while ((dirent = client_readdir(reader)) != NULL) + { + free(dirent); + found++; + + /* Create files while getting the listing. */ + + if (remaining) + { + sprintf(buffer, "%s/file-%d.txt", filename, filenum++); + + file_t *file = open_file(buffer, have_uid, uid); + + if (file == NULL) + { + printf("Could not open file: %s\n", buffer); + return 1; + } + + remaining--; + } + } + + printf("Files found: %d\n", found); + + /* Re-read, counting files. */ + + reader = open_directory(filename, have_uid, uid); + + if (reader == NULL) + { + printf("Could not read from directory.\n"); + return 1; + } + + found = 0; + + while ((dirent = client_readdir(reader)) != NULL) + { + free(dirent); + found++; + } + + printf("Files found: %d\n", found); + + return 0; +} + +// vim: tabstop=2 expandtab shiftwidth=2