Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
dCache
cta
Commits
b6ec11f7
Commit
b6ec11f7
authored
Aug 02, 2013
by
Victor Kotlyar
Browse files
added implementation for getPositionInfo
We use READ POSTION command with data replay in SHORT FORM. Tested with mhvtl.
parent
ecf6d814
Changes
3
Hide whitespace changes
Inline
Side-by-side
Drive/Drive.hh
View file @
b6ec11f7
...
...
@@ -63,6 +63,7 @@ namespace Tape {
* Returned by getPositionInfo()
*/
class
positionInfo
{
public:
uint32_t
currentPosition
;
uint32_t
oldestDirtyObject
;
uint32_t
dirtyObjectsCount
;
...
...
@@ -193,7 +194,39 @@ namespace Tape {
* @return positionInfo class. This contains the logical position, plus information
* on the dirty data still in the write buffer.
*/
virtual
positionInfo
getPositionInfo
()
throw
(
Exception
)
{
throw
Exception
(
"Not implemented"
);
}
virtual
positionInfo
getPositionInfo
()
throw
(
Exception
)
{
SCSI
::
Structures
::
readPositionCDB_t
cdb
;
SCSI
::
Structures
::
readPositionDataShortForm_t
positionData
;
SCSI
::
Structures
::
senseData_t
<
255
>
senseBuff
;
SCSI
::
Structures
::
LinuxSGIO_t
sgh
;
positionInfo
posInfo
;
sgh
.
setCDB
(
&
cdb
);
sgh
.
setDataBuffer
(
&
positionData
);
sgh
.
setSenseBuffer
(
&
senseBuff
);
sgh
.
dxfer_direction
=
SG_DXFER_FROM_DEV
;
/* Manage both system error and SCSI errors. */
if
(
-
1
==
m_sysWrapper
.
ioctl
(
m_tapeFD
,
SG_IO
,
&
sgh
))
throw
Tape
::
Exceptions
::
Errnum
(
"Failed SG_IO ioctl"
);
if
(
SCSI
::
Status
::
GOOD
!=
sgh
.
status
)
throw
Tape
::
Exception
(
std
::
string
(
"SCSI error in getPositionInfo: "
)
+
SCSI
::
statusToString
(
sgh
.
status
));
if
(
0
==
positionData
.
PERR
)
{
// Location fields are valid
posInfo
.
currentPosition
=
SCSI
::
Structures
::
toU32
(
positionData
.
firstBlockLocation
);
posInfo
.
oldestDirtyObject
=
SCSI
::
Structures
::
toU32
(
positionData
.
lastBlockLocation
);
posInfo
.
dirtyObjectsCount
=
SCSI
::
Structures
::
toU32
(
positionData
.
blocksInBuffer
);
posInfo
.
dirtyBytesCount
=
SCSI
::
Structures
::
toU32
(
positionData
.
bytesInBuffer
);
}
else
{
posInfo
.
currentPosition
=
0
;
posInfo
.
oldestDirtyObject
=
0
;
posInfo
.
dirtyObjectsCount
=
0
;
posInfo
.
dirtyBytesCount
=
0
;
}
return
posInfo
;
}
/**
* Get tape alert information from the drive. There is a quite long list of possible tape alerts.
...
...
SCSI/Structures.hh
View file @
b6ec11f7
...
...
@@ -106,6 +106,21 @@ namespace SCSI {
return
ntohl
(
*
((
uint32_t
*
)
t
));
}
/**
* Helper function to deal with endianness.
* for 3 bytes! fields in SCSI replies
* @param t byte array in SCSI order representing a 32 bits number
* @return
*/
inline
uint32_t
toU32
(
const
unsigned
char
(
&
t
)[
3
])
{
unsigned
char
tmp
[
4
];
tmp
[
0
]
=
0
;
tmp
[
1
]
=
t
[
0
];
tmp
[
2
]
=
t
[
1
];
tmp
[
3
]
=
t
[
2
];
/* Like network, SCSI is BigEndian */
return
ntohl
(
*
((
uint32_t
*
)
tmp
));
}
/**
* Helper function to deal with endianness.
* for signed values
...
...
@@ -241,6 +256,71 @@ namespace SCSI {
unsigned
char
control
;
// Control byte
};
/*
* READ POSITION CDB as described in SSC-3.
*/
class
readPositionCDB_t
{
public:
readPositionCDB_t
()
{
zeroStruct
(
this
);
opCode
=
SCSI
::
Commands
::
READ_POSITION
;
}
// byte 0
unsigned
char
opCode
;
// OPERATION CODE (34h)
// byte 1
// *note* for T10000 we have BT:1, LONG:1, TCLP:1, Reserved:5
unsigned
char
serviceAction
:
5
;
// Service action to choice FORM
unsigned
char
:
3
;
// Reserved
// bytes 2-6
unsigned
char
reserved
[
5
];
// Reserved
// bytes 7-8
unsigned
char
allocationLenght
[
2
]
;
// used for EXTENDENT FORM
// byte 9
unsigned
char
control
;
// Control byte
};
/*
* READ POSITION data format, short form as described in SSC-3.
*/
class
readPositionDataShortForm_t
{
public:
readPositionDataShortForm_t
()
{
zeroStruct
(
this
);
}
// byte 0
unsigned
char
BPEW
:
1
;
// Beyond Programmable Early Warning
unsigned
char
PERR
:
1
;
// Position ERroR
unsigned
char
LOLU
:
1
;
// Logical Object Location Unknown or Block Position Unknown(BPU) for T10000
unsigned
char
:
1
;
// Reserved
unsigned
char
BYCU
:
1
;
// BYte Count Unknown
unsigned
char
LOCU
:
1
;
// Logical Object Count Unknown or Block Count Unknown(BCU) for T10000
unsigned
char
EOP
:
1
;
// End Of Partition
unsigned
char
BOP
:
1
;
// Beginning of Partition
// byte 1
unsigned
char
partitionNumber
;
// Service action to choice FORM
// bytes 2-3
unsigned
char
reserved
[
2
];
// Reserved
// bytes 4-7
unsigned
char
firstBlockLocation
[
4
];
// First Logical object location in SSC3,IBM,LTO
// bytes 8-11
unsigned
char
lastBlockLocation
[
4
];
// Last Logical object location in SSC3,IBM,LTO
// byte 12
unsigned
char
:
8
;
// Reserved
// bytes 13-15
unsigned
char
blocksInBuffer
[
3
];
// Number of logical objects in object buffer
// bytes 16-19
unsigned
char
bytesInBuffer
[
4
];
// Number if bytes in object buffer
};
/*
* LOG SELECT CDB as described in SPC-4.
*/
...
...
SCSI/StructuresTest.cc
View file @
b6ec11f7
...
...
@@ -258,6 +258,87 @@ namespace UnitTests {
ASSERT_EQ
(
0xBC
,
locate10CDB
.
control
);
}
TEST
(
SCSI_Structures
,
readPositionCDB_t
)
{
SCSI
::
Structures
::
readPositionCDB_t
readPositionCDB
;
unsigned
char
*
buff
=
(
unsigned
char
*
)
&
readPositionCDB
;
/*
* Make sure this struct is a POD (plain old data without virtual table)
* (and has the right size).
*/
ASSERT_EQ
(
10
,
sizeof
(
readPositionCDB
));
/* Check proper initialization an location of struct members match
the bit/byte locations defined in SPC-4 */
ASSERT_EQ
(
SCSI
::
Commands
::
READ_POSITION
,
readPositionCDB
.
opCode
);
buff
[
0
]
=
0xAB
;
ASSERT_EQ
(
0xAB
,
readPositionCDB
.
opCode
);
ASSERT_EQ
(
0
,
readPositionCDB
.
serviceAction
);
buff
[
1
]
|=
(
0x15
&
0xFF
)
<<
0
;
ASSERT_EQ
(
0x15
,
readPositionCDB
.
serviceAction
);
buff
[
2
]
|=
0xFF
;
buff
[
3
]
=
0xFF
;
buff
[
4
]
=
0xFF
;
buff
[
5
]
=
0xFF
;
buff
[
6
]
=
0xFF
;
ASSERT_EQ
(
0
,
SCSI
::
Structures
::
toU16
(
readPositionCDB
.
allocationLenght
));
buff
[
7
]
|=
0x0A
;
buff
[
8
]
|=
0xBC
;
ASSERT_EQ
(
0x0ABC
,
SCSI
::
Structures
::
toU16
(
readPositionCDB
.
allocationLenght
));
ASSERT_EQ
(
0
,
readPositionCDB
.
control
);
buff
[
9
]
|=
0xBC
;
ASSERT_EQ
(
0xBC
,
readPositionCDB
.
control
);
}
TEST
(
SCSI_Structures
,
readPositionDataShortForm_t
)
{
SCSI
::
Structures
::
readPositionDataShortForm_t
readPositionData
;
unsigned
char
*
buff
=
(
unsigned
char
*
)
&
readPositionData
;
ASSERT_EQ
(
20
,
sizeof
(
readPositionData
));
ASSERT_EQ
(
0
,
readPositionData
.
BPEW
);
buff
[
0
]
|=
(
0x1
&
0xFF
)
<<
0
;
ASSERT_EQ
(
0x1
,
readPositionData
.
BPEW
);
ASSERT_EQ
(
0
,
readPositionData
.
PERR
);
buff
[
0
]
|=
(
0x2
&
0xFF
)
<<
0
;
ASSERT_EQ
(
0x1
,
readPositionData
.
PERR
);
ASSERT_EQ
(
0
,
readPositionData
.
LOLU
);
buff
[
0
]
|=
(
0x4
&
0xFF
)
<<
0
;
ASSERT_EQ
(
0x1
,
readPositionData
.
LOLU
);
ASSERT_EQ
(
0
,
readPositionData
.
BYCU
);
buff
[
0
]
|=
(
0x10
&
0xFF
)
<<
0
;
ASSERT_EQ
(
0x1
,
readPositionData
.
BYCU
);
ASSERT_EQ
(
0
,
readPositionData
.
LOCU
);
buff
[
0
]
|=
(
0x20
&
0xFF
)
<<
0
;
ASSERT_EQ
(
0x1
,
readPositionData
.
LOCU
);
ASSERT_EQ
(
0
,
readPositionData
.
EOP
);
buff
[
0
]
|=
(
0x40
&
0xFF
)
<<
0
;
ASSERT_EQ
(
0x1
,
readPositionData
.
EOP
);
ASSERT_EQ
(
0
,
readPositionData
.
BOP
);
buff
[
0
]
|=
(
0x80
&
0xFF
)
<<
0
;
ASSERT_EQ
(
0x1
,
readPositionData
.
BOP
);
ASSERT_EQ
(
0
,
readPositionData
.
partitionNumber
);
buff
[
1
]
|=
0xBC
;
ASSERT_EQ
(
0xBC
,
readPositionData
.
partitionNumber
);
buff
[
2
]
|=
0xFF
;
buff
[
3
]
=
0xFF
;
ASSERT_EQ
(
0
,
SCSI
::
Structures
::
toU32
(
readPositionData
.
firstBlockLocation
));
buff
[
4
]
|=
0x0A
;
buff
[
5
]
|=
0xBC
;
buff
[
6
]
|=
0xDE
;
buff
[
7
]
|=
0xF0
;
ASSERT_EQ
(
0x0ABCDEF0
,
SCSI
::
Structures
::
toU32
(
readPositionData
.
firstBlockLocation
));
ASSERT_EQ
(
0
,
SCSI
::
Structures
::
toU32
(
readPositionData
.
lastBlockLocation
));
buff
[
8
]
|=
0x9A
;
buff
[
9
]
|=
0xBC
;
buff
[
10
]
|=
0xDE
;
buff
[
11
]
|=
0xF9
;
ASSERT_EQ
(
0x9ABCDEF9
,
SCSI
::
Structures
::
toU32
(
readPositionData
.
lastBlockLocation
));
buff
[
12
]
|=
0xFF
;
ASSERT_EQ
(
0
,
SCSI
::
Structures
::
toU32
(
readPositionData
.
blocksInBuffer
));
buff
[
13
]
|=
0x9A
;
buff
[
14
]
|=
0xBC
;
buff
[
15
]
|=
0xDE
;
ASSERT_EQ
(
0x009ABCDE
,
SCSI
::
Structures
::
toU32
(
readPositionData
.
blocksInBuffer
));
ASSERT_EQ
(
0
,
SCSI
::
Structures
::
toU32
(
readPositionData
.
bytesInBuffer
));
buff
[
16
]
|=
0x7A
;
buff
[
17
]
|=
0xBC
;
buff
[
18
]
|=
0xDE
;
buff
[
19
]
|=
0xF7
;
ASSERT_EQ
(
0x7ABCDEF7
,
SCSI
::
Structures
::
toU32
(
readPositionData
.
bytesInBuffer
));
}
TEST
(
SCSI_Structures
,
tapeAlertLogPage_t_and_parameters
)
{
SCSI
::
Structures
::
tapeAlertLogPage_t
<
12
>
tal
;
unsigned
char
*
buff
=
(
unsigned
char
*
)
&
tal
;
...
...
@@ -354,6 +435,11 @@ namespace UnitTests {
ASSERT_EQ
(
0x1020304
,
SCSI
::
Structures
::
toU32
(
num
));
}
TEST
(
SCSI_Structures
,
toU32_3byte
)
{
unsigned
char
num
[
3
]
=
{
0xAA
,
0xBB
,
0xCC
};
ASSERT_EQ
(
0x00AABBCC
,
SCSI
::
Structures
::
toU32
(
num
));
}
TEST
(
SCSI_Structures
,
toS32
)
{
unsigned
char
num
[
4
]
=
{
0xE6
,
0x29
,
0x66
,
0x5B
};
ASSERT_EQ
(
-
433494437
,
SCSI
::
Structures
::
toS32
(
num
));
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment