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