1*cf84ac9aSAndroid Build Coastguard Worker /*
2*cf84ac9aSAndroid Build Coastguard Worker * Support for decoding of DM_* ioctl commands.
3*cf84ac9aSAndroid Build Coastguard Worker *
4*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 2016 Mikulas Patocka <[email protected]>
5*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 2016 Masatake Yamato <[email protected]>
6*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 2016 Dmitry V. Levin <[email protected]>
7*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 2016 Eugene Syromyatnikov <[email protected]>
8*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 2016-2018 The strace developers.
9*cf84ac9aSAndroid Build Coastguard Worker * All rights reserved.
10*cf84ac9aSAndroid Build Coastguard Worker *
11*cf84ac9aSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
12*cf84ac9aSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
13*cf84ac9aSAndroid Build Coastguard Worker * are met:
14*cf84ac9aSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
15*cf84ac9aSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
16*cf84ac9aSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
17*cf84ac9aSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
18*cf84ac9aSAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
19*cf84ac9aSAndroid Build Coastguard Worker * 3. The name of the author may not be used to endorse or promote products
20*cf84ac9aSAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
21*cf84ac9aSAndroid Build Coastguard Worker *
22*cf84ac9aSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23*cf84ac9aSAndroid Build Coastguard Worker * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24*cf84ac9aSAndroid Build Coastguard Worker * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25*cf84ac9aSAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26*cf84ac9aSAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27*cf84ac9aSAndroid Build Coastguard Worker * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28*cf84ac9aSAndroid Build Coastguard Worker * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29*cf84ac9aSAndroid Build Coastguard Worker * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30*cf84ac9aSAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31*cf84ac9aSAndroid Build Coastguard Worker * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*cf84ac9aSAndroid Build Coastguard Worker */
33*cf84ac9aSAndroid Build Coastguard Worker
34*cf84ac9aSAndroid Build Coastguard Worker #include "defs.h"
35*cf84ac9aSAndroid Build Coastguard Worker
36*cf84ac9aSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_DM_IOCTL_H
37*cf84ac9aSAndroid Build Coastguard Worker
38*cf84ac9aSAndroid Build Coastguard Worker # include "print_fields.h"
39*cf84ac9aSAndroid Build Coastguard Worker # include <linux/dm-ioctl.h>
40*cf84ac9aSAndroid Build Coastguard Worker # include <linux/ioctl.h>
41*cf84ac9aSAndroid Build Coastguard Worker
42*cf84ac9aSAndroid Build Coastguard Worker # if DM_VERSION_MAJOR == 4
43*cf84ac9aSAndroid Build Coastguard Worker
44*cf84ac9aSAndroid Build Coastguard Worker /* Definitions for command which have been added later */
45*cf84ac9aSAndroid Build Coastguard Worker
46*cf84ac9aSAndroid Build Coastguard Worker # ifndef DM_LIST_VERSIONS
47*cf84ac9aSAndroid Build Coastguard Worker # define DM_LIST_VERSIONS _IOWR(DM_IOCTL, 0x0d, struct dm_ioctl)
48*cf84ac9aSAndroid Build Coastguard Worker # endif
49*cf84ac9aSAndroid Build Coastguard Worker # ifndef DM_TARGET_MSG
50*cf84ac9aSAndroid Build Coastguard Worker # define DM_TARGET_MSG _IOWR(DM_IOCTL, 0x0e, struct dm_ioctl)
51*cf84ac9aSAndroid Build Coastguard Worker # endif
52*cf84ac9aSAndroid Build Coastguard Worker # ifndef DM_DEV_SET_GEOMETRY
53*cf84ac9aSAndroid Build Coastguard Worker # define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, 0x0f, struct dm_ioctl)
54*cf84ac9aSAndroid Build Coastguard Worker # endif
55*cf84ac9aSAndroid Build Coastguard Worker # ifndef DM_DEV_ARM_POLL
56*cf84ac9aSAndroid Build Coastguard Worker # define DM_DEV_ARM_POLL _IOWR(DM_IOCTL, 0x10, struct dm_ioctl)
57*cf84ac9aSAndroid Build Coastguard Worker # endif
58*cf84ac9aSAndroid Build Coastguard Worker
59*cf84ac9aSAndroid Build Coastguard Worker
60*cf84ac9aSAndroid Build Coastguard Worker static void
dm_decode_device(const unsigned int code,const struct dm_ioctl * ioc)61*cf84ac9aSAndroid Build Coastguard Worker dm_decode_device(const unsigned int code, const struct dm_ioctl *ioc)
62*cf84ac9aSAndroid Build Coastguard Worker {
63*cf84ac9aSAndroid Build Coastguard Worker switch (code) {
64*cf84ac9aSAndroid Build Coastguard Worker case DM_REMOVE_ALL:
65*cf84ac9aSAndroid Build Coastguard Worker case DM_LIST_DEVICES:
66*cf84ac9aSAndroid Build Coastguard Worker case DM_LIST_VERSIONS:
67*cf84ac9aSAndroid Build Coastguard Worker break;
68*cf84ac9aSAndroid Build Coastguard Worker default:
69*cf84ac9aSAndroid Build Coastguard Worker if (ioc->dev)
70*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_DEV(", ", *ioc, dev);
71*cf84ac9aSAndroid Build Coastguard Worker
72*cf84ac9aSAndroid Build Coastguard Worker if (ioc->name[0])
73*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_CSTRING(", ", *ioc, name);
74*cf84ac9aSAndroid Build Coastguard Worker
75*cf84ac9aSAndroid Build Coastguard Worker if (ioc->uuid[0])
76*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_CSTRING(", ", *ioc, uuid);
77*cf84ac9aSAndroid Build Coastguard Worker
78*cf84ac9aSAndroid Build Coastguard Worker break;
79*cf84ac9aSAndroid Build Coastguard Worker }
80*cf84ac9aSAndroid Build Coastguard Worker }
81*cf84ac9aSAndroid Build Coastguard Worker
82*cf84ac9aSAndroid Build Coastguard Worker static void
dm_decode_values(struct tcb * tcp,const unsigned int code,const struct dm_ioctl * ioc)83*cf84ac9aSAndroid Build Coastguard Worker dm_decode_values(struct tcb *tcp, const unsigned int code,
84*cf84ac9aSAndroid Build Coastguard Worker const struct dm_ioctl *ioc)
85*cf84ac9aSAndroid Build Coastguard Worker {
86*cf84ac9aSAndroid Build Coastguard Worker if (entering(tcp)) {
87*cf84ac9aSAndroid Build Coastguard Worker switch (code) {
88*cf84ac9aSAndroid Build Coastguard Worker case DM_TABLE_LOAD:
89*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *ioc, target_count);
90*cf84ac9aSAndroid Build Coastguard Worker break;
91*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_SUSPEND:
92*cf84ac9aSAndroid Build Coastguard Worker if (ioc->flags & DM_SUSPEND_FLAG)
93*cf84ac9aSAndroid Build Coastguard Worker break;
94*cf84ac9aSAndroid Build Coastguard Worker ATTRIBUTE_FALLTHROUGH;
95*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_RENAME:
96*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_REMOVE:
97*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_WAIT:
98*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *ioc, event_nr);
99*cf84ac9aSAndroid Build Coastguard Worker break;
100*cf84ac9aSAndroid Build Coastguard Worker }
101*cf84ac9aSAndroid Build Coastguard Worker } else if (!syserror(tcp)) {
102*cf84ac9aSAndroid Build Coastguard Worker switch (code) {
103*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_CREATE:
104*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_RENAME:
105*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_SUSPEND:
106*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_STATUS:
107*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_WAIT:
108*cf84ac9aSAndroid Build Coastguard Worker case DM_TABLE_LOAD:
109*cf84ac9aSAndroid Build Coastguard Worker case DM_TABLE_CLEAR:
110*cf84ac9aSAndroid Build Coastguard Worker case DM_TABLE_DEPS:
111*cf84ac9aSAndroid Build Coastguard Worker case DM_TABLE_STATUS:
112*cf84ac9aSAndroid Build Coastguard Worker case DM_TARGET_MSG:
113*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *ioc, target_count);
114*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *ioc, open_count);
115*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *ioc, event_nr);
116*cf84ac9aSAndroid Build Coastguard Worker break;
117*cf84ac9aSAndroid Build Coastguard Worker }
118*cf84ac9aSAndroid Build Coastguard Worker }
119*cf84ac9aSAndroid Build Coastguard Worker }
120*cf84ac9aSAndroid Build Coastguard Worker
121*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/dm_flags.h"
122*cf84ac9aSAndroid Build Coastguard Worker
123*cf84ac9aSAndroid Build Coastguard Worker static void
dm_decode_flags(const struct dm_ioctl * ioc)124*cf84ac9aSAndroid Build Coastguard Worker dm_decode_flags(const struct dm_ioctl *ioc)
125*cf84ac9aSAndroid Build Coastguard Worker {
126*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_FLAGS(", ", *ioc, flags, dm_flags, "DM_???");
127*cf84ac9aSAndroid Build Coastguard Worker }
128*cf84ac9aSAndroid Build Coastguard Worker
129*cf84ac9aSAndroid Build Coastguard Worker static void
dm_decode_dm_target_spec(struct tcb * const tcp,const kernel_ulong_t addr,const struct dm_ioctl * const ioc)130*cf84ac9aSAndroid Build Coastguard Worker dm_decode_dm_target_spec(struct tcb *const tcp, const kernel_ulong_t addr,
131*cf84ac9aSAndroid Build Coastguard Worker const struct dm_ioctl *const ioc)
132*cf84ac9aSAndroid Build Coastguard Worker {
133*cf84ac9aSAndroid Build Coastguard Worker static const uint32_t target_spec_size =
134*cf84ac9aSAndroid Build Coastguard Worker sizeof(struct dm_target_spec);
135*cf84ac9aSAndroid Build Coastguard Worker uint32_t i;
136*cf84ac9aSAndroid Build Coastguard Worker uint32_t offset = ioc->data_start;
137*cf84ac9aSAndroid Build Coastguard Worker uint32_t offset_end = 0;
138*cf84ac9aSAndroid Build Coastguard Worker
139*cf84ac9aSAndroid Build Coastguard Worker if (abbrev(tcp)) {
140*cf84ac9aSAndroid Build Coastguard Worker if (ioc->target_count)
141*cf84ac9aSAndroid Build Coastguard Worker tprints(", ...");
142*cf84ac9aSAndroid Build Coastguard Worker
143*cf84ac9aSAndroid Build Coastguard Worker return;
144*cf84ac9aSAndroid Build Coastguard Worker }
145*cf84ac9aSAndroid Build Coastguard Worker
146*cf84ac9aSAndroid Build Coastguard Worker for (i = 0; i < ioc->target_count; i++) {
147*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
148*cf84ac9aSAndroid Build Coastguard Worker
149*cf84ac9aSAndroid Build Coastguard Worker if (i && offset <= offset_end)
150*cf84ac9aSAndroid Build Coastguard Worker goto misplaced;
151*cf84ac9aSAndroid Build Coastguard Worker
152*cf84ac9aSAndroid Build Coastguard Worker offset_end = offset + target_spec_size;
153*cf84ac9aSAndroid Build Coastguard Worker
154*cf84ac9aSAndroid Build Coastguard Worker if (offset_end <= offset || offset_end > ioc->data_size)
155*cf84ac9aSAndroid Build Coastguard Worker goto misplaced;
156*cf84ac9aSAndroid Build Coastguard Worker
157*cf84ac9aSAndroid Build Coastguard Worker if (i >= max_strlen) {
158*cf84ac9aSAndroid Build Coastguard Worker tprints("...");
159*cf84ac9aSAndroid Build Coastguard Worker break;
160*cf84ac9aSAndroid Build Coastguard Worker }
161*cf84ac9aSAndroid Build Coastguard Worker
162*cf84ac9aSAndroid Build Coastguard Worker struct dm_target_spec s;
163*cf84ac9aSAndroid Build Coastguard Worker
164*cf84ac9aSAndroid Build Coastguard Worker if (umove_or_printaddr(tcp, addr + offset, &s))
165*cf84ac9aSAndroid Build Coastguard Worker break;
166*cf84ac9aSAndroid Build Coastguard Worker
167*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U("{", s, sector_start);
168*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", s, length);
169*cf84ac9aSAndroid Build Coastguard Worker
170*cf84ac9aSAndroid Build Coastguard Worker if (exiting(tcp))
171*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_D(", ", s, status);
172*cf84ac9aSAndroid Build Coastguard Worker
173*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_CSTRING(", ", s, target_type);
174*cf84ac9aSAndroid Build Coastguard Worker
175*cf84ac9aSAndroid Build Coastguard Worker tprints(", string=");
176*cf84ac9aSAndroid Build Coastguard Worker printstr_ex(tcp, addr + offset_end, ioc->data_size - offset_end,
177*cf84ac9aSAndroid Build Coastguard Worker QUOTE_0_TERMINATED);
178*cf84ac9aSAndroid Build Coastguard Worker tprints("}");
179*cf84ac9aSAndroid Build Coastguard Worker
180*cf84ac9aSAndroid Build Coastguard Worker if (entering(tcp))
181*cf84ac9aSAndroid Build Coastguard Worker offset += s.next;
182*cf84ac9aSAndroid Build Coastguard Worker else
183*cf84ac9aSAndroid Build Coastguard Worker offset = ioc->data_start + s.next;
184*cf84ac9aSAndroid Build Coastguard Worker }
185*cf84ac9aSAndroid Build Coastguard Worker
186*cf84ac9aSAndroid Build Coastguard Worker return;
187*cf84ac9aSAndroid Build Coastguard Worker
188*cf84ac9aSAndroid Build Coastguard Worker misplaced:
189*cf84ac9aSAndroid Build Coastguard Worker tprints("???");
190*cf84ac9aSAndroid Build Coastguard Worker tprints_comment("misplaced struct dm_target_spec");
191*cf84ac9aSAndroid Build Coastguard Worker }
192*cf84ac9aSAndroid Build Coastguard Worker
193*cf84ac9aSAndroid Build Coastguard Worker bool
dm_print_dev(struct tcb * tcp,void * dev_ptr,size_t dev_size,void * dummy)194*cf84ac9aSAndroid Build Coastguard Worker dm_print_dev(struct tcb *tcp, void *dev_ptr, size_t dev_size, void *dummy)
195*cf84ac9aSAndroid Build Coastguard Worker {
196*cf84ac9aSAndroid Build Coastguard Worker uint64_t *dev = (uint64_t *) dev_ptr;
197*cf84ac9aSAndroid Build Coastguard Worker
198*cf84ac9aSAndroid Build Coastguard Worker print_dev_t(*dev);
199*cf84ac9aSAndroid Build Coastguard Worker
200*cf84ac9aSAndroid Build Coastguard Worker return 1;
201*cf84ac9aSAndroid Build Coastguard Worker }
202*cf84ac9aSAndroid Build Coastguard Worker
203*cf84ac9aSAndroid Build Coastguard Worker static void
dm_decode_dm_target_deps(struct tcb * const tcp,const kernel_ulong_t addr,const struct dm_ioctl * const ioc)204*cf84ac9aSAndroid Build Coastguard Worker dm_decode_dm_target_deps(struct tcb *const tcp, const kernel_ulong_t addr,
205*cf84ac9aSAndroid Build Coastguard Worker const struct dm_ioctl *const ioc)
206*cf84ac9aSAndroid Build Coastguard Worker {
207*cf84ac9aSAndroid Build Coastguard Worker if (ioc->data_start == ioc->data_size)
208*cf84ac9aSAndroid Build Coastguard Worker return;
209*cf84ac9aSAndroid Build Coastguard Worker
210*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
211*cf84ac9aSAndroid Build Coastguard Worker
212*cf84ac9aSAndroid Build Coastguard Worker if (abbrev(tcp)) {
213*cf84ac9aSAndroid Build Coastguard Worker tprints("...");
214*cf84ac9aSAndroid Build Coastguard Worker return;
215*cf84ac9aSAndroid Build Coastguard Worker }
216*cf84ac9aSAndroid Build Coastguard Worker
217*cf84ac9aSAndroid Build Coastguard Worker static const uint32_t target_deps_dev_offs =
218*cf84ac9aSAndroid Build Coastguard Worker offsetof(struct dm_target_deps, dev);
219*cf84ac9aSAndroid Build Coastguard Worker uint64_t dev_buf;
220*cf84ac9aSAndroid Build Coastguard Worker struct dm_target_deps s;
221*cf84ac9aSAndroid Build Coastguard Worker uint32_t offset = ioc->data_start;
222*cf84ac9aSAndroid Build Coastguard Worker uint32_t offset_end = offset + target_deps_dev_offs;
223*cf84ac9aSAndroid Build Coastguard Worker uint32_t space;
224*cf84ac9aSAndroid Build Coastguard Worker
225*cf84ac9aSAndroid Build Coastguard Worker if (offset_end <= offset || offset_end > ioc->data_size)
226*cf84ac9aSAndroid Build Coastguard Worker goto misplaced;
227*cf84ac9aSAndroid Build Coastguard Worker
228*cf84ac9aSAndroid Build Coastguard Worker if (umove_or_printaddr(tcp, addr + offset, &s))
229*cf84ac9aSAndroid Build Coastguard Worker return;
230*cf84ac9aSAndroid Build Coastguard Worker
231*cf84ac9aSAndroid Build Coastguard Worker space = (ioc->data_size - offset_end) / sizeof(dev_buf);
232*cf84ac9aSAndroid Build Coastguard Worker
233*cf84ac9aSAndroid Build Coastguard Worker if (s.count > space)
234*cf84ac9aSAndroid Build Coastguard Worker goto misplaced;
235*cf84ac9aSAndroid Build Coastguard Worker
236*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U("{", s, count);
237*cf84ac9aSAndroid Build Coastguard Worker
238*cf84ac9aSAndroid Build Coastguard Worker tprints(", deps=");
239*cf84ac9aSAndroid Build Coastguard Worker print_array(tcp, addr + offset_end, s.count, &dev_buf, sizeof(dev_buf),
240*cf84ac9aSAndroid Build Coastguard Worker tfetch_mem, dm_print_dev, NULL);
241*cf84ac9aSAndroid Build Coastguard Worker
242*cf84ac9aSAndroid Build Coastguard Worker tprints("}");
243*cf84ac9aSAndroid Build Coastguard Worker
244*cf84ac9aSAndroid Build Coastguard Worker return;
245*cf84ac9aSAndroid Build Coastguard Worker
246*cf84ac9aSAndroid Build Coastguard Worker misplaced:
247*cf84ac9aSAndroid Build Coastguard Worker tprints("???");
248*cf84ac9aSAndroid Build Coastguard Worker tprints_comment("misplaced struct dm_target_deps");
249*cf84ac9aSAndroid Build Coastguard Worker }
250*cf84ac9aSAndroid Build Coastguard Worker
251*cf84ac9aSAndroid Build Coastguard Worker static void
dm_decode_dm_name_list(struct tcb * const tcp,const kernel_ulong_t addr,const struct dm_ioctl * const ioc)252*cf84ac9aSAndroid Build Coastguard Worker dm_decode_dm_name_list(struct tcb *const tcp, const kernel_ulong_t addr,
253*cf84ac9aSAndroid Build Coastguard Worker const struct dm_ioctl *const ioc)
254*cf84ac9aSAndroid Build Coastguard Worker {
255*cf84ac9aSAndroid Build Coastguard Worker static const uint32_t name_list_name_offs =
256*cf84ac9aSAndroid Build Coastguard Worker offsetof(struct dm_name_list, name);
257*cf84ac9aSAndroid Build Coastguard Worker struct dm_name_list s;
258*cf84ac9aSAndroid Build Coastguard Worker uint32_t offset = ioc->data_start;
259*cf84ac9aSAndroid Build Coastguard Worker uint32_t offset_end = 0;
260*cf84ac9aSAndroid Build Coastguard Worker uint32_t count;
261*cf84ac9aSAndroid Build Coastguard Worker int rc;
262*cf84ac9aSAndroid Build Coastguard Worker
263*cf84ac9aSAndroid Build Coastguard Worker if (ioc->data_start == ioc->data_size)
264*cf84ac9aSAndroid Build Coastguard Worker return;
265*cf84ac9aSAndroid Build Coastguard Worker
266*cf84ac9aSAndroid Build Coastguard Worker if (abbrev(tcp)) {
267*cf84ac9aSAndroid Build Coastguard Worker tprints(", ...");
268*cf84ac9aSAndroid Build Coastguard Worker return;
269*cf84ac9aSAndroid Build Coastguard Worker }
270*cf84ac9aSAndroid Build Coastguard Worker
271*cf84ac9aSAndroid Build Coastguard Worker for (count = 0;; count++) {
272*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
273*cf84ac9aSAndroid Build Coastguard Worker
274*cf84ac9aSAndroid Build Coastguard Worker if (count && offset <= offset_end)
275*cf84ac9aSAndroid Build Coastguard Worker goto misplaced;
276*cf84ac9aSAndroid Build Coastguard Worker
277*cf84ac9aSAndroid Build Coastguard Worker offset_end = offset + name_list_name_offs;
278*cf84ac9aSAndroid Build Coastguard Worker
279*cf84ac9aSAndroid Build Coastguard Worker if (offset_end <= offset || offset_end > ioc->data_size)
280*cf84ac9aSAndroid Build Coastguard Worker goto misplaced;
281*cf84ac9aSAndroid Build Coastguard Worker
282*cf84ac9aSAndroid Build Coastguard Worker if (count >= max_strlen) {
283*cf84ac9aSAndroid Build Coastguard Worker tprints("...");
284*cf84ac9aSAndroid Build Coastguard Worker break;
285*cf84ac9aSAndroid Build Coastguard Worker }
286*cf84ac9aSAndroid Build Coastguard Worker
287*cf84ac9aSAndroid Build Coastguard Worker if (umove_or_printaddr(tcp, addr + offset, &s))
288*cf84ac9aSAndroid Build Coastguard Worker break;
289*cf84ac9aSAndroid Build Coastguard Worker
290*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_DEV("{", s, dev);
291*cf84ac9aSAndroid Build Coastguard Worker tprints(", name=");
292*cf84ac9aSAndroid Build Coastguard Worker rc = printstr_ex(tcp, addr + offset_end,
293*cf84ac9aSAndroid Build Coastguard Worker ioc->data_size - offset_end,
294*cf84ac9aSAndroid Build Coastguard Worker QUOTE_0_TERMINATED);
295*cf84ac9aSAndroid Build Coastguard Worker
296*cf84ac9aSAndroid Build Coastguard Worker /*
297*cf84ac9aSAndroid Build Coastguard Worker * In Linux v4.13-rc1~137^2~13 it has been decided to cram in
298*cf84ac9aSAndroid Build Coastguard Worker * one more undocumented field after the device name, as if the
299*cf84ac9aSAndroid Build Coastguard Worker * format decoding was not twisted enough already. So, we have
300*cf84ac9aSAndroid Build Coastguard Worker * to check "next" now, and if it _looks like_ that there is
301*cf84ac9aSAndroid Build Coastguard Worker * a space for one additional integer, let's print it. As if the
302*cf84ac9aSAndroid Build Coastguard Worker * perversity with "name string going further than pointer to
303*cf84ac9aSAndroid Build Coastguard Worker * the next one" wasn't enough. Moreover, the calculation was
304*cf84ac9aSAndroid Build Coastguard Worker * broken for m32 on 64-bit kernels until v4.14-rc4~20^2~3, and
305*cf84ac9aSAndroid Build Coastguard Worker * we have no ability to detect kernel bit-ness (on x86, at
306*cf84ac9aSAndroid Build Coastguard Worker * least), so refrain from printing it for the DM versions below
307*cf84ac9aSAndroid Build Coastguard Worker * 4.37 (the original version was also aligned differently than
308*cf84ac9aSAndroid Build Coastguard Worker * now even on 64 bit).
309*cf84ac9aSAndroid Build Coastguard Worker */
310*cf84ac9aSAndroid Build Coastguard Worker
311*cf84ac9aSAndroid Build Coastguard Worker if ((rc > 0) && ioc->version[1] >= 37) {
312*cf84ac9aSAndroid Build Coastguard Worker kernel_ulong_t event_addr =
313*cf84ac9aSAndroid Build Coastguard Worker (addr + offset_end + rc + 7) & ~7;
314*cf84ac9aSAndroid Build Coastguard Worker uint32_t event_nr;
315*cf84ac9aSAndroid Build Coastguard Worker
316*cf84ac9aSAndroid Build Coastguard Worker if ((event_addr + sizeof(event_nr)) <=
317*cf84ac9aSAndroid Build Coastguard Worker (addr + offset + s.next) &&
318*cf84ac9aSAndroid Build Coastguard Worker !umove(tcp, event_addr, &event_nr))
319*cf84ac9aSAndroid Build Coastguard Worker tprintf(", event_nr=%" PRIu32, event_nr);
320*cf84ac9aSAndroid Build Coastguard Worker }
321*cf84ac9aSAndroid Build Coastguard Worker
322*cf84ac9aSAndroid Build Coastguard Worker tprints("}");
323*cf84ac9aSAndroid Build Coastguard Worker
324*cf84ac9aSAndroid Build Coastguard Worker if (!s.next)
325*cf84ac9aSAndroid Build Coastguard Worker break;
326*cf84ac9aSAndroid Build Coastguard Worker
327*cf84ac9aSAndroid Build Coastguard Worker offset += s.next;
328*cf84ac9aSAndroid Build Coastguard Worker }
329*cf84ac9aSAndroid Build Coastguard Worker
330*cf84ac9aSAndroid Build Coastguard Worker return;
331*cf84ac9aSAndroid Build Coastguard Worker
332*cf84ac9aSAndroid Build Coastguard Worker misplaced:
333*cf84ac9aSAndroid Build Coastguard Worker tprints("???");
334*cf84ac9aSAndroid Build Coastguard Worker tprints_comment("misplaced struct dm_name_list");
335*cf84ac9aSAndroid Build Coastguard Worker }
336*cf84ac9aSAndroid Build Coastguard Worker
337*cf84ac9aSAndroid Build Coastguard Worker static void
dm_decode_dm_target_versions(struct tcb * const tcp,const kernel_ulong_t addr,const struct dm_ioctl * const ioc)338*cf84ac9aSAndroid Build Coastguard Worker dm_decode_dm_target_versions(struct tcb *const tcp, const kernel_ulong_t addr,
339*cf84ac9aSAndroid Build Coastguard Worker const struct dm_ioctl *const ioc)
340*cf84ac9aSAndroid Build Coastguard Worker {
341*cf84ac9aSAndroid Build Coastguard Worker static const uint32_t target_vers_name_offs =
342*cf84ac9aSAndroid Build Coastguard Worker offsetof(struct dm_target_versions, name);
343*cf84ac9aSAndroid Build Coastguard Worker struct dm_target_versions s;
344*cf84ac9aSAndroid Build Coastguard Worker uint32_t offset = ioc->data_start;
345*cf84ac9aSAndroid Build Coastguard Worker uint32_t offset_end = 0;
346*cf84ac9aSAndroid Build Coastguard Worker uint32_t count;
347*cf84ac9aSAndroid Build Coastguard Worker
348*cf84ac9aSAndroid Build Coastguard Worker if (ioc->data_start == ioc->data_size)
349*cf84ac9aSAndroid Build Coastguard Worker return;
350*cf84ac9aSAndroid Build Coastguard Worker
351*cf84ac9aSAndroid Build Coastguard Worker if (abbrev(tcp)) {
352*cf84ac9aSAndroid Build Coastguard Worker tprints(", ...");
353*cf84ac9aSAndroid Build Coastguard Worker return;
354*cf84ac9aSAndroid Build Coastguard Worker }
355*cf84ac9aSAndroid Build Coastguard Worker
356*cf84ac9aSAndroid Build Coastguard Worker for (count = 0;; count++) {
357*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
358*cf84ac9aSAndroid Build Coastguard Worker
359*cf84ac9aSAndroid Build Coastguard Worker if (count && offset <= offset_end)
360*cf84ac9aSAndroid Build Coastguard Worker goto misplaced;
361*cf84ac9aSAndroid Build Coastguard Worker
362*cf84ac9aSAndroid Build Coastguard Worker offset_end = offset + target_vers_name_offs;
363*cf84ac9aSAndroid Build Coastguard Worker
364*cf84ac9aSAndroid Build Coastguard Worker if (offset_end <= offset || offset_end > ioc->data_size)
365*cf84ac9aSAndroid Build Coastguard Worker goto misplaced;
366*cf84ac9aSAndroid Build Coastguard Worker
367*cf84ac9aSAndroid Build Coastguard Worker if (count >= max_strlen) {
368*cf84ac9aSAndroid Build Coastguard Worker tprints("...");
369*cf84ac9aSAndroid Build Coastguard Worker break;
370*cf84ac9aSAndroid Build Coastguard Worker }
371*cf84ac9aSAndroid Build Coastguard Worker
372*cf84ac9aSAndroid Build Coastguard Worker if (umove_or_printaddr(tcp, addr + offset, &s))
373*cf84ac9aSAndroid Build Coastguard Worker break;
374*cf84ac9aSAndroid Build Coastguard Worker
375*cf84ac9aSAndroid Build Coastguard Worker tprints("{name=");
376*cf84ac9aSAndroid Build Coastguard Worker printstr_ex(tcp, addr + offset_end, ioc->data_size - offset_end,
377*cf84ac9aSAndroid Build Coastguard Worker QUOTE_0_TERMINATED);
378*cf84ac9aSAndroid Build Coastguard Worker tprintf(", version=%" PRIu32 ".%" PRIu32 ".%" PRIu32 "}",
379*cf84ac9aSAndroid Build Coastguard Worker s.version[0], s.version[1], s.version[2]);
380*cf84ac9aSAndroid Build Coastguard Worker
381*cf84ac9aSAndroid Build Coastguard Worker if (!s.next)
382*cf84ac9aSAndroid Build Coastguard Worker break;
383*cf84ac9aSAndroid Build Coastguard Worker
384*cf84ac9aSAndroid Build Coastguard Worker offset += s.next;
385*cf84ac9aSAndroid Build Coastguard Worker }
386*cf84ac9aSAndroid Build Coastguard Worker
387*cf84ac9aSAndroid Build Coastguard Worker return;
388*cf84ac9aSAndroid Build Coastguard Worker
389*cf84ac9aSAndroid Build Coastguard Worker misplaced:
390*cf84ac9aSAndroid Build Coastguard Worker tprints("???");
391*cf84ac9aSAndroid Build Coastguard Worker tprints_comment("misplaced struct dm_target_versions");
392*cf84ac9aSAndroid Build Coastguard Worker }
393*cf84ac9aSAndroid Build Coastguard Worker
394*cf84ac9aSAndroid Build Coastguard Worker static void
dm_decode_dm_target_msg(struct tcb * const tcp,const kernel_ulong_t addr,const struct dm_ioctl * const ioc)395*cf84ac9aSAndroid Build Coastguard Worker dm_decode_dm_target_msg(struct tcb *const tcp, const kernel_ulong_t addr,
396*cf84ac9aSAndroid Build Coastguard Worker const struct dm_ioctl *const ioc)
397*cf84ac9aSAndroid Build Coastguard Worker {
398*cf84ac9aSAndroid Build Coastguard Worker if (ioc->data_start == ioc->data_size)
399*cf84ac9aSAndroid Build Coastguard Worker return;
400*cf84ac9aSAndroid Build Coastguard Worker
401*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
402*cf84ac9aSAndroid Build Coastguard Worker
403*cf84ac9aSAndroid Build Coastguard Worker if (abbrev(tcp)) {
404*cf84ac9aSAndroid Build Coastguard Worker tprints("...");
405*cf84ac9aSAndroid Build Coastguard Worker return;
406*cf84ac9aSAndroid Build Coastguard Worker }
407*cf84ac9aSAndroid Build Coastguard Worker
408*cf84ac9aSAndroid Build Coastguard Worker static const uint32_t target_msg_message_offs =
409*cf84ac9aSAndroid Build Coastguard Worker offsetof(struct dm_target_msg, message);
410*cf84ac9aSAndroid Build Coastguard Worker uint32_t offset = ioc->data_start;
411*cf84ac9aSAndroid Build Coastguard Worker uint32_t offset_end = offset + target_msg_message_offs;
412*cf84ac9aSAndroid Build Coastguard Worker
413*cf84ac9aSAndroid Build Coastguard Worker if (offset_end > offset && offset_end <= ioc->data_size) {
414*cf84ac9aSAndroid Build Coastguard Worker struct dm_target_msg s;
415*cf84ac9aSAndroid Build Coastguard Worker
416*cf84ac9aSAndroid Build Coastguard Worker if (umove_or_printaddr(tcp, addr + offset, &s))
417*cf84ac9aSAndroid Build Coastguard Worker return;
418*cf84ac9aSAndroid Build Coastguard Worker
419*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U("{", s, sector);
420*cf84ac9aSAndroid Build Coastguard Worker tprints(", message=");
421*cf84ac9aSAndroid Build Coastguard Worker printstr_ex(tcp, addr + offset_end, ioc->data_size - offset_end,
422*cf84ac9aSAndroid Build Coastguard Worker QUOTE_0_TERMINATED);
423*cf84ac9aSAndroid Build Coastguard Worker tprints("}");
424*cf84ac9aSAndroid Build Coastguard Worker } else {
425*cf84ac9aSAndroid Build Coastguard Worker tprints("???");
426*cf84ac9aSAndroid Build Coastguard Worker tprints_comment("misplaced struct dm_target_msg");
427*cf84ac9aSAndroid Build Coastguard Worker }
428*cf84ac9aSAndroid Build Coastguard Worker }
429*cf84ac9aSAndroid Build Coastguard Worker
430*cf84ac9aSAndroid Build Coastguard Worker static void
dm_decode_string(struct tcb * const tcp,const kernel_ulong_t addr,const struct dm_ioctl * const ioc)431*cf84ac9aSAndroid Build Coastguard Worker dm_decode_string(struct tcb *const tcp, const kernel_ulong_t addr,
432*cf84ac9aSAndroid Build Coastguard Worker const struct dm_ioctl *const ioc)
433*cf84ac9aSAndroid Build Coastguard Worker {
434*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
435*cf84ac9aSAndroid Build Coastguard Worker
436*cf84ac9aSAndroid Build Coastguard Worker if (abbrev(tcp)) {
437*cf84ac9aSAndroid Build Coastguard Worker tprints("...");
438*cf84ac9aSAndroid Build Coastguard Worker return;
439*cf84ac9aSAndroid Build Coastguard Worker }
440*cf84ac9aSAndroid Build Coastguard Worker
441*cf84ac9aSAndroid Build Coastguard Worker uint32_t offset = ioc->data_start;
442*cf84ac9aSAndroid Build Coastguard Worker
443*cf84ac9aSAndroid Build Coastguard Worker if (offset <= ioc->data_size) {
444*cf84ac9aSAndroid Build Coastguard Worker tprints("string=");
445*cf84ac9aSAndroid Build Coastguard Worker printstr_ex(tcp, addr + offset, ioc->data_size - offset,
446*cf84ac9aSAndroid Build Coastguard Worker QUOTE_0_TERMINATED);
447*cf84ac9aSAndroid Build Coastguard Worker } else {
448*cf84ac9aSAndroid Build Coastguard Worker tprints("???");
449*cf84ac9aSAndroid Build Coastguard Worker tprints_comment("misplaced string");
450*cf84ac9aSAndroid Build Coastguard Worker }
451*cf84ac9aSAndroid Build Coastguard Worker }
452*cf84ac9aSAndroid Build Coastguard Worker
453*cf84ac9aSAndroid Build Coastguard Worker static inline bool
dm_ioctl_has_params(const unsigned int code)454*cf84ac9aSAndroid Build Coastguard Worker dm_ioctl_has_params(const unsigned int code)
455*cf84ac9aSAndroid Build Coastguard Worker {
456*cf84ac9aSAndroid Build Coastguard Worker switch (code) {
457*cf84ac9aSAndroid Build Coastguard Worker case DM_VERSION:
458*cf84ac9aSAndroid Build Coastguard Worker case DM_REMOVE_ALL:
459*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_CREATE:
460*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_REMOVE:
461*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_SUSPEND:
462*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_STATUS:
463*cf84ac9aSAndroid Build Coastguard Worker case DM_TABLE_CLEAR:
464*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_ARM_POLL:
465*cf84ac9aSAndroid Build Coastguard Worker return false;
466*cf84ac9aSAndroid Build Coastguard Worker }
467*cf84ac9aSAndroid Build Coastguard Worker
468*cf84ac9aSAndroid Build Coastguard Worker return true;
469*cf84ac9aSAndroid Build Coastguard Worker }
470*cf84ac9aSAndroid Build Coastguard Worker
471*cf84ac9aSAndroid Build Coastguard Worker static int
dm_known_ioctl(struct tcb * const tcp,const unsigned int code,const kernel_ulong_t arg)472*cf84ac9aSAndroid Build Coastguard Worker dm_known_ioctl(struct tcb *const tcp, const unsigned int code,
473*cf84ac9aSAndroid Build Coastguard Worker const kernel_ulong_t arg)
474*cf84ac9aSAndroid Build Coastguard Worker {
475*cf84ac9aSAndroid Build Coastguard Worker struct dm_ioctl *ioc = NULL;
476*cf84ac9aSAndroid Build Coastguard Worker struct dm_ioctl *entering_ioc = NULL;
477*cf84ac9aSAndroid Build Coastguard Worker bool ioc_changed = false;
478*cf84ac9aSAndroid Build Coastguard Worker
479*cf84ac9aSAndroid Build Coastguard Worker if (entering(tcp)) {
480*cf84ac9aSAndroid Build Coastguard Worker ioc = malloc(sizeof(*ioc));
481*cf84ac9aSAndroid Build Coastguard Worker if (!ioc)
482*cf84ac9aSAndroid Build Coastguard Worker return 0;
483*cf84ac9aSAndroid Build Coastguard Worker } else {
484*cf84ac9aSAndroid Build Coastguard Worker ioc = alloca(sizeof(*ioc));
485*cf84ac9aSAndroid Build Coastguard Worker }
486*cf84ac9aSAndroid Build Coastguard Worker
487*cf84ac9aSAndroid Build Coastguard Worker if ((umoven(tcp, arg, offsetof(struct dm_ioctl, data), ioc) < 0) ||
488*cf84ac9aSAndroid Build Coastguard Worker (ioc->data_size < offsetof(struct dm_ioctl, data_size))) {
489*cf84ac9aSAndroid Build Coastguard Worker if (entering(tcp))
490*cf84ac9aSAndroid Build Coastguard Worker free(ioc);
491*cf84ac9aSAndroid Build Coastguard Worker return 0;
492*cf84ac9aSAndroid Build Coastguard Worker }
493*cf84ac9aSAndroid Build Coastguard Worker if (entering(tcp))
494*cf84ac9aSAndroid Build Coastguard Worker set_tcb_priv_data(tcp, ioc, free);
495*cf84ac9aSAndroid Build Coastguard Worker else {
496*cf84ac9aSAndroid Build Coastguard Worker entering_ioc = get_tcb_priv_data(tcp);
497*cf84ac9aSAndroid Build Coastguard Worker
498*cf84ac9aSAndroid Build Coastguard Worker /*
499*cf84ac9aSAndroid Build Coastguard Worker * retrieve_status, __dev_status called only in case of success,
500*cf84ac9aSAndroid Build Coastguard Worker * so it looks like there's no need to check open_count,
501*cf84ac9aSAndroid Build Coastguard Worker * event_nr, target_count, dev fields for change (they are
502*cf84ac9aSAndroid Build Coastguard Worker * printed only in case of absence of errors).
503*cf84ac9aSAndroid Build Coastguard Worker */
504*cf84ac9aSAndroid Build Coastguard Worker if (!entering_ioc ||
505*cf84ac9aSAndroid Build Coastguard Worker (ioc->version[0] != entering_ioc->version[0]) ||
506*cf84ac9aSAndroid Build Coastguard Worker (ioc->version[1] != entering_ioc->version[1]) ||
507*cf84ac9aSAndroid Build Coastguard Worker (ioc->version[2] != entering_ioc->version[2]) ||
508*cf84ac9aSAndroid Build Coastguard Worker (ioc->data_size != entering_ioc->data_size) ||
509*cf84ac9aSAndroid Build Coastguard Worker (ioc->data_start != entering_ioc->data_start) ||
510*cf84ac9aSAndroid Build Coastguard Worker (ioc->flags != entering_ioc->flags))
511*cf84ac9aSAndroid Build Coastguard Worker ioc_changed = true;
512*cf84ac9aSAndroid Build Coastguard Worker }
513*cf84ac9aSAndroid Build Coastguard Worker
514*cf84ac9aSAndroid Build Coastguard Worker if (exiting(tcp) && syserror(tcp) && !ioc_changed)
515*cf84ac9aSAndroid Build Coastguard Worker return RVAL_IOCTL_DECODED;
516*cf84ac9aSAndroid Build Coastguard Worker
517*cf84ac9aSAndroid Build Coastguard Worker /*
518*cf84ac9aSAndroid Build Coastguard Worker * device mapper code uses %d in some places and %u in another, but
519*cf84ac9aSAndroid Build Coastguard Worker * fields themselves are declared as __u32.
520*cf84ac9aSAndroid Build Coastguard Worker */
521*cf84ac9aSAndroid Build Coastguard Worker tprintf("%s{version=%u.%u.%u", entering(tcp) ? ", " : " => ",
522*cf84ac9aSAndroid Build Coastguard Worker ioc->version[0], ioc->version[1], ioc->version[2]);
523*cf84ac9aSAndroid Build Coastguard Worker /*
524*cf84ac9aSAndroid Build Coastguard Worker * if we use a different version of ABI, do not attempt to decode
525*cf84ac9aSAndroid Build Coastguard Worker * ioctl fields
526*cf84ac9aSAndroid Build Coastguard Worker */
527*cf84ac9aSAndroid Build Coastguard Worker if (ioc->version[0] != DM_VERSION_MAJOR) {
528*cf84ac9aSAndroid Build Coastguard Worker tprints_comment("unsupported device mapper ABI version");
529*cf84ac9aSAndroid Build Coastguard Worker goto skip;
530*cf84ac9aSAndroid Build Coastguard Worker }
531*cf84ac9aSAndroid Build Coastguard Worker
532*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *ioc, data_size);
533*cf84ac9aSAndroid Build Coastguard Worker
534*cf84ac9aSAndroid Build Coastguard Worker if (ioc->data_size < offsetof(struct dm_ioctl, data)) {
535*cf84ac9aSAndroid Build Coastguard Worker tprints_comment("data_size too small");
536*cf84ac9aSAndroid Build Coastguard Worker goto skip;
537*cf84ac9aSAndroid Build Coastguard Worker }
538*cf84ac9aSAndroid Build Coastguard Worker
539*cf84ac9aSAndroid Build Coastguard Worker if (dm_ioctl_has_params(code))
540*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *ioc, data_start);
541*cf84ac9aSAndroid Build Coastguard Worker
542*cf84ac9aSAndroid Build Coastguard Worker dm_decode_device(code, ioc);
543*cf84ac9aSAndroid Build Coastguard Worker dm_decode_values(tcp, code, ioc);
544*cf84ac9aSAndroid Build Coastguard Worker dm_decode_flags(ioc);
545*cf84ac9aSAndroid Build Coastguard Worker
546*cf84ac9aSAndroid Build Coastguard Worker switch (code) {
547*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_WAIT:
548*cf84ac9aSAndroid Build Coastguard Worker case DM_TABLE_STATUS:
549*cf84ac9aSAndroid Build Coastguard Worker if (entering(tcp) || syserror(tcp))
550*cf84ac9aSAndroid Build Coastguard Worker break;
551*cf84ac9aSAndroid Build Coastguard Worker dm_decode_dm_target_spec(tcp, arg, ioc);
552*cf84ac9aSAndroid Build Coastguard Worker break;
553*cf84ac9aSAndroid Build Coastguard Worker case DM_TABLE_LOAD:
554*cf84ac9aSAndroid Build Coastguard Worker if (exiting(tcp))
555*cf84ac9aSAndroid Build Coastguard Worker break;
556*cf84ac9aSAndroid Build Coastguard Worker dm_decode_dm_target_spec(tcp, arg, ioc);
557*cf84ac9aSAndroid Build Coastguard Worker break;
558*cf84ac9aSAndroid Build Coastguard Worker case DM_TABLE_DEPS:
559*cf84ac9aSAndroid Build Coastguard Worker if (entering(tcp) || syserror(tcp))
560*cf84ac9aSAndroid Build Coastguard Worker break;
561*cf84ac9aSAndroid Build Coastguard Worker dm_decode_dm_target_deps(tcp, arg, ioc);
562*cf84ac9aSAndroid Build Coastguard Worker break;
563*cf84ac9aSAndroid Build Coastguard Worker case DM_LIST_DEVICES:
564*cf84ac9aSAndroid Build Coastguard Worker if (entering(tcp) || syserror(tcp))
565*cf84ac9aSAndroid Build Coastguard Worker break;
566*cf84ac9aSAndroid Build Coastguard Worker dm_decode_dm_name_list(tcp, arg, ioc);
567*cf84ac9aSAndroid Build Coastguard Worker break;
568*cf84ac9aSAndroid Build Coastguard Worker case DM_LIST_VERSIONS:
569*cf84ac9aSAndroid Build Coastguard Worker if (entering(tcp) || syserror(tcp))
570*cf84ac9aSAndroid Build Coastguard Worker break;
571*cf84ac9aSAndroid Build Coastguard Worker dm_decode_dm_target_versions(tcp, arg, ioc);
572*cf84ac9aSAndroid Build Coastguard Worker break;
573*cf84ac9aSAndroid Build Coastguard Worker case DM_TARGET_MSG:
574*cf84ac9aSAndroid Build Coastguard Worker if (entering(tcp))
575*cf84ac9aSAndroid Build Coastguard Worker dm_decode_dm_target_msg(tcp, arg, ioc);
576*cf84ac9aSAndroid Build Coastguard Worker else if (!syserror(tcp) && ioc->flags & DM_DATA_OUT_FLAG)
577*cf84ac9aSAndroid Build Coastguard Worker dm_decode_string(tcp, arg, ioc);
578*cf84ac9aSAndroid Build Coastguard Worker break;
579*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_RENAME:
580*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_SET_GEOMETRY:
581*cf84ac9aSAndroid Build Coastguard Worker if (exiting(tcp))
582*cf84ac9aSAndroid Build Coastguard Worker break;
583*cf84ac9aSAndroid Build Coastguard Worker dm_decode_string(tcp, arg, ioc);
584*cf84ac9aSAndroid Build Coastguard Worker break;
585*cf84ac9aSAndroid Build Coastguard Worker }
586*cf84ac9aSAndroid Build Coastguard Worker
587*cf84ac9aSAndroid Build Coastguard Worker skip:
588*cf84ac9aSAndroid Build Coastguard Worker tprints("}");
589*cf84ac9aSAndroid Build Coastguard Worker return entering(tcp) ? 0 : RVAL_IOCTL_DECODED;
590*cf84ac9aSAndroid Build Coastguard Worker }
591*cf84ac9aSAndroid Build Coastguard Worker
592*cf84ac9aSAndroid Build Coastguard Worker int
dm_ioctl(struct tcb * const tcp,const unsigned int code,const kernel_ulong_t arg)593*cf84ac9aSAndroid Build Coastguard Worker dm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
594*cf84ac9aSAndroid Build Coastguard Worker {
595*cf84ac9aSAndroid Build Coastguard Worker switch (code) {
596*cf84ac9aSAndroid Build Coastguard Worker case DM_VERSION:
597*cf84ac9aSAndroid Build Coastguard Worker case DM_REMOVE_ALL:
598*cf84ac9aSAndroid Build Coastguard Worker case DM_LIST_DEVICES:
599*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_CREATE:
600*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_REMOVE:
601*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_RENAME:
602*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_SUSPEND:
603*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_STATUS:
604*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_WAIT:
605*cf84ac9aSAndroid Build Coastguard Worker case DM_TABLE_LOAD:
606*cf84ac9aSAndroid Build Coastguard Worker case DM_TABLE_CLEAR:
607*cf84ac9aSAndroid Build Coastguard Worker case DM_TABLE_DEPS:
608*cf84ac9aSAndroid Build Coastguard Worker case DM_TABLE_STATUS:
609*cf84ac9aSAndroid Build Coastguard Worker case DM_LIST_VERSIONS:
610*cf84ac9aSAndroid Build Coastguard Worker case DM_TARGET_MSG:
611*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_SET_GEOMETRY:
612*cf84ac9aSAndroid Build Coastguard Worker case DM_DEV_ARM_POLL:
613*cf84ac9aSAndroid Build Coastguard Worker return dm_known_ioctl(tcp, code, arg);
614*cf84ac9aSAndroid Build Coastguard Worker default:
615*cf84ac9aSAndroid Build Coastguard Worker return RVAL_DECODED;
616*cf84ac9aSAndroid Build Coastguard Worker }
617*cf84ac9aSAndroid Build Coastguard Worker }
618*cf84ac9aSAndroid Build Coastguard Worker
619*cf84ac9aSAndroid Build Coastguard Worker # else /* !(DM_VERSION_MAJOR == 4) */
620*cf84ac9aSAndroid Build Coastguard Worker
621*cf84ac9aSAndroid Build Coastguard Worker int
dm_ioctl(struct tcb * const tcp,const unsigned int code,const kernel_ulong_t arg)622*cf84ac9aSAndroid Build Coastguard Worker dm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
623*cf84ac9aSAndroid Build Coastguard Worker {
624*cf84ac9aSAndroid Build Coastguard Worker return RVAL_DECODED;
625*cf84ac9aSAndroid Build Coastguard Worker }
626*cf84ac9aSAndroid Build Coastguard Worker
627*cf84ac9aSAndroid Build Coastguard Worker # endif /* DM_VERSION_MAJOR == 4 */
628*cf84ac9aSAndroid Build Coastguard Worker #endif /* HAVE_LINUX_DM_IOCTL_H */
629