SG_IO v4 support ?
Dmitry V. Levin
ldv at altlinux.org
Fri Jan 23 01:24:32 UTC 2015
Hi,
On Wed, Jan 21, 2015 at 05:04:44PM +0100, Bart Van Assche wrote:
> Hello,
>
> If anyone would like to add SG_IO v4 support in strace, the (very
> lightly tested) patch below could be used as a starting point. Please
> note that I'm not familiar with the strace code base.
Thanks, see my comments below.
> Best regards,
>
> Bart.
>
> [PATCH] scsi: Add bsg support
>
> The Linux kernel supports two different versions of the SG_IO API,
> namely v3 and v4. This patch adds support for version 4 of this API.
> At least the sg3_utils package supports version 4 of this API. Version
> 4 of this API is used if /dev/bsg/H:C:I:L is used as device name.
> ---
> scsi.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 105 insertions(+), 7 deletions(-)
>
> diff --git a/scsi.c b/scsi.c
> index daf7252..cbc8d7a 100644
> --- a/scsi.c
> +++ b/scsi.c
> @@ -32,6 +32,7 @@
>
> # include <sys/ioctl.h>
> # include <scsi/sg.h>
> +# include <linux/bsg.h>
We usually wrap new linux kernel includes in ifdefs:
#ifdef HAVE_LINUX_BSG_H
# include <linux/bsg.h>
#endif
> #include "xlat/sg_io_dxfer_direction.h"
>
> @@ -59,9 +60,8 @@ print_sg_io_buffer(struct tcb *tcp, unsigned char *addr, const unsigned int len)
> }
>
> static void
> -print_sg_io_req(struct tcb *tcp, struct sg_io_hdr *sg_io)
> +print_sg_io_v3_req(struct tcb *tcp, struct sg_io_hdr *sg_io)
> {
> - tprintf("{'%c', ", sg_io->interface_id);
> printxval(sg_io_dxfer_direction, sg_io->dxfer_direction,
> "SG_DXFER_???");
> tprintf(", cmd[%u]=[", sg_io->cmd_len);
> @@ -82,7 +82,7 @@ print_sg_io_req(struct tcb *tcp, struct sg_io_hdr *sg_io)
> }
>
> static void
> -print_sg_io_res(struct tcb *tcp, struct sg_io_hdr *sg_io)
> +print_sg_io_v3_res(struct tcb *tcp, struct sg_io_hdr *sg_io)
> {
> if (sg_io->dxfer_direction == SG_DXFER_FROM_DEV ||
> sg_io->dxfer_direction == SG_DXFER_TO_FROM_DEV) {
> @@ -102,26 +102,124 @@ print_sg_io_res(struct tcb *tcp, struct sg_io_hdr *sg_io)
> tprintf("info=%#x}", sg_io->info);
> }
>
> +static void
> +print_sg_io_v4_req(struct tcb *tcp, struct sg_io_v4 *sg_io)
> +{
> + static const struct xlat sgv4_prot[] = {
> + { BSG_PROTOCOL_SCSI, "BSG_PROTOCOL_SCSI" },
> + };
> + static const struct xlat sgv4_subpr[] = {
> + { BSG_SUB_PROTOCOL_SCSI_CMD, "BSG_SUB_PROTOCOL_SCSI_CMD" },
> + { BSG_SUB_PROTOCOL_SCSI_TMF, "BSG_SUB_PROTOCOL_SCSI_TMF" },
> + { BSG_SUB_PROTOCOL_SCSI_TRANSPORT,
> + "BSG_SUB_PROTOCOL_SCSI_TRANSPORT" },
> + };
We no longer add xlat structures directly into .c source files.
Instead, there are xlat/*.in files that are automatically converted in
xlat/*.h files that in turn are included by .c files. You can see
examples in the file you are patching.
> +static void
> +print_sg_io_req(struct tcb *tcp, struct sg_io_hdr *sg_io)
> +{
> + tprintf("{'%c', ", sg_io->interface_id);
> + switch (sg_io->interface_id) {
> + case 'S':
> + print_sg_io_v3_req(tcp, sg_io);
> + break;
> + case 'Q':
> + print_sg_io_v4_req(tcp, (void *)sg_io);
> + break;
> + }
> +}
> +
> +static void
> +print_sg_io_res(struct tcb *tcp, struct sg_io_hdr *sg_io)
> +{
> + switch (sg_io->interface_id) {
> + case 'S':
> + print_sg_io_v3_res(tcp, sg_io);
> + break;
> + case 'Q':
> + print_sg_io_v4_res(tcp, (void *)sg_io);
> + break;
> + }
> +}
It's usually better to pass a pointer to a union rather than to pass
a pointer to a struct and then cast it to another struct.
> +
> int
> scsi_ioctl(struct tcb *tcp, const unsigned int code, long arg)
> {
> switch (code) {
> case SG_IO:
> if (entering(tcp)) {
> - struct sg_io_hdr sg_io;
> + union {
> + struct sg_io_hdr sg_io_v3;
> + struct sg_io_v4 sg_io_v4;
> + } sg_io;
>
> if (umove(tcp, arg, &sg_io) < 0)
> tprintf(", %#lx", arg);
This code is unconditionally trying to fetch sg_io_v4 (which is noticeably
larger than sg_io_v3), so if the structure passed to this syscall is
sg_io_v3, there is a change that this umove call would fail.
I'd probably start with fetching only sg_io_v3, check whether it's
actually sg_io_v3 or sg_io_v4, and fetch remaining bytes if it happened
to be sg_io_v4.
--
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20150123/830c0600/attachment.bin>
More information about the Strace-devel
mailing list