Gebruikershulpmiddelen

Site-hulpmiddelen


publiek:ltfs_en_tape

Verschillen

Dit geeft de verschillen weer tussen de geselecteerde revisie en de huidige revisie van de pagina.

Link naar deze vergelijking

Beide kanten vorige revisieVorige revisie
Volgende revisie
Vorige revisie
publiek:ltfs_en_tape [2025/11/24 20:45] adminpubliek:ltfs_en_tape [2026/01/02 10:38] (huidige) admin
Regel 1: Regel 1:
 ======LTFS en Tape====== ======LTFS en Tape======
 +
 +=====Hardware=====
 +Als eerste kun je controleren of de PCI-kaart geïnstalleerd is. Dat doe je met het volgende commando:
 +<code>
 +lspci
 +</code>
 +Daar kun je iets zien van bijv. Fibre Channel ...
 +
 +Met het volgende commando kun je zien welke devices er zijn. Dit kunnen bijvoorbeeld harddisks, maar ook de tapestreamers zijn:
 +<code>
 +lsscsi -g
 +</code>
 +
 +Je ziet hier in de laatste twee kolommen zowel een stx en sgx. Dit zijn twee interfaces naar dezelfde hardware. 
 +  - STx = tape-interfacae : data/backups: (st is niet terugspoelen, nst wel, st0 = nst0 / st1 = nst1 / etc). 
 +  - SGx = direct SCSI : Status/beheer: vaak sg. Denk aan logs opvragen etc. dus ook status van drive etc.
 +
 +<WRAP center round important 60%>
 +Je kunt sgY niet simpelweg “omrekenen” naar stX op basis van nummers; die tellers lopen onafhankelijk. De koppeling maak je via hetzelfde SCSI-adres (zoals ik eerder liet zien met sysfs/udev).</WRAP>
 +
  
 =====Tapedrive====== =====Tapedrive======
Regel 18: Regel 38:
  
 Wanneer het lang geleden is dat een tape gereinigd is, kun je een cleaning-tape laden. Dan wordt de drive automatisch gereinigd. Wanneer het lang geleden is dat een tape gereinigd is, kun je een cleaning-tape laden. Dan wordt de drive automatisch gereinigd.
 +
 +Als je benieuwd bent hoe oud een tape is, dan kun je dat uitlezen met:
 +<code>
 +./tape-age.sh
 +</code>
 +
 +Vrije ruimte kun je zien met:
 +<code>
 +df -h /mnt/ltfs
 +</code>
  
 ---- ----
Regel 39: Regel 69:
 <code> <code>
 ./list_size.sh ./list_size.sh
 +</code>
 +
 +====Doorlopen van de tape====
 +===Terugspoelen naar begin van de tape===
 +<code>
 +mt -f /dev/nst0 rewind
 +</code>
 +
 +===Tonen welke tar op die plek staat===
 +<code>
 +tar -tvf /dev/nst0
 +</code>
 +
 +===Naar volgende en vorige set===
 +<code>
 +mt -f /dev/nst0 fsf 1
 +</code>
 +<code>
 +mt -f /dev/nst0 bsfm 1
 +</code>
 +Daarna weer tonen.
 +
 +====Naar einde====
 +Met dit commando kun je naar het einde van de tape schrijven:
 +<code>
 +mt -f /dev/nst0 eod
 </code> </code>
  
Regel 60: Regel 116:
 </code> </code>
  
-=====Tape terugspoelen=====+====Tape terugspoelen====
 Terugspoelen kan handmatig door het volgende commando Terugspoelen kan handmatig door het volgende commando
 <code> <code>
Regel 107: Regel 163:
 </code> </code>
  
-=====Handige kopieeropdrachten=====+Daarna moet je de tape offline halen: 
 +<code> 
 +sudo mt -f /dev/nst0 offline 
 +</code> 
 + 
 +Dan kun je controleren of de tape 'offline' is. Dat gaat via: 
 +<code> 
 +sudo mt -f /dev/nst0 status 
 +</code> 
 + 
 +=====Handige kopieeropdrachten enzo=====
 Als je wilt zien hoe het kopiëren gaat dan kun je pv gebruiken. Eerst installeren: Als je wilt zien hoe het kopiëren gaat dan kun je pv gebruiken. Eerst installeren:
 <code> <code>
