lto-scripts/README.MD

3.1 KiB

LTO Backup Scripts

Scripts to help me perform my backups to Ultrium LTO tapes.

Movies Library

  • mkbak_media.sh: Incremental subdirectory backup. Take each directory in my cwd, tar it, and append it to tape, one tape entry per directory. Create / extend a CSV index denoting when and to what tape ID the backup was made. Do not backup directories that were already backed up to other media (using the index). Note: Changes in directories will not be detected. The directory name is the only clue.

LTO Notes

General stuff

  • dev/nst does not auto-rewind, dev/st does
  • use mt-st seek / tell to position the tape at block indexes
  • Remaining capacity: https://serverfault.com/questions/853302/determine-remaining-capacity-of-lto-tape
    • sg_logs -a $DEV | sed -n 's/\s*Main partition remaining capacity (in MiB):\s*\(.*\)/\1/p'
  • Disable compression: mt-st -f /dev/nst0 compression 0
  • Make seek/tell work: mt-st -f /dev/nst0 stsetoptions scsi2logical

Improve start/stop

If you have a slow source / destination, consider using mbuffer with a size of a couple of Gigs. But that might also break speed matching, causing start / stop rather than going slower... idk.

Backups

Encrypted tar using GPG

tar cvO --exclude dir/excludeme dir/ | gpg --encrypt --sign --default-key KEY-ID -r KEY-ID -z 0 dd of=/dev/nst0 bs=512k

To decrypt, simply use gpg --decrypt /dev/nst0

LTFS on LTO-6

My drives are a little weird, to get it to work I need to edit LTFS sources.

ltfs-2.4.3.1-10461/src/tape_drivers/linux/sg/sg_tape.c: Type is incorrectly auto detected, we need to always /* Use LogPage 0x31 */

See this patch for inspiration

diff --git a/src/tape_drivers/linux/sg/sg_tape.c b/src/tape_drivers/linux/sg/sg_tape.c
index f583079..1169e44 100644
--- a/src/tape_drivers/linux/sg/sg_tape.c
+++ b/src/tape_drivers/linux/sg/sg_tape.c
@@ -513,6 +513,12 @@ static int _raw_open(struct sg_data *priv)
 		return -EDEV_DEVICE_UNSUPPORTABLE; /* Unsupported device */
 	}
 
+	/* Special care about Quantum model B */
+	if (priv->vendor == VENDOR_QUANTUM) {
+		if (id_data.product_id[7] == ' ')
+			priv->vendor = VENDOR_QUANTUM_B;
+	}
+
 	if (priv->drive_serial[0]) {
 		/* if serial number is already set, compare it */
 		if (strcmp(priv->drive_serial, id_data.unit_serial)) {
@@ -2969,7 +2975,8 @@ int sg_remaining_capacity(void *device, struct tc_remaining_cap *cap)
 	memset(buffer, 0, LOGSENSEPAGE);
 
 	if ((IS_LTO(priv->drive_type) && (DRIVE_GEN(priv->drive_type) == 0x05)) ||
-		(priv->vendor == VENDOR_HP && IS_LTO(priv->drive_type) && (DRIVE_GEN(priv->drive_type) == 0x06))) {
+		(priv->vendor == VENDOR_HP && IS_LTO(priv->drive_type) && (DRIVE_GEN(priv->drive_type) == 0x06)) ||
+		(priv->vendor == VENDOR_QUANTUM_B && IS_LTO(priv->drive_type))) {
 
 		/* Use LogPage 0x31 */
 		ret = sg_logsense(device, (uint8_t)LOG_TAPECAPACITY, (uint8_t)0, (void *)buffer, LOGSENSEPAGE);
diff --git a/src/tape_drivers/tape_drivers.h b/src/tape_drivers/tape_drivers.h
index a9d7bf5..6e11771 100644
--- a/src/tape_drivers/tape_drivers.h
+++ b/src/tape_drivers/tape_drivers.h
@@ -178,6 +178,7 @@ enum {
 	VENDOR_IBM,
 	VENDOR_HP,
 	VENDOR_QUANTUM,
+	VENDOR_QUANTUM_B,
 };
 
 enum {