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