Bug 468040 - sg_map26 works incorrectly when there are > 32 tape drives
Summary: sg_map26 works incorrectly when there are > 32 tape drives
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: sg3_utils
Version: 5.4
Hardware: All
OS: Linux
medium
medium
Target Milestone: rc
: ---
Assignee: Dan Horák
QA Contact: BaseOS QE
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2008-10-22 14:42 UTC by Alex Sidorenko
Modified: 2013-06-17 08:17 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2009-09-02 11:23:32 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2009:1357 0 normal SHIPPED_LIVE sg3_utils bug fix and enhancement update 2009-09-01 10:51:52 UTC

Description Alex Sidorenko 2008-10-22 14:42:48 UTC
Description of problem:

sg_map26 maps incorrectly tape drives with number >= 32

Version-Release number of selected component (if applicable):

All versions - the bug was present even in the latest upstream version, I contacted an upstream developer and he has provided a fix

How reproducible:


Steps to Reproduce:

1. 
(if you do not have a real host with > 32 tape drives)

# mknod /dev/nst32 c 9 384
# ls -l /dev/nst*
 crw-r--r-- 1 root root 9, 128 2008-10-08 09:42 /dev/nst0
 crw-r--r-- 1 root root 9, 384 2008-10-08 09:38 /dev/nst32

2. 
# sg_map26  -r 3 /dev/nst0
# /sys/class/scsi_tape/st0
# sg_map26  -r 3 /dev/nst32
 /sys/class/scsi_tape/st0
  
Actual results:

nst32 is mapped to st0

Expected results:

it should be mapped to st32

Analysis
========

2.6 kernels scatter the tape number between two bit ranges, the minor numbers
consist of the following bit fields:

dev_upper non-rew mode dev-lower
 20 -  8     7    6 5  4      0

So /dev/nst0-nst31 have minor 128-159, but /dev/nst32 will start using bits
20-8 and its minor will be 128+256=384

In sg_map26.c the tape drive minor is decoded incorrectly, by stripping all 
high bits using the mask 0x1f:

sg_map26.c:

map_st(...) {
  <snip>
        snprintf(name, sizeof(name), "%sst%d", sys_st_dir,
                 (mi & 0x1f));

which leaves only 5 bits. As a result sprintf will produce

    /sys/class/scsi_tape/nst0

_both_ for nst0 and nst32. After that we'll output nst0 instead of nst32.

The fix
=======

I have contacted the maintainer of sg3_utils (Douglas Gilbert) and he has provided a fix.

To decode the minor properly, we now use TAPE_NR(minor) macro, similar to 
what 'st' command does (this macro was copied from kernel sources).

Please find a diff and the fixed sg_map26.c attached, as received from Douglas. The fix has been tested on a real system with > 32 tape drives

Comment 7 errata-xmlrpc 2009-09-02 11:23:32 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2009-1357.html


Note You need to log in before you can comment on or make changes to this bug.