2
0

qemu-io.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840
  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. gettimeofday(&t1, NULL);
  517. cnt = do_aio_readv(&qiov, offset, &total);
  518. gettimeofday(&t2, NULL);
  519. if (cnt < 0) {
  520. printf("readv failed: %s\n", strerror(-cnt));
  521. goto out;
  522. }
  523. if (Pflag) {
  524. void *cmp_buf = malloc(qiov.size);
  525. memset(cmp_buf, pattern, qiov.size);
  526. if (memcmp(buf, cmp_buf, qiov.size)) {
  527. printf("Pattern verification failed at offset %"
  528. PRId64 ", %zd bytes\n", offset, qiov.size);
  529. }
  530. free(cmp_buf);
  531. }
  532. if (qflag) {
  533. goto out;
  534. }
  535. if (vflag) {
  536. dump_buffer(buf, offset, qiov.size);
  537. }
  538. /* Finally, report back -- -C gives a parsable format */
  539. t2 = tsub(t2, t1);
  540. print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
  541. out:
  542. qemu_io_free(buf);
  543. return 0;
  544. }
  545. static void write_help(void)
  546. {
  547. printf(
  548. "\n"
  549. " writes a range of bytes from the given offset\n"
  550. "\n"
  551. " Example:\n"
  552. " 'write 512 1k' - writes 1 kilobyte at 512 bytes into the open file\n"
  553. "\n"
  554. " Writes into a segment of the currently open file, using a buffer\n"
  555. " filled with a set pattern (0xcdcdcdcd).\n"
  556. " -b, -- write to the VM state rather than the virtual disk\n"
  557. " -p, -- use bdrv_pwrite to write the file\n"
  558. " -P, -- use different pattern to fill file\n"
  559. " -C, -- report statistics in a machine parsable format\n"
  560. " -q, -- quiet mode, do not show I/O statistics\n"
  561. "\n");
  562. }
  563. static int write_f(int argc, char **argv);
  564. static const cmdinfo_t write_cmd = {
  565. .name = "write",
  566. .altname = "w",
  567. .cfunc = write_f,
  568. .argmin = 2,
  569. .argmax = -1,
  570. .args = "[-abCpq] [-P pattern ] off len",
  571. .oneline = "writes a number of bytes at a specified offset",
  572. .help = write_help,
  573. };
  574. static int write_f(int argc, char **argv)
  575. {
  576. struct timeval t1, t2;
  577. int Cflag = 0, pflag = 0, qflag = 0, bflag = 0;
  578. int c, cnt;
  579. char *buf;
  580. int64_t offset;
  581. int count;
  582. /* Some compilers get confused and warn if this is not initialized. */
  583. int total = 0;
  584. int pattern = 0xcd;
  585. while ((c = getopt(argc, argv, "bCpP:q")) != EOF) {
  586. switch (c) {
  587. case 'b':
  588. bflag = 1;
  589. break;
  590. case 'C':
  591. Cflag = 1;
  592. break;
  593. case 'p':
  594. pflag = 1;
  595. break;
  596. case 'P':
  597. pattern = parse_pattern(optarg);
  598. if (pattern < 0) {
  599. return 0;
  600. }
  601. break;
  602. case 'q':
  603. qflag = 1;
  604. break;
  605. default:
  606. return command_usage(&write_cmd);
  607. }
  608. }
  609. if (optind != argc - 2) {
  610. return command_usage(&write_cmd);
  611. }
  612. if (bflag && pflag) {
  613. printf("-b and -p cannot be specified at the same time\n");
  614. return 0;
  615. }
  616. offset = cvtnum(argv[optind]);
  617. if (offset < 0) {
  618. printf("non-numeric length argument -- %s\n", argv[optind]);
  619. return 0;
  620. }
  621. optind++;
  622. count = cvtnum(argv[optind]);
  623. if (count < 0) {
  624. printf("non-numeric length argument -- %s\n", argv[optind]);
  625. return 0;
  626. }
  627. if (!pflag) {
  628. if (offset & 0x1ff) {
  629. printf("offset %" PRId64 " is not sector aligned\n",
  630. offset);
  631. return 0;
  632. }
  633. if (count & 0x1ff) {
  634. printf("count %d is not sector aligned\n",
  635. count);
  636. return 0;
  637. }
  638. }
  639. buf = qemu_io_alloc(count, pattern);
  640. gettimeofday(&t1, NULL);
  641. if (pflag) {
  642. cnt = do_pwrite(buf, offset, count, &total);
  643. } else if (bflag) {
  644. cnt = do_save_vmstate(buf, offset, count, &total);
  645. } else {
  646. cnt = do_write(buf, offset, count, &total);
  647. }
  648. gettimeofday(&t2, NULL);
  649. if (cnt < 0) {
  650. printf("write failed: %s\n", strerror(-cnt));
  651. goto out;
  652. }
  653. if (qflag) {
  654. goto out;
  655. }
  656. /* Finally, report back -- -C gives a parsable format */
  657. t2 = tsub(t2, t1);
  658. print_report("wrote", &t2, offset, count, total, cnt, Cflag);
  659. out:
  660. qemu_io_free(buf);
  661. return 0;
  662. }
  663. static void
  664. writev_help(void)
  665. {
  666. printf(
  667. "\n"
  668. " writes a range of bytes from the given offset source from multiple buffers\n"
  669. "\n"
  670. " Example:\n"
  671. " 'write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
  672. "\n"
  673. " Writes into a segment of the currently open file, using a buffer\n"
  674. " filled with a set pattern (0xcdcdcdcd).\n"
  675. " -P, -- use different pattern to fill file\n"
  676. " -C, -- report statistics in a machine parsable format\n"
  677. " -q, -- quiet mode, do not show I/O statistics\n"
  678. "\n");
  679. }
  680. static int writev_f(int argc, char **argv);
  681. static const cmdinfo_t writev_cmd = {
  682. .name = "writev",
  683. .cfunc = writev_f,
  684. .argmin = 2,
  685. .argmax = -1,
  686. .args = "[-Cq] [-P pattern ] off len [len..]",
  687. .oneline = "writes a number of bytes at a specified offset",
  688. .help = writev_help,
  689. };
  690. static int writev_f(int argc, char **argv)
  691. {
  692. struct timeval t1, t2;
  693. int Cflag = 0, qflag = 0;
  694. int c, cnt;
  695. char *buf;
  696. int64_t offset;
  697. /* Some compilers get confused and warn if this is not initialized. */
  698. int total = 0;
  699. int nr_iov;
  700. int pattern = 0xcd;
  701. QEMUIOVector qiov;
  702. while ((c = getopt(argc, argv, "CqP:")) != EOF) {
  703. switch (c) {
  704. case 'C':
  705. Cflag = 1;
  706. break;
  707. case 'q':
  708. qflag = 1;
  709. break;
  710. case 'P':
  711. pattern = parse_pattern(optarg);
  712. if (pattern < 0) {
  713. return 0;
  714. }
  715. break;
  716. default:
  717. return command_usage(&writev_cmd);
  718. }
  719. }
  720. if (optind > argc - 2) {
  721. return command_usage(&writev_cmd);
  722. }
  723. offset = cvtnum(argv[optind]);
  724. if (offset < 0) {
  725. printf("non-numeric length argument -- %s\n", argv[optind]);
  726. return 0;
  727. }
  728. optind++;
  729. if (offset & 0x1ff) {
  730. printf("offset %" PRId64 " is not sector aligned\n",
  731. offset);
  732. return 0;
  733. }
  734. nr_iov = argc - optind;
  735. buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern);
  736. gettimeofday(&t1, NULL);
  737. cnt = do_aio_writev(&qiov, offset, &total);
  738. gettimeofday(&t2, NULL);
  739. if (cnt < 0) {
  740. printf("writev failed: %s\n", strerror(-cnt));
  741. goto out;
  742. }
  743. if (qflag) {
  744. goto out;
  745. }
  746. /* Finally, report back -- -C gives a parsable format */
  747. t2 = tsub(t2, t1);
  748. print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
  749. out:
  750. qemu_io_free(buf);
  751. return 0;
  752. }
  753. static void multiwrite_help(void)
  754. {
  755. printf(
  756. "\n"
  757. " writes a range of bytes from the given offset source from multiple buffers,\n"
  758. " in a batch of requests that may be merged by qemu\n"
  759. "\n"
  760. " Example:\n"
  761. " 'multiwrite 512 1k 1k ; 4k 1k' \n"
  762. " writes 2 kB at 512 bytes and 1 kB at 4 kB into the open file\n"
  763. "\n"
  764. " Writes into a segment of the currently open file, using a buffer\n"
  765. " filled with a set pattern (0xcdcdcdcd). The pattern byte is increased\n"
  766. " by one for each request contained in the multiwrite command.\n"
  767. " -P, -- use different pattern to fill file\n"
  768. " -C, -- report statistics in a machine parsable format\n"
  769. " -q, -- quiet mode, do not show I/O statistics\n"
  770. "\n");
  771. }
  772. static int multiwrite_f(int argc, char **argv);
  773. static const cmdinfo_t multiwrite_cmd = {
  774. .name = "multiwrite",
  775. .cfunc = multiwrite_f,
  776. .argmin = 2,
  777. .argmax = -1,
  778. .args = "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]",
  779. .oneline = "issues multiple write requests at once",
  780. .help = multiwrite_help,
  781. };
  782. static int multiwrite_f(int argc, char **argv)
  783. {
  784. struct timeval t1, t2;
  785. int Cflag = 0, qflag = 0;
  786. int c, cnt;
  787. char **buf;
  788. int64_t offset, first_offset = 0;
  789. /* Some compilers get confused and warn if this is not initialized. */
  790. int total = 0;
  791. int nr_iov;
  792. int nr_reqs;
  793. int pattern = 0xcd;
  794. QEMUIOVector *qiovs;
  795. int i;
  796. BlockRequest *reqs;
  797. while ((c = getopt(argc, argv, "CqP:")) != EOF) {
  798. switch (c) {
  799. case 'C':
  800. Cflag = 1;
  801. break;
  802. case 'q':
  803. qflag = 1;
  804. break;
  805. case 'P':
  806. pattern = parse_pattern(optarg);
  807. if (pattern < 0) {
  808. return 0;
  809. }
  810. break;
  811. default:
  812. return command_usage(&writev_cmd);
  813. }
  814. }
  815. if (optind > argc - 2) {
  816. return command_usage(&writev_cmd);
  817. }
  818. nr_reqs = 1;
  819. for (i = optind; i < argc; i++) {
  820. if (!strcmp(argv[i], ";")) {
  821. nr_reqs++;
  822. }
  823. }
  824. reqs = qemu_malloc(nr_reqs * sizeof(*reqs));
  825. buf = qemu_malloc(nr_reqs * sizeof(*buf));
  826. qiovs = qemu_malloc(nr_reqs * sizeof(*qiovs));
  827. for (i = 0; i < nr_reqs; i++) {
  828. int j;
  829. /* Read the offset of the request */
  830. offset = cvtnum(argv[optind]);
  831. if (offset < 0) {
  832. printf("non-numeric offset argument -- %s\n", argv[optind]);
  833. return 0;
  834. }
  835. optind++;
  836. if (offset & 0x1ff) {
  837. printf("offset %lld is not sector aligned\n",
  838. (long long)offset);
  839. return 0;
  840. }
  841. if (i == 0) {
  842. first_offset = offset;
  843. }
  844. /* Read lengths for qiov entries */
  845. for (j = optind; j < argc; j++) {
  846. if (!strcmp(argv[j], ";")) {
  847. break;
  848. }
  849. }
  850. nr_iov = j - optind;
  851. /* Build request */
  852. reqs[i].qiov = &qiovs[i];
  853. buf[i] = create_iovec(reqs[i].qiov, &argv[optind], nr_iov, pattern);
  854. reqs[i].sector = offset >> 9;
  855. reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
  856. optind = j + 1;
  857. offset += reqs[i].qiov->size;
  858. pattern++;
  859. }
  860. gettimeofday(&t1, NULL);
  861. cnt = do_aio_multiwrite(reqs, nr_reqs, &total);
  862. gettimeofday(&t2, NULL);
  863. if (cnt < 0) {
  864. printf("aio_multiwrite failed: %s\n", strerror(-cnt));
  865. goto out;
  866. }
  867. if (qflag) {
  868. goto out;
  869. }
  870. /* Finally, report back -- -C gives a parsable format */
  871. t2 = tsub(t2, t1);
  872. print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);
  873. out:
  874. for (i = 0; i < nr_reqs; i++) {
  875. qemu_io_free(buf[i]);
  876. qemu_iovec_destroy(&qiovs[i]);
  877. }
  878. qemu_free(buf);
  879. qemu_free(reqs);
  880. qemu_free(qiovs);
  881. return 0;
  882. }
  883. struct aio_ctx {
  884. QEMUIOVector qiov;
  885. int64_t offset;
  886. char *buf;
  887. int qflag;
  888. int vflag;
  889. int Cflag;
  890. int Pflag;
  891. int pattern;
  892. struct timeval t1;
  893. };
  894. static void aio_write_done(void *opaque, int ret)
  895. {
  896. struct aio_ctx *ctx = opaque;
  897. struct timeval t2;
  898. gettimeofday(&t2, NULL);
  899. if (ret < 0) {
  900. printf("aio_write failed: %s\n", strerror(-ret));
  901. goto out;
  902. }
  903. if (ctx->qflag) {
  904. goto out;
  905. }
  906. /* Finally, report back -- -C gives a parsable format */
  907. t2 = tsub(t2, ctx->t1);
  908. print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
  909. ctx->qiov.size, 1, ctx->Cflag);
  910. out:
  911. qemu_io_free(ctx->buf);
  912. free(ctx);
  913. }
  914. static void aio_read_done(void *opaque, int ret)
  915. {
  916. struct aio_ctx *ctx = opaque;
  917. struct timeval t2;
  918. gettimeofday(&t2, NULL);
  919. if (ret < 0) {
  920. printf("readv failed: %s\n", strerror(-ret));
  921. goto out;
  922. }
  923. if (ctx->Pflag) {
  924. void *cmp_buf = malloc(ctx->qiov.size);
  925. memset(cmp_buf, ctx->pattern, ctx->qiov.size);
  926. if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
  927. printf("Pattern verification failed at offset %"
  928. PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
  929. }
  930. free(cmp_buf);
  931. }
  932. if (ctx->qflag) {
  933. goto out;
  934. }
  935. if (ctx->vflag) {
  936. dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
  937. }
  938. /* Finally, report back -- -C gives a parsable format */
  939. t2 = tsub(t2, ctx->t1);
  940. print_report("read", &t2, ctx->offset, ctx->qiov.size,
  941. ctx->qiov.size, 1, ctx->Cflag);
  942. out:
  943. qemu_io_free(ctx->buf);
  944. free(ctx);
  945. }
  946. static void aio_read_help(void)
  947. {
  948. printf(
  949. "\n"
  950. " asynchronously reads a range of bytes from the given offset\n"
  951. "\n"
  952. " Example:\n"
  953. " 'aio_read -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
  954. "\n"
  955. " Reads a segment of the currently open file, optionally dumping it to the\n"
  956. " standard output stream (with -v option) for subsequent inspection.\n"
  957. " The read is performed asynchronously and the aio_flush command must be\n"
  958. " used to ensure all outstanding aio requests have been completed\n"
  959. " -C, -- report statistics in a machine parsable format\n"
  960. " -P, -- use a pattern to verify read data\n"
  961. " -v, -- dump buffer to standard output\n"
  962. " -q, -- quiet mode, do not show I/O statistics\n"
  963. "\n");
  964. }
  965. static int aio_read_f(int argc, char **argv);
  966. static const cmdinfo_t aio_read_cmd = {
  967. .name = "aio_read",
  968. .cfunc = aio_read_f,
  969. .argmin = 2,
  970. .argmax = -1,
  971. .args = "[-Cqv] [-P pattern ] off len [len..]",
  972. .oneline = "asynchronously reads a number of bytes",
  973. .help = aio_read_help,
  974. };
  975. static int aio_read_f(int argc, char **argv)
  976. {
  977. int nr_iov, c;
  978. struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
  979. BlockDriverAIOCB *acb;
  980. while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
  981. switch (c) {
  982. case 'C':
  983. ctx->Cflag = 1;
  984. break;
  985. case 'P':
  986. ctx->Pflag = 1;
  987. ctx->pattern = parse_pattern(optarg);
  988. if (ctx->pattern < 0) {
  989. free(ctx);
  990. return 0;
  991. }
  992. break;
  993. case 'q':
  994. ctx->qflag = 1;
  995. break;
  996. case 'v':
  997. ctx->vflag = 1;
  998. break;
  999. default:
  1000. free(ctx);
  1001. return command_usage(&aio_read_cmd);
  1002. }
  1003. }
  1004. if (optind > argc - 2) {
  1005. free(ctx);
  1006. return command_usage(&aio_read_cmd);
  1007. }
  1008. ctx->offset = cvtnum(argv[optind]);
  1009. if (ctx->offset < 0) {
  1010. printf("non-numeric length argument -- %s\n", argv[optind]);
  1011. free(ctx);
  1012. return 0;
  1013. }
  1014. optind++;
  1015. if (ctx->offset & 0x1ff) {
  1016. printf("offset %" PRId64 " is not sector aligned\n",
  1017. ctx->offset);
  1018. free(ctx);
  1019. return 0;
  1020. }
  1021. nr_iov = argc - optind;
  1022. ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);
  1023. gettimeofday(&ctx->t1, NULL);
  1024. acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
  1025. ctx->qiov.size >> 9, aio_read_done, ctx);
  1026. if (!acb) {
  1027. free(ctx->buf);
  1028. free(ctx);
  1029. return -EIO;
  1030. }
  1031. return 0;
  1032. }
  1033. static void aio_write_help(void)
  1034. {
  1035. printf(
  1036. "\n"
  1037. " asynchronously writes a range of bytes from the given offset source\n"
  1038. " from multiple buffers\n"
  1039. "\n"
  1040. " Example:\n"
  1041. " 'aio_write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
  1042. "\n"
  1043. " Writes into a segment of the currently open file, using a buffer\n"
  1044. " filled with a set pattern (0xcdcdcdcd).\n"
  1045. " The write is performed asynchronously and the aio_flush command must be\n"
  1046. " used to ensure all outstanding aio requests have been completed\n"
  1047. " -P, -- use different pattern to fill file\n"
  1048. " -C, -- report statistics in a machine parsable format\n"
  1049. " -q, -- quiet mode, do not show I/O statistics\n"
  1050. "\n");
  1051. }
  1052. static int aio_write_f(int argc, char **argv);
  1053. static const cmdinfo_t aio_write_cmd = {
  1054. .name = "aio_write",
  1055. .cfunc = aio_write_f,
  1056. .argmin = 2,
  1057. .argmax = -1,
  1058. .args = "[-Cq] [-P pattern ] off len [len..]",
  1059. .oneline = "asynchronously writes a number of bytes",
  1060. .help = aio_write_help,
  1061. };
  1062. static int aio_write_f(int argc, char **argv)
  1063. {
  1064. int nr_iov, c;
  1065. int pattern = 0xcd;
  1066. struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
  1067. BlockDriverAIOCB *acb;
  1068. while ((c = getopt(argc, argv, "CqP:")) != EOF) {
  1069. switch (c) {
  1070. case 'C':
  1071. ctx->Cflag = 1;
  1072. break;
  1073. case 'q':
  1074. ctx->qflag = 1;
  1075. break;
  1076. case 'P':
  1077. pattern = parse_pattern(optarg);
  1078. if (pattern < 0) {
  1079. return 0;
  1080. }
  1081. break;
  1082. default:
  1083. free(ctx);
  1084. return command_usage(&aio_write_cmd);
  1085. }
  1086. }
  1087. if (optind > argc - 2) {
  1088. free(ctx);
  1089. return command_usage(&aio_write_cmd);
  1090. }
  1091. ctx->offset = cvtnum(argv[optind]);
  1092. if (ctx->offset < 0) {
  1093. printf("non-numeric length argument -- %s\n", argv[optind]);
  1094. free(ctx);
  1095. return 0;
  1096. }
  1097. optind++;
  1098. if (ctx->offset & 0x1ff) {
  1099. printf("offset %" PRId64 " is not sector aligned\n",
  1100. ctx->offset);
  1101. free(ctx);
  1102. return 0;
  1103. }
  1104. nr_iov = argc - optind;
  1105. ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);
  1106. gettimeofday(&ctx->t1, NULL);
  1107. acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
  1108. ctx->qiov.size >> 9, aio_write_done, ctx);
  1109. if (!acb) {
  1110. free(ctx->buf);
  1111. free(ctx);
  1112. return -EIO;
  1113. }
  1114. return 0;
  1115. }
  1116. static int aio_flush_f(int argc, char **argv)
  1117. {
  1118. qemu_aio_flush();
  1119. return 0;
  1120. }
  1121. static const cmdinfo_t aio_flush_cmd = {
  1122. .name = "aio_flush",
  1123. .cfunc = aio_flush_f,
  1124. .oneline = "completes all outstanding aio requests"
  1125. };
  1126. static int flush_f(int argc, char **argv)
  1127. {
  1128. bdrv_flush(bs);
  1129. return 0;
  1130. }
  1131. static const cmdinfo_t flush_cmd = {
  1132. .name = "flush",
  1133. .altname = "f",
  1134. .cfunc = flush_f,
  1135. .oneline = "flush all in-core file state to disk",
  1136. };
  1137. static int truncate_f(int argc, char **argv)
  1138. {
  1139. int64_t offset;
  1140. int ret;
  1141. offset = cvtnum(argv[1]);
  1142. if (offset < 0) {
  1143. printf("non-numeric truncate argument -- %s\n", argv[1]);
  1144. return 0;
  1145. }
  1146. ret = bdrv_truncate(bs, offset);
  1147. if (ret < 0) {
  1148. printf("truncate: %s\n", strerror(-ret));
  1149. return 0;
  1150. }
  1151. return 0;
  1152. }
  1153. static const cmdinfo_t truncate_cmd = {
  1154. .name = "truncate",
  1155. .altname = "t",
  1156. .cfunc = truncate_f,
  1157. .argmin = 1,
  1158. .argmax = 1,
  1159. .args = "off",
  1160. .oneline = "truncates the current file at the given offset",
  1161. };
  1162. static int length_f(int argc, char **argv)
  1163. {
  1164. int64_t size;
  1165. char s1[64];
  1166. size = bdrv_getlength(bs);
  1167. if (size < 0) {
  1168. printf("getlength: %s\n", strerror(-size));
  1169. return 0;
  1170. }
  1171. cvtstr(size, s1, sizeof(s1));
  1172. printf("%s\n", s1);
  1173. return 0;
  1174. }
  1175. static const cmdinfo_t length_cmd = {
  1176. .name = "length",
  1177. .altname = "l",
  1178. .cfunc = length_f,
  1179. .oneline = "gets the length of the current file",
  1180. };
  1181. static int info_f(int argc, char **argv)
  1182. {
  1183. BlockDriverInfo bdi;
  1184. char s1[64], s2[64];
  1185. int ret;
  1186. if (bs->drv && bs->drv->format_name) {
  1187. printf("format name: %s\n", bs->drv->format_name);
  1188. }
  1189. if (bs->drv && bs->drv->protocol_name) {
  1190. printf("format name: %s\n", bs->drv->protocol_name);
  1191. }
  1192. ret = bdrv_get_info(bs, &bdi);
  1193. if (ret) {
  1194. return 0;
  1195. }
  1196. cvtstr(bdi.cluster_size, s1, sizeof(s1));
  1197. cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
  1198. printf("cluster size: %s\n", s1);
  1199. printf("vm state offset: %s\n", s2);
  1200. return 0;
  1201. }
  1202. static const cmdinfo_t info_cmd = {
  1203. .name = "info",
  1204. .altname = "i",
  1205. .cfunc = info_f,
  1206. .oneline = "prints information about the current file",
  1207. };
  1208. static void discard_help(void)
  1209. {
  1210. printf(
  1211. "\n"
  1212. " discards a range of bytes from the given offset\n"
  1213. "\n"
  1214. " Example:\n"
  1215. " 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
  1216. "\n"
  1217. " Discards a segment of the currently open file.\n"
  1218. " -C, -- report statistics in a machine parsable format\n"
  1219. " -q, -- quiet mode, do not show I/O statistics\n"
  1220. "\n");
  1221. }
  1222. static int discard_f(int argc, char **argv);
  1223. static const cmdinfo_t discard_cmd = {
  1224. .name = "discard",
  1225. .altname = "d",
  1226. .cfunc = discard_f,
  1227. .argmin = 2,
  1228. .argmax = -1,
  1229. .args = "[-Cq] off len",
  1230. .oneline = "discards a number of bytes at a specified offset",
  1231. .help = discard_help,
  1232. };
  1233. static int discard_f(int argc, char **argv)
  1234. {
  1235. struct timeval t1, t2;
  1236. int Cflag = 0, qflag = 0;
  1237. int c, ret;
  1238. int64_t offset;
  1239. int count;
  1240. while ((c = getopt(argc, argv, "Cq")) != EOF) {
  1241. switch (c) {
  1242. case 'C':
  1243. Cflag = 1;
  1244. break;
  1245. case 'q':
  1246. qflag = 1;
  1247. break;
  1248. default:
  1249. return command_usage(&discard_cmd);
  1250. }
  1251. }
  1252. if (optind != argc - 2) {
  1253. return command_usage(&discard_cmd);
  1254. }
  1255. offset = cvtnum(argv[optind]);
  1256. if (offset < 0) {
  1257. printf("non-numeric length argument -- %s\n", argv[optind]);
  1258. return 0;
  1259. }
  1260. optind++;
  1261. count = cvtnum(argv[optind]);
  1262. if (count < 0) {
  1263. printf("non-numeric length argument -- %s\n", argv[optind]);
  1264. return 0;
  1265. }
  1266. gettimeofday(&t1, NULL);
  1267. ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS,
  1268. count >> BDRV_SECTOR_BITS);
  1269. gettimeofday(&t2, NULL);
  1270. if (ret < 0) {
  1271. printf("discard failed: %s\n", strerror(-ret));
  1272. goto out;
  1273. }
  1274. /* Finally, report back -- -C gives a parsable format */
  1275. if (!qflag) {
  1276. t2 = tsub(t2, t1);
  1277. print_report("discard", &t2, offset, count, count, 1, Cflag);
  1278. }
  1279. out:
  1280. return 0;
  1281. }
  1282. static int alloc_f(int argc, char **argv)
  1283. {
  1284. int64_t offset;
  1285. int nb_sectors, remaining;
  1286. char s1[64];
  1287. int num, sum_alloc;
  1288. int ret;
  1289. offset = cvtnum(argv[1]);
  1290. if (offset & 0x1ff) {
  1291. printf("offset %" PRId64 " is not sector aligned\n",
  1292. offset);
  1293. return 0;
  1294. }
  1295. if (argc == 3) {
  1296. nb_sectors = cvtnum(argv[2]);
  1297. } else {
  1298. nb_sectors = 1;
  1299. }
  1300. remaining = nb_sectors;
  1301. sum_alloc = 0;
  1302. while (remaining) {
  1303. ret = bdrv_is_allocated(bs, offset >> 9, nb_sectors, &num);
  1304. remaining -= num;
  1305. if (ret) {
  1306. sum_alloc += num;
  1307. }
  1308. }
  1309. cvtstr(offset, s1, sizeof(s1));
  1310. printf("%d/%d sectors allocated at offset %s\n",
  1311. sum_alloc, nb_sectors, s1);
  1312. return 0;
  1313. }
  1314. static const cmdinfo_t alloc_cmd = {
  1315. .name = "alloc",
  1316. .altname = "a",
  1317. .argmin = 1,
  1318. .argmax = 2,
  1319. .cfunc = alloc_f,
  1320. .args = "off [sectors]",
  1321. .oneline = "checks if a sector is present in the file",
  1322. };
  1323. static int map_f(int argc, char **argv)
  1324. {
  1325. int64_t offset;
  1326. int64_t nb_sectors;
  1327. char s1[64];
  1328. int num, num_checked;
  1329. int ret;
  1330. const char *retstr;
  1331. offset = 0;
  1332. nb_sectors = bs->total_sectors;
  1333. do {
  1334. num_checked = MIN(nb_sectors, INT_MAX);
  1335. ret = bdrv_is_allocated(bs, offset, num_checked, &num);
  1336. retstr = ret ? " allocated" : "not allocated";
  1337. cvtstr(offset << 9ULL, s1, sizeof(s1));
  1338. printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n",
  1339. offset << 9ULL, num, num_checked, retstr, s1, ret);
  1340. offset += num;
  1341. nb_sectors -= num;
  1342. } while (offset < bs->total_sectors);
  1343. return 0;
  1344. }
  1345. static const cmdinfo_t map_cmd = {
  1346. .name = "map",
  1347. .argmin = 0,
  1348. .argmax = 0,
  1349. .cfunc = map_f,
  1350. .args = "",
  1351. .oneline = "prints the allocated areas of a file",
  1352. };
  1353. static int close_f(int argc, char **argv)
  1354. {
  1355. bdrv_close(bs);
  1356. bs = NULL;
  1357. return 0;
  1358. }
  1359. static const cmdinfo_t close_cmd = {
  1360. .name = "close",
  1361. .altname = "c",
  1362. .cfunc = close_f,
  1363. .oneline = "close the current open file",
  1364. };
  1365. static int openfile(char *name, int flags, int growable)
  1366. {
  1367. if (bs) {
  1368. fprintf(stderr, "file open already, try 'help close'\n");
  1369. return 1;
  1370. }
  1371. if (growable) {
  1372. if (bdrv_file_open(&bs, name, flags)) {
  1373. fprintf(stderr, "%s: can't open device %s\n", progname, name);
  1374. return 1;
  1375. }
  1376. } else {
  1377. bs = bdrv_new("hda");
  1378. if (bdrv_open(bs, name, flags, NULL) < 0) {
  1379. fprintf(stderr, "%s: can't open device %s\n", progname, name);
  1380. bs = NULL;
  1381. return 1;
  1382. }
  1383. }
  1384. return 0;
  1385. }
  1386. static void open_help(void)
  1387. {
  1388. printf(
  1389. "\n"
  1390. " opens a new file in the requested mode\n"
  1391. "\n"
  1392. " Example:\n"
  1393. " 'open -Cn /tmp/data' - creates/opens data file read-write and uncached\n"
  1394. "\n"
  1395. " Opens a file for subsequent use by all of the other qemu-io commands.\n"
  1396. " -r, -- open file read-only\n"
  1397. " -s, -- use snapshot file\n"
  1398. " -n, -- disable host cache\n"
  1399. " -g, -- allow file to grow (only applies to protocols)"
  1400. "\n");
  1401. }
  1402. static int open_f(int argc, char **argv);
  1403. static const cmdinfo_t open_cmd = {
  1404. .name = "open",
  1405. .altname = "o",
  1406. .cfunc = open_f,
  1407. .argmin = 1,
  1408. .argmax = -1,
  1409. .flags = CMD_NOFILE_OK,
  1410. .args = "[-Crsn] [path]",
  1411. .oneline = "open the file specified by path",
  1412. .help = open_help,
  1413. };
  1414. static int open_f(int argc, char **argv)
  1415. {
  1416. int flags = 0;
  1417. int readonly = 0;
  1418. int growable = 0;
  1419. int c;
  1420. while ((c = getopt(argc, argv, "snrg")) != EOF) {
  1421. switch (c) {
  1422. case 's':
  1423. flags |= BDRV_O_SNAPSHOT;
  1424. break;
  1425. case 'n':
  1426. flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
  1427. break;
  1428. case 'r':
  1429. readonly = 1;
  1430. break;
  1431. case 'g':
  1432. growable = 1;
  1433. break;
  1434. default:
  1435. return command_usage(&open_cmd);
  1436. }
  1437. }
  1438. if (!readonly) {
  1439. flags |= BDRV_O_RDWR;
  1440. }
  1441. if (optind != argc - 1) {
  1442. return command_usage(&open_cmd);
  1443. }
  1444. return openfile(argv[optind], flags, growable);
  1445. }
  1446. static int init_args_command(int index)
  1447. {
  1448. /* only one device allowed so far */
  1449. if (index >= 1) {
  1450. return 0;
  1451. }
  1452. return ++index;
  1453. }
  1454. static int init_check_command(const cmdinfo_t *ct)
  1455. {
  1456. if (ct->flags & CMD_FLAG_GLOBAL) {
  1457. return 1;
  1458. }
  1459. if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
  1460. fprintf(stderr, "no file open, try 'help open'\n");
  1461. return 0;
  1462. }
  1463. return 1;
  1464. }
  1465. static void usage(const char *name)
  1466. {
  1467. printf(
  1468. "Usage: %s [-h] [-V] [-rsnm] [-c cmd] ... [file]\n"
  1469. "QEMU Disk exerciser\n"
  1470. "\n"
  1471. " -c, --cmd command to execute\n"
  1472. " -r, --read-only export read-only\n"
  1473. " -s, --snapshot use snapshot file\n"
  1474. " -n, --nocache disable host cache\n"
  1475. " -g, --growable allow file to grow (only applies to protocols)\n"
  1476. " -m, --misalign misalign allocations for O_DIRECT\n"
  1477. " -k, --native-aio use kernel AIO implementation (on Linux only)\n"
  1478. " -h, --help display this help and exit\n"
  1479. " -V, --version output version information and exit\n"
  1480. "\n",
  1481. name);
  1482. }
  1483. int main(int argc, char **argv)
  1484. {
  1485. int readonly = 0;
  1486. int growable = 0;
  1487. const char *sopt = "hVc:rsnmgk";
  1488. const struct option lopt[] = {
  1489. { "help", 0, NULL, 'h' },
  1490. { "version", 0, NULL, 'V' },
  1491. { "offset", 1, NULL, 'o' },
  1492. { "cmd", 1, NULL, 'c' },
  1493. { "read-only", 0, NULL, 'r' },
  1494. { "snapshot", 0, NULL, 's' },
  1495. { "nocache", 0, NULL, 'n' },
  1496. { "misalign", 0, NULL, 'm' },
  1497. { "growable", 0, NULL, 'g' },
  1498. { "native-aio", 0, NULL, 'k' },
  1499. { NULL, 0, NULL, 0 }
  1500. };
  1501. int c;
  1502. int opt_index = 0;
  1503. int flags = 0;
  1504. progname = basename(argv[0]);
  1505. while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
  1506. switch (c) {
  1507. case 's':
  1508. flags |= BDRV_O_SNAPSHOT;
  1509. break;
  1510. case 'n':
  1511. flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
  1512. break;
  1513. case 'c':
  1514. add_user_command(optarg);
  1515. break;
  1516. case 'r':
  1517. readonly = 1;
  1518. break;
  1519. case 'm':
  1520. misalign = 1;
  1521. break;
  1522. case 'g':
  1523. growable = 1;
  1524. break;
  1525. case 'k':
  1526. flags |= BDRV_O_NATIVE_AIO;
  1527. break;
  1528. case 'V':
  1529. printf("%s version %s\n", progname, VERSION);
  1530. exit(0);
  1531. case 'h':
  1532. usage(progname);
  1533. exit(0);
  1534. default:
  1535. usage(progname);
  1536. exit(1);
  1537. }
  1538. }
  1539. if ((argc - optind) > 1) {
  1540. usage(progname);
  1541. exit(1);
  1542. }
  1543. bdrv_init();
  1544. /* initialize commands */
  1545. quit_init();
  1546. help_init();
  1547. add_command(&open_cmd);
  1548. add_command(&close_cmd);
  1549. add_command(&read_cmd);
  1550. add_command(&readv_cmd);
  1551. add_command(&write_cmd);
  1552. add_command(&writev_cmd);
  1553. add_command(&multiwrite_cmd);
  1554. add_command(&aio_read_cmd);
  1555. add_command(&aio_write_cmd);
  1556. add_command(&aio_flush_cmd);
  1557. add_command(&flush_cmd);
  1558. add_command(&truncate_cmd);
  1559. add_command(&length_cmd);
  1560. add_command(&info_cmd);
  1561. add_command(&discard_cmd);
  1562. add_command(&alloc_cmd);
  1563. add_command(&map_cmd);
  1564. add_args_command(init_args_command);
  1565. add_check_command(init_check_command);
  1566. /* open the device */
  1567. if (!readonly) {
  1568. flags |= BDRV_O_RDWR;
  1569. }
  1570. if ((argc - optind) == 1) {
  1571. openfile(argv[optind], flags, growable);
  1572. }
  1573. command_loop();
  1574. /*
  1575. * Make sure all outstanding requests get flushed the program exits.
  1576. */
  1577. qemu_aio_flush();
  1578. if (bs) {
  1579. bdrv_close(bs);
  1580. }
  1581. return 0;
  1582. }