Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

block.c 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * Copyright (c) 2009, 2010 Jeff Mahoney <jeffm@suse.com>
  3. * Copyright (c) 2011-2016 Dmitry V. Levin <ldv@altlinux.org>
  4. * Copyright (c) 2011-2018 The strace developers.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. The name of the author may not be used to endorse or promote products
  16. * derived from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  19. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  20. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  21. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. #include "defs.h"
  30. #include DEF_MPERS_TYPE(struct_blk_user_trace_setup)
  31. #include DEF_MPERS_TYPE(struct_blkpg_ioctl_arg)
  32. #include DEF_MPERS_TYPE(struct_blkpg_partition)
  33. #include <linux/ioctl.h>
  34. #include <linux/fs.h>
  35. typedef struct {
  36. int op;
  37. int flags;
  38. int datalen;
  39. void *data;
  40. } struct_blkpg_ioctl_arg;
  41. #define BLKPG_DEVNAMELTH 64
  42. #define BLKPG_VOLNAMELTH 64
  43. typedef struct {
  44. int64_t start; /* starting offset in bytes */
  45. int64_t length; /* length in bytes */
  46. int pno; /* partition number */
  47. char devname[BLKPG_DEVNAMELTH]; /* partition name, like sda5 or c0d1p2,
  48. to be used in kernel messages */
  49. char volname[BLKPG_VOLNAMELTH]; /* volume label */
  50. } struct_blkpg_partition;
  51. #define BLKTRACE_BDEV_SIZE 32
  52. typedef struct blk_user_trace_setup {
  53. char name[BLKTRACE_BDEV_SIZE]; /* output */
  54. uint16_t act_mask; /* input */
  55. uint32_t buf_size; /* input */
  56. uint32_t buf_nr; /* input */
  57. uint64_t start_lba;
  58. uint64_t end_lba;
  59. uint32_t pid;
  60. } struct_blk_user_trace_setup;
  61. #include MPERS_DEFS
  62. #include "print_fields.h"
  63. #ifndef BLKPG
  64. # define BLKPG _IO(0x12, 105)
  65. #endif
  66. /*
  67. * ioctl numbers <= 114 are present in Linux 2.4. The following ones have been
  68. * added since then and headers containing them may not be available on every
  69. * system.
  70. */
  71. #ifndef BLKTRACESETUP
  72. # define BLKTRACESETUP _IOWR(0x12, 115, struct_blk_user_trace_setup)
  73. #endif
  74. #ifndef BLKTRACESTART
  75. # define BLKTRACESTART _IO(0x12, 116)
  76. #endif
  77. #ifndef BLKTRACESTOP
  78. # define BLKTRACESTOP _IO(0x12, 117)
  79. #endif
  80. #ifndef BLKTRACETEARDOWN
  81. # define BLKTRACETEARDOWN _IO(0x12, 118)
  82. #endif
  83. #ifndef BLKDISCARD
  84. # define BLKDISCARD _IO(0x12, 119)
  85. #endif
  86. #ifndef BLKIOMIN
  87. # define BLKIOMIN _IO(0x12, 120)
  88. #endif
  89. #ifndef BLKIOOPT
  90. # define BLKIOOPT _IO(0x12, 121)
  91. #endif
  92. #ifndef BLKALIGNOFF
  93. # define BLKALIGNOFF _IO(0x12, 122)
  94. #endif
  95. #ifndef BLKPBSZGET
  96. # define BLKPBSZGET _IO(0x12, 123)
  97. #endif
  98. #ifndef BLKDISCARDZEROES
  99. # define BLKDISCARDZEROES _IO(0x12, 124)
  100. #endif
  101. #ifndef BLKSECDISCARD
  102. # define BLKSECDISCARD _IO(0x12, 125)
  103. #endif
  104. #ifndef BLKROTATIONAL
  105. # define BLKROTATIONAL _IO(0x12, 126)
  106. #endif
  107. #ifndef BLKZEROOUT
  108. # define BLKZEROOUT _IO(0x12, 127)
  109. #endif
  110. #include "xlat/blkpg_ops.h"
  111. static void
  112. print_blkpg_req(struct tcb *tcp, const struct_blkpg_ioctl_arg *blkpg)
  113. {
  114. struct_blkpg_partition p;
  115. PRINT_FIELD_XVAL("{", *blkpg, op, blkpg_ops, "BLKPG_???");
  116. PRINT_FIELD_D(", ", *blkpg, flags);
  117. PRINT_FIELD_D(", ", *blkpg, datalen);
  118. tprints(", data=");
  119. if (!umove_or_printaddr(tcp, ptr_to_kulong(blkpg->data), &p)) {
  120. PRINT_FIELD_D("{", p, start);
  121. PRINT_FIELD_D(", ", p, length);
  122. PRINT_FIELD_D(", ", p, pno);
  123. PRINT_FIELD_CSTRING(", ", p, devname);
  124. PRINT_FIELD_CSTRING(", ", p, volname);
  125. tprints("}");
  126. }
  127. tprints("}");
  128. }
  129. MPERS_PRINTER_DECL(int, block_ioctl, struct tcb *const tcp,
  130. const unsigned int code, const kernel_ulong_t arg)
  131. {
  132. switch (code) {
  133. /* take arg as a value, not as a pointer */
  134. case BLKRASET:
  135. case BLKFRASET:
  136. tprintf(", %" PRI_klu, arg);
  137. break;
  138. /* return an unsigned short */
  139. case BLKSECTGET:
  140. case BLKROTATIONAL:
  141. if (entering(tcp))
  142. return 0;
  143. tprints(", ");
  144. printnum_short(tcp, arg, "%hu");
  145. break;
  146. /* return a signed int */
  147. case BLKROGET:
  148. case BLKBSZGET:
  149. case BLKSSZGET:
  150. case BLKALIGNOFF:
  151. if (entering(tcp))
  152. return 0;
  153. ATTRIBUTE_FALLTHROUGH;
  154. /* take a signed int */
  155. case BLKROSET:
  156. case BLKBSZSET:
  157. tprints(", ");
  158. printnum_int(tcp, arg, "%d");
  159. break;
  160. /* return an unsigned int */
  161. case BLKPBSZGET:
  162. case BLKIOMIN:
  163. case BLKIOOPT:
  164. case BLKDISCARDZEROES:
  165. if (entering(tcp))
  166. return 0;
  167. tprints(", ");
  168. printnum_int(tcp, arg, "%u");
  169. break;
  170. /* return a signed long */
  171. case BLKRAGET:
  172. case BLKFRAGET:
  173. if (entering(tcp))
  174. return 0;
  175. tprints(", ");
  176. printnum_slong(tcp, arg);
  177. break;
  178. /* returns an unsigned long */
  179. case BLKGETSIZE:
  180. if (entering(tcp))
  181. return 0;
  182. tprints(", ");
  183. printnum_ulong(tcp, arg);
  184. break;
  185. #ifdef HAVE_BLKGETSIZE64
  186. /* returns an uint64_t */
  187. case BLKGETSIZE64:
  188. if (entering(tcp))
  189. return 0;
  190. tprints(", ");
  191. printnum_int64(tcp, arg, "%" PRIu64);
  192. break;
  193. #endif
  194. /* takes a pair of uint64_t */
  195. case BLKDISCARD:
  196. case BLKSECDISCARD:
  197. case BLKZEROOUT:
  198. tprints(", ");
  199. printpair_int64(tcp, arg, "%" PRIu64);
  200. break;
  201. /* More complex types */
  202. case BLKPG: {
  203. struct_blkpg_ioctl_arg blkpg;
  204. tprints(", ");
  205. if (!umove_or_printaddr(tcp, arg, &blkpg))
  206. print_blkpg_req(tcp, &blkpg);
  207. break;
  208. }
  209. case BLKTRACESETUP:
  210. if (entering(tcp)) {
  211. struct_blk_user_trace_setup buts;
  212. tprints(", ");
  213. if (umove_or_printaddr(tcp, arg, &buts))
  214. break;
  215. PRINT_FIELD_U("{", buts, act_mask);
  216. PRINT_FIELD_U(", ", buts, buf_size);
  217. PRINT_FIELD_U(", ", buts, buf_nr);
  218. PRINT_FIELD_U(", ", buts, start_lba);
  219. PRINT_FIELD_U(", ", buts, end_lba);
  220. PRINT_FIELD_U(", ", buts, pid);
  221. return 0;
  222. } else {
  223. struct_blk_user_trace_setup buts;
  224. if (!syserror(tcp) && !umove(tcp, arg, &buts))
  225. PRINT_FIELD_CSTRING(", ", buts, name);
  226. tprints("}");
  227. break;
  228. }
  229. /* No arguments */
  230. case BLKRRPART:
  231. case BLKFLSBUF:
  232. case BLKTRACESTART:
  233. case BLKTRACESTOP:
  234. case BLKTRACETEARDOWN:
  235. break;
  236. default:
  237. return RVAL_DECODED;
  238. }
  239. return RVAL_IOCTL_DECODED;
  240. }