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.

loop.c 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * Copyright (c) 2012 The Chromium OS Authors.
  3. * Written by Mike Frysinger <vapier@gentoo.org>.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. The name of the author may not be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  18. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  19. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  21. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  25. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "defs.h"
  28. #include <linux/ioctl.h>
  29. #include <linux/loop.h>
  30. #include "xlat/loop_flags_options.h"
  31. #include "xlat/loop_crypt_type_options.h"
  32. static void
  33. decode_loop_info(struct tcb *const tcp, const kernel_ulong_t addr)
  34. {
  35. struct loop_info info;
  36. tprints(", ");
  37. if (umove_or_printaddr(tcp, addr, &info))
  38. return;
  39. tprintf("{lo_number=%d", info.lo_number);
  40. if (!abbrev(tcp)) {
  41. tprintf(", lo_device=%#lx, lo_inode=%lu, lo_rdevice=%#lx",
  42. (unsigned long) info.lo_device,
  43. info.lo_inode,
  44. (unsigned long) info.lo_rdevice);
  45. }
  46. tprintf(", lo_offset=%#x", info.lo_offset);
  47. if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) {
  48. tprints(", lo_encrypt_type=");
  49. printxval(loop_crypt_type_options, info.lo_encrypt_type,
  50. "LO_CRYPT_???");
  51. tprintf(", lo_encrypt_key_size=%d", info.lo_encrypt_key_size);
  52. }
  53. tprints(", lo_flags=");
  54. printflags(loop_flags_options, info.lo_flags, "LO_FLAGS_???");
  55. tprints(", lo_name=");
  56. print_quoted_string(info.lo_name, LO_NAME_SIZE,
  57. QUOTE_0_TERMINATED);
  58. if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) {
  59. tprints(", lo_encrypt_key=");
  60. print_quoted_string((void *) info.lo_encrypt_key,
  61. LO_KEY_SIZE, 0);
  62. }
  63. if (!abbrev(tcp))
  64. tprintf(", lo_init=[%#lx, %#lx]"
  65. ", reserved=[%#x, %#x, %#x, %#x]}",
  66. info.lo_init[0], info.lo_init[1],
  67. info.reserved[0], info.reserved[1],
  68. info.reserved[2], info.reserved[3]);
  69. else
  70. tprints(", ...}");
  71. }
  72. static void
  73. decode_loop_info64(struct tcb *const tcp, const kernel_ulong_t addr)
  74. {
  75. struct loop_info64 info64;
  76. tprints(", ");
  77. if (umove_or_printaddr(tcp, addr, &info64))
  78. return;
  79. if (!abbrev(tcp)) {
  80. tprintf("{lo_device=%" PRIu64 ", lo_inode=%" PRIu64
  81. ", lo_rdevice=%" PRIu64 ", lo_offset=%#" PRIx64
  82. ", lo_sizelimit=%" PRIu64 ", lo_number=%" PRIu32,
  83. (uint64_t) info64.lo_device,
  84. (uint64_t) info64.lo_inode,
  85. (uint64_t) info64.lo_rdevice,
  86. (uint64_t) info64.lo_offset,
  87. (uint64_t) info64.lo_sizelimit,
  88. (uint32_t) info64.lo_number);
  89. } else {
  90. tprintf("{lo_offset=%#" PRIx64 ", lo_number=%" PRIu32,
  91. (uint64_t) info64.lo_offset,
  92. (uint32_t) info64.lo_number);
  93. }
  94. if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) {
  95. tprints(", lo_encrypt_type=");
  96. printxval(loop_crypt_type_options, info64.lo_encrypt_type,
  97. "LO_CRYPT_???");
  98. tprintf(", lo_encrypt_key_size=%" PRIu32,
  99. info64.lo_encrypt_key_size);
  100. }
  101. tprints(", lo_flags=");
  102. printflags(loop_flags_options, info64.lo_flags, "LO_FLAGS_???");
  103. tprints(", lo_file_name=");
  104. print_quoted_string((void *) info64.lo_file_name,
  105. LO_NAME_SIZE, QUOTE_0_TERMINATED);
  106. if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) {
  107. tprints(", lo_crypt_name=");
  108. print_quoted_string((void *) info64.lo_crypt_name,
  109. LO_NAME_SIZE, QUOTE_0_TERMINATED);
  110. tprints(", lo_encrypt_key=");
  111. print_quoted_string((void *) info64.lo_encrypt_key,
  112. LO_KEY_SIZE, 0);
  113. }
  114. if (!abbrev(tcp))
  115. tprintf(", lo_init=[%#" PRIx64 ", %#" PRIx64 "]}",
  116. (uint64_t) info64.lo_init[0],
  117. (uint64_t) info64.lo_init[1]);
  118. else
  119. tprints(", ...}");
  120. }
  121. int
  122. loop_ioctl(struct tcb *const tcp, const unsigned int code,
  123. const kernel_ulong_t arg)
  124. {
  125. if (!verbose(tcp))
  126. return RVAL_DECODED;
  127. switch (code) {
  128. case LOOP_GET_STATUS:
  129. if (entering(tcp))
  130. return 0;
  131. /* fall through */
  132. case LOOP_SET_STATUS:
  133. decode_loop_info(tcp, arg);
  134. break;
  135. case LOOP_GET_STATUS64:
  136. if (entering(tcp))
  137. return 0;
  138. /* fall through */
  139. case LOOP_SET_STATUS64:
  140. decode_loop_info64(tcp, arg);
  141. break;
  142. case LOOP_CLR_FD:
  143. #ifdef LOOP_SET_CAPACITY
  144. case LOOP_SET_CAPACITY:
  145. #endif
  146. #ifdef LOOP_CTL_GET_FREE
  147. /* newer loop-control stuff */
  148. case LOOP_CTL_GET_FREE:
  149. #endif
  150. /* Takes no arguments */
  151. break;
  152. case LOOP_SET_FD:
  153. case LOOP_CHANGE_FD:
  154. tprints(", ");
  155. printfd(tcp, arg);
  156. break;
  157. #ifdef LOOP_CTL_ADD
  158. /* newer loop-control stuff */
  159. case LOOP_CTL_ADD:
  160. case LOOP_CTL_REMOVE:
  161. tprintf(", %d", (int) arg);
  162. break;
  163. #endif
  164. #ifdef LOOP_SET_DIRECT_IO
  165. case LOOP_SET_DIRECT_IO:
  166. tprintf(", %" PRI_klu, arg);
  167. break;
  168. #endif
  169. default:
  170. return RVAL_DECODED;
  171. }
  172. return RVAL_DECODED | 1;
  173. }