LTFS Tapes

I wrote a post on LTO tapes some time ago. At the time I didn’t try LTFS - getting the HP tools up and running was a pain in the arse, and I wasn’t fussy about filesystem access.

I’ve since given it a go, and it’s actually not as bad as I thought it would be. This happened because I was restoring files from a tape, realised that everything just worked on Fedora 42, and figured I’d use the time to take a look around for a tape management interface. While looking, I stumbled across YATM, Yet-Another-Tape-Manager, that manages LTFS tapes. I ultimately decided I was happy enough printing labels that say what’s on the tape, rather than doing anything fancy - but looking at the scripts shipped with YATM, it didn’t look terribly difficult to get started with LTFS.

LTFS Versions

As with everything enterprise-y, there are multiple implementations of LTFS.

I chose to use the HP LTFS tools. I already knew from my previous experiments that my tape drive responds to HP’s tools, and unsurprisingly that was also the case here. However, I did need to modify a few small things to have them compile.

HPE LTFS

If you do intend to use the HP LTFS tooling linked above, on modern GNU/Linux, you’ll need to make a small change to ltfs.h.

Specifically, adding the following to deal with changes to GCC’s defaults (this is an assumption, maybe it’s a C standard thing). There may be a better way to do this:

diff --git a/ltfs/src/libltfs/ltfs.h b/ltfs/src/libltfs/ltfs.h
index e209d27..6f03663 100644
--- a/ltfs/src/libltfs/ltfs.h
+++ b/ltfs/src/libltfs/ltfs.h
@@ -72,6 +72,8 @@ extern "C" {
 #include "arch/win/win_util.h"
 #endif
 
+#define FALSE false
+#define TRUE true
 
 #include <stdio.h>
 #include <stdbool.h>

And update arch_info.c to reflect the location of the headers for GLIBC’s (deprecated) syscall interface. This will likely break at some point, hopefully HP update their code:

diff --git a/ltfs/src/libltfs/arch/arch_info.c b/ltfs/src/libltfs/arch/arch_info.c
index 179428f..0d837a8 100644
--- a/ltfs/src/libltfs/arch/arch_info.c
+++ b/ltfs/src/libltfs/arch/arch_info.c
@@ -48,7 +48,7 @@
 
 #include "libltfs/ltfs.h"
 #ifndef mingw_PLATFORM
-#include <sys/sysctl.h>
+#include <linux/sysctl.h>
 #endif
 #include <sys/types.h>
 #include <sys/stat.h>

After which configure, make, make install as usual.

Formatting Tapes

HP LTFS constitutes a number of binaries. The two we require are mkltfs and ltfs.

Formatting tapes with LTFS is done with the former:

# /dev/st0 is the SCSI tape device, -n takes a string, -s an alphanumeric, character-limited barcode
root@assam:/mnt# mkltfs -d /dev/st0 -n 'some arbitrary label' -s 'PICO27'
LTFS15000I Starting mkltfs, HPE StoreOpen Software version 3.4.2, log level 2
LTFS15041I Launched by "mkltfs -d /dev/st0 -n some arbitrary label -s PICO27"
LTFS15042I This binary is built for Linux (x86_64)
LTFS15043I GCC version is 15.1.1 20250521 (Red Hat 15.1.1-2)
LTFS17087I Kernel version: Linux version 6.15.8-200.fc42.x86_64 (mockbuild@93f30e7b946b413d81e83e0dc19ac3a8) (gcc (GCC) 15.1.1 20250521 (Red Hat 15.1.1-2), GNU ld version 2.44-5.fc42) #1 SMP PREEMPT_DYNAMIC Thu Jul 24 13:26:52 UTC 2025 i386
LTFS17089I Distribution: Fedora release 42 (Adams)
LTFS17089I Distribution: NAME="Fedora Linux"
LTFS17089I Distribution: Fedora release 42 (Adams)
LTFS17089I Distribution: Fedora release 42 (Adams)
LTFS15003I Formatting device '/dev/st0'
LTFS15004I LTFS volume blocksize: 524288
LTFS15005I Index partition placement policy: None

LTFS17085I Plugin: Loading "ltotape" driver
LTFS20013I Drive type is TANDBERG DATA LTO5, serial number is HUJ4472C93
LTFS17160I Maximum device block size is 524288
LTFS17157I Changing the drive setting to write-anywhere mode
LTFS17302W Cannot retrieve attribute (volumelockstate=0x1623)
LTFS17302W Cannot retrieve attribute (Application Vendor=0x800)
LTFS15049I Checking the medium (mount)
LTFS15010I Creating data partition b on SCSI partition 1
LTFS15011I Creating index partition a on SCSI partition 0
LTFS17165I Resetting the medium's capacity proportion
LTFS11097I Partitioning the medium
LTFS20107I Replacing existing MAM barcode A05497L5 with user-specified PICO27
LTFS20075E Failed to write attribute (-1)
LTFS20076I Triggering drive diagnostic dump
LTFS20096I Diagnostic dump complete
LTFS20024W Cannot store attribute 0x820 (-1)
LTFS11100I Writing label to partition b
LTFS11278I Writing index to partition b
LTFS11100I Writing label to partition a
LTFS11278I Writing index to partition a
LTFS15013I Volume UUID is: 8c3380e6-ad55-4b3c-a0ad-71968108e08b

LTFS15019I Volume capacity is 1335 GB
LTFS20076I Triggering drive diagnostic dump
LTFS20096I Diagnostic dump complete
LTFS15024I Medium formatted successfully

Mounting Tapes

Tapes are mounted via FUSE, using the ltfs command. You have a few options, though the only option I’ve felt the need to set is -o eject, which causes the drive to rewind and eject the tape when the tape is unmounted:

root@assam:/mnt# ltfs /mnt/TAPE -o eject
8bff LTFS14000I LTFS starting, HPE StoreOpen Software version 3.4.2, log level 2
8bff LTFS14058I LTFS Format Specification version 2.4.0
8bff LTFS14104I Launched by "ltfs /mnt/TAPE -o eject"
8bff LTFS14105I This binary is built for Linux (x86_64)
8bff LTFS14106I GCC version is 15.1.1 20250521 (Red Hat 15.1.1-2)
8bff LTFS17087I Kernel version: Linux version 6.15.8-200.fc42.x86_64 (mockbuild@93f30e7b946b413d81e83e0dc19ac3a8) (gcc (GCC) 15.1.1 20250521 (Red Hat 15.1.1-2), GNU ld version 2.44-5.fc42) #1 SMP PREEMPT_DYNAMIC Thu Jul 24 13:26:52 UTC 2025 i386
8bff LTFS17089I Distribution: Fedora release 42 (Adams)
8bff LTFS17089I Distribution: NAME="Fedora Linux"
8bff LTFS17089I Distribution: Fedora release 42 (Adams)
8bff LTFS17089I Distribution: Fedora release 42 (Adams)
8bff LTFS14063I Sync type is "time", Sync time is 300 sec
8bff LTFS17085I Plugin: Loading "ltotape" driver
8bff LTFS17085I Plugin: Loading "unified" iosched
8bff LTFS20013I Drive type is TANDBERG DATA LTO5, serial number is HUJ4472C93
8bff LTFS17160I Maximum device block size is 524288
8bff LTFS17157I Changing the drive setting to write-anywhere mode
8bff LTFS11005I Mounting the volume
8bff LTFS14111I Initial setup completed successfully
8bff LTFS14112I Invoke 'mount' command to check the result of final setup
8bff LTFS14113I Specified mount point is listed if succeeded

After which the tape appears as a filesystem in all the typical places, and even goes as far as to track space used:

root@assam:/mnt# df -h | grep st0
ltfs:/dev/nst0        1.4T   70G  1.3T   6% /mnt/TAPE

Caveats

Naturally, there’s a sizable performance penalty associated with writing to LTFS rather than writing data by a simple index. Writing my music library, most files seems to transfer around 20-30MB/s. Large files (video) tops out around 35MB/s.

Compared to piping tar into mbuffer, it’s maybe as much as ten times slower for some workloads. Though I think it’s still worth it, given the FUSE driver is smart enough to cache the directory tree, and individual files, rather than… well, everything. Listing the directory tree is still more responsive than listingthe same tree over NFS.

The fact HP LTFS isn’t in the Fedora repository is a bit sad. It’s also inevitable that it will likely stop working for periods of time as the interfaces to libfuse and other dependencies (libicu, libxml2, e2fsprogs) change. I can’t imagine HP are particularly bothered about these tools running on anything newer than the latest version of RHEL/HP-UX.

Interestingly they seem to support MacOS. Maybe the next thing I should do is find a USB-C PCI-E caddy and try to use my drive on my work Mac (and from Asahi - I’m curious if it has support for those sorts of peripherals).

OpenLTFS doesn’t appear to be in the repository either. I haven’t tried it. I’d assume that it serves a similar role to ISO SQL and would likely work.

Sadly Brother doesn’t make 17mm labels for the P-Touch label printer I have (and use with 3mm labels that fit the spines of my Minidiscs). The closest they make are labels in 12mm and 18mm, the latter just a fraction too large. Still, there’s no reason you can’t buy A4 sheets of printable LTO tape labels if you have a lot of tapes.

Future Topics

I haven’t looked hard at ltfsck. It has some interesting options in its help output:

root@assam:~$ ltfsck -h
LTFS17085I Plugin: Loading "ltotape" driver
Usage: ltfsck [options] filesys

filesys                           Device file for the tape drive

Available options are:
  -g, --generation=<generation>   Specify the generation to roll back
  -r, --rollback                  Roll back to the point specified by -g
  -F, --Force                     Force rollback when there are files open for write in the index. (Effective only for -r option)
  -n, --no-rollback               Do not roll back. Verify the point specified by -g (default)
  -f, --full-recovery             Recover extra data blocks into directory _ltfs_lostandfound
  -z, --deep-recovery             Recover EOD missing cartridge.
                                  Some blocks might be erased, but recover to final unmount point
                                  with an index version of at least  2.0.0  or earlier.
                                  (Must be used for a cartridge that cannot be recovered by a normal option.)
  -l, --list-rollback-points      List rollback points
  -m, --full-index-info           Display full index information (Effective only for -l option)
  -w, --list-open-files           List open for write files at rollback points. (Effective only for -l option)
  -c, --count-open-files          Count open for write files at rollback points. (Effective only for -l option)
  -v, --traverse=<strategy>       Set traverse mode for listing roll back points. Strategy should be forward or backward. (default: backward)
  -j, --erase-history             Erase history at rollback
  -k, --keep-history              Keep history at rollback (default)
  -q, --quiet                     Suppress informational messages
  -t, --trace                     Enable diagnostic output
      --syslogtrace               Enable diagnostic output to stderr and syslog
  -V, --version                   Version information
  -h, --help                      This help
  -p, --advanced-help             Full help, including advanced options

Usage example:
  ltfsck /dev/nst0
  ltfsck --generation --rollback /dev/nst0
  ltfsck --deep-recovery --full-recovery /dev/nst0

Generations? Rollback points? I’m still using plain-old (trustworthy) XFS partitions for everything, so I don’t even have those features on my NAS.

I have a vague understanding LTFS is an abstraction on top of typical index-based writing, and as such will likely just append changes (or files?) to the end of the tape. So in theory if a file changes a lot, but you have space remaining, you’ll end up storing multiple versions of that file.

It’s one to explore in the future.