Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:32

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup tests
0007  *
0008  * @brief Block device tests.
0009  */
0010 
0011 /*
0012  * Copyright (c) 2012 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #ifdef HAVE_CONFIG_H
0037 #include "config.h"
0038 #endif
0039 
0040 #include "tmacros.h"
0041 
0042 #include <sys/stat.h>
0043 #include <stdio.h>
0044 #include <fcntl.h>
0045 #include <stdlib.h>
0046 #include <unistd.h>
0047 
0048 #include <rtems.h>
0049 #include <rtems/ramdisk.h>
0050 #include <rtems/diskdevs.h>
0051 #include <rtems/malloc.h>
0052 
0053 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0054 
0055 const char rtems_test_name[] = "BLOCK 11";
0056 
0057 #define ASSERT_SC(sc) rtems_test_assert((sc) == RTEMS_SUCCESSFUL)
0058 
0059 #define CHUNK_MAX 32U
0060 
0061 #define AREA_SIZE ((CHUNK_MAX * (CHUNK_MAX + 1U)) / 2U)
0062 
0063 #define BLOCK_SIZE 4U
0064 
0065 #define BLOCK_COUNT (AREA_SIZE / BLOCK_SIZE)
0066 
0067 static const char rda [] = "/dev/rda";
0068 
0069 static const char rda1 [] = "/dev/rda1";
0070 
0071 static const char dev_invalid [] = "/dev/invalid";
0072 
0073 static const char not_exist [] = "not_exist";
0074 
0075 static const char not_blkdev [] = "not_blkdev";
0076 
0077 static const char invalid_blkdev [] = "invalid_blkdev";
0078 
0079 static long area_a [AREA_SIZE / sizeof(long)];
0080 
0081 static long area_b [AREA_SIZE / sizeof(long)];
0082 
0083 static rtems_status_code invalid_initialize(
0084   rtems_device_major_number major,
0085   rtems_device_minor_number minor,
0086   void *arg
0087 )
0088 {
0089   rtems_status_code sc;
0090 
0091   sc = rtems_io_register_name(&dev_invalid[0], major, 0);
0092   ASSERT_SC(sc);
0093 
0094   return sc;
0095 }
0096 
0097 static rtems_status_code invalid_control(
0098   rtems_device_major_number major,
0099   rtems_device_minor_number minor,
0100   void *arg
0101 )
0102 {
0103   return RTEMS_INVALID_NUMBER;
0104 }
0105 
0106 static void area_init(long *area)
0107 {
0108   size_t i;
0109   size_t n = AREA_SIZE / sizeof(long);
0110 
0111   for (i = 0; i < n; ++i) {
0112     area [i] = mrand48();
0113   }
0114 }
0115 
0116 static void area_read(int fd, long *area)
0117 {
0118   size_t i;
0119   size_t n = CHUNK_MAX;
0120   char *dst = (char *) area;
0121 
0122   for (i = 0; i <= n; ++i) {
0123     ssize_t m = read(fd, dst, i);
0124     rtems_test_assert(m == (ssize_t) i);
0125     dst += i;
0126   }
0127 }
0128 
0129 static void area_write(int fd, const long *area)
0130 {
0131   size_t i;
0132   size_t n = CHUNK_MAX;
0133   const char *src = (const char *) area;
0134 
0135   for (i = 0; i <= n; ++i) {
0136     ssize_t m = write(fd, src, i);
0137     rtems_test_assert(m == (ssize_t) i);
0138     src += i;
0139   }
0140 }
0141 
0142 static void area_compare(const long *area_a, const long *area_b, bool equal)
0143 {
0144   bool actual_equal = memcmp(area_a, area_b, AREA_SIZE) == 0;
0145   rtems_test_assert(actual_equal == equal);
0146 }
0147 
0148 static void test_blkdev_imfs_read_and_write(void)
0149 {
0150   rtems_status_code sc;
0151   int rv;
0152   ramdisk *rd;
0153   int fd;
0154   off_t off;
0155 
0156   rd = ramdisk_allocate(area_a, BLOCK_SIZE, BLOCK_COUNT, false);
0157   rtems_test_assert(rd != NULL);
0158 
0159   ramdisk_enable_free_at_delete_request(rd);
0160 
0161   sc = rtems_blkdev_create(
0162     rda,
0163     BLOCK_SIZE,
0164     BLOCK_COUNT,
0165     ramdisk_ioctl,
0166     rd
0167   );
0168   ASSERT_SC(sc);
0169 
0170   fd = open(rda, O_RDWR);
0171   rtems_test_assert(fd >= 0);
0172 
0173   area_init(area_a);
0174   area_read(fd, area_b);
0175   area_compare(area_a, area_b, true);
0176 
0177   off = lseek(fd, 0, SEEK_SET);
0178   rtems_test_assert(off == 0);
0179 
0180   area_init(area_b);
0181   area_write(fd, area_b);
0182   area_compare(area_a, area_b, false);
0183 
0184   rv = close(fd);
0185   rtems_test_assert(rv == 0);
0186 
0187   rv = unlink(rda);
0188   rtems_test_assert(rv == 0);
0189 
0190   area_compare(area_a, area_b, true);
0191 }
0192 
0193 static void test_blkdev_imfs_parameters(void)
0194 {
0195   rtems_status_code sc;
0196   int rv;
0197   ramdisk *rd;
0198   int fd;
0199   rtems_disk_device *dd;
0200   struct stat st;
0201 
0202   rd = ramdisk_allocate(NULL, BLOCK_SIZE, BLOCK_COUNT, false);
0203   rtems_test_assert(rd != NULL);
0204 
0205   ramdisk_enable_free_at_delete_request(rd);
0206 
0207   sc = rtems_blkdev_create(
0208     rda,
0209     BLOCK_SIZE,
0210     BLOCK_COUNT,
0211     ramdisk_ioctl,
0212     rd
0213   );
0214   ASSERT_SC(sc);
0215 
0216   sc = rtems_blkdev_create_partition(
0217     rda1,
0218     rda,
0219     1,
0220     BLOCK_COUNT - 1
0221   );
0222   ASSERT_SC(sc);
0223 
0224   fd = open(rda, O_RDWR);
0225   rtems_test_assert(fd >= 0);
0226 
0227   rv = fstat(fd, &st);
0228   rtems_test_assert(rv == 0);
0229 
0230   rv = rtems_disk_fd_get_disk_device(fd, &dd);
0231   rtems_test_assert(rv == 0);
0232 
0233   rtems_test_assert(rtems_disk_get_driver_data(dd) == rd);
0234   rtems_test_assert(rtems_disk_get_device_identifier(dd) == st.st_rdev);
0235   rtems_test_assert(rtems_disk_get_media_block_size(dd) == BLOCK_SIZE);
0236   rtems_test_assert(rtems_disk_get_block_size(dd) == BLOCK_SIZE);
0237   rtems_test_assert(rtems_disk_get_block_begin(dd) == 0);
0238   rtems_test_assert(rtems_disk_get_block_count(dd) == BLOCK_COUNT);
0239 
0240   rv = close(fd);
0241   rtems_test_assert(rv == 0);
0242 
0243   fd = open(rda1, O_RDWR);
0244   rtems_test_assert(fd >= 0);
0245 
0246   rv = fstat(fd, &st);
0247   rtems_test_assert(rv == 0);
0248 
0249   rv = rtems_disk_fd_get_disk_device(fd, &dd);
0250   rtems_test_assert(rv == 0);
0251 
0252   rtems_test_assert(rtems_disk_get_driver_data(dd) == rd);
0253   rtems_test_assert(rtems_disk_get_device_identifier(dd) == st.st_rdev);
0254   rtems_test_assert(rtems_disk_get_media_block_size(dd) == BLOCK_SIZE);
0255   rtems_test_assert(rtems_disk_get_block_size(dd) == BLOCK_SIZE);
0256   rtems_test_assert(rtems_disk_get_block_begin(dd) == 1);
0257   rtems_test_assert(rtems_disk_get_block_count(dd) == BLOCK_COUNT - 1);
0258 
0259   rv = close(fd);
0260   rtems_test_assert(rv == 0);
0261 
0262   rv = unlink(rda1);
0263   rtems_test_assert(rv == 0);
0264 
0265   rv = unlink(rda);
0266   rtems_test_assert(rv == 0);
0267 }
0268 
0269 static void test_blkdev_imfs_errors(void)
0270 {
0271   static uintptr_t disk_size [] = { sizeof(rtems_disk_device) + sizeof(int) };
0272 
0273   rtems_status_code sc;
0274   int rv;
0275   ramdisk *rd;
0276   void *opaque;
0277   struct stat st;
0278 
0279   rd = ramdisk_allocate(NULL, BLOCK_SIZE, BLOCK_COUNT, false);
0280   rtems_test_assert(rd != NULL);
0281 
0282   ramdisk_enable_free_at_delete_request(rd);
0283 
0284   sc = rtems_blkdev_create(
0285     rda,
0286     0,
0287     BLOCK_COUNT,
0288     ramdisk_ioctl,
0289     rd
0290   );
0291   rtems_test_assert(sc == RTEMS_INVALID_NUMBER);
0292 
0293   sc = rtems_blkdev_create(
0294     rda,
0295     BLOCK_SIZE,
0296     0,
0297     ramdisk_ioctl,
0298     rd
0299   );
0300   rtems_test_assert(sc == RTEMS_INVALID_NUMBER);
0301 
0302   opaque = rtems_heap_greedy_allocate(NULL, 0);
0303   sc = rtems_blkdev_create(
0304     rda,
0305     BLOCK_SIZE,
0306     BLOCK_COUNT,
0307     ramdisk_ioctl,
0308     rd
0309   );
0310   rtems_test_assert(sc == RTEMS_NO_MEMORY);
0311   rtems_heap_greedy_free(opaque);
0312 
0313   opaque = rtems_heap_greedy_allocate(disk_size, 1);
0314   sc = rtems_blkdev_create(
0315     rda,
0316     BLOCK_SIZE,
0317     BLOCK_COUNT,
0318     ramdisk_ioctl,
0319     rd
0320   );
0321   rtems_test_assert(sc == RTEMS_UNSATISFIED);
0322   rtems_heap_greedy_free(opaque);
0323 
0324   sc = rtems_blkdev_create(
0325     rda,
0326     BLOCK_SIZE,
0327     BLOCK_COUNT,
0328     ramdisk_ioctl,
0329     rd
0330   );
0331   ASSERT_SC(sc);
0332 
0333   sc = rtems_blkdev_create_partition(
0334     rda1,
0335     not_exist,
0336     0,
0337     BLOCK_COUNT
0338   );
0339   rtems_test_assert(sc == RTEMS_INVALID_ID);
0340 
0341   rv = lstat(&dev_invalid[0], &st);
0342   rtems_test_assert(rv == 0);
0343 
0344   rv = mknod(not_blkdev, S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO, st.st_rdev);
0345   rtems_test_assert(rv == 0);
0346 
0347   sc = rtems_blkdev_create_partition(
0348     rda1,
0349     not_blkdev,
0350     0,
0351     BLOCK_COUNT
0352   );
0353   rtems_test_assert(sc == RTEMS_INVALID_NODE);
0354 
0355   rv = mknod(invalid_blkdev, S_IFBLK | S_IRWXU | S_IRWXG | S_IRWXO, st.st_rdev);
0356   rtems_test_assert(rv == 0);
0357 
0358   sc = rtems_blkdev_create_partition(
0359     rda1,
0360     invalid_blkdev,
0361     0,
0362     BLOCK_COUNT
0363   );
0364   rtems_test_assert(sc == RTEMS_NOT_IMPLEMENTED);
0365 
0366   sc = rtems_blkdev_create_partition(
0367     rda1,
0368     rda,
0369     0,
0370     0
0371   );
0372   rtems_test_assert(sc == RTEMS_INVALID_NUMBER);
0373 
0374   sc = rtems_blkdev_create_partition(
0375     rda1,
0376     rda,
0377     BLOCK_COUNT,
0378     BLOCK_COUNT
0379   );
0380   rtems_test_assert(sc == RTEMS_INVALID_NUMBER);
0381 
0382   sc = rtems_blkdev_create_partition(
0383     rda1,
0384     rda,
0385     0,
0386     BLOCK_COUNT + 1
0387   );
0388   rtems_test_assert(sc == RTEMS_INVALID_NUMBER);
0389 
0390   opaque = rtems_heap_greedy_allocate(NULL, 0);
0391   sc = rtems_blkdev_create_partition(
0392     rda1,
0393     rda,
0394     0,
0395     BLOCK_COUNT
0396   );
0397   rtems_test_assert(sc == RTEMS_NO_MEMORY);
0398   rtems_heap_greedy_free(opaque);
0399 
0400   opaque = rtems_heap_greedy_allocate(disk_size, 1);
0401   sc = rtems_blkdev_create_partition(
0402     rda1,
0403     rda,
0404     0,
0405     BLOCK_COUNT
0406   );
0407   rtems_test_assert(sc == RTEMS_UNSATISFIED);
0408   rtems_heap_greedy_free(opaque);
0409 
0410   rv = unlink(rda);
0411   rtems_test_assert(rv == 0);
0412 }
0413 
0414 static rtems_task Init(rtems_task_argument argument)
0415 {
0416   TEST_BEGIN();
0417 
0418   test_blkdev_imfs_read_and_write();
0419   test_blkdev_imfs_parameters();
0420   test_blkdev_imfs_errors();
0421 
0422   TEST_END();
0423   exit(0);
0424 }
0425 
0426 #define CONFIGURE_INIT
0427 
0428 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0429 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0430 #define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
0431 
0432 #define CONFIGURE_APPLICATION_EXTRA_DRIVERS \
0433   { .initialization_entry = invalid_initialize, \
0434     .control_entry = invalid_control }
0435 
0436 #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 5
0437 
0438 #define CONFIGURE_MAXIMUM_TASKS 1
0439 
0440 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0441 
0442 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0443 
0444 #include <rtems/confdefs.h>