L4Re/departure

Annotated tests/dstest_block_client.cc

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