L4Re/departure

tests/dstest_block_client.cc

339:8349c51951e2
2022-05-22 Paul Boddie Changed the mmap interface to employ explicit visible region limits. mmap-region-flags
     1 /*     2  * Test dataspace operations.     3  *     4  * Copyright (C) 2020, 2021, 2022 Paul Boddie <paul@boddie.org.uk>     5  *     6  * This program is free software; you can redistribute it and/or     7  * modify it under the terms of the GNU General Public License as     8  * published by the Free Software Foundation; either version 2 of     9  * the License, or (at your option) any later version.    10  *    11  * This program is distributed in the hope that it will be useful,    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    14  * GNU General Public License for more details.    15  *    16  * You should have received a copy of the GNU General Public License    17  * along with this program; if not, write to the Free Software    18  * Foundation, Inc., 51 Franklin Street, Fifth Floor,    19  * Boston, MA  02110-1301, USA    20  */    21     22 #include <l4/re/env.h>    23 #include <l4/sys/err.h>    24     25 #include <systypes/fcntl.h>    26     27 #include <stdio.h>    28 #include <string.h>    29 #include <stdlib.h>    30     31 #include <fsclient/file.h>    32 #include <mem/memory_utils.h>    33     34     35     36 static void show(file_t *file, unsigned long step, unsigned long sample)    37 {    38   /* Allocate a buffer for sampling from the file. */    39     40   char buf[sample + 1];    41     42   for (unsigned long offset = 0; offset < file_populated_span(file); offset += step)    43   {    44     unsigned long remaining = file_populated_span(file) - offset;    45     unsigned long sample_remaining = remaining < sample ? remaining : sample;    46     47     printf("%ld bytes from %p...\n", sample_remaining, (file->memory + offset));    48     memcpy(buf, (file->memory + offset), sample_remaining);    49     buf[sample_remaining] = '\0';    50     51     unsigned long leading = 0;    52     char *outbuf = buf;    53     54     while ((*outbuf == '\0') && (leading < sample_remaining))    55     {    56       outbuf++;    57       leading++;    58     }    59     60     if (leading)    61       printf("[%ld zero bytes]\n", leading);    62     63     printf("%s\n", outbuf);    64     65     printf("[%ld bytes after string]\n", sample_remaining - leading - strlen(outbuf));    66   }    67 }    68     69 int main(int argc, char *argv[])    70 {    71   if (argc < 4)    72   {    73     printf("Need filename, step and sample size.\n");    74     return 1;    75   }    76     77   /* Obtain filename and access parameters. */    78     79   char *filename = argv[1];    80   unsigned long step = atoi(argv[2]);    81   unsigned long sample = atoi(argv[3]);    82     83   /* Obtain access to the filesystem. */    84     85   l4_cap_idx_t server = l4re_env_get_cap("server");    86     87   /* Invoke the open method to receive the file reference. */    88     89   file_t file;    90   long err = file_open(&file, filename, O_RDWR, server);    91     92   if (err)    93   {    94     printf("Could not obtain file: %s\n", l4sys_errtostr(err));    95     return 1;    96   }    97     98   /* A region of the file is mapped. Here, the start and length will not provide    99      page-aligned offsets, but the region is nevertheless not masked. */   100    101   err = file_mmap(&file, 10, 290, 0, 0, file_region_flags(file.flags));   102    103   if (err)   104   {   105     printf("Could not map file region: %s\n", l4sys_errtostr(err));   106     return 1;   107   }   108    109   printf("File contents:\n");   110    111   show(&file, step, sample);   112    113   printf("File shown.\n");   114    115   /* A region of the file is mapped. Here, the resulting offsets will be used to   116      define a masked region. */   117    118   err = file_mmap(&file, 10, 290, 10, 290, file_region_flags(file.flags));   119    120   if (err)   121   {   122     printf("Could not map file region: %s\n", l4sys_errtostr(err));   123     return 1;   124   }   125    126   printf("File contents:\n");   127    128   show(&file, step, sample);   129    130   printf("File shown.\n");   131    132   /* Resizing must occur before writing beyond the end of file. Otherwise, the   133      data may get discarded if the supporting flexpage needs to be flushed. */   134    135   offset_t old_size = file_populated_span(&file);   136   offset_t new_region = round(old_size, page(1));   137   offset_t new_size = new_region + old_size;   138    139   printf("Resize to %ld...\n", new_size);   140    141   err = file_resize(&file, new_size);   142    143   if (err)   144   {   145     printf("Could not resize file: %s\n", l4sys_errtostr(err));   146     return 1;   147   }   148    149   printf("Resized file...\n");   150    151   /* Re-map to avoid masking the region. */   152    153   err = file_mmap(&file, 10, new_size - 20, 0, 0, file_region_flags(file.flags));   154    155   if (err)   156   {   157     printf("Could not map file region: %s\n", l4sys_errtostr(err));   158     return 1;   159   }   160    161   /* Copy the sampled data to another file region. */   162    163   printf("Copy data to %ld...\n", new_region);   164    165   for (unsigned long offset = 0; offset < old_size; offset += step)   166   {   167     printf("Copying to %ld...\n", new_region + offset);   168     memcpy(file.memory + new_region + offset, file.memory + offset, sample);   169     if (step > sample)   170       memset(file.memory + new_region + offset + sample, 0, step - sample);   171   }   172    173   printf("File contents:\n");   174    175   show(&file, step, sample);   176    177   printf("File shown.\n");   178    179   /* Re-map to mask the region again. */   180    181   err = file_mmap(&file, 0, new_size, 10, new_size - 20, file_region_flags(file.flags));   182    183   if (err)   184   {   185     printf("Could not map file region: %s\n", l4sys_errtostr(err));   186     return 1;   187   }   188    189   printf("File contents:\n");   190    191   show(&file, step, sample);   192    193   printf("File shown.\n");   194    195   return 0;   196 }   197    198 // vim: tabstop=2 expandtab shiftwidth=2