Regel 119: Regel 185:
 Daarbij wordt de tool gestart met de grootte waardoor je kunt zien hoe lang het gaat duren. Daarbij wordt de tool gestart met de grootte waardoor je kunt zien hoe lang het gaat duren.
  
 +Dit commando heb ik in een copy.sh gezet waarmee ik niet alle informatie hoef te kennen. De broncode staat beneden.
  
 +Je kunt met één commando ook van alle subfolders in een map een losse zip-file maken. Dat gaat als volgt:
 +<code>
 +mkdir -p zips && for d in */; do zip -rv "zips/${d%/}.zip" "$d"; done
 +mkdir -p zips && for d in */; do [[ "$d" != "zips/" ]] && zip -rv "zips/${d%/}.zip" "$d"; done
 +</code>
  
 ---- ----
 +
 +=====Tapeloader=====
 +Je kunt de tapeloader uitlezen met het volgende commando :
 +<code>
 +sudo mtx -f /dev/sch0 status
 +</code>
 +
  
 =====Broncodes===== =====Broncodes=====
  
-===list_size.sh===+====list_size.sh====
 <code> <code>
 sudo sg_logs -p 0x31 /dev/sg3 \ sudo sg_logs -p 0x31 /dev/sg3 \
Regel 137: Regel 216:
 </code> </code>
  
-===list_all_sets.sh===+====list_all_sets.sh====
 <code> <code>
 #!/usr/bin/env bash #!/usr/bin/env bash
Regel 163: Regel 242:
 </code> </code>
  
-===testdrive.sh===+====testdrive.sh====
 <code> <code>
 #!/usr/bin/env bash #!/usr/bin/env bash
Regel 326: Regel 405:
 </code> </code>
  
-===tapeinfo.sh===+====tapeinfo.sh====
 <code> <code>
 #!/usr/bin/env bash #!/usr/bin/env bash
