source: rtems/testsuites/fstests/fsimfsgeneric01/init.c @ a9df916

4.11
Last change on this file since a9df916 was a9df916, checked in by Sebastian Huber <sebastian.huber@…>, on Feb 8, 2015 at 6:43:09 PM

IMFS: Add fine grained configuration

Remove miniIMFS. Statically initialize the root IMFS.

Add configuration options to disable individual
features of the root IMFS, e.g.

o CONFIGURE_IMFS_DISABLE_CHOWN,
o CONFIGURE_IMFS_DISABLE_FCHMOD,
o CONFIGURE_IMFS_DISABLE_LINK,
o CONFIGURE_IMFS_DISABLE_MKNOD,
o CONFIGURE_IMFS_DISABLE_MOUNT,
o CONFIGURE_IMFS_DISABLE_READLINK,
o CONFIGURE_IMFS_DISABLE_RENAME,
o CONFIGURE_IMFS_DISABLE_RMNOD,
o CONFIGURE_IMFS_DISABLE_SYMLINK,
o CONFIGURE_IMFS_DISABLE_UNMOUNT, and
o CONFIGURE_IMFS_DISABLE_UTIME.

  • Property mode set to 100644
File size: 9.8 KB
Line 
1/*
2 * Copyright (c) 2012-2014 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include "tmacros.h"
20
21#include <sys/stat.h>
22#include <sys/ioctl.h>
23#include <sys/uio.h>
24#include <fcntl.h>
25#include <unistd.h>
26#include <errno.h>
27
28#include <rtems/imfs.h>
29#include <rtems/malloc.h>
30#include <rtems/libcsupport.h>
31
32const char rtems_test_name[] = "FSIMFSGENERIC 1";
33
34typedef enum {
35  TEST_NEW,
36  TEST_INITIALIZED,
37  TEST_FSTAT_OPEN_0,
38  TEST_FSTAT_OPEN_1,
39  TEST_OPEN,
40  TEST_READ,
41  TEST_WRITE,
42  TEST_IOCTL,
43  TEST_LSEEK,
44  TEST_FTRUNCATE,
45  TEST_FSYNC,
46  TEST_FDATASYNC,
47  TEST_FCNTL,
48  TEST_READV,
49  TEST_WRITEV,
50  TEST_CLOSED,
51  TEST_FSTAT_UNLINK,
52  TEST_REMOVED,
53  TEST_DESTROYED
54} test_state;
55
56static int handler_open(
57  rtems_libio_t *iop,
58  const char *path,
59  int oflag,
60  mode_t mode
61)
62{
63  test_state *state = IMFS_generic_get_context_by_iop(iop);
64
65  rtems_test_assert(*state == TEST_FSTAT_OPEN_1);
66  *state = TEST_OPEN;
67
68  return 0;
69}
70
71static int handler_close(
72  rtems_libio_t *iop
73)
74{
75  test_state *state = IMFS_generic_get_context_by_iop(iop);
76
77  rtems_test_assert(*state == TEST_WRITEV);
78  *state = TEST_CLOSED;
79
80  return 0;
81}
82
83static ssize_t handler_read(
84  rtems_libio_t *iop,
85  void *buffer,
86  size_t count
87)
88{
89  test_state *state = IMFS_generic_get_context_by_iop(iop);
90
91  rtems_test_assert(*state == TEST_OPEN);
92  *state = TEST_READ;
93
94  return 0;
95}
96
97static ssize_t handler_write(
98  rtems_libio_t *iop,
99  const void *buffer,
100  size_t count
101)
102{
103  test_state *state = IMFS_generic_get_context_by_iop(iop);
104
105  rtems_test_assert(*state == TEST_READ);
106  *state = TEST_WRITE;
107
108  return 0;
109}
110
111static int handler_ioctl(
112  rtems_libio_t *iop,
113  uint32_t request,
114  void *buffer
115)
116{
117  test_state *state = IMFS_generic_get_context_by_iop(iop);
118
119  rtems_test_assert(*state == TEST_WRITE);
120  *state = TEST_IOCTL;
121
122  return 0;
123}
124
125static off_t handler_lseek(
126  rtems_libio_t *iop,
127  off_t length,
128  int whence
129)
130{
131  test_state *state = IMFS_generic_get_context_by_iop(iop);
132
133  rtems_test_assert(*state == TEST_IOCTL);
134  *state = TEST_LSEEK;
135
136  return 0;
137}
138
139static int handler_fstat(
140  const rtems_filesystem_location_info_t *loc,
141  struct stat *buf
142)
143{
144  test_state *state = IMFS_generic_get_context_by_location(loc);
145
146  switch (*state) {
147    case TEST_INITIALIZED:
148      *state = TEST_FSTAT_OPEN_0;
149      break;
150    case TEST_FSTAT_OPEN_0:
151      *state = TEST_FSTAT_OPEN_1;
152      break;
153    case TEST_CLOSED:
154      *state = TEST_FSTAT_UNLINK;
155      break;
156    default:
157      printk("x\n");
158      //rtems_test_assert(0);
159      break;
160  }
161
162  buf->st_mode = S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO;
163
164  return 0;
165}
166
167static int handler_ftruncate(
168  rtems_libio_t *iop,
169  off_t length
170)
171{
172  test_state *state = IMFS_generic_get_context_by_iop(iop);
173
174  rtems_test_assert(*state == TEST_LSEEK);
175  *state = TEST_FTRUNCATE;
176
177  return 0;
178}
179
180static int handler_fsync(
181  rtems_libio_t *iop
182)
183{
184  test_state *state = IMFS_generic_get_context_by_iop(iop);
185
186  rtems_test_assert(*state == TEST_FTRUNCATE);
187  *state = TEST_FSYNC;
188
189  return 0;
190}
191
192static int handler_fdatasync(
193  rtems_libio_t *iop
194)
195{
196  test_state *state = IMFS_generic_get_context_by_iop(iop);
197
198  rtems_test_assert(*state == TEST_FSYNC);
199  *state = TEST_FDATASYNC;
200
201  return 0;
202}
203
204static int handler_fcntl(
205  rtems_libio_t *iop,
206  int cmd
207)
208{
209  test_state *state = IMFS_generic_get_context_by_iop(iop);
210
211  rtems_test_assert(*state == TEST_FDATASYNC);
212  *state = TEST_FCNTL;
213
214  return 0;
215}
216
217static ssize_t handler_readv(
218  rtems_libio_t *iop,
219  const struct iovec *iov,
220  int iovcnt,
221  ssize_t total
222)
223{
224  test_state *state = IMFS_generic_get_context_by_iop(iop);
225
226  rtems_test_assert(*state == TEST_FCNTL);
227  *state = TEST_READV;
228
229  return 0;
230}
231
232static ssize_t handler_writev(
233  rtems_libio_t *iop,
234  const struct iovec *iov,
235  int iovcnt,
236  ssize_t total
237)
238{
239  test_state *state = IMFS_generic_get_context_by_iop(iop);
240
241  rtems_test_assert(*state == TEST_READV);
242  *state = TEST_WRITEV;
243
244  return 0;
245}
246
247static const rtems_filesystem_file_handlers_r node_handlers = {
248  .open_h = handler_open,
249  .close_h = handler_close,
250  .read_h = handler_read,
251  .write_h = handler_write,
252  .ioctl_h = handler_ioctl,
253  .lseek_h = handler_lseek,
254  .fstat_h = handler_fstat,
255  .ftruncate_h = handler_ftruncate,
256  .fsync_h = handler_fsync,
257  .fdatasync_h = handler_fdatasync,
258  .fcntl_h = handler_fcntl,
259  .readv_h = handler_readv,
260  .writev_h = handler_writev
261};
262
263static IMFS_jnode_t *node_initialize(
264  IMFS_jnode_t *node,
265  void *arg
266)
267{
268  test_state *state = NULL;
269
270  node = IMFS_node_initialize_generic(node, arg);
271  state = IMFS_generic_get_context_by_node(node);
272
273  rtems_test_assert(*state == TEST_NEW);
274  *state = TEST_INITIALIZED;
275
276  return node;
277}
278
279static IMFS_jnode_t *node_remove(IMFS_jnode_t *node)
280{
281  test_state *state = IMFS_generic_get_context_by_node(node);
282
283  rtems_test_assert(*state == TEST_FSTAT_UNLINK);
284  *state = TEST_REMOVED;
285
286  return node;
287}
288
289static void node_destroy(IMFS_jnode_t *node)
290{
291  test_state *state = IMFS_generic_get_context_by_node(node);
292
293  rtems_test_assert(*state == TEST_REMOVED);
294  *state = TEST_DESTROYED;
295
296  IMFS_node_destroy_default(node);
297}
298
299static const IMFS_node_control node_control = {
300  .handlers = &node_handlers,
301  .node_initialize = node_initialize,
302  .node_remove = node_remove,
303  .node_destroy = node_destroy
304};
305
306static void test_imfs_make_generic_node(void)
307{
308  test_state state = TEST_NEW;
309  int rv = 0;
310  int fd = 0;
311  const char *path = "generic";
312  char buf [1];
313  ssize_t n = 0;
314  off_t off = 0;
315  struct iovec iov = {
316    .iov_base = &buf [0],
317    .iov_len = (int) sizeof(buf)
318  };
319
320  rv = IMFS_make_generic_node(
321    path,
322    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
323    &node_control,
324    &state
325  );
326  rtems_test_assert(rv == 0);
327
328  fd = open(path, O_RDWR);
329  rtems_test_assert(fd >= 0);
330
331  n = read(fd, buf, sizeof(buf));
332  rtems_test_assert(n == 0);
333
334  n = write(fd, buf, sizeof(buf));
335  rtems_test_assert(n == 0);
336
337  rv = ioctl(fd, 0);
338  rtems_test_assert(rv == 0);
339
340  off = lseek(fd, off, SEEK_SET);
341  rtems_test_assert(off == 0);
342
343  rv = ftruncate(fd, 0);
344  rtems_test_assert(rv == 0);
345
346  rv = fsync(fd);
347  rtems_test_assert(rv == 0);
348
349  rv = fdatasync(fd);
350  rtems_test_assert(rv == 0);
351
352  rv = fcntl(fd, F_GETFD);
353  rtems_test_assert(rv >= 0);
354
355  rv = readv(fd, &iov, 1);
356  rtems_test_assert(rv == 0);
357
358  rv = writev(fd, &iov, 1);
359  rtems_test_assert(rv == 0);
360
361  rv = close(fd);
362  rtems_test_assert(rv == 0);
363
364  rv = unlink(path);
365  rtems_test_assert(rv == 0);
366
367  rtems_test_assert(state == TEST_DESTROYED);
368}
369
370static IMFS_jnode_t *node_initialize_error(
371  IMFS_jnode_t *node,
372  void *arg
373)
374{
375  errno = EIO;
376
377  return NULL;
378}
379
380static IMFS_jnode_t *node_remove_inhibited(IMFS_jnode_t *node)
381{
382  rtems_test_assert(false);
383
384  return node;
385}
386
387static void node_destroy_inhibited(IMFS_jnode_t *node)
388{
389  rtems_test_assert(false);
390}
391
392static const IMFS_node_control node_initialization_error_control = {
393  .handlers = &node_handlers,
394  .node_initialize = node_initialize_error,
395  .node_remove = node_remove_inhibited,
396  .node_destroy = node_destroy_inhibited
397};
398
399static const rtems_filesystem_operations_table *imfs_ops;
400
401static int other_clone(rtems_filesystem_location_info_t *loc)
402{
403  return (*imfs_ops->clonenod_h)(loc);
404}
405
406static void test_imfs_make_generic_node_errors(void)
407{
408  int rv = 0;
409  const char *path = "generic";
410  rtems_chain_control *chain = &rtems_filesystem_mount_table;
411  rtems_filesystem_mount_table_entry_t *mt_entry =
412    (rtems_filesystem_mount_table_entry_t *) rtems_chain_first(chain);
413  rtems_filesystem_operations_table other_ops;
414  void *opaque = NULL;
415  rtems_resource_snapshot before;
416
417  rtems_resource_snapshot_take(&before);
418
419  errno = 0;
420  rv = IMFS_make_generic_node(
421    path,
422    S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO,
423    &node_control,
424    NULL
425  );
426  rtems_test_assert(rv == -1);
427  rtems_test_assert(errno == EINVAL);
428  rtems_test_assert(rtems_resource_snapshot_check(&before));
429
430  errno = 0;
431  imfs_ops = mt_entry->ops;
432  other_ops = *imfs_ops;
433  other_ops.clonenod_h = other_clone;
434  mt_entry->ops = &other_ops;
435  rv = IMFS_make_generic_node(
436    path,
437    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
438    &node_control,
439    NULL
440  );
441  mt_entry->ops = imfs_ops;
442  rtems_test_assert(rv == -1);
443  rtems_test_assert(errno == ENOTSUP);
444  rtems_test_assert(rtems_resource_snapshot_check(&before));
445
446  errno = 0;
447  opaque = rtems_heap_greedy_allocate(NULL, 0);
448  rv = IMFS_make_generic_node(
449    path,
450    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
451    &node_control,
452    NULL
453  );
454  rtems_heap_greedy_free(opaque);
455  rtems_test_assert(rv == -1);
456  rtems_test_assert(errno == ENOMEM);
457  rtems_test_assert(rtems_resource_snapshot_check(&before));
458
459  errno = 0;
460  rv = IMFS_make_generic_node(
461    path,
462    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
463    &node_initialization_error_control,
464    NULL
465  );
466  rtems_test_assert(rv == -1);
467  rtems_test_assert(errno == EIO);
468  rtems_test_assert(rtems_resource_snapshot_check(&before));
469
470  errno = 0;
471  rv = IMFS_make_generic_node(
472    "/nil/nada",
473    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
474    &node_control,
475    NULL
476  );
477  rtems_test_assert(rv == -1);
478  rtems_test_assert(errno == ENOENT);
479  rtems_test_assert(rtems_resource_snapshot_check(&before));
480}
481
482static void Init(rtems_task_argument arg)
483{
484  TEST_BEGIN();
485
486  test_imfs_make_generic_node();
487  test_imfs_make_generic_node_errors();
488
489  TEST_END();
490  rtems_test_exit(0);
491}
492
493#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
494#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
495
496#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4
497
498#define CONFIGURE_MAXIMUM_TASKS 1
499
500#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
501
502#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
503
504#define CONFIGURE_INIT
505
506#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.