# HG changeset patch # User Paul Boddie # Date 1654457459 -7200 # Node ID 8345cdd26583d4e2c85a52c729082bf9e2c12104 # Parent 6a681557d327e9274ddc8fb1b563c453e1b83a98 Added a test of manual dataspace usage to map memory regions. diff -r 6a681557d327 -r 8345cdd26583 conf/dstest_file_mapping.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/dstest_file_mapping.cfg Sun Jun 05 21:30:59 2022 +0200 @@ -0,0 +1,23 @@ +-- vim:set ft=lua: + +local L4 = require("L4"); + +local l = L4.default_loader; + +local server = l:new_channel(); + +l:startv({ + caps = { + server = server:svr(), + }, + log = { "server", "r" }, + }, + "rom/dstest_host_server", "10"); + +l:startv({ + caps = { + server = server, + }, + log = { "client", "g" }, + }, + "rom/dstest_file_mapping", "rom/dstest_file_mapping.cfg", 1024, 1024); diff -r 6a681557d327 -r 8345cdd26583 conf/dstest_file_mapping.list --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/dstest_file_mapping.list Sun Jun 05 21:30:59 2022 +0200 @@ -0,0 +1,25 @@ +entry dstest_file_mapping +roottask moe rom/dstest_file_mapping.cfg +module dstest_file_mapping.cfg +module l4re +module ned +module dstest_file_mapping +module dstest_host_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 6a681557d327 -r 8345cdd26583 tests/Makefile --- a/tests/Makefile Sun Jun 05 18:50:47 2022 +0200 +++ b/tests/Makefile Sun Jun 05 21:30:59 2022 +0200 @@ -14,7 +14,8 @@ dstest_pipe_client \ dstest_test_client \ dstest_map_test \ - dstest_exec + dstest_exec \ + dstest_file_mapping MODE = static @@ -36,10 +37,14 @@ # Individual interfaces. +CLIENT_INTERFACES_CC = dataspace mapped_file + SERVER_INTERFACES_CC = $(call common_interfaces,$(COMP_INTERFACES_CC)) # Generated and plain source files. +CLIENT_INTERFACES_SRC_CC = $(call interfaces_to_client_cc,$(CLIENT_INTERFACES_CC)) + SERVER_INTERFACES_SRC_CC = $(call interfaces_to_server_cc,$(SERVER_INTERFACES_CC) $(COMP_INTERFACES_CC)) # Normal source files. @@ -71,10 +76,15 @@ PLAIN_SRC_CC_dstest_exec = dstest_exec.cc SRC_CC_dstest_exec = $(PLAIN_SRC_CC_dstest_exec) $(SERVER_INTERFACES_SRC_CC) +PLAIN_SRC_CC_dstest_file_mapping = dstest_file_mapping.cc +SRC_CC_dstest_file_mapping = $(PLAIN_SRC_CC_dstest_file_mapping) $(CLIENT_INTERFACES_SRC_CC) + REQUIRES_LIBS = l4re_c-util libexec libfsclient libmem libipc libstdc++ libsystypes libe2access_blockserver PRIVATE_INCDIR = $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR) include $(L4DIR)/mk/prog.mk include $(IDL_MK_DIR)/interface_rules.mk +$(PLAIN_SRC_CC_dstest_file_mapping): $(CLIENT_INTERFACES_SRC_CC) + $(PLAIN_SRC_CC_dstest_exec): $(SERVER_INTERFACES_SRC_CC) diff -r 6a681557d327 -r 8345cdd26583 tests/dstest_file_mapping.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/dstest_file_mapping.cc Sun Jun 05 21:30:59 2022 +0200 @@ -0,0 +1,143 @@ +/* + * Test dataspace operations. + * + * Copyright (C) 2020, 2021, 2022 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 +#include + +#include "dataspace_client.h" +#include "mapped_file_client.h" + + + +/* NOTE: Copied from libfsclient. */ + +static void _update_extent(file_t *file) +{ + /* Handle files ending after or within the region. */ + + if (file->size > file->start_pos) + { + if (file->size > file->end_pos) + file->data_end = file->end_pos - file->start_pos; + else + file->data_end = file->size - file->start_pos; + } + + /* Handle files ending before the region. */ + + else + file->data_end = 0; +} + + + +int main(int argc, char *argv[]) +{ + if (argc < 4) + { + printf("Need filename, step and sample size.\n"); + return 1; + } + + /* Obtain filename and access parameters. */ + + char *filename = argv[1]; + unsigned long step = atoi(argv[2]); + unsigned long sample = atoi(argv[3]); + + /* Allocate a buffer for sampling from the file. */ + + char buf[sample + 1]; + + /* Obtain access to the filesystem. */ + + l4_cap_idx_t server = l4re_env_get_cap("server"); + + /* Invoke the open method to receive the file reference. */ + + file_t file; + long err = file_open(&file, filename, O_RDWR, server); + + if (err) + { + printf("Could not obtain file: %s\n", l4sys_errtostr(err)); + return 1; + } + + /* A region of the file is mapped. */ + + client_MappedFile mapped_file(file.ref); + + err = mapped_file.mmap(0, page(10), 0, 0, &file.start_pos, &file.end_pos, &file.size); + + if (err) + { + printf("Could not map file region: %s\n", l4sys_errtostr(err)); + return 1; + } + + /* Fix up the file data structure manually. */ + + file.memory = (char *) 0x2000000; + _update_extent(&file); + + /* Explicitly map the file into this address space, without region mapper + usage. The receive window base must be a multiple of its size. */ + + client_Dataspace dataspace(file.ref); + l4_snd_fpage_t region = {0, l4_fpage((l4_addr_t) file.memory, L4_PAGESHIFT + 4, 0)}; + + printf("region = {%lx, {%lx, %d}}\n", region.snd_base, l4_fpage_memaddr(region.fpage), l4_fpage_size(region.fpage)); + + err = dataspace.map(0, 0, L4_FPAGE_RO, ®ion); + + if (err) + { + printf("Could not invoke map successfully: %s\n", l4sys_errtostr(err)); + return 1; + } + + for (unsigned long offset = 0; offset < file_populated_span(&file); offset += step) + { + unsigned long remaining = file_populated_span(&file) - offset; + unsigned long sample_remaining = remaining < sample ? remaining : sample; + + printf("%ld bytes from %p...\n", sample_remaining, (file.memory + offset)); + strncpy(buf, (file.memory + offset), sample_remaining); + buf[sample_remaining] = '\0'; + printf("%s\n", buf); + } + + printf("File shown.\n"); + + return 0; +} + +// vim: tabstop=2 expandtab shiftwidth=2