Regel 424: Regel 503:
  
 main "$@" main "$@"
 +</code>
 +
 +====Copy.sh====
 +<code>
 +#!/usr/bin/env bash
 +set -euo pipefail
 +
 +echo "=== PV copy tool (1 bestand) ==="
 +echo
 +
 +have_cmd() { command -v "$1" >/dev/null 2>&1; }
 +
 +# ----------------------------
 +# Source file picker (fzf)
 +# ----------------------------
 +select_src_file() {
 +  local start_dir="${1:-$PWD}"
 +
 +  if have_cmd fzf; then
 +    # Alleen files, vanaf start_dir
 +    find "$start_dir" -type f 2>/dev/null \
 +      | fzf --prompt="Selecteer bronbestand: " --height=80% --reverse
 +  else
 +    local src
 +    read -r -e -p "Bronbestand (volledig pad): " src
 +    printf "%s" "$src"
 +  fi
 +}
 +
 +# ----------------------------
 +# Destination directory picker (ONLY dirs, 1 level per keer)
 +# - browse level-by-level
 +# - choose parent
 +# - choose current dir
 +# ----------------------------
 +pick_dir_level_by_level() {
 +  local cur="${1:-$PWD}"
 +
 +  # Normaliseer pad (resolve symlinks, etc.)
 +  cur="$(cd "$cur" 2>/dev/null && pwd -P)" || cur="$PWD"
 +
 +  while true; do
 +    local parent choice
 +    parent="$(dirname "$cur")"
 +
 +    if have_cmd fzf; then
 +      choice="$(
 +        {
 +          echo "[..] (parent: $parent)"
 +          echo "[.]  (kies deze map: $cur)"
 +          # Alleen subdirectories, 1 level diep
 +          find "$cur" -mindepth 1 -maxdepth 1 -type d -printf "%f/\n" 2>/dev/null | sort
 +        } | fzf --prompt="Doelfolder: $cur > " --height=80% --reverse
 +      )" || return 1
 +    else
 +      local dst
 +      read -r -e -p "Doelfolder (pad): " dst
 +      printf "%s" "$dst"
 +      return 0
 +    fi
 +
 +    case "$choice" in
 +      "[..]"*)
 +        cur="$parent"
 +        ;;
 +      "[.]"*)
 +        printf "%s" "$cur"
 +        return 0
 +        ;;
 +      */)
 +        local sub="${choice%/}"
 +        cur="$cur/$sub"
 +        ;;
 +      *)
 +        ;;
 +    esac
 +  done
 +}
 +
 +# ----------------------------
 +# Mount helpers
 +# ----------------------------
 +mountpoint_for_path() {
 +  # print het mountpoint (TARGET) voor een pad
 +  findmnt -no TARGET --target "$1" 2>/dev/null || true
 +}
 +
 +mount_opts_for_mountpoint() {
 +  # print mount options voor mountpoint
 +  findmnt -no OPTIONS "$1" 2>/dev/null || true
 +}
 +
 +is_mount_ro() {
 +  local mp="$1"
 +  [[ -n "$mp" ]] || return 1
 +  mount_opts_for_mountpoint "$mp" | grep -qw ro
 +}
 +
 +fstype_for_path() {
 +  findmnt -no FSTYPE --target "$1" 2>/dev/null || true
 +}
 +
 +avail_bytes_on_mount() {
 +  local path="$1"
 +  df -B1 --output=avail "$path" | tail -n1 | tr -d ' '
 +}
 +
 +human_bytes() {
 +  # simpele humanizer (B, KiB, MiB, GiB, TiB)
 +  local b="$1"
 +  local -a units=("B" "KiB" "MiB" "GiB" "TiB" "PiB")
 +  local u=0
 +  local v="$b"
 +  while [[ "$v" -ge 1024 && "$u" -lt 5 ]]; do
 +    v=$((v/1024))
 +    u=$((u+1))
 +  done
 +  printf "%s %s" "$v" "${units[$u]}"
 +}
 +
 +is_ltfs_path() {
 +  # Detecteer LTFS op basis van fstype of pad
 +  local fstype
 +  fstype="$(fstype_for_path "$1")"
 +  [[ "$fstype" == "ltfs" ]] && return 0
 +  [[ "$1" == /mnt/ltfs* ]] && return 0
 +  return 1
 +}
 +
 +# ----------------------------
 +# 1) Bron selecteren
 +# ----------------------------
 +SRC="$(select_src_file "$PWD")" || true
 +
 +if [[ -z "${SRC:-}" ]]; then
 +  echo "Geen bron opgegeven, exit." >&2
 +  exit 1
 +fi
 +
 +if [[ ! -f "$SRC" ]]; then
 +  echo "Bronbestand bestaat niet: $SRC" >&2
 +  exit 1
 +fi
 +
 +# ----------------------------
 +# 2) Doelfolder selecteren (1 level per keer)
 +# ----------------------------
 +DST_DIR="$(pick_dir_level_by_level "$PWD")" || true
 +
 +if [[ -z "${DST_DIR:-}" ]]; then
 +  echo "Geen doelfolder opgegeven, exit." >&2
 +  exit 1
 +fi
 +
 +mkdir -p "$DST_DIR"
 +
 +DST_MOUNT="$(mountpoint_for_path "$DST_DIR")"
 +DST_FSTYPE="$(fstype_for_path "$DST_DIR")"
 +
 +# Safety 1: stop direct als het destination filesystem read-only is
 +if [[ -n "$DST_MOUNT" ]] && is_mount_ro "$DST_MOUNT"; then
 +  echo
 +  echo "ERROR: Doel filesystem is read-only."
 +  echo "  Doelpad      : $DST_DIR"
 +  echo "  Mountpoint   : $DST_MOUNT"
 +  echo "  Fstype       : ${DST_FSTYPE:-unknown}"
 +  echo
 +  echo "Dit gebeurt vaak bij LTFS als de data-partitie geen ruimte meer heeft om een nieuwe index te schrijven."
 +  exit 1
 +fi
 +
 +# ----------------------------
 +# 3) Doelbestandsnaam
 +# ----------------------------
 +DEFAULT_NAME="$(basename "$SRC")"
 +read -r -e -p "Doelbestandsnaam [${DEFAULT_NAME}]: " DST_NAME
 +DST_NAME="${DST_NAME:-$DEFAULT_NAME}"
 +
 +DST="${DST_DIR%/}/$DST_NAME"
 +
 +# ----------------------------
 +# 4) Overschrijf-check
 +# ----------------------------
 +if [[ -e "$DST" ]]; then
 +  echo
 +  echo "Doelbestand bestaat al: $DST"
 +  read -r -p "Overschrijven? (y/N): " ans
 +  case "${ans:-N}" in
 +    y|Y|yes|YES) echo "Oké, ik overschrijf het bestand." ;;
 +    *) echo "Afgebroken. Geen wijzigingen gedaan."; exit 0 ;;
 +  esac
 +fi
 +
 +# ----------------------------
 +# 5) Space-check vooraf
 +# ----------------------------
 +SRC_SIZE="$(stat -c%s "$SRC")"
 +AVAIL="$(avail_bytes_on_mount "$DST_DIR")"
 +
 +# MARGES:
 +# - Op normale FS is 1GiB genoeg.
 +# - Op LTFS: neem liever groter, omdat index writes ruimte nodig hebben.
 +if is_ltfs_path "$DST_DIR"; then
 +  SAFETY_MARGIN=$((10*1024*1024*1024))  # 10 GiB marge voor LTFS (index/metadata + “niet tot 99% vullen”)
 +else
 +  SAFETY_MARGIN=$((1*1024*1024*1024))   # 1 GiB voor normale filesystems
 +fi
 +
 +NEEDED=$((SRC_SIZE + SAFETY_MARGIN))
 +
 +if [[ "$AVAIL" -lt "$NEEDED" ]]; then
 +  echo
 +  echo "ERROR: Onvoldoende vrije ruimte op doel filesystem."
 +  echo "  Bronbestand grootte          : $SRC_SIZE bytes ($(human_bytes "$SRC_SIZE"))"
 +  echo "  Vrij beschikbaar (df avail)  : $AVAIL bytes ($(human_bytes "$AVAIL"))"
 +  echo "  Benodigd incl. marge         : $NEEDED bytes ($(human_bytes "$NEEDED"))"
 +  echo
 +  if is_ltfs_path "$DST_DIR"; then
 +    echo "LTFS-tip: als de tape bijna vol is, kan LTFS read-only worden omdat hij geen index meer kan schrijven."
 +    echo "Kies een nieuwe tape/volume of laat meer vrije ruimte over."
 +  fi
 +  exit 1
 +fi
 +
 +# ----------------------------
 +# 6) Kopiëren met pv (veilig: eerst temp, dan mv)
 +# ----------------------------
 +echo
 +echo "Kopieer:"
 +echo "  Bron : $SRC"
 +echo "  Doel : $DST"
 +echo "  (Schrijf eerst naar partial en hernoem bij succes)"
 +echo
 +
 +TMP_DST="${DST}.partial.$$"
 +
 +cleanup() {
 +  # Ruim partial op als we falen/stoppen.
 +  # (Als destination read-only werd vlak voor mv, laten we hem soms bewust staan)
 +  if [[ -e "$TMP_DST" ]]; then
 +    rm -f "$TMP_DST" 2>/dev/null || true
 +  fi
 +}
 +trap cleanup EXIT INT TERM
 +
 +# Copy
 +pv -s "$SRC_SIZE" "$SRC" > "$TMP_DST"
 +sync
 +
 +# Safety 2: vlak vóór final mv opnieuw RO checken (LTFS kan intussen ro worden)
 +DST_MOUNT2="$(mountpoint_for_path "$DST_DIR")"
 +if [[ -n "$DST_MOUNT2" ]] && is_mount_ro "$DST_MOUNT2"; then
 +  echo
 +  echo "ERROR: Doel filesystem is intussen read-only geworden."
 +  echo "Partial bestand blijft staan voor inspectie:"
 +  echo "  $TMP_DST"
 +  echo
 +  echo "Je kunt het partial bestand handmatig verwijderen of naar een andere locatie kopiëren."
 +  trap - EXIT INT TERM
 +  exit 1
 +fi
 +
 +# Rename to final
 +mv -f "$TMP_DST" "$DST"
 +trap - EXIT INT TERM
 +
 +echo
 +echo "Klaar. Resultaat:"
 +ls -lh "$DST"
 +
 +</code>
 +
 +====tape-age.sh====
 +<code>
 +for id in 0x0400 0x0401 0x0406 0x0806 0x0803 0x0003 0x0222 0x0223 0x0220 0x0221; do
 +  sudo sg_read_attr -f $id /dev/sg4
 +done
 </code> </code>
publiek/ltfs_en_tape.1764013557.txt.gz · Laatst gewijzigd: door admin

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki