]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - io/init.c
xfs_io: add crc32 self test
[thirdparty/xfsprogs-dev.git] / io / init.c
index 60fb024bde4a3575cb62f5f3d444ad1dc222131d..83f08f2da8d4c1ab45aa083c49adcd3554f85e7b 100644 (file)
--- a/io/init.c
+++ b/io/init.c
@@ -1,36 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) 2003-2005 Silicon Graphics, Inc.  All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like.  Any license provided herein, whether implied or
- * otherwise, applies only to this software file.  Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA  94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * Copyright (c) 2003-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
  */
 
-#include <xfs/libxfs.h>
+#include <pthread.h>
+#include "platform_defs.h"
 #include "command.h"
 #include "input.h"
 #include "init.h"
 char   *progname;
 int    exitcode;
 int    expert;
+static int     idlethread;
 size_t pagesize;
 struct timeval stopwatch;
 
-void
+static void
 usage(void)
 {
        fprintf(stderr,
-               _("Usage: %s [-adFfmrRstx] [-p prog] [-c cmd]... file\n"),
+_("Usage: %s [-adfinrRstVx] [-m mode] [-p prog] [[-c|-C] cmd]... file\n"),
                progname);
        exit(1);
 }
 
 void
 init_cvtnum(
-       unsigned int    *blocksize,
-       unsigned int    *sectsize)
+       size_t *blocksize,
+       size_t *sectsize)
 {
        if (!file || (file->flags & IO_FOREIGN)) {
                *blocksize = 4096;
@@ -70,28 +46,55 @@ init_commands(void)
 {
        attr_init();
        bmap_init();
+       copy_range_init();
+       cowextsize_init();
+       encrypt_init();
        fadvise_init();
+       fiemap_init();
        file_init();
+       flink_init();
        freeze_init();
+       fsmap_init();
        fsync_init();
        getrusage_init();
        help_init();
        imap_init();
        inject_init();
+       label_init();
+       log_writes_init();
+       madvise_init();
+       mincore_init();
        mmap_init();
        open_init();
+       parent_init();
        pread_init();
        prealloc_init();
        pwrite_init();
        quit_init();
+       readdir_init();
+       reflink_init();
+       repair_init();
        resblks_init();
+       scrub_init();
+       seek_init();
        sendfile_init();
        shutdown_init();
+       stat_init();
+       swapext_init();
+       sync_init();
+       sync_range_init();
        truncate_init();
+       utimes_init();
+       crc32cselftest_init();
 }
 
+/*
+ * This allows xfs_io commands specified on the command line to be run on every
+ * open file in the file table. Commands that should not be iterated across all
+ * open files need to specify CMD_FLAG_ONESHOT in their command flags.
+ */
 static int
-init_args_command(
+filetable_iterator(
        int     index)
 {
        if (index >= filecount)
@@ -122,7 +125,7 @@ init_check_command(
        return 1;
 }
 
-void
+static void
 init(
        int             argc,
        char            **argv)
@@ -131,6 +134,7 @@ init(
        char            *sp;
        mode_t          mode = 0600;
        xfs_fsop_geom_t geometry = { 0 };
+       struct fs_path  fsp;
 
        progname = basename(argv[0]);
        setlocale(LC_ALL, "");
@@ -140,23 +144,30 @@ init(
        pagesize = getpagesize();
        gettimeofday(&stopwatch, NULL);
 
-       while ((c = getopt(argc, argv, "ac:dFfmp:rRstVx")) != EOF) {
+       fs_table_initialise(0, NULL, 0, NULL);
+       while ((c = getopt(argc, argv, "ac:C:dFfiLm:p:PnrRstTVx")) != EOF) {
                switch (c) {
-               case 'a':       /* append */
+               case 'a':
                        flags |= IO_APPEND;
                        break;
-               case 'c':       /* commands */
+               case 'c':
                        add_user_command(optarg);
                        break;
+               case 'C':
+                       add_oneshot_user_command(optarg);
+                       break;
                case 'd':
                        flags |= IO_DIRECT;
                        break;
                case 'F':
-                       flags |= IO_FOREIGN;
+                       /* Ignored / deprecated now, handled automatically */
                        break;
                case 'f':
                        flags |= IO_CREAT;
                        break;
+               case 'i':
+                       idlethread = 1;
+                       break;
                case 'm':
                        mode = strtoul(optarg, &sp, 0);
                        if (!sp || sp == optarg) {
@@ -165,6 +176,9 @@ init(
                                exit(1);
                        }
                        break;
+               case 'n':
+                       flags |= IO_NONBLOCK;
+                       break;
                case 'p':
                        progname = optarg;
                        break;
@@ -177,9 +191,18 @@ init(
                case 't':
                        flags |= IO_TRUNC;
                        break;
+               case 'P':
+                       flags |= IO_PATH;
+                       break;
+               case 'L':
+                       flags |= IO_NOFOLLOW;
+                       break;
                case 'R':
                        flags |= IO_REALTIME;
                        break;
+               case 'T':
+                       flags |= IO_TMPFILE;
+                       break;
                case 'x':
                        expert = 1;
                        break;
@@ -192,25 +215,54 @@ init(
        }
 
        while (optind < argc) {
-               if ((c = openfile(argv[optind], flags & IO_FOREIGN ?
-                                       NULL : &geometry, flags, mode)) < 0)
+               c = openfile(argv[optind], &geometry, flags, mode, &fsp);
+               if (c < 0)
                        exit(1);
-               if (addfile(argv[optind], c, &geometry, flags) < 0)
+               if (!platform_test_xfs_fd(c))
+                       flags |= IO_FOREIGN;
+               if (addfile(argv[optind], c, &geometry, flags, &fsp) < 0)
                        exit(1);
                optind++;
        }
 
        init_commands();
-       add_args_command(init_args_command);
+       add_command_iterator(filetable_iterator);
        add_check_command(init_check_command);
 }
 
+/*
+ * The purpose of this idle thread is to test io from a multi threaded process.
+ * With single threaded process, the file table is not shared and file structs
+ * are not reference counted. Spawning an idle thread can help detecting file
+ * struct reference leaks.
+ */
+static void *
+idle_loop(void *arg)
+{
+       for (;;)
+               pause();
+       return NULL;
+}
+
+static void
+start_idle_thread(void)
+{
+       pthread_t t;
+
+       if (pthread_create(&t, NULL, idle_loop, NULL)) {
+               fprintf(stderr, "Error creating idle thread\n");
+               exit(1);
+       }
+}
+
 int
 main(
        int     argc,
        char    **argv)
 {
        init(argc, argv);
+       if (idlethread)
+               start_idle_thread();
        command_loop();
        return exitcode;
 }