-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmtst.go
473 lines (425 loc) · 11.2 KB
/
mtst.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
package mtio
import "bytes"
//MtGet is structure for MTIOCGET - mag tape get status command
type MtGet struct {
// Type of magtape device
Type int64
// Residual count: (not sure)
// number of bytes ignored, or
// number of files not skipped, or
// number of records not skipped
ResID int64
// The following registers are device dependent
// Status register
DsReg int64
// Generic (device independent) status
GStat int64
// Error register
ErReg int64
// The next two fields are not always used
// Current file number
FileNo int32
// Current block number
BlkNo int32
}
//MtOp is structure for MTIOCTOP - magnetic tape operation command
type MtOp struct {
// Operation ID
op int16
// Padding to match C structures
Pad int16
// Operation count
count int32
}
//MtPos is structure for MTIOCPOS - mag tape get position command
type MtPos struct {
//BlkNo Current block number
BlkNo int64
}
const (
// MTIO ioctl commands
//MTIOCTOP do a mag tape op
MTIOCTOP = 0x40086d01
//MTIOCGET get tape status
MTIOCGET = 0x80306d02
//MTIOCPOS get tape position
MTIOCPOS = 0x80086d03
//Magnetic Tape operations [Not all operations supported by all drivers]
//MTRESET +reset drive in case of problems
MTRESET = 0
//MTFSF Forward space over FileMark, position at first record of next file
MTFSF = 1
//MTBSF Backward space FileMark (position before FM)
MTBSF = 2
//MTFSR Forward space record
MTFSR = 3
//MTBSR Backward space record
MTBSR = 4
//MTWEOF Write an end-of-file record (mark)
MTWEOF = 5
//MTREW Rewind
MTREW = 6
//MTOFFL Rewind and put the drive offline (eject?)
MTOFFL = 7
//MTNOP No op, set status only (read with MTIOCGET)
MTNOP = 8
//MTRETEN Retension tape
MTRETEN = 9
//MTBSFM +backward space FileMark, position at FM
MTBSFM = 10
//MTFSFM +forward space FileMark, position at FM
MTFSFM = 11
//MTEOM Goto end of recorded media (for appending files)
//MTEOM positions after the last FM, ready for appending another file
MTEOM = 12
//MTERASE Erase tape -- be careful!
MTERASE = 13
//MTRAS1 Run self test 1 (nondestructive)
MTRAS1 = 14
//MTRAS2 Run self test 2 (destructive)
MTRAS2 = 15
//MTRAS3 Reserved for self test 3
MTRAS3 = 16
//MTSETBLK Set block length (SCSI)
MTSETBLK = 20
//MTSETDENSITY Set tape density (SCSI)
MTSETDENSITY = 21
//MTSEEK Seek to block (Tandberg, etc.)
MTSEEK = 22
//MTTELL Tell block (Tandberg, etc.)
MTTELL = 23
//MTSETDRVBUFFER Set the drive buffering according to SCSI-2
//Ordinary buffered operation with code 1
MTSETDRVBUFFER = 24
//MTFSS Space forward over setmarks
MTFSS = 25
//MTBSS Space backward over setmarks
MTBSS = 26
//MTWSM Write setmarks
MTWSM = 27
//MTLOCK Lock the drive door
MTLOCK = 28
//MTUNLOCK Unlock the drive door
MTUNLOCK = 29
//MTLOAD Execute the SCSI load command
MTLOAD = 30
//MTUNLOAD Execute the SCSI unload command
MTUNLOAD = 31
//MTCOMPRESSION Control compression with SCSI mode page 15
MTCOMPRESSION = 32
//MTSETPART Change the active tape partition
MTSETPART = 33
//MTMKPART Format the tape with one or two partitions
MTMKPART = 34
//Constants for mt_type. Not all of these are supported, and
//these are not all of the ones that are supported.
//MTISUNKNOWN unknown
MTISUNKNOWN = 0x01
//MTISQIC02 Generic QIC-02 tape streamer
MTISQIC02 = 0x02
//MTISWT5150 Wangtek 5150EQ, QIC-150, QIC-02
MTISWT5150 = 0x03
//MTISARCHIVE5945L2 Archive 5945L-2, QIC-24, QIC-02?
MTISARCHIVE5945L2 = 0x04
//MTISCMSJ500 CMS Jumbo 500 (QIC-02?)
MTISCMSJ500 = 0x05
//MTISTDC3610 Tandberg 6310, QIC-24
MTISTDC3610 = 0x06
//MTISARCHIVEVP60I Archive VP60i, QIC-02
MTISARCHIVEVP60I = 0x07
//MTISARCHIVE2150L Archive Viper 2150L
MTISARCHIVE2150L = 0x08
//MTISARCHIVE2060L Archive Viper 2060L
MTISARCHIVE2060L = 0x09
//MTISARCHIVESC499 Archive SC-499 QIC-36 controller
MTISARCHIVESC499 = 0x0A
//MTISQIC02ALLFEATURES Generic QIC-02 with all features
MTISQIC02ALLFEATURES = 0x0F
//MTISWT5099EEN24 Wangtek 5099-een24, 60MB, QIC-24
MTISWT5099EEN24 = 0x11
//MTISTEACMT2ST Teac MT-2ST 155mb drive, Teac DC-1 card (Wangtek type)
MTISTEACMT2ST = 0x12
//MTISEVEREXFT40A Everex FT40A (QIC-40)
MTISEVEREXFT40A = 0x32
//MTISDDS1 DDS device without partitions
MTISDDS1 = 0x51
//MTISDDS2 DDS device with partitions
MTISDDS2 = 0x52
//MTISONSTREAMSC OnStream SCSI tape drives (SC-x0) and SCSI emulated (DI, DP, USB)
MTISONSTREAMSC = 0x61
//MTISSCSI1 Generic ANSI SCSI-1 tape unit
MTISSCSI1 = 0x71
//MTISSCSI2 Generic ANSI SCSI-2 tape unit
MTISSCSI2 = 0x72
//MTISFTAPEFLAG QIC-40/80/3010/3020 ftape supported drives
//20bit vendor ID + 0x800000 (see vendors.h in ftape distribution)
MTISFTAPEFLAG = 0x800000
//SCSI-tape specific definitions
//Bitfield shifts in the status
//MTSTBLKSIZESHIFT blocksize shift
MTSTBLKSIZESHIFT = 0
//MTSTBLKSIZEMASK blocksize mask
MTSTBLKSIZEMASK = 0xffffff
//MTSTDENSITYSHIFT density shift
MTSTDENSITYSHIFT = 24
//MTSTDENSITYMASK density mask
MTSTDENSITYMASK = 0xff000000
//MTSTSOFTERRSHIFT soft error shift
MTSTSOFTERRSHIFT = 0
//MTSTSOFTERRMASK soft error mask
MTSTSOFTERRMASK = 0xffff
//Bitfields for the MTSETDRVBUFFER ioctl
//MTSTOPTIONS MTSETDRVBUFFER options
MTSTOPTIONS = 0xf0000000
//MTSTBOOLEANS MTSETDRVBUFFER booleans
MTSTBOOLEANS = 0x10000000
//MTSTSETBOOLEANS MTSETDRVBUFFER set booleans
MTSTSETBOOLEANS = 0x30000000
//MTSTCLEARBOOLEANS MTSETDRVBUFFER clear booleans
MTSTCLEARBOOLEANS = 0x40000000
//MTSTWRITETHRESHOLD MTSETDRVBUFFER write threshold
MTSTWRITETHRESHOLD = 0x20000000
//MTSTDEFBLKSIZE MTSETDRVBUFFER default blocksize
MTSTDEFBLKSIZE = 0x50000000
//MTSTDEFOPTIONS MTSETDRVBUFFER default options
MTSTDEFOPTIONS = 0x60000000
//MTSTTIMEOUTS timeouts
MTSTTIMEOUTS = 0x70000000
//MTSTSETTIMEOUT set timeout
MTSTSETTIMEOUT = (MTSTTIMEOUTS | 0x000000)
//MTSTSETLONGTIMEOUT set long timeout
MTSTSETLONGTIMEOUT = (MTSTTIMEOUTS | 0x100000)
//MTSTSETCLN set cln
MTSTSETCLN = 0x80000000
//MTSTBUFFERWRITES buffered writes
MTSTBUFFERWRITES = 0x1
//MTSTASYNCWRITES async writes
MTSTASYNCWRITES = 0x2
//MTSTREADAHEAD read ahead
MTSTREADAHEAD = 0x4
//MTSTDEBUGGING debugging
MTSTDEBUGGING = 0x8
//MTSTTWOFM write two filemarks
MTSTTWOFM = 0x10
//MTSTFASTMTEOM send MTEOM directly to drive
MTSTFASTMTEOM = 0x20
//MTSTAUTOLOCK auto lock
MTSTAUTOLOCK = 0x40
//MTSTDEFWRITES apply settings to drive defaults
MTSTDEFWRITES = 0x80
//MTSTCANBSR correct readahaead backspace position
MTSTCANBSR = 0x100
//MTSTNOBLKLIMS dont use READ BLOCK LIMITS
MTSTNOBLKLIMS = 0x200
//MTSTCANPARTITIONS enable partitions
MTSTCANPARTITIONS = 0x400
//MTSTSCSI2LOGICAL use logical block addresses
MTSTSCSI2LOGICAL = 0x800
//MTSTSYSV sysv
MTSTSYSV = 0x1000
//MTSTNOWAIT no wait
MTSTNOWAIT = 0x2000
//MTSTSILI SILI
MTSTSILI = 0x4000
//The mode parameters to be controlled
//Parameter chosen with bits 20-28
//MTSTCLEARDEFAULT clear default
MTSTCLEARDEFAULT = 0xfffff
//MTSTDEFDENSITY default density
MTSTDEFDENSITY = (MTSTDEFOPTIONS | 0x100000)
//MTSTDEFCOMPRESSION default compression
MTSTDEFCOMPRESSION = (MTSTDEFOPTIONS | 0x200000)
//MTSTDEFDRVBUFFER default buffering
MTSTDEFDRVBUFFER = (MTSTDEFOPTIONS | 0x300000)
//MTSTHPLOADEROFFSET arguments for the special HP changer load command
MTSTHPLOADEROFFSET = 10000
)
//MtTypeToString converts type to string
func MtTypeToString(t int64) string {
switch t {
case MTISUNKNOWN:
return "Unknown type of tape device"
case MTISQIC02:
return "Generic QIC-02 tape streamer"
case MTISWT5150:
return "Wangtek 5150, QIC-150"
case MTISARCHIVE5945L2:
return "Archive 5945L-2"
case MTISCMSJ500:
return "CMS Jumbo 500"
case MTISTDC3610:
return "Tandberg TDC 3610, QIC-24"
case MTISARCHIVEVP60I:
return "Archive VP60i, QIC-02"
case MTISARCHIVE2150L:
return "Archive Viper 2150L"
case MTISARCHIVE2060L:
return "Archive Viper 2060L"
case MTISARCHIVESC499:
return "Archive SC-499 QIC-36 controller"
case MTISQIC02ALLFEATURES:
return "Generic QIC-02 tape, all features"
case MTISWT5099EEN24:
return "Wangtek 5099-een24, 60MB"
case MTISTEACMT2ST:
return "Teac MT-2ST 155mb data cassette drive"
case MTISEVEREXFT40A:
return "Everex FT40A, QIC-40"
case MTISDDS1:
return "DDS device without partitions"
case MTISDDS2:
return "DDS device with partitions"
case MTISSCSI1:
return "Generic SCSI-1 tape"
case MTISSCSI2:
return "Generic SCSI-2 tape"
}
return "invalid type"
}
//IsEOF GStat reports EOF
func IsEOF(s int64) bool {
return s&0x80000000 != 0
}
//IsBOT GStat reports BOT
func IsBOT(s int64) bool {
return s&0x40000000 != 0
}
//IsEOT GStat reports EOT
func IsEOT(s int64) bool {
return s&0x20000000 != 0
}
//IsSM GStat reports DDS setmark
func IsSM(s int64) bool {
return s&0x10000000 != 0
}
//IsEOD GStat reports DDS EOD
func IsEOD(s int64) bool {
return s&0x08000000 != 0
}
//IsWrProt GStat reports write protected
func IsWrProt(s int64) bool {
return s&0x04000000 != 0
}
//IsOnline GStat reports online
func IsOnline(s int64) bool {
return s&0x01000000 != 0
}
//IsD6250 GStat reports D_6250
func IsD6250(s int64) bool {
return s&0x00800000 != 0
}
//IsD1600 GStat reports D_1600
func IsD1600(s int64) bool {
return s&0x00400000 != 0
}
//IsD800 GStat reports D_800
func IsD800(s int64) bool {
return s&0x00200000 != 0
}
//IsDrOpen GStat reports Door open
func IsDrOpen(s int64) bool {
return s&0x00040000 != 0
}
//IsImRepEn GStat reports Immediate report mode
func IsImRepEn(s int64) bool {
return s&0x00010000 != 0
}
//IsCln GStat reports Cleaning requested
func IsCln(s int64) bool {
return s&0x00008000 != 0
}
func appendBuf(b *bytes.Buffer, s string) error {
if b.Len() == 0 {
_, err := b.WriteString(s)
return err
}
_, err := b.WriteString(" ")
if err != nil {
return err
}
_, err = b.WriteString(s)
return err
}
//MtStatusToString convert status to string with enabled options listed
func MtStatusToString(s int64) string {
var b bytes.Buffer
if IsEOF(s) {
err := appendBuf(&b, "EOF")
if err != nil {
return "Internal Error " + err.Error()
}
}
if IsBOT(s) {
err := appendBuf(&b, "BOT")
if err != nil {
return "Internal Error " + err.Error()
}
}
if IsEOT(s) {
err := appendBuf(&b, "EOT")
if err != nil {
return "Internal Error " + err.Error()
}
}
if IsSM(s) {
err := appendBuf(&b, "SM")
if err != nil {
return "Internal Error " + err.Error()
}
}
if IsEOD(s) {
err := appendBuf(&b, "EOD")
if err != nil {
return "Internal Error " + err.Error()
}
}
if IsWrProt(s) {
err := appendBuf(&b, "WR_PROT")
if err != nil {
return "Internal Error " + err.Error()
}
}
if IsOnline(s) {
err := appendBuf(&b, "ONLINE")
if err != nil {
return "Internal Error " + err.Error()
}
}
if IsD6250(s) {
err := appendBuf(&b, "D_6250")
if err != nil {
return "Internal Error " + err.Error()
}
}
if IsD1600(s) {
err := appendBuf(&b, "D_1600")
if err != nil {
return "Internal Error " + err.Error()
}
}
if IsD800(s) {
err := appendBuf(&b, "D_800")
if err != nil {
return "Internal Error " + err.Error()
}
}
if IsDrOpen(s) {
err := appendBuf(&b, "DR_OPEN")
if err != nil {
return "Internal Error " + err.Error()
}
}
if IsImRepEn(s) {
err := appendBuf(&b, "IM_REP_EN")
if err != nil {
return "Internal Error " + err.Error()
}
}
if IsCln(s) {
err := appendBuf(&b, "CLN")
if err != nil {
return "Internal Error " + err.Error()
}
}
return b.String()
}