Statistics
| Branch: | Revision:

root / qemu-io.c @ 797ac58c

History | View | Annotate | Download (6.7 kB)

1
/*
2
 * Command line utility to exercise the QEMU I/O path.
3
 *
4
 * Copyright (C) 2009 Red Hat, Inc.
5
 * Copyright (c) 2003-2005 Silicon Graphics, Inc.
6
 *
7
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8
 * See the COPYING file in the top-level directory.
9
 */
10
#include <sys/time.h>
11
#include <sys/types.h>
12
#include <stdarg.h>
13
#include <stdio.h>
14
#include <getopt.h>
15
#include <libgen.h>
16

    
17
#include "qemu-common.h"
18
#include "qemu/main-loop.h"
19
#include "block/block_int.h"
20
#include "cmd.h"
21
#include "trace/control.h"
22

    
23
#define VERSION        "0.0.1"
24

    
25
#define CMD_NOFILE_OK   0x01
26

    
27
char *progname;
28

    
29
BlockDriverState *qemuio_bs;
30
extern int qemuio_misalign;
31

    
32
static int close_f(BlockDriverState *bs, int argc, char **argv)
33
{
34
    bdrv_delete(bs);
35
    qemuio_bs = NULL;
36
    return 0;
37
}
38

    
39
static const cmdinfo_t close_cmd = {
40
    .name       = "close",
41
    .altname    = "c",
42
    .cfunc      = close_f,
43
    .oneline    = "close the current open file",
44
};
45

    
46
static int openfile(char *name, int flags, int growable)
47
{
48
    if (qemuio_bs) {
49
        fprintf(stderr, "file open already, try 'help close'\n");
50
        return 1;
51
    }
52

    
53
    if (growable) {
54
        if (bdrv_file_open(&qemuio_bs, name, NULL, flags)) {
55
            fprintf(stderr, "%s: can't open device %s\n", progname, name);
56
            return 1;
57
        }
58
    } else {
59
        qemuio_bs = bdrv_new("hda");
60

    
61
        if (bdrv_open(qemuio_bs, name, NULL, flags, NULL) < 0) {
62
            fprintf(stderr, "%s: can't open device %s\n", progname, name);
63
            bdrv_delete(qemuio_bs);
64
            qemuio_bs = NULL;
65
            return 1;
66
        }
67
    }
68

    
69
    return 0;
70
}
71

    
72
static void open_help(void)
73
{
74
    printf(
75
"\n"
76
" opens a new file in the requested mode\n"
77
"\n"
78
" Example:\n"
79
" 'open -Cn /tmp/data' - creates/opens data file read-write and uncached\n"
80
"\n"
81
" Opens a file for subsequent use by all of the other qemu-io commands.\n"
82
" -r, -- open file read-only\n"
83
" -s, -- use snapshot file\n"
84
" -n, -- disable host cache\n"
85
" -g, -- allow file to grow (only applies to protocols)"
86
"\n");
87
}
88

    
89
static int open_f(BlockDriverState *bs, int argc, char **argv);
90

    
91
static const cmdinfo_t open_cmd = {
92
    .name       = "open",
93
    .altname    = "o",
94
    .cfunc      = open_f,
95
    .argmin     = 1,
96
    .argmax     = -1,
97
    .flags      = CMD_NOFILE_OK,
98
    .args       = "[-Crsn] [path]",
99
    .oneline    = "open the file specified by path",
100
    .help       = open_help,
101
};
102

    
103
static int open_f(BlockDriverState *bs, int argc, char **argv)
104
{
105
    int flags = 0;
106
    int readonly = 0;
107
    int growable = 0;
108
    int c;
109

    
110
    while ((c = getopt(argc, argv, "snrg")) != EOF) {
111
        switch (c) {
112
        case 's':
113
            flags |= BDRV_O_SNAPSHOT;
114
            break;
115
        case 'n':
116
            flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
117
            break;
118
        case 'r':
119
            readonly = 1;
120
            break;
121
        case 'g':
122
            growable = 1;
123
            break;
124
        default:
125
            return command_usage(&open_cmd);
126
        }
127
    }
128

    
129
    if (!readonly) {
130
        flags |= BDRV_O_RDWR;
131
    }
132

    
133
    if (optind != argc - 1) {
134
        return command_usage(&open_cmd);
135
    }
136

    
137
    return openfile(argv[optind], flags, growable);
138
}
139

    
140
static void usage(const char *name)
141
{
142
    printf(
143
"Usage: %s [-h] [-V] [-rsnm] [-c cmd] ... [file]\n"
144
"QEMU Disk exerciser\n"
145
"\n"
146
"  -c, --cmd            command to execute\n"
147
"  -r, --read-only      export read-only\n"
148
"  -s, --snapshot       use snapshot file\n"
149
"  -n, --nocache        disable host cache\n"
150
"  -g, --growable       allow file to grow (only applies to protocols)\n"
151
"  -m, --misalign       misalign allocations for O_DIRECT\n"
152
"  -k, --native-aio     use kernel AIO implementation (on Linux only)\n"
153
"  -t, --cache=MODE     use the given cache mode for the image\n"
154
"  -T, --trace FILE     enable trace events listed in the given file\n"
155
"  -h, --help           display this help and exit\n"
156
"  -V, --version        output version information and exit\n"
157
"\n",
158
    name);
159
}
160

    
161

    
162
int main(int argc, char **argv)
163
{
164
    int readonly = 0;
165
    int growable = 0;
166
    const char *sopt = "hVc:d:rsnmgkt:T:";
167
    const struct option lopt[] = {
168
        { "help", 0, NULL, 'h' },
169
        { "version", 0, NULL, 'V' },
170
        { "offset", 1, NULL, 'o' },
171
        { "cmd", 1, NULL, 'c' },
172
        { "read-only", 0, NULL, 'r' },
173
        { "snapshot", 0, NULL, 's' },
174
        { "nocache", 0, NULL, 'n' },
175
        { "misalign", 0, NULL, 'm' },
176
        { "growable", 0, NULL, 'g' },
177
        { "native-aio", 0, NULL, 'k' },
178
        { "discard", 1, NULL, 'd' },
179
        { "cache", 1, NULL, 't' },
180
        { "trace", 1, NULL, 'T' },
181
        { NULL, 0, NULL, 0 }
182
    };
183
    int c;
184
    int opt_index = 0;
185
    int flags = BDRV_O_UNMAP;
186

    
187
    progname = basename(argv[0]);
188

    
189
    while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
190
        switch (c) {
191
        case 's':
192
            flags |= BDRV_O_SNAPSHOT;
193
            break;
194
        case 'n':
195
            flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
196
            break;
197
        case 'd':
198
            if (bdrv_parse_discard_flags(optarg, &flags) < 0) {
199
                error_report("Invalid discard option: %s", optarg);
200
                exit(1);
201
            }
202
            break;
203
        case 'c':
204
            add_user_command(optarg);
205
            break;
206
        case 'r':
207
            readonly = 1;
208
            break;
209
        case 'm':
210
            qemuio_misalign = 1;
211
            break;
212
        case 'g':
213
            growable = 1;
214
            break;
215
        case 'k':
216
            flags |= BDRV_O_NATIVE_AIO;
217
            break;
218
        case 't':
219
            if (bdrv_parse_cache_flags(optarg, &flags) < 0) {
220
                error_report("Invalid cache option: %s", optarg);
221
                exit(1);
222
            }
223
            break;
224
        case 'T':
225
            if (!trace_backend_init(optarg, NULL)) {
226
                exit(1); /* error message will have been printed */
227
            }
228
            break;
229
        case 'V':
230
            printf("%s version %s\n", progname, VERSION);
231
            exit(0);
232
        case 'h':
233
            usage(progname);
234
            exit(0);
235
        default:
236
            usage(progname);
237
            exit(1);
238
        }
239
    }
240

    
241
    if ((argc - optind) > 1) {
242
        usage(progname);
243
        exit(1);
244
    }
245

    
246
    qemu_init_main_loop();
247
    bdrv_init();
248

    
249
    /* initialize commands */
250
    quit_init();
251
    add_command(&open_cmd);
252
    add_command(&close_cmd);
253

    
254
    /* open the device */
255
    if (!readonly) {
256
        flags |= BDRV_O_RDWR;
257
    }
258

    
259
    if ((argc - optind) == 1) {
260
        openfile(argv[optind], flags, growable);
261
    }
262
    command_loop();
263

    
264
    /*
265
     * Make sure all outstanding requests complete before the program exits.
266
     */
267
    bdrv_drain_all();
268

    
269
    if (qemuio_bs) {
270
        bdrv_delete(qemuio_bs);
271
    }
272
    return 0;
273
}