Skip to content

uiscsi/tapesim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tapesim

An in-memory SSC-3 tape drive simulation library for Go.

Status: Standalone module with 46 unit tests under race detector. Used by uiscsi-tape mock target and the upcoming TCMU tape handler.

Overview

tapesim encapsulates all tape state -- position, filemarks, block size, EOM enforcement, density, compression, and error injection -- in a single Media type. It exposes operations matching SSC-3 semantics so that both the mock iSCSI target and the TCMU handler can delegate tape logic to a shared, independently tested implementation.

tapesim is stdlib-only and has no external dependencies.

Features

  • SSC-3 tape operations -- Read, Write, WriteFilemarks, Space, Rewind, ReadPosition
  • Two-tier EOM -- early warning past configurable threshold, hard VOLUME OVERFLOW at media boundary
  • Filemark handling -- SPACE positions at filemark (non-consuming per SSC-3), Read detects and consumes
  • SPACE codes -- blocks, filemarks, end-of-data, with forward/backward and boundary clamping
  • Fixed and variable block modes -- configurable via SetBlockSize
  • Compression state -- DCE/DDE flags for MODE SENSE/SELECT support
  • Sense data encoding -- SenseInfo with EncodeFixedSense (18-byte fixed-format, response code 0x70)
  • Error injection -- per-opcode FIFO queues for deterministic fault testing (InjectError, InjectShortRead, InjectFilemark)
  • Unit attention -- optional consume-once UA for TCMU handler use
  • Functional options -- NewMedia constructor with WithEOMThreshold, WithBlockSize, WithDensityCode, WithUnitAttention
  • No external dependencies -- stdlib only

Usage

import "github.com/uiscsi/tapesim"

// Create a 1 GB tape media with 90% EOM threshold (default).
m := tapesim.NewMedia(1<<30)

// Write data.
data := []byte("hello tape")
n, sense := m.Write(data, false) // variable mode
if sense != nil {
    // Handle EOM warning or volume overflow.
}

// Rewind and read back.
m.Rewind()
buf := make([]byte, 1024)
n, sense = m.Read(buf, false)

// Write a filemark and space to it.
m.WriteFilemarks(1)
m.Rewind()
sense = m.Space(0x01, 1) // SPACE FILEMARKS forward 1

// Encode sense data for SCSI response.
si := &tapesim.SenseInfo{Key: 0x00, FM: true, ASC: 0x00, ASCQ: 0x01}
senseBytes := tapesim.EncodeFixedSense(si)

API

Type / Function Description
NewMedia(size, ...Option) Create tape media with functional options
Media.Read(buf, fixed) Read from current position
Media.Write(data, fixed) Write at current position
Media.WriteFilemarks(count) Record filemarks
Media.Space(code, count) Position by blocks, filemarks, or end-of-data
Media.Rewind() Reset position to beginning
Media.ReadPosition() Current position with BOP/EOP flags
Media.BlockSize() / SetBlockSize() Fixed vs variable block mode
Media.BlockLimits() Min/max block size
Media.Compression() / SetCompression() DCE/DDE state
Media.InjectError(op, key, asc, ascq) Queue a sense error for testing
Media.InjectShortRead(op, len) Queue a short read for testing
Media.InjectFilemark(pos) Insert a filemark at position
DecodeSPACECount(cdb2, cdb3, cdb4) Sign-extend 24-bit SPACE count
EncodeFixedSense(si) Encode SenseInfo to 18-byte fixed format

Testing

go test -race ./...

Requirements

  • Go 1.25+

License

GNU General Public License v3.0 -- see LICENSE.

Related Projects

  • uiscsi -- pure-userspace iSCSI initiator library
  • uiscsi-tape -- SSC tape driver over iSCSI
  • tapeplayer -- TUI FLAC audio player for iSCSI tape drives
  • go-tcmu -- Go bindings for Linux TCMU (target core user)

About

SSC-3 tape drive simulation library

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages