]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - io/init.c
xfsprogs: make static things static
[thirdparty/xfsprogs-dev.git] / io / init.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2003-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6
7 #include <pthread.h>
8 #include "platform_defs.h"
9 #include "command.h"
10 #include "input.h"
11 #include "init.h"
12 #include "io.h"
13
14 char *progname;
15 int exitcode;
16 int expert;
17 static int idlethread;
18 size_t pagesize;
19 struct timeval stopwatch;
20
21 static void
22 usage(void)
23 {
24 fprintf(stderr,
25 _("Usage: %s [-adfinrRstVx] [-m mode] [-p prog] [[-c|-C] cmd]... file\n"),
26 progname);
27 exit(1);
28 }
29
30 void
31 init_cvtnum(
32 size_t *blocksize,
33 size_t *sectsize)
34 {
35 if (!file || (file->flags & IO_FOREIGN)) {
36 *blocksize = 4096;
37 *sectsize = 512;
38 } else {
39 *blocksize = file->geom.blocksize;
40 *sectsize = file->geom.sectsize;
41 }
42 }
43
44 static void
45 init_commands(void)
46 {
47 attr_init();
48 bmap_init();
49 copy_range_init();
50 cowextsize_init();
51 encrypt_init();
52 fadvise_init();
53 fiemap_init();
54 file_init();
55 flink_init();
56 freeze_init();
57 fsmap_init();
58 fsync_init();
59 getrusage_init();
60 help_init();
61 imap_init();
62 inject_init();
63 label_init();
64 log_writes_init();
65 madvise_init();
66 mincore_init();
67 mmap_init();
68 open_init();
69 parent_init();
70 pread_init();
71 prealloc_init();
72 pwrite_init();
73 quit_init();
74 readdir_init();
75 reflink_init();
76 repair_init();
77 resblks_init();
78 scrub_init();
79 seek_init();
80 sendfile_init();
81 shutdown_init();
82 stat_init();
83 swapext_init();
84 sync_init();
85 sync_range_init();
86 truncate_init();
87 utimes_init();
88 }
89
90 /*
91 * This allows xfs_io commands specified on the command line to be run on every
92 * open file in the file table. Commands that should not be iterated across all
93 * open files need to specify CMD_FLAG_ONESHOT in their command flags.
94 */
95 static int
96 filetable_iterator(
97 int index)
98 {
99 if (index >= filecount)
100 return 0;
101 file = &filetable[index++];
102 return index;
103 }
104
105 static int
106 init_check_command(
107 const cmdinfo_t *ct)
108 {
109 if (!file && !(ct->flags & CMD_NOFILE_OK)) {
110 fprintf(stderr, _("no files are open, try 'help open'\n"));
111 return 0;
112 }
113 if (!mapping && !(ct->flags & CMD_NOMAP_OK)) {
114 fprintf(stderr, _("no mapped regions, try 'help mmap'\n"));
115 return 0;
116 }
117 if (file && !(ct->flags & CMD_FOREIGN_OK) &&
118 (file->flags & IO_FOREIGN)) {
119 fprintf(stderr,
120 _("foreign file active, %s command is for XFS filesystems only\n"),
121 ct->name);
122 return 0;
123 }
124 return 1;
125 }
126
127 static void
128 init(
129 int argc,
130 char **argv)
131 {
132 int c, flags = 0;
133 char *sp;
134 mode_t mode = 0600;
135 xfs_fsop_geom_t geometry = { 0 };
136 struct fs_path fsp;
137
138 progname = basename(argv[0]);
139 setlocale(LC_ALL, "");
140 bindtextdomain(PACKAGE, LOCALEDIR);
141 textdomain(PACKAGE);
142
143 pagesize = getpagesize();
144 gettimeofday(&stopwatch, NULL);
145
146 fs_table_initialise(0, NULL, 0, NULL);
147 while ((c = getopt(argc, argv, "ac:C:dFfiLm:p:PnrRstTVx")) != EOF) {
148 switch (c) {
149 case 'a':
150 flags |= IO_APPEND;
151 break;
152 case 'c':
153 add_user_command(optarg);
154 break;
155 case 'C':
156 add_oneshot_user_command(optarg);
157 break;
158 case 'd':
159 flags |= IO_DIRECT;
160 break;
161 case 'F':
162 /* Ignored / deprecated now, handled automatically */
163 break;
164 case 'f':
165 flags |= IO_CREAT;
166 break;
167 case 'i':
168 idlethread = 1;
169 break;
170 case 'm':
171 mode = strtoul(optarg, &sp, 0);
172 if (!sp || sp == optarg) {
173 fprintf(stderr, _("non-numeric mode -- %s\n"),
174 optarg);
175 exit(1);
176 }
177 break;
178 case 'n':
179 flags |= IO_NONBLOCK;
180 break;
181 case 'p':
182 progname = optarg;
183 break;
184 case 'r':
185 flags |= IO_READONLY;
186 break;
187 case 's':
188 flags |= IO_OSYNC;
189 break;
190 case 't':
191 flags |= IO_TRUNC;
192 break;
193 case 'P':
194 flags |= IO_PATH;
195 break;
196 case 'L':
197 flags |= IO_NOFOLLOW;
198 break;
199 case 'R':
200 flags |= IO_REALTIME;
201 break;
202 case 'T':
203 flags |= IO_TMPFILE;
204 break;
205 case 'x':
206 expert = 1;
207 break;
208 case 'V':
209 printf(_("%s version %s\n"), progname, VERSION);
210 exit(0);
211 default:
212 usage();
213 }
214 }
215
216 while (optind < argc) {
217 c = openfile(argv[optind], &geometry, flags, mode, &fsp);
218 if (c < 0)
219 exit(1);
220 if (!platform_test_xfs_fd(c))
221 flags |= IO_FOREIGN;
222 if (addfile(argv[optind], c, &geometry, flags, &fsp) < 0)
223 exit(1);
224 optind++;
225 }
226
227 init_commands();
228 add_command_iterator(filetable_iterator);
229 add_check_command(init_check_command);
230 }
231
232 /*
233 * The purpose of this idle thread is to test io from a multi threaded process.
234 * With single threaded process, the file table is not shared and file structs
235 * are not reference counted. Spawning an idle thread can help detecting file
236 * struct reference leaks.
237 */
238 static void *
239 idle_loop(void *arg)
240 {
241 for (;;)
242 pause();
243 return NULL;
244 }
245
246 static void
247 start_idle_thread(void)
248 {
249 pthread_t t;
250
251 if (pthread_create(&t, NULL, idle_loop, NULL)) {
252 fprintf(stderr, "Error creating idle thread\n");
253 exit(1);
254 }
255 }
256
257 int
258 main(
259 int argc,
260 char **argv)
261 {
262 init(argc, argv);
263 if (idlethread)
264 start_idle_thread();
265 command_loop();
266 return exitcode;
267 }