source: rtems/cpukit/libfs/src/rfs/rtems-rfs-shell.c @ 0b8e827

4.104.115
Last change on this file since 0b8e827 was 5fe3834, checked in by Joel Sherrill <joel.sherrill@…>, on 03/22/10 at 14:55:37

2010-03-22 Joel Sherrill <joel.sherrill@…>

  • libfs/src/rfs/rtems-rfs-bitmaps-ut.c, libfs/src/rfs/rtems-rfs-block.c, libfs/src/rfs/rtems-rfs-buffer.c, libfs/src/rfs/rtems-rfs-dir.c, libfs/src/rfs/rtems-rfs-file.c, libfs/src/rfs/rtems-rfs-format.c, libfs/src/rfs/rtems-rfs-group.c, libfs/src/rfs/rtems-rfs-rtems-file.c, libfs/src/rfs/rtems-rfs-shell.c: Fix printf format warning. Primarily for size_t.
  • Property mode set to 100644
File size: 18.4 KB
Line 
1/*
2 *  COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
3 *
4 *  The license and distribution terms for this file may be
5 *  found in the file LICENSE in this distribution or at
6 *  http://www.rtems.com/license/LICENSE.
7 *
8 *  $Id$
9 */
10/**
11 * @file
12 *
13 * @ingroup rtems-rfs
14 *
15 * RTEMS File Systems Shell Commands Support
16 */
17
18#include <string.h>
19
20#include <rtems/rfs/rtems-rfs-block.h>
21#include <rtems/rfs/rtems-rfs-buffer.h>
22#include <rtems/rfs/rtems-rfs-group.h>
23#include <rtems/rfs/rtems-rfs-inode.h>
24#include <rtems/rfs/rtems-rfs-dir.h>
25#include <rtems/rtems-rfs-format.h>
26
27#include <sys/statvfs.h>
28
29#if __rtems__
30#include "rtems-rfs-rtems.h"
31#endif
32
33/**
34 * The type of the shell handlers we have.
35 */
36typedef int (*rtems_rfs_shell_handler) (rtems_rfs_file_system* fs, int argc, char *argv[]);
37
38/**
39 * Table of handlers we parse to invoke the command.
40 */
41typedef struct rtems_rfs_shell_cmd_t
42{
43  const char*             name;
44  rtems_rfs_shell_handler handler;
45  const char*             help;
46} rtems_rfs_shell_cmd;
47
48/**
49 * Lock the file system.
50 */
51static void
52rtems_rfs_shell_lock_rfs (rtems_rfs_file_system* fs)
53{
54#if __rtems__
55  rtems_rfs_rtems_lock (fs);
56#endif 
57}
58
59/**
60 * Unlock the file system.
61 */
62static void
63rtems_rfs_shell_unlock_rfs (rtems_rfs_file_system* fs)
64{
65#if __rtems__
66  rtems_rfs_rtems_unlock (fs);
67#endif 
68}
69
70/**
71 * Get the file system data from the specific path. Checks to make sure the path is
72 * pointing to a valid RFS file system.
73 */
74static int
75rtems_rfs_get_fs (const char* path, rtems_rfs_file_system** fs)
76{
77  struct statvfs sb;
78  int            rc;
79
80  rc = statvfs (path, &sb);
81  if (rc < 0)
82  {
83    printf ("error: cannot statvfs path: %s: (%d) %s\n",
84            path, errno, strerror (errno));
85    return -1;
86  }
87
88  if (sb.f_fsid != RTEMS_RFS_SB_MAGIC)
89  {
90    printf ("error: path '%s' is not on an RFS file system\n", path);
91    return -1;
92  }
93
94#if __rtems__
95  /*
96   * Now find the path location on the file system. This will give the file
97   * system data.
98   */
99  {
100    rtems_filesystem_location_info_t pathloc;
101    rc = rtems_filesystem_evaluate_path (path, strlen (path), 0, &pathloc, true);
102    *fs = rtems_rfs_rtems_pathloc_dev (&pathloc);
103    rtems_filesystem_freenode (&pathloc);
104  }
105#endif
106 
107  return rc;
108}
109
110static int
111rtems_rfs_shell_data (rtems_rfs_file_system* fs, int argc, char *argv[])
112{
113  size_t blocks;
114  size_t inodes;
115  int    bpcent;
116  int    ipcent;
117
118  printf ("RFS Filesystem Data\n");
119  printf ("             flags: %08lx\n", fs->flags);
120#if 0
121  printf ("            device: %08lx\n", rtems_rfs_fs_device (fs));
122#endif
123  printf ("            blocks: %zu\n",  rtems_rfs_fs_blocks (fs));
124  printf ("        block size: %zu\n",  rtems_rfs_fs_block_size (fs));
125  printf ("              size: %llu\n", rtems_rfs_fs_size (fs));
126  printf ("  media block size: %lu\n",  rtems_rfs_fs_media_block_size (fs));
127  printf ("        media size: %llu\n", rtems_rfs_fs_media_size (fs));
128  printf ("            inodes: %lu\n",  rtems_rfs_fs_inodes (fs));
129  printf ("        bad blocks: %lu\n",  fs->bad_blocks);
130  printf ("  max. name length: %lu\n",  rtems_rfs_fs_max_name (fs));
131  printf ("            groups: %d\n",   fs->group_count);
132  printf ("      group blocks: %zd\n",  fs->group_blocks);
133  printf ("      group inodes: %zd\n",  fs->group_inodes);
134  printf ("  inodes per block: %zd\n",  fs->inodes_per_block);
135  printf ("  blocks per block: %zd\n",  fs->blocks_per_block);
136  printf ("     singly blocks: %zd\n",  fs->block_map_singly_blocks);
137  printf ("    doublly blocks: %zd\n",  fs->block_map_doubly_blocks);
138  printf (" max. held buffers: %ld\n",  fs->max_held_buffers);
139
140  rtems_rfs_shell_lock_rfs (fs);
141
142  rtems_rfs_group_usage (fs, &blocks, &inodes);
143 
144  rtems_rfs_shell_unlock_rfs (fs);
145
146  bpcent = (blocks * 1000) / rtems_rfs_fs_blocks (fs);
147  ipcent = (inodes * 1000) / rtems_rfs_fs_inodes (fs);
148 
149  printf ("       blocks used: %zd (%d.%d%%)\n",
150          blocks, bpcent / 10, bpcent % 10);
151  printf ("       inodes used: %zd (%d.%d%%)\n",
152          inodes, ipcent / 10, ipcent % 10);
153 
154  return 0;
155}
156
157static int
158rtems_rfs_shell_block (rtems_rfs_file_system* fs, int argc, char *argv[])
159{
160  rtems_rfs_buffer_handle buffer;
161  rtems_rfs_block_no      block;
162  uint8_t*                data;
163  bool                    state;
164  int                     b;
165  int                     rc;
166 
167  if (argc <= 1)
168  {
169    printf ("error: no block number provided\n");
170    return 1;
171  }
172
173  block = strtoul (argv[1], 0, 0);
174
175  rtems_rfs_shell_lock_rfs (fs);
176 
177  rc = rtems_rfs_group_bitmap_test (fs, false, block, &state);
178  if (rc > 0)
179  {
180    rtems_rfs_shell_unlock_rfs (fs);
181    printf ("error: testing block state: block=%lu: (%d) %s\n",
182            block, rc, strerror (rc));
183    return 1;
184  }
185
186  printf (" %5lu: block %s\n", block, state ? "allocated" : "free");
187   
188  rc = rtems_rfs_buffer_handle_open (fs, &buffer);
189  if (rc > 0)
190  {
191    rtems_rfs_shell_unlock_rfs (fs);
192    printf ("error: opening buffer handle: block=%lu: (%d) %s\n",
193            block, rc, strerror (rc));
194    return 1;
195  }
196
197  rc = rtems_rfs_buffer_handle_request (fs, &buffer, block, true);
198  if (rc > 0)
199  {
200    rtems_rfs_buffer_handle_close (fs, &buffer);
201    rtems_rfs_shell_unlock_rfs (fs);
202    printf ("error: requesting buffer handle: block=%lu: (%d) %s\n",
203            block, rc, strerror (rc));
204    return 1;
205  }
206
207  for (b = 0, data = rtems_rfs_buffer_data (&buffer);
208       b < rtems_rfs_fs_block_size (fs);
209       b++, data++)
210  {
211    int mod = b % 16;
212    if (mod == 0)
213    {
214      if (b)
215        printf ("\n");
216      printf ("%04x ", b);
217    }
218    if (mod == 8)
219      printf (" ");
220    printf ("%02x ", *data);
221  }
222
223  printf ("\n");
224 
225  rc = rtems_rfs_buffer_handle_close (fs, &buffer);
226  if (rc > 0)
227  {
228    rtems_rfs_shell_unlock_rfs (fs);
229    printf ("error: closing buffer handle: block=%lu: (%d) %s\n",
230            block, rc, strerror (rc));
231    return 1;
232  }
233 
234  rtems_rfs_shell_unlock_rfs (fs);
235 
236  return 0;
237}
238
239static int
240rtems_rfs_shell_inode (rtems_rfs_file_system* fs, int argc, char *argv[])
241{
242  rtems_rfs_ino start;
243  rtems_rfs_ino end;
244  rtems_rfs_ino total;
245  rtems_rfs_ino ino;
246  bool          show_all;
247  bool          error_check_only;
248  bool          forced;
249  bool          have_start;
250  bool          have_end;
251  int           arg;
252  int           b;
253  int           rc;
254
255  total = fs->group_inodes * fs->group_count;
256  start = RTEMS_RFS_ROOT_INO;
257  end = total - 1;
258  show_all = false;
259  error_check_only = false;
260  forced = false;
261  have_start = have_end = false;
262
263  for (arg = 1; arg < argc; arg++)
264  {
265    if (argv[arg][0] == '-')
266    {
267      switch (argv[arg][1])
268      {
269        case 'a':
270          show_all = true;
271          break;
272        case 'e':
273          error_check_only = true;
274          break;
275        case 'f':
276          forced = true;
277          break;
278        default:
279          printf ("warning: option ignored: %s\n", argv[arg]);
280          break;
281      }
282    }
283    else
284    {
285      if (have_end && have_start)
286        printf ("warning: option ignored: %s\n", argv[arg]);
287      else if (!have_start)
288      {
289        start = end = strtoul (argv[arg], 0, 0);
290        have_start = true;
291      }
292      else
293      {
294        end = strtoul (argv[arg], 0, 0);
295        have_end = true;
296      }
297    }
298  }
299
300  if ((start < 0) || (end < 0) ||
301      (start >= total) || (end >= total))
302  {
303    printf ("error: inode out of range (0->%ld).\n", total - 1);
304    return 1;
305  }
306
307  rtems_rfs_shell_lock_rfs (fs);
308 
309  for (ino = start; ino <= end; ino++)
310  {
311    rtems_rfs_inode_handle inode;
312    bool                   allocated;
313
314    rc = rtems_rfs_group_bitmap_test (fs, true, ino, &allocated);
315    if (rc > 0)
316    {
317      rtems_rfs_shell_unlock_rfs (fs);
318      printf ("error: testing inode state: ino=%lu: (%d) %s\n",
319              ino, rc, strerror (rc));
320      return 1;
321    }
322
323    if (show_all || allocated)
324    {
325      uint16_t mode;
326      bool     error;
327
328      rc = rtems_rfs_inode_open (fs, ino, &inode, true);
329      if (rc > 0)
330      {
331        rtems_rfs_shell_unlock_rfs (fs);
332        printf ("error: opening inode handle: ino=%lu: (%d) %s\n",
333                ino, rc, strerror (rc));
334        return 1;
335      }
336
337      error = false;
338     
339      mode = rtems_rfs_inode_get_mode (&inode);
340
341      if (error_check_only)
342      {
343        if (!RTEMS_RFS_S_ISDIR (mode) &&
344            !RTEMS_RFS_S_ISCHR (mode) &&
345            !RTEMS_RFS_S_ISBLK (mode) &&
346            !RTEMS_RFS_S_ISREG (mode) &&
347            !RTEMS_RFS_S_ISLNK (mode))
348          error = true;
349        else
350        {
351#if NEED_TO_HANDLE_DIFFERENT_TYPES
352          int b;
353          for (b = 0; b < RTEMS_RFS_INODE_BLOCKS; b++)
354          {
355            uint32_t block;
356            block = rtems_rfs_inode_get_block (&inode, b);
357            if ((block <= RTEMS_RFS_SUPERBLOCK_SIZE) ||
358                (block >= rtems_rfs_fs_blocks (fs)))
359              error = true;
360          }
361#endif
362        }
363      }
364
365      if (!error_check_only || error)
366      {
367        printf (" %5lu: pos=%06lu:%04zx %c ",
368                ino, rtems_rfs_buffer_bnum (&inode.buffer),
369                inode.offset * RTEMS_RFS_INODE_SIZE,
370                allocated ? 'A' : 'F');
371   
372        if (!allocated && !forced)
373          printf (" --\n");
374        else
375        {     
376          const char* type;
377          type = "UKN";
378          if (RTEMS_RFS_S_ISDIR (mode))
379            type = "DIR";
380          else if (RTEMS_RFS_S_ISCHR (mode))
381            type = "CHR";
382          else if (RTEMS_RFS_S_ISBLK (mode))
383            type = "BLK";
384          else if (RTEMS_RFS_S_ISREG (mode))
385            type = "REG";
386          else if (RTEMS_RFS_S_ISLNK (mode))
387            type = "LNK";
388          printf ("links=%03i mode=%04x (%s/%03o) bo=%04u bc=%04lu b=[",
389                  rtems_rfs_inode_get_links (&inode),
390                  mode, type, mode & ((1 << 10) - 1),
391                  rtems_rfs_inode_get_block_offset (&inode),
392                  rtems_rfs_inode_get_block_count (&inode));
393          for (b = 0; b < (RTEMS_RFS_INODE_BLOCKS - 1); b++)
394            printf ("%lu ", rtems_rfs_inode_get_block (&inode, b));
395          printf ("%lu]\n", rtems_rfs_inode_get_block (&inode, b));
396        }
397      }
398     
399      rc = rtems_rfs_inode_close (fs, &inode);
400      if (rc > 0)
401      {
402        rtems_rfs_shell_unlock_rfs (fs);
403        printf ("error: closing inode handle: ino=%lu: (%d) %s\n",
404                ino, rc, strerror (rc));
405        return 1;
406      }
407    }
408  }
409 
410  rtems_rfs_shell_unlock_rfs (fs);
411 
412  return 0;
413}
414
415static int
416rtems_rfs_shell_dir (rtems_rfs_file_system* fs, int argc, char *argv[])
417{
418  rtems_rfs_buffer_handle buffer;
419  rtems_rfs_block_no      block;
420  uint8_t*                data;
421  bool                    state;
422  int                     entry;
423  int                     b;
424  int                     rc;
425 
426  if (argc <= 1)
427  {
428    printf ("error: no block number provided\n");
429    return 1;
430  }
431
432  block = strtoul (argv[1], 0, 0);
433
434  rtems_rfs_shell_lock_rfs (fs);
435 
436  rc = rtems_rfs_group_bitmap_test (fs, false, block, &state);
437  if (rc > 0)
438  {
439    rtems_rfs_shell_unlock_rfs (fs);
440    printf ("error: testing block state: block=%lu: (%d) %s\n",
441            block, rc, strerror (rc));
442    return 1;
443  }
444
445  printf (" %5lu: block %s\n", block, state ? "allocated" : "free");
446
447  rc = rtems_rfs_buffer_handle_open (fs, &buffer);
448  if (rc > 0)
449  {
450    rtems_rfs_shell_unlock_rfs (fs);
451    printf ("error: opening buffer handle: block=%lu: (%d) %s\n",
452            block, rc, strerror (rc));
453    return 1;
454  }
455
456  rc = rtems_rfs_buffer_handle_request (fs, &buffer, block, true);
457  if (rc > 0)
458  {
459    rtems_rfs_buffer_handle_close (fs, &buffer);
460    rtems_rfs_shell_unlock_rfs (fs);
461    printf ("error: requesting buffer handle: block=%lu: (%d) %s\n",
462            block, rc, strerror (rc));
463    return 1;
464  }
465
466  b = 0;
467  entry = 1;
468  data = rtems_rfs_buffer_data (&buffer);
469 
470  while (b < (rtems_rfs_fs_block_size (fs) - RTEMS_RFS_DIR_ENTRY_SIZE - 1))
471  {
472    rtems_rfs_ino eino;
473    int           elength;
474    int           length;
475    int           c;
476
477    eino    = rtems_rfs_dir_entry_ino (data);
478    elength = rtems_rfs_dir_entry_length (data);
479   
480    if (elength == RTEMS_RFS_DIR_ENTRY_EMPTY)
481      break;
482
483    if ((elength < RTEMS_RFS_DIR_ENTRY_SIZE) ||
484        (elength >= rtems_rfs_fs_max_name (fs)))
485    {
486      printf (" %5d: entry length appears corrupt: %d\n", entry, elength);
487      break;
488    }
489   
490    if ((eino < RTEMS_RFS_ROOT_INO) || (eino >= rtems_rfs_fs_inodes (fs)))
491    {
492      printf (" %5d: entry ino appears corrupt: ino=%ld\n", entry, eino);
493      break;
494    }
495   
496    length = elength - RTEMS_RFS_DIR_ENTRY_SIZE;
497   
498    printf (" %5d: %04x inode=%-6u hash=%08x name[%03u]=",
499            entry, b,
500            rtems_rfs_dir_entry_ino (data),
501            rtems_rfs_dir_entry_hash (data),
502            length);
503
504    if (length > 50)
505      length = 50;
506   
507    for (c = 0; c < length; c++)
508      printf ("%c", data[RTEMS_RFS_DIR_ENTRY_SIZE + c]);
509    if (length < elength - RTEMS_RFS_DIR_ENTRY_SIZE)
510      printf ("...");
511    printf ("\n");
512
513    b += elength;
514    data += elength;
515    entry++;
516  }
517 
518  rc = rtems_rfs_buffer_handle_close (fs, &buffer);
519  if (rc > 0)
520  {
521    rtems_rfs_shell_unlock_rfs (fs);
522    printf ("error: closing buffer handle: block=%lu: (%d) %s\n",
523            block, rc, strerror (rc));
524    return 1;
525  }
526 
527  rtems_rfs_shell_unlock_rfs (fs);
528 
529  return 0;
530}
531
532static int
533rtems_rfs_shell_group (rtems_rfs_file_system* fs, int argc, char *argv[])
534{
535  int start;
536  int end;
537  int g;
538
539  start = 0;
540  end = fs->group_count - 1;
541
542  switch (argc)
543  {
544    case 1:
545      break;
546    case 2:
547      start = end = strtoul (argv[1], 0, 0);
548      break;
549    case 3:
550      start = strtoul (argv[1], 0, 0);
551      end = strtoul (argv[2], 0, 0);
552      break;
553    default:
554      printf ("error: too many arguments.\n");
555      return 1;
556  }
557
558  if ((start < 0) || (end < 0) ||
559      (start >= fs->group_count) || (end >= fs->group_count))
560  {
561    printf ("error: group out of range (0->%d).\n", fs->group_count);
562    return 1;
563  }
564 
565  rtems_rfs_shell_lock_rfs (fs);
566
567  for (g = start; g <= end; g++)
568  {
569    rtems_rfs_group* group = &fs->groups[g];
570    size_t           blocks;
571    size_t           inodes;
572    blocks = group->size - rtems_rfs_bitmap_map_free (&group->block_bitmap);
573    inodes = fs->group_inodes - rtems_rfs_bitmap_map_free (&group->inode_bitmap);
574    printf (" %4d: base=%-7lu size=%-6zu blocks=%-5zu (%3zu%%) inode=%-5zu (%3zu%%)\n",
575            g, group->base, group->size,
576            blocks, (blocks * 100)  / group->size,
577            inodes, (inodes * 100) / fs->group_inodes);
578  }
579 
580  rtems_rfs_shell_unlock_rfs (fs);
581 
582  return 0;
583}
584
585
586void
587rtems_rfs_shell_usage (const char* arg)
588{
589  printf ("%s: RFS debugger\n", arg);
590  printf ("  %s [-hl] <path> <command>\n", arg);
591  printf ("   where:\n");
592  printf ("     path:    Path to the mounted RFS file system\n");
593  printf ("     command: A debugger command. See -l for a list plus help.\n");
594  printf ("     -h:      This help\n");
595  printf ("     -l:      The debugger command list.\n");
596}
597
598int
599rtems_shell_debugrfs (int argc, char *argv[])
600{
601  const rtems_rfs_shell_cmd table[] =
602  {
603    { "block", rtems_rfs_shell_block,
604      "Display the contents of a block, block <bno>, block <bno>..<bno>" },
605    { "data", rtems_rfs_shell_data,
606      "Display file system data, data" },
607    { "dir", rtems_rfs_shell_dir,
608      "Display a block as a table for directory entrie, dir <bno>" },
609    { "group", rtems_rfs_shell_group,
610      "Display the group data of a file system, group, group <group>, group <start> <end>" },
611    { "inode", rtems_rfs_shell_inode,
612      "Display an inode, inode <ino>, inode> <ino>..<ino>" }
613  };
614
615  int arg;
616  int t;
617 
618  for (arg = 1; arg < argc; arg++)
619  {
620    if (argv[arg][0] != '-')
621      break;
622
623    switch (argv[arg][1])
624    {
625      case 'h':
626        rtems_rfs_shell_usage (argv[0]);
627        return 0;
628      case 'l':
629        printf ("%s: commands are:\n", argv[0]);
630        for (t = 0; t < (sizeof (table) / sizeof (const rtems_rfs_shell_cmd)); t++)
631          printf ("  %s\t\t%s\n", table[t].name, table[t].help);
632        return 0;
633      default:
634        printf ("error: unknown option: %s\n", argv[arg]);
635        return 1;
636    }
637  }
638
639  if ((argc - arg) < 2)
640    printf ("error: you need at least a path and command, try %s -h\n", argv[0]);
641  else
642  {
643    rtems_rfs_file_system* fs;
644    if (rtems_rfs_get_fs (argv[arg], &fs) == 0)
645    {
646      for (t = 0; t < (sizeof (table) / sizeof (const rtems_rfs_shell_cmd)); t++)
647        if (strcmp (argv[arg + 1], table[t].name) == 0)
648          return table[t].handler (fs, argc - 2, argv + 2);
649      printf ("error: command not found: %s\n", argv[arg + 1]);
650    }
651  }
652 
653  return 1;
654}
655
656int
657rtems_shell_rfs_format (int argc, char* argv[])
658{
659  rtems_rfs_format_config config;
660  const char*             driver = NULL;
661  int                     arg;
662
663  memset (&config, 0, sizeof (rtems_rfs_format_config));
664
665  for (arg = 1; arg < argc; arg++)
666  {
667    if (argv[arg][0] == '-')
668    {
669      switch (argv[arg][1])
670      {
671        case 'v':
672          config.verbose = true;
673          break;
674         
675        case 's':
676          arg++;
677          if (arg >= argc)
678          {
679            printf ("error: block size needs an argument\n");
680            return 1;
681          }
682          config.block_size = strtoul (argv[arg], 0, 0);
683          break;
684       
685        case 'b':
686          arg++;
687          if (arg >= argc)
688          {
689            printf ("error: group block count needs an argument\n");
690            return 1;
691          }
692          config.group_blocks = strtoul (argv[arg], 0, 0);
693          break;
694         
695        case 'i':
696          arg++;
697          if (arg >= argc)
698          {
699            printf ("error: group inode count needs an argument\n");
700            return 1;
701          }
702          config.group_inodes = strtoul (argv[arg], 0, 0);
703          break;
704
705        case 'I':
706          config.initialise_inodes = true;
707          break;
708         
709        case 'o':
710          arg++;
711          if (arg >= argc)
712          {
713            printf ("error: inode percentage overhead needs an argument\n");
714            return 1;
715          }
716          config.inode_overhead = strtoul (argv[arg], 0, 0);
717          break;
718         
719        default:
720          printf ("error: invalid option: %s\n", argv[arg]);
721          return 1;
722      }
723    }
724    else
725    {
726      if (!driver)
727        driver = argv[arg];
728      else
729      {
730        printf ("error: only one driver name allowed: %s\n", argv[arg]);
731        return 1;
732      }
733    }
734  }
735
736  if (rtems_rfs_format (driver, &config) < 0)
737  {
738    printf ("error: format of %s failed: %s\n",
739            driver, strerror (errno));
740    return 1;
741  }
742 
743  return 0;
744}
Note: See TracBrowser for help on using the repository browser.