qemu-io.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864
  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. #include "qemu-common.h"
  17. #include "block_int.h"
  18. #include "cmd.h"
  19. #define VERSION "0.0.1"
  20. #define CMD_NOFILE_OK 0x01
  21. char *progname;
  22. static BlockDriverState *bs;
  23. static int misalign;
  24. /*
  25. * Parse the pattern argument to various sub-commands.
  26. *
  27. * Because the pattern is used as an argument to memset it must evaluate
  28. * to an unsigned integer that fits into a single byte.
  29. */
  30. static int parse_pattern(const char *arg)
  31. {
  32. char *endptr = NULL;
  33. long pattern;
  34. pattern = strtol(arg, &endptr, 0);
  35. if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
  36. printf("%s is not a valid pattern byte\n", arg);
  37. return -1;
  38. }
  39. return pattern;
  40. }
  41. /*
  42. * Memory allocation helpers.
  43. *
  44. * Make sure memory is aligned by default, or purposefully misaligned if
  45. * that is specified on the command line.
  46. */
  47. #define MISALIGN_OFFSET 16
  48. static void *qemu_io_alloc(size_t len, int pattern)
  49. {
  50. void *buf;
  51. if (misalign) {
  52. len += MISALIGN_OFFSET;
  53. }
  54. buf = qemu_blockalign(bs, len);
  55. memset(buf, pattern, len);
  56. if (misalign) {
  57. buf += MISALIGN_OFFSET;
  58. }
  59. return buf;
  60. }
  61. static void qemu_io_free(void *p)
  62. {
  63. if (misalign) {
  64. p -= MISALIGN_OFFSET;
  65. }
  66. qemu_vfree(p);
  67. }
  68. static void dump_buffer(const void *buffer, int64_t offset, int len)
  69. {
  70. int i, j;
  71. const uint8_t *p;
  72. for (i = 0, p = buffer; i < len; i += 16) {
  73. const uint8_t *s = p;
  74. printf("%08" PRIx64 ": ", offset + i);
  75. for (j = 0; j < 16 && i + j < len; j++, p++) {
  76. printf("%02x ", *p);
  77. }
  78. printf(" ");
  79. for (j = 0; j < 16 && i + j < len; j++, s++) {
  80. if (isalnum(*s)) {
  81. printf("%c", *s);
  82. } else {
  83. printf(".");
  84. }
  85. }
  86. printf("\n");
  87. }
  88. }
  89. static void print_report(const char *op, struct timeval *t, int64_t offset,
  90. int count, int total, int cnt, int Cflag)
  91. {
  92. char s1[64], s2[64], ts[64];
  93. timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
  94. if (!Cflag) {
  95. cvtstr((double)total, s1, sizeof(s1));
  96. cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
  97. printf("%s %d/%d bytes at offset %" PRId64 "\n",
  98. op, total, count, offset);
  99. printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
  100. s1, cnt, ts, s2, tdiv((double)cnt, *t));
  101. } else {/* bytes,ops,time,bytes/sec,ops/sec */
  102. printf("%d,%d,%s,%.3f,%.3f\n",
  103. total, cnt, ts,
  104. tdiv((double)total, *t),
  105. tdiv((double)cnt, *t));
  106. }
  107. }
  108. /*
  109. * Parse multiple length statements for vectored I/O, and construct an I/O
  110. * vector matching it.
  111. */
  112. static void *
  113. create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
  114. {
  115. size_t *sizes = calloc(nr_iov, sizeof(size_t));
  116. size_t count = 0;
  117. void *buf = NULL;
  118. void *p;
  119. int i;
  120. for (i = 0; i < nr_iov; i++) {
  121. char *arg = argv[i];
  122. int64_t len;
  123. len = cvtnum(arg);
  124. if (len < 0) {
  125. printf("non-numeric length argument -- %s\n", arg);
  126. goto fail;
  127. }
  128. /* should be SIZE_T_MAX, but that doesn't exist */
  129. if (len > INT_MAX) {
  130. printf("too large length argument -- %s\n", arg);
  131. goto fail;
  132. }
  133. if (len & 0x1ff) {
  134. printf("length argument %" PRId64
  135. " is not sector aligned\n", len);
  136. goto fail;
  137. }
  138. sizes[i] = len;
  139. count += len;
  140. }
  141. qemu_iovec_init(qiov, nr_iov);
  142. buf = p = qemu_io_alloc(count, pattern);
  143. for (i = 0; i < nr_iov; i++) {
  144. qemu_iovec_add(qiov, p, sizes[i]);
  145. p += sizes[i];
  146. }
  147. fail:
  148. free(sizes);
  149. return buf;
  150. }
  151. static int do_read(char *buf, int64_t offset, int count, int *total)
  152. {
  153. int ret;
  154. ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9);
  155. if (ret < 0) {
  156. return ret;
  157. }
  158. *total = count;
  159. return 1;
  160. }
  161. static int do_write(char *buf, int64_t offset, int count, int *total)
  162. {
  163. int ret;
  164. ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9);
  165. if (ret < 0) {
  166. return ret;
  167. }
  168. *total = count;
  169. return 1;
  170. }
  171. static int do_pread(char *buf, int64_t offset, int count, int *total)
  172. {
  173. *total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
  174. if (*total < 0) {
  175. return *total;
  176. }
  177. return 1;
  178. }
  179. static int do_pwrite(char *buf, int64_t offset, int count, int *total)
  180. {
  181. *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
  182. if (*total < 0) {
  183. return *total;
  184. }
  185. return 1;
  186. }
  187. static int do_load_vmstate(char *buf, int64_t offset, int count, int *total)
  188. {
  189. *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
  190. if (*total < 0) {
  191. return *total;
  192. }
  193. return 1;
  194. }
  195. static int do_save_vmstate(char *buf, int64_t offset, int count, int *total)
  196. {
  197. *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
  198. if (*total < 0) {
  199. return *total;
  200. }
  201. return 1;
  202. }
  203. #define NOT_DONE 0x7fffffff
  204. static void aio_rw_done(void *opaque, int ret)
  205. {
  206. *(int *)opaque = ret;
  207. }
  208. static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total)
  209. {
  210. BlockDriverAIOCB *acb;
  211. int async_ret = NOT_DONE;
  212. acb = bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
  213. aio_rw_done, &async_ret);
  214. if (!acb) {
  215. return -EIO;
  216. }
  217. while (async_ret == NOT_DONE) {
  218. qemu_aio_wait();
  219. }
  220. *total = qiov->size;
  221. return async_ret < 0 ? async_ret : 1;
  222. }
  223. static int do_aio_writev(QEMUIOVector *qiov, int64_t offset, int *total)
  224. {
  225. BlockDriverAIOCB *acb;
  226. int async_ret = NOT_DONE;
  227. acb = bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
  228. aio_rw_done, &async_ret);
  229. if (!acb) {
  230. return -EIO;
  231. }
  232. while (async_ret == NOT_DONE) {
  233. qemu_aio_wait();
  234. }
  235. *total = qiov->size;
  236. return async_ret < 0 ? async_ret : 1;
  237. }
  238. struct multiwrite_async_ret {
  239. int num_done;
  240. int error;
  241. };
  242. static void multiwrite_cb(void *opaque, int ret)
  243. {
  244. struct multiwrite_async_ret *async_ret = opaque;
  245. async_ret->num_done++;
  246. if (ret < 0) {
  247. async_ret->error = ret;
  248. }
  249. }
  250. static int do_aio_multiwrite(BlockRequest* reqs, int num_reqs, int *total)
  251. {
  252. int i, ret;
  253. struct multiwrite_async_ret async_ret = {
  254. .num_done = 0,
  255. .error = 0,
  256. };
  257. *total = 0;
  258. for (i = 0; i < num_reqs; i++) {
  259. reqs[i].cb = multiwrite_cb;
  260. reqs[i].opaque = &async_ret;
  261. *total += reqs[i].qiov->size;
  262. }
  263. ret = bdrv_aio_multiwrite(bs, reqs, num_reqs);
  264. if (ret < 0) {
  265. return ret;
  266. }
  267. while (async_ret.num_done < num_reqs) {
  268. qemu_aio_wait();
  269. }
  270. return async_ret.error < 0 ? async_ret.error : 1;
  271. }
  272. static void read_help(void)
  273. {
  274. printf(
  275. "\n"
  276. " reads a range of bytes from the given offset\n"
  277. "\n"
  278. " Example:\n"
  279. " 'read -v 512 1k' - dumps 1 kilobyte read from 512 bytes into the file\n"
  280. "\n"
  281. " Reads a segment of the currently open file, optionally dumping it to the\n"
  282. " standard output stream (with -v option) for subsequent inspection.\n"
  283. " -b, -- read from the VM state rather than the virtual disk\n"
  284. " -C, -- report statistics in a machine parsable format\n"
  285. " -l, -- length for pattern verification (only with -P)\n"
  286. " -p, -- use bdrv_pread to read the file\n"
  287. " -P, -- use a pattern to verify read data\n"
  288. " -q, -- quiet mode, do not show I/O statistics\n"
  289. " -s, -- start offset for pattern verification (only with -P)\n"
  290. " -v, -- dump buffer to standard output\n"
  291. "\n");
  292. }
  293. static int read_f(int argc, char **argv);
  294. static const cmdinfo_t read_cmd = {
  295. .name = "read",
  296. .altname = "r",
  297. .cfunc = read_f,
  298. .argmin = 2,
  299. .argmax = -1,
  300. .args = "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
  301. .oneline = "reads a number of bytes at a specified offset",
  302. .help = read_help,
  303. };
  304. static int read_f(int argc, char **argv)
  305. {
  306. struct timeval t1, t2;
  307. int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
  308. int Pflag = 0, sflag = 0, lflag = 0, bflag = 0;
  309. int c, cnt;
  310. char *buf;
  311. int64_t offset;
  312. int count;
  313. /* Some compilers get confused and warn if this is not initialized. */
  314. int total = 0;
  315. int pattern = 0, pattern_offset = 0, pattern_count = 0;
  316. while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) {
  317. switch (c) {
  318. case 'b':
  319. bflag = 1;
  320. break;
  321. case 'C':
  322. Cflag = 1;
  323. break;
  324. case 'l':
  325. lflag = 1;
  326. pattern_count = cvtnum(optarg);
  327. if (pattern_count < 0) {
  328. printf("non-numeric length argument -- %s\n", optarg);
  329. return 0;
  330. }
  331. break;
  332. case 'p':
  333. pflag = 1;
  334. break;
  335. case 'P':
  336. Pflag = 1;
  337. pattern = parse_pattern(optarg);
  338. if (pattern < 0) {
  339. return 0;
  340. }
  341. break;
  342. case 'q':
  343. qflag = 1;
  344. break;
  345. case 's':
  346. sflag = 1;
  347. pattern_offset = cvtnum(optarg);
  348. if (pattern_offset < 0) {
  349. printf("non-numeric length argument -- %s\n", optarg);
  350. return 0;
  351. }
  352. break;
  353. case 'v':
  354. vflag = 1;
  355. break;
  356. default:
  357. return command_usage(&read_cmd);
  358. }
  359. }
  360. if (optind != argc - 2) {
  361. return command_usage(&read_cmd);
  362. }
  363. if (bflag && pflag) {
  364. printf("-b and -p cannot be specified at the same time\n");
  365. return 0;
  366. }
  367. offset = cvtnum(argv[optind]);
  368. if (offset < 0) {
  369. printf("non-numeric length argument -- %s\n", argv[optind]);
  370. return 0;
  371. }
  372. optind++;
  373. count = cvtnum(argv[optind]);
  374. if (count < 0) {
  375. printf("non-numeric length argument -- %s\n", argv[optind]);
  376. return 0;
  377. }
  378. if (!Pflag && (lflag || sflag)) {
  379. return command_usage(&read_cmd);
  380. }
  381. if (!lflag) {
  382. pattern_count = count - pattern_offset;
  383. }
  384. if ((pattern_count < 0) || (pattern_count + pattern_offset > count)) {
  385. printf("pattern verfication range exceeds end of read data\n");
  386. return 0;
  387. }
  388. if (!pflag) {
  389. if (offset & 0x1ff) {
  390. printf("offset %" PRId64 " is not sector aligned\n",
  391. offset);
  392. return 0;
  393. }
  394. if (count & 0x1ff) {
  395. printf("count %d is not sector aligned\n",
  396. count);
  397. return 0;
  398. }
  399. }
  400. buf = qemu_io_alloc(count, 0xab);
  401. gettimeofday(&t1, NULL);
  402. if (pflag) {
  403. cnt = do_pread(buf, offset, count, &total);
  404. } else if (bflag) {
  405. cnt = do_load_vmstate(buf, offset, count, &total);
  406. } else {
  407. cnt = do_read(buf, offset, count, &total);
  408. }
  409. gettimeofday(&t2, NULL);
  410. if (cnt < 0) {
  411. printf("read failed: %s\n", strerror(-cnt));
  412. goto out;
  413. }
  414. if (Pflag) {
  415. void *cmp_buf = malloc(pattern_count);
  416. memset(cmp_buf, pattern, pattern_count);
  417. if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
  418. printf("Pattern verification failed at offset %"
  419. PRId64 ", %d bytes\n",
  420. offset + pattern_offset, pattern_count);
  421. }
  422. free(cmp_buf);
  423. }
  424. if (qflag) {
  425. goto out;
  426. }
  427. if (vflag) {
  428. dump_buffer(buf, offset, count);
  429. }
  430. /* Finally, report back -- -C gives a parsable format */
  431. t2 = tsub(t2, t1);
  432. print_report("read", &t2, offset, count, total, cnt, Cflag);
  433. out:
  434. qemu_io_free(buf);
  435. return 0;
  436. }
  437. static void readv_help(void)
  438. {
  439. printf(
  440. "\n"
  441. " reads a range of bytes from the given offset into multiple buffers\n"
  442. "\n"
  443. " Example:\n"
  444. " 'readv -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
  445. "\n"
  446. " Reads a segment of the currently open file, optionally dumping it to the\n"
  447. " standard output stream (with -v option) for subsequent inspection.\n"
  448. " Uses multiple iovec buffers if more than one byte range is specified.\n"
  449. " -C, -- report statistics in a machine parsable format\n"
  450. " -P, -- use a pattern to verify read data\n"
  451. " -v, -- dump buffer to standard output\n"
  452. " -q, -- quiet mode, do not show I/O statistics\n"
  453. "\n");
  454. }
  455. static int readv_f(int argc, char **argv);
  456. static const cmdinfo_t readv_cmd = {
  457. .name = "readv",
  458. .cfunc = readv_f,
  459. .argmin = 2,
  460. .argmax = -1,
  461. .args = "[-Cqv] [-P pattern ] off len [len..]",
  462. .oneline = "reads a number of bytes at a specified offset",
  463. .help = readv_help,
  464. };
  465. static int readv_f(int argc, char **argv)
  466. {
  467. struct timeval t1, t2;
  468. int Cflag = 0, qflag = 0, vflag = 0;
  469. int c, cnt;
  470. char *buf;
  471. int64_t offset;
  472. /* Some compilers get confused and warn if this is not initialized. */
  473. int total = 0;
  474. int nr_iov;
  475. QEMUIOVector qiov;
  476. int pattern = 0;
  477. int Pflag = 0;
  478. while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
  479. switch (c) {
  480. case 'C':
  481. Cflag = 1;
  482. break;
  483. case 'P':
  484. Pflag = 1;
  485. pattern = parse_pattern(optarg);
  486. if (pattern < 0) {
  487. return 0;
  488. }
  489. break;
  490. case 'q':
  491. qflag = 1;
  492. break;
  493. case 'v':
  494. vflag = 1;
  495. break;
  496. default:
  497. return command_usage(&readv_cmd);
  498. }
  499. }
  500. if (optind > argc - 2) {
  501. return command_usage(&readv_cmd);
  502. }
  503. offset = cvtnum(argv[optind]);
  504. if (offset < 0) {
  505. printf("non-numeric length argument -- %s\n", argv[optind]);
  506. return 0;
  507. }
  508. optind++;
  509. if (offset & 0x1ff) {
  510. printf("offset %" PRId64 " is not sector aligned\n",
  511. offset);
  512. return 0;
  513. }
  514. nr_iov = argc - optind;
  515. buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab);
  516. if (buf == NULL) {
  517. return 0;
  518. }
  519. gettimeofday(&t1, NULL);
  520. cnt = do_aio_readv(&qiov, offset, &total);
  521. gettimeofday(&t2, NULL);
  522. if (cnt < 0) {
  523. printf("readv failed: %s\n", strerror(-cnt));
  524. goto out;
  525. }
  526. if (Pflag) {
  527. void *cmp_buf = malloc(qiov.size);
  528. memset(cmp_buf, pattern, qiov.size);
  529. if (memcmp(buf, cmp_buf, qiov.size)) {
  530. printf("Pattern verification failed at offset %"
  531. PRId64 ", %zd bytes\n", offset, qiov.size);
  532. }
  533. free(cmp_buf);
  534. }
  535. if (qflag) {
  536. goto out;
  537. }
  538. if (vflag) {
  539. dump_buffer(buf, offset, qiov.size);
  540. }
  541. /* Finally, report back -- -C gives a parsable format */
  542. t2 = tsub(t2, t1);
  543. print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
  544. out:
  545. qemu_io_free(buf);
  546. return 0;
  547. }
  548. static void write_help(void)
  549. {
  550. printf(
  551. "\n"
  552. " writes a range of bytes from the given offset\n"
  553. "\n"
  554. " Example:\n"
  555. " 'write 512 1k' - writes 1 kilobyte at 512 bytes into the open file\n"
  556. "\n"
  557. " Writes into a segment of the currently open file, using a buffer\n"
  558. " filled with a set pattern (0xcdcdcdcd).\n"
  559. " -b, -- write to the VM state rather than the virtual disk\n"
  560. " -p, -- use bdrv_pwrite to write the file\n"
  561. " -P, -- use different pattern to fill file\n"
  562. " -C, -- report statistics in a machine parsable format\n"
  563. " -q, -- quiet mode, do not show I/O statistics\n"
  564. "\n");
  565. }
  566. static int write_f(int argc, char **argv);
  567. static const cmdinfo_t write_cmd = {
  568. .name = "write",
  569. .altname = "w",
  570. .cfunc = write_f,
  571. .argmin = 2,
  572. .argmax = -1,
  573. .args = "[-abCpq] [-P pattern ] off len",
  574. .oneline = "writes a number of bytes at a specified offset",
  575. .help = write_help,
  576. };
  577. static int write_f(int argc, char **argv)
  578. {
  579. struct timeval t1, t2;
  580. int Cflag = 0, pflag = 0, qflag = 0, bflag = 0;
  581. int c, cnt;
  582. char *buf;
  583. int64_t offset;
  584. int count;
  585. /* Some compilers get confused and warn if this is not initialized. */
  586. int total = 0;
  587. int pattern = 0xcd;
  588. while ((c = getopt(argc, argv, "bCpP:q")) != EOF) {
  589. switch (c) {
  590. case 'b':
  591. bflag = 1;
  592. break;
  593. case 'C':
  594. Cflag = 1;
  595. break;
  596. case 'p':
  597. pflag = 1;
  598. break;
  599. case 'P':
  600. pattern = parse_pattern(optarg);
  601. if (pattern < 0) {
  602. return 0;
  603. }
  604. break;
  605. case 'q':
  606. qflag = 1;
  607. break;
  608. default:
  609. return command_usage(&write_cmd);
  610. }
  611. }
  612. if (optind != argc - 2) {
  613. return command_usage(&write_cmd);
  614. }
  615. if (bflag && pflag) {
  616. printf("-b and -p cannot be specified at the same time\n");
  617. return 0;
  618. }
  619. offset = cvtnum(argv[optind]);
  620. if (offset < 0) {
  621. printf("non-numeric length argument -- %s\n", argv[optind]);
  622. return 0;
  623. }
  624. optind++;
  625. count = cvtnum(argv[optind]);
  626. if (count < 0) {
  627. printf("non-numeric length argument -- %s\n", argv[optind]);
  628. return 0;
  629. }
  630. if (!pflag) {
  631. if (offset & 0x1ff) {
  632. printf("offset %" PRId64 " is not sector aligned\n",
  633. offset);
  634. return 0;
  635. }
  636. if (count & 0x1ff) {
  637. printf("count %d is not sector aligned\n",
  638. count);
  639. return 0;
  640. }
  641. }
  642. buf = qemu_io_alloc(count, pattern);
  643. gettimeofday(&t1, NULL);
  644. if (pflag) {
  645. cnt = do_pwrite(buf, offset, count, &total);
  646. } else if (bflag) {
  647. cnt = do_save_vmstate(buf, offset, count, &total);
  648. } else {
  649. cnt = do_write(buf, offset, count, &total);
  650. }
  651. gettimeofday(&t2, NULL);
  652. if (cnt < 0) {
  653. printf("write failed: %s\n", strerror(-cnt));
  654. goto out;
  655. }
  656. if (qflag) {
  657. goto out;
  658. }
  659. /* Finally, report back -- -C gives a parsable format */
  660. t2 = tsub(t2, t1);
  661. print_report("wrote", &t2, offset, count, total, cnt, Cflag);
  662. out:
  663. qemu_io_free(buf);
  664. return 0;
  665. }
  666. static void
  667. writev_help(void)
  668. {
  669. printf(
  670. "\n"
  671. " writes a range of bytes from the given offset source from multiple buffers\n"
  672. "\n"
  673. " Example:\n"
  674. " 'write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
  675. "\n"
  676. " Writes into a segment of the currently open file, using a buffer\n"
  677. " filled with a set pattern (0xcdcdcdcd).\n"
  678. " -P, -- use different pattern to fill file\n"
  679. " -C, -- report statistics in a machine parsable format\n"
  680. " -q, -- quiet mode, do not show I/O statistics\n"
  681. "\n");
  682. }
  683. static int writev_f(int argc, char **argv);
  684. static const cmdinfo_t writev_cmd = {
  685. .name = "writev",
  686. .cfunc = writev_f,
  687. .argmin = 2,
  688. .argmax = -1,
  689. .args = "[-Cq] [-P pattern ] off len [len..]",
  690. .oneline = "writes a number of bytes at a specified offset",
  691. .help = writev_help,
  692. };
  693. static int writev_f(int argc, char **argv)
  694. {
  695. struct timeval t1, t2;
  696. int Cflag = 0, qflag = 0;
  697. int c, cnt;
  698. char *buf;
  699. int64_t offset;
  700. /* Some compilers get confused and warn if this is not initialized. */
  701. int total = 0;
  702. int nr_iov;
  703. int pattern = 0xcd;
  704. QEMUIOVector qiov;
  705. while ((c = getopt(argc, argv, "CqP:")) != EOF) {
  706. switch (c) {
  707. case 'C':
  708. Cflag = 1;
  709. break;
  710. case 'q':
  711. qflag = 1;
  712. break;
  713. case 'P':
  714. pattern = parse_pattern(optarg);
  715. if (pattern < 0) {
  716. return 0;
  717. }
  718. break;
  719. default:
  720. return command_usage(&writev_cmd);
  721. }
  722. }
  723. if (optind > argc - 2) {
  724. return command_usage(&writev_cmd);
  725. }
  726. offset = cvtnum(argv[optind]);
  727. if (offset < 0) {
  728. printf("non-numeric length argument -- %s\n", argv[optind]);
  729. return 0;
  730. }
  731. optind++;
  732. if (offset & 0x1ff) {
  733. printf("offset %" PRId64 " is not sector aligned\n",
  734. offset);
  735. return 0;
  736. }
  737. nr_iov = argc - optind;
  738. buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern);
  739. if (buf == NULL) {
  740. return 0;
  741. }
  742. gettimeofday(&t1, NULL);
  743. cnt = do_aio_writev(&qiov, offset, &total);
  744. gettimeofday(&t2, NULL);
  745. if (cnt < 0) {
  746. printf("writev failed: %s\n", strerror(-cnt));
  747. goto out;
  748. }
  749. if (qflag) {
  750. goto out;
  751. }
  752. /* Finally, report back -- -C gives a parsable format */
  753. t2 = tsub(t2, t1);
  754. print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
  755. out:
  756. qemu_io_free(buf);
  757. return 0;
  758. }
  759. static void multiwrite_help(void)
  760. {
  761. printf(
  762. "\n"
  763. " writes a range of bytes from the given offset source from multiple buffers,\n"
  764. " in a batch of requests that may be merged by qemu\n"
  765. "\n"
  766. " Example:\n"
  767. " 'multiwrite 512 1k 1k ; 4k 1k'\n"
  768. " writes 2 kB at 512 bytes and 1 kB at 4 kB into the open file\n"
  769. "\n"
  770. " Writes into a segment of the currently open file, using a buffer\n"
  771. " filled with a set pattern (0xcdcdcdcd). The pattern byte is increased\n"
  772. " by one for each request contained in the multiwrite command.\n"
  773. " -P, -- use different pattern to fill file\n"
  774. " -C, -- report statistics in a machine parsable format\n"
  775. " -q, -- quiet mode, do not show I/O statistics\n"
  776. "\n");
  777. }
  778. static int multiwrite_f(int argc, char **argv);
  779. static const cmdinfo_t multiwrite_cmd = {
  780. .name = "multiwrite",
  781. .cfunc = multiwrite_f,
  782. .argmin = 2,
  783. .argmax = -1,
  784. .args = "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]",
  785. .oneline = "issues multiple write requests at once",
  786. .help = multiwrite_help,
  787. };
  788. static int multiwrite_f(int argc, char **argv)
  789. {
  790. struct timeval t1, t2;
  791. int Cflag = 0, qflag = 0;
  792. int c, cnt;
  793. char **buf;
  794. int64_t offset, first_offset = 0;
  795. /* Some compilers get confused and warn if this is not initialized. */
  796. int total = 0;
  797. int nr_iov;
  798. int nr_reqs;
  799. int pattern = 0xcd;
  800. QEMUIOVector *qiovs;
  801. int i;
  802. BlockRequest *reqs;
  803. while ((c = getopt(argc, argv, "CqP:")) != EOF) {
  804. switch (c) {
  805. case 'C':
  806. Cflag = 1;
  807. break;
  808. case 'q':
  809. qflag = 1;
  810. break;
  811. case 'P':
  812. pattern = parse_pattern(optarg);
  813. if (pattern < 0) {
  814. return 0;
  815. }
  816. break;
  817. default:
  818. return command_usage(&writev_cmd);
  819. }
  820. }
  821. if (optind > argc - 2) {
  822. return command_usage(&writev_cmd);
  823. }
  824. nr_reqs = 1;
  825. for (i = optind; i < argc; i++) {
  826. if (!strcmp(argv[i], ";")) {
  827. nr_reqs++;
  828. }
  829. }
  830. reqs = g_malloc0(nr_reqs * sizeof(*reqs));
  831. buf = g_malloc0(nr_reqs * sizeof(*buf));
  832. qiovs = g_malloc(nr_reqs * sizeof(*qiovs));
  833. for (i = 0; i < nr_reqs && optind < argc; i++) {
  834. int j;
  835. /* Read the offset of the request */
  836. offset = cvtnum(argv[optind]);
  837. if (offset < 0) {
  838. printf("non-numeric offset argument -- %s\n", argv[optind]);
  839. goto out;
  840. }
  841. optind++;
  842. if (offset & 0x1ff) {
  843. printf("offset %lld is not sector aligned\n",
  844. (long long)offset);
  845. goto out;
  846. }
  847. if (i == 0) {
  848. first_offset = offset;
  849. }
  850. /* Read lengths for qiov entries */
  851. for (j = optind; j < argc; j++) {
  852. if (!strcmp(argv[j], ";")) {
  853. break;
  854. }
  855. }
  856. nr_iov = j - optind;
  857. /* Build request */
  858. buf[i] = create_iovec(&qiovs[i], &argv[optind], nr_iov, pattern);
  859. if (buf[i] == NULL) {
  860. goto out;
  861. }
  862. reqs[i].qiov = &qiovs[i];
  863. reqs[i].sector = offset >> 9;
  864. reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
  865. optind = j + 1;
  866. pattern++;
  867. }
  868. /* If there were empty requests at the end, ignore them */
  869. nr_reqs = i;
  870. gettimeofday(&t1, NULL);
  871. cnt = do_aio_multiwrite(reqs, nr_reqs, &total);
  872. gettimeofday(&t2, NULL);
  873. if (cnt < 0) {
  874. printf("aio_multiwrite failed: %s\n", strerror(-cnt));
  875. goto out;
  876. }
  877. if (qflag) {
  878. goto out;
  879. }
  880. /* Finally, report back -- -C gives a parsable format */
  881. t2 = tsub(t2, t1);
  882. print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);
  883. out:
  884. for (i = 0; i < nr_reqs; i++) {
  885. qemu_io_free(buf[i]);
  886. if (reqs[i].qiov != NULL) {
  887. qemu_iovec_destroy(&qiovs[i]);
  888. }
  889. }
  890. g_free(buf);
  891. g_free(reqs);
  892. g_free(qiovs);
  893. return 0;
  894. }
  895. struct aio_ctx {
  896. QEMUIOVector qiov;
  897. int64_t offset;
  898. char *buf;
  899. int qflag;
  900. int vflag;
  901. int Cflag;
  902. int Pflag;
  903. int pattern;
  904. struct timeval t1;
  905. };
  906. static void aio_write_done(void *opaque, int ret)
  907. {
  908. struct aio_ctx *ctx = opaque;
  909. struct timeval t2;
  910. gettimeofday(&t2, NULL);
  911. if (ret < 0) {
  912. printf("aio_write failed: %s\n", strerror(-ret));
  913. goto out;
  914. }
  915. if (ctx->qflag) {
  916. goto out;
  917. }
  918. /* Finally, report back -- -C gives a parsable format */
  919. t2 = tsub(t2, ctx->t1);
  920. print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
  921. ctx->qiov.size, 1, ctx->Cflag);
  922. out:
  923. qemu_io_free(ctx->buf);
  924. free(ctx);
  925. }
  926. static void aio_read_done(void *opaque, int ret)
  927. {
  928. struct aio_ctx *ctx = opaque;
  929. struct timeval t2;
  930. gettimeofday(&t2, NULL);
  931. if (ret < 0) {
  932. printf("readv failed: %s\n", strerror(-ret));
  933. goto out;
  934. }
  935. if (ctx->Pflag) {
  936. void *cmp_buf = malloc(ctx->qiov.size);
  937. memset(cmp_buf, ctx->pattern, ctx->qiov.size);
  938. if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
  939. printf("Pattern verification failed at offset %"
  940. PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
  941. }
  942. free(cmp_buf);
  943. }
  944. if (ctx->qflag) {
  945. goto out;
  946. }
  947. if (ctx->vflag) {
  948. dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
  949. }
  950. /* Finally, report back -- -C gives a parsable format */
  951. t2 = tsub(t2, ctx->t1);
  952. print_report("read", &t2, ctx->offset, ctx->qiov.size,
  953. ctx->qiov.size, 1, ctx->Cflag);
  954. out:
  955. qemu_io_free(ctx->buf);
  956. free(ctx);
  957. }
  958. static void aio_read_help(void)
  959. {
  960. printf(
  961. "\n"
  962. " asynchronously reads a range of bytes from the given offset\n"
  963. "\n"
  964. " Example:\n"
  965. " 'aio_read -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
  966. "\n"
  967. " Reads a segment of the currently open file, optionally dumping it to the\n"
  968. " standard output stream (with -v option) for subsequent inspection.\n"
  969. " The read is performed asynchronously and the aio_flush command must be\n"
  970. " used to ensure all outstanding aio requests have been completed\n"
  971. " -C, -- report statistics in a machine parsable format\n"
  972. " -P, -- use a pattern to verify read data\n"
  973. " -v, -- dump buffer to standard output\n"
  974. " -q, -- quiet mode, do not show I/O statistics\n"
  975. "\n");
  976. }
  977. static int aio_read_f(int argc, char **argv);
  978. static const cmdinfo_t aio_read_cmd = {
  979. .name = "aio_read",
  980. .cfunc = aio_read_f,
  981. .argmin = 2,
  982. .argmax = -1,
  983. .args = "[-Cqv] [-P pattern ] off len [len..]",
  984. .oneline = "asynchronously reads a number of bytes",
  985. .help = aio_read_help,
  986. };
  987. static int aio_read_f(int argc, char **argv)
  988. {
  989. int nr_iov, c;
  990. struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
  991. BlockDriverAIOCB *acb;
  992. while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
  993. switch (c) {
  994. case 'C':
  995. ctx->Cflag = 1;
  996. break;
  997. case 'P':
  998. ctx->Pflag = 1;
  999. ctx->pattern = parse_pattern(optarg);
  1000. if (ctx->pattern < 0) {
  1001. free(ctx);
  1002. return 0;
  1003. }
  1004. break;
  1005. case 'q':
  1006. ctx->qflag = 1;
  1007. break;
  1008. case 'v':
  1009. ctx->vflag = 1;
  1010. break;
  1011. default:
  1012. free(ctx);
  1013. return command_usage(&aio_read_cmd);
  1014. }
  1015. }
  1016. if (optind > argc - 2) {
  1017. free(ctx);
  1018. return command_usage(&aio_read_cmd);
  1019. }
  1020. ctx->offset = cvtnum(argv[optind]);
  1021. if (ctx->offset < 0) {
  1022. printf("non-numeric length argument -- %s\n", argv[optind]);
  1023. free(ctx);
  1024. return 0;
  1025. }
  1026. optind++;
  1027. if (ctx->offset & 0x1ff) {
  1028. printf("offset %" PRId64 " is not sector aligned\n",
  1029. ctx->offset);
  1030. free(ctx);
  1031. return 0;
  1032. }
  1033. nr_iov = argc - optind;
  1034. ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);
  1035. if (ctx->buf == NULL) {
  1036. free(ctx);
  1037. return 0;
  1038. }
  1039. gettimeofday(&ctx->t1, NULL);
  1040. acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
  1041. ctx->qiov.size >> 9, aio_read_done, ctx);
  1042. if (!acb) {
  1043. free(ctx->buf);
  1044. free(ctx);
  1045. return -EIO;
  1046. }
  1047. return 0;
  1048. }
  1049. static void aio_write_help(void)
  1050. {
  1051. printf(
  1052. "\n"
  1053. " asynchronously writes a range of bytes from the given offset source\n"
  1054. " from multiple buffers\n"
  1055. "\n"
  1056. " Example:\n"
  1057. " 'aio_write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
  1058. "\n"
  1059. " Writes into a segment of the currently open file, using a buffer\n"
  1060. " filled with a set pattern (0xcdcdcdcd).\n"
  1061. " The write is performed asynchronously and the aio_flush command must be\n"
  1062. " used to ensure all outstanding aio requests have been completed\n"
  1063. " -P, -- use different pattern to fill file\n"
  1064. " -C, -- report statistics in a machine parsable format\n"
  1065. " -q, -- quiet mode, do not show I/O statistics\n"
  1066. "\n");
  1067. }
  1068. static int aio_write_f(int argc, char **argv);
  1069. static const cmdinfo_t aio_write_cmd = {
  1070. .name = "aio_write",
  1071. .cfunc = aio_write_f,
  1072. .argmin = 2,
  1073. .argmax = -1,
  1074. .args = "[-Cq] [-P pattern ] off len [len..]",
  1075. .oneline = "asynchronously writes a number of bytes",
  1076. .help = aio_write_help,
  1077. };
  1078. static int aio_write_f(int argc, char **argv)
  1079. {
  1080. int nr_iov, c;
  1081. int pattern = 0xcd;
  1082. struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
  1083. BlockDriverAIOCB *acb;
  1084. while ((c = getopt(argc, argv, "CqP:")) != EOF) {
  1085. switch (c) {
  1086. case 'C':
  1087. ctx->Cflag = 1;
  1088. break;
  1089. case 'q':
  1090. ctx->qflag = 1;
  1091. break;
  1092. case 'P':
  1093. pattern = parse_pattern(optarg);
  1094. if (pattern < 0) {
  1095. free(ctx);
  1096. return 0;
  1097. }
  1098. break;
  1099. default:
  1100. free(ctx);
  1101. return command_usage(&aio_write_cmd);
  1102. }
  1103. }
  1104. if (optind > argc - 2) {
  1105. free(ctx);
  1106. return command_usage(&aio_write_cmd);
  1107. }
  1108. ctx->offset = cvtnum(argv[optind]);
  1109. if (ctx->offset < 0) {
  1110. printf("non-numeric length argument -- %s\n", argv[optind]);
  1111. free(ctx);
  1112. return 0;
  1113. }
  1114. optind++;
  1115. if (ctx->offset & 0x1ff) {
  1116. printf("offset %" PRId64 " is not sector aligned\n",
  1117. ctx->offset);
  1118. free(ctx);
  1119. return 0;
  1120. }
  1121. nr_iov = argc - optind;
  1122. ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);
  1123. if (ctx->buf == NULL) {
  1124. free(ctx);
  1125. return 0;
  1126. }
  1127. gettimeofday(&ctx->t1, NULL);
  1128. acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
  1129. ctx->qiov.size >> 9, aio_write_done, ctx);
  1130. if (!acb) {
  1131. free(ctx->buf);
  1132. free(ctx);
  1133. return -EIO;
  1134. }
  1135. return 0;
  1136. }
  1137. static int aio_flush_f(int argc, char **argv)
  1138. {
  1139. qemu_aio_flush();
  1140. return 0;
  1141. }
  1142. static const cmdinfo_t aio_flush_cmd = {
  1143. .name = "aio_flush",
  1144. .cfunc = aio_flush_f,
  1145. .oneline = "completes all outstanding aio requests"
  1146. };
  1147. static int flush_f(int argc, char **argv)
  1148. {
  1149. bdrv_flush(bs);
  1150. return 0;
  1151. }
  1152. static const cmdinfo_t flush_cmd = {
  1153. .name = "flush",
  1154. .altname = "f",
  1155. .cfunc = flush_f,
  1156. .oneline = "flush all in-core file state to disk",
  1157. };
  1158. static int truncate_f(int argc, char **argv)
  1159. {
  1160. int64_t offset;
  1161. int ret;
  1162. offset = cvtnum(argv[1]);
  1163. if (offset < 0) {
  1164. printf("non-numeric truncate argument -- %s\n", argv[1]);
  1165. return 0;
  1166. }
  1167. ret = bdrv_truncate(bs, offset);
  1168. if (ret < 0) {
  1169. printf("truncate: %s\n", strerror(-ret));
  1170. return 0;
  1171. }
  1172. return 0;
  1173. }
  1174. static const cmdinfo_t truncate_cmd = {
  1175. .name = "truncate",
  1176. .altname = "t",
  1177. .cfunc = truncate_f,
  1178. .argmin = 1,
  1179. .argmax = 1,
  1180. .args = "off",
  1181. .oneline = "truncates the current file at the given offset",
  1182. };
  1183. static int length_f(int argc, char **argv)
  1184. {
  1185. int64_t size;
  1186. char s1[64];
  1187. size = bdrv_getlength(bs);
  1188. if (size < 0) {
  1189. printf("getlength: %s\n", strerror(-size));
  1190. return 0;
  1191. }
  1192. cvtstr(size, s1, sizeof(s1));
  1193. printf("%s\n", s1);
  1194. return 0;
  1195. }
  1196. static const cmdinfo_t length_cmd = {
  1197. .name = "length",
  1198. .altname = "l",
  1199. .cfunc = length_f,
  1200. .oneline = "gets the length of the current file",
  1201. };
  1202. static int info_f(int argc, char **argv)
  1203. {
  1204. BlockDriverInfo bdi;
  1205. char s1[64], s2[64];
  1206. int ret;
  1207. if (bs->drv && bs->drv->format_name) {
  1208. printf("format name: %s\n", bs->drv->format_name);
  1209. }
  1210. if (bs->drv && bs->drv->protocol_name) {
  1211. printf("format name: %s\n", bs->drv->protocol_name);
  1212. }
  1213. ret = bdrv_get_info(bs, &bdi);
  1214. if (ret) {
  1215. return 0;
  1216. }
  1217. cvtstr(bdi.cluster_size, s1, sizeof(s1));
  1218. cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
  1219. printf("cluster size: %s\n", s1);
  1220. printf("vm state offset: %s\n", s2);
  1221. return 0;
  1222. }
  1223. static const cmdinfo_t info_cmd = {
  1224. .name = "info",
  1225. .altname = "i",
  1226. .cfunc = info_f,
  1227. .oneline = "prints information about the current file",
  1228. };
  1229. static void discard_help(void)
  1230. {
  1231. printf(
  1232. "\n"
  1233. " discards a range of bytes from the given offset\n"
  1234. "\n"
  1235. " Example:\n"
  1236. " 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
  1237. "\n"
  1238. " Discards a segment of the currently open file.\n"
  1239. " -C, -- report statistics in a machine parsable format\n"
  1240. " -q, -- quiet mode, do not show I/O statistics\n"
  1241. "\n");
  1242. }
  1243. static int discard_f(int argc, char **argv);
  1244. static const cmdinfo_t discard_cmd = {
  1245. .name = "discard",
  1246. .altname = "d",
  1247. .cfunc = discard_f,
  1248. .argmin = 2,
  1249. .argmax = -1,
  1250. .args = "[-Cq] off len",
  1251. .oneline = "discards a number of bytes at a specified offset",
  1252. .help = discard_help,
  1253. };
  1254. static int discard_f(int argc, char **argv)
  1255. {
  1256. struct timeval t1, t2;
  1257. int Cflag = 0, qflag = 0;
  1258. int c, ret;
  1259. int64_t offset;
  1260. int count;
  1261. while ((c = getopt(argc, argv, "Cq")) != EOF) {
  1262. switch (c) {
  1263. case 'C':
  1264. Cflag = 1;
  1265. break;
  1266. case 'q':
  1267. qflag = 1;
  1268. break;
  1269. default:
  1270. return command_usage(&discard_cmd);
  1271. }
  1272. }
  1273. if (optind != argc - 2) {
  1274. return command_usage(&discard_cmd);
  1275. }
  1276. offset = cvtnum(argv[optind]);
  1277. if (offset < 0) {
  1278. printf("non-numeric length argument -- %s\n", argv[optind]);
  1279. return 0;
  1280. }
  1281. optind++;
  1282. count = cvtnum(argv[optind]);
  1283. if (count < 0) {
  1284. printf("non-numeric length argument -- %s\n", argv[optind]);
  1285. return 0;
  1286. }
  1287. gettimeofday(&t1, NULL);
  1288. ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS,
  1289. count >> BDRV_SECTOR_BITS);
  1290. gettimeofday(&t2, NULL);
  1291. if (ret < 0) {
  1292. printf("discard failed: %s\n", strerror(-ret));
  1293. goto out;
  1294. }
  1295. /* Finally, report back -- -C gives a parsable format */
  1296. if (!qflag) {
  1297. t2 = tsub(t2, t1);
  1298. print_report("discard", &t2, offset, count, count, 1, Cflag);
  1299. }
  1300. out:
  1301. return 0;
  1302. }
  1303. static int alloc_f(int argc, char **argv)
  1304. {
  1305. int64_t offset;
  1306. int nb_sectors, remaining;
  1307. char s1[64];
  1308. int num, sum_alloc;
  1309. int ret;
  1310. offset = cvtnum(argv[1]);
  1311. if (offset & 0x1ff) {
  1312. printf("offset %" PRId64 " is not sector aligned\n",
  1313. offset);
  1314. return 0;
  1315. }
  1316. if (argc == 3) {
  1317. nb_sectors = cvtnum(argv[2]);
  1318. } else {
  1319. nb_sectors = 1;
  1320. }
  1321. remaining = nb_sectors;
  1322. sum_alloc = 0;
  1323. while (remaining) {
  1324. ret = bdrv_is_allocated(bs, offset >> 9, nb_sectors, &num);
  1325. remaining -= num;
  1326. if (ret) {
  1327. sum_alloc += num;
  1328. }
  1329. }
  1330. cvtstr(offset, s1, sizeof(s1));
  1331. printf("%d/%d sectors allocated at offset %s\n",
  1332. sum_alloc, nb_sectors, s1);
  1333. return 0;
  1334. }
  1335. static const cmdinfo_t alloc_cmd = {
  1336. .name = "alloc",
  1337. .altname = "a",
  1338. .argmin = 1,
  1339. .argmax = 2,
  1340. .cfunc = alloc_f,
  1341. .args = "off [sectors]",
  1342. .oneline = "checks if a sector is present in the file",
  1343. };
  1344. static int map_f(int argc, char **argv)
  1345. {
  1346. int64_t offset;
  1347. int64_t nb_sectors;
  1348. char s1[64];
  1349. int num, num_checked;
  1350. int ret;
  1351. const char *retstr;
  1352. offset = 0;
  1353. nb_sectors = bs->total_sectors;
  1354. do {
  1355. num_checked = MIN(nb_sectors, INT_MAX);
  1356. ret = bdrv_is_allocated(bs, offset, num_checked, &num);
  1357. retstr = ret ? " allocated" : "not allocated";
  1358. cvtstr(offset << 9ULL, s1, sizeof(s1));
  1359. printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n",
  1360. offset << 9ULL, num, num_checked, retstr, s1, ret);
  1361. offset += num;
  1362. nb_sectors -= num;
  1363. } while (offset < bs->total_sectors);
  1364. return 0;
  1365. }
  1366. static const cmdinfo_t map_cmd = {
  1367. .name = "map",
  1368. .argmin = 0,
  1369. .argmax = 0,
  1370. .cfunc = map_f,
  1371. .args = "",
  1372. .oneline = "prints the allocated areas of a file",
  1373. };
  1374. static int close_f(int argc, char **argv)
  1375. {
  1376. bdrv_delete(bs);
  1377. bs = NULL;
  1378. return 0;
  1379. }
  1380. static const cmdinfo_t close_cmd = {
  1381. .name = "close",
  1382. .altname = "c",
  1383. .cfunc = close_f,
  1384. .oneline = "close the current open file",
  1385. };
  1386. static int openfile(char *name, int flags, int growable)
  1387. {
  1388. if (bs) {
  1389. fprintf(stderr, "file open already, try 'help close'\n");
  1390. return 1;
  1391. }
  1392. if (growable) {
  1393. if (bdrv_file_open(&bs, name, flags)) {
  1394. fprintf(stderr, "%s: can't open device %s\n", progname, name);
  1395. return 1;
  1396. }
  1397. } else {
  1398. bs = bdrv_new("hda");
  1399. if (bdrv_open(bs, name, flags, NULL) < 0) {
  1400. fprintf(stderr, "%s: can't open device %s\n", progname, name);
  1401. bdrv_delete(bs);
  1402. bs = NULL;
  1403. return 1;
  1404. }
  1405. }
  1406. return 0;
  1407. }
  1408. static void open_help(void)
  1409. {
  1410. printf(
  1411. "\n"
  1412. " opens a new file in the requested mode\n"
  1413. "\n"
  1414. " Example:\n"
  1415. " 'open -Cn /tmp/data' - creates/opens data file read-write and uncached\n"
  1416. "\n"
  1417. " Opens a file for subsequent use by all of the other qemu-io commands.\n"
  1418. " -r, -- open file read-only\n"
  1419. " -s, -- use snapshot file\n"
  1420. " -n, -- disable host cache\n"
  1421. " -g, -- allow file to grow (only applies to protocols)"
  1422. "\n");
  1423. }
  1424. static int open_f(int argc, char **argv);
  1425. static const cmdinfo_t open_cmd = {
  1426. .name = "open",
  1427. .altname = "o",
  1428. .cfunc = open_f,
  1429. .argmin = 1,
  1430. .argmax = -1,
  1431. .flags = CMD_NOFILE_OK,
  1432. .args = "[-Crsn] [path]",
  1433. .oneline = "open the file specified by path",
  1434. .help = open_help,
  1435. };
  1436. static int open_f(int argc, char **argv)
  1437. {
  1438. int flags = 0;
  1439. int readonly = 0;
  1440. int growable = 0;
  1441. int c;
  1442. while ((c = getopt(argc, argv, "snrg")) != EOF) {
  1443. switch (c) {
  1444. case 's':
  1445. flags |= BDRV_O_SNAPSHOT;
  1446. break;
  1447. case 'n':
  1448. flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
  1449. break;
  1450. case 'r':
  1451. readonly = 1;
  1452. break;
  1453. case 'g':
  1454. growable = 1;
  1455. break;
  1456. default:
  1457. return command_usage(&open_cmd);
  1458. }
  1459. }
  1460. if (!readonly) {
  1461. flags |= BDRV_O_RDWR;
  1462. }
  1463. if (optind != argc - 1) {
  1464. return command_usage(&open_cmd);
  1465. }
  1466. return openfile(argv[optind], flags, growable);
  1467. }
  1468. static int init_args_command(int index)
  1469. {
  1470. /* only one device allowed so far */
  1471. if (index >= 1) {
  1472. return 0;
  1473. }
  1474. return ++index;
  1475. }
  1476. static int init_check_command(const cmdinfo_t *ct)
  1477. {
  1478. if (ct->flags & CMD_FLAG_GLOBAL) {
  1479. return 1;
  1480. }
  1481. if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
  1482. fprintf(stderr, "no file open, try 'help open'\n");
  1483. return 0;
  1484. }
  1485. return 1;
  1486. }
  1487. static void usage(const char *name)
  1488. {
  1489. printf(
  1490. "Usage: %s [-h] [-V] [-rsnm] [-c cmd] ... [file]\n"
  1491. "QEMU Disk exerciser\n"
  1492. "\n"
  1493. " -c, --cmd command to execute\n"
  1494. " -r, --read-only export read-only\n"
  1495. " -s, --snapshot use snapshot file\n"
  1496. " -n, --nocache disable host cache\n"
  1497. " -g, --growable allow file to grow (only applies to protocols)\n"
  1498. " -m, --misalign misalign allocations for O_DIRECT\n"
  1499. " -k, --native-aio use kernel AIO implementation (on Linux only)\n"
  1500. " -h, --help display this help and exit\n"
  1501. " -V, --version output version information and exit\n"
  1502. "\n",
  1503. name);
  1504. }
  1505. int main(int argc, char **argv)
  1506. {
  1507. int readonly = 0;
  1508. int growable = 0;
  1509. const char *sopt = "hVc:rsnmgk";
  1510. const struct option lopt[] = {
  1511. { "help", 0, NULL, 'h' },
  1512. { "version", 0, NULL, 'V' },
  1513. { "offset", 1, NULL, 'o' },
  1514. { "cmd", 1, NULL, 'c' },
  1515. { "read-only", 0, NULL, 'r' },
  1516. { "snapshot", 0, NULL, 's' },
  1517. { "nocache", 0, NULL, 'n' },
  1518. { "misalign", 0, NULL, 'm' },
  1519. { "growable", 0, NULL, 'g' },
  1520. { "native-aio", 0, NULL, 'k' },
  1521. { NULL, 0, NULL, 0 }
  1522. };
  1523. int c;
  1524. int opt_index = 0;
  1525. int flags = 0;
  1526. progname = basename(argv[0]);
  1527. while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
  1528. switch (c) {
  1529. case 's':
  1530. flags |= BDRV_O_SNAPSHOT;
  1531. break;
  1532. case 'n':
  1533. flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
  1534. break;
  1535. case 'c':
  1536. add_user_command(optarg);
  1537. break;
  1538. case 'r':
  1539. readonly = 1;
  1540. break;
  1541. case 'm':
  1542. misalign = 1;
  1543. break;
  1544. case 'g':
  1545. growable = 1;
  1546. break;
  1547. case 'k':
  1548. flags |= BDRV_O_NATIVE_AIO;
  1549. break;
  1550. case 'V':
  1551. printf("%s version %s\n", progname, VERSION);
  1552. exit(0);
  1553. case 'h':
  1554. usage(progname);
  1555. exit(0);
  1556. default:
  1557. usage(progname);
  1558. exit(1);
  1559. }
  1560. }
  1561. if ((argc - optind) > 1) {
  1562. usage(progname);
  1563. exit(1);
  1564. }
  1565. bdrv_init();
  1566. /* initialize commands */
  1567. quit_init();
  1568. help_init();
  1569. add_command(&open_cmd);
  1570. add_command(&close_cmd);
  1571. add_command(&read_cmd);
  1572. add_command(&readv_cmd);
  1573. add_command(&write_cmd);
  1574. add_command(&writev_cmd);
  1575. add_command(&multiwrite_cmd);
  1576. add_command(&aio_read_cmd);
  1577. add_command(&aio_write_cmd);
  1578. add_command(&aio_flush_cmd);
  1579. add_command(&flush_cmd);
  1580. add_command(&truncate_cmd);
  1581. add_command(&length_cmd);
  1582. add_command(&info_cmd);
  1583. add_command(&discard_cmd);
  1584. add_command(&alloc_cmd);
  1585. add_command(&map_cmd);
  1586. add_args_command(init_args_command);
  1587. add_check_command(init_check_command);
  1588. /* open the device */
  1589. if (!readonly) {
  1590. flags |= BDRV_O_RDWR;
  1591. }
  1592. if ((argc - optind) == 1) {
  1593. openfile(argv[optind], flags, growable);
  1594. }
  1595. command_loop();
  1596. /*
  1597. * Make sure all outstanding requests get flushed the program exits.
  1598. */
  1599. qemu_aio_flush();
  1600. if (bs) {
  1601. bdrv_delete(bs);
  1602. }
  1603. return 0;
  1604. }