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/12/05 09:06] adminpubliek:ltfs_en_tape [2026/01/02 10:38] (huidige) admin
Regel 42: Regel 42:
 <code> <code>
 ./tape-age.sh ./tape-age.sh
 +</code>
 +
 +Vrije ruimte kun je zien met:
 +<code>
 +df -h /mnt/ltfs
 </code> </code>
  
Regel 158: 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 171: Regel 186:
  
 Dit commando heb ik in een copy.sh gezet waarmee ik niet alle informatie hoef te kennen. De broncode staat beneden. 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>
  
 ---- ----
Regel 492: Regel 513:
 echo echo
  
-# Vraag bronbestand +have_cmd() { command -"$1>/dev/null 2>&1; }
-read -r -e -p "Bronbestand (volledig pad): SRC+
  
-if [[ -z "${SRC}" ]]; then+# ---------------------------- 
 +# 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   echo "Geen bron opgegeven, exit." >&2
   exit 1   exit 1
Regel 505: Regel 647:
 fi fi
  
-Vraag doelfolder +---------------------------- 
-read ---"Doelfolder (pad)DST_DIR+# 2) Doelfolder selecteren (1 level per keer) 
 +---------------------------- 
 +DST_DIR="$(pick_dir_level_by_level "$PWD")" || true
  
-if [[ -z "${DST_DIR}" ]]; then+if [[ -z "${DST_DIR:-}" ]]; then
   echo "Geen doelfolder opgegeven, exit." >&2   echo "Geen doelfolder opgegeven, exit." >&2
   exit 1   exit 1
 fi fi
  
-# Maak doelfolder indien nodig 
 mkdir -p "$DST_DIR" mkdir -p "$DST_DIR"
  
-Vraag optioneel doelnaam+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")" DEFAULT_NAME="$(basename "$SRC")"
 read -r -e -p "Doelbestandsnaam [${DEFAULT_NAME}]: " DST_NAME read -r -e -p "Doelbestandsnaam [${DEFAULT_NAME}]: " DST_NAME
Regel 523: Regel 683:
 DST="${DST_DIR%/}/$DST_NAME" DST="${DST_DIR%/}/$DST_NAME"
  
-# Overschrijf-check+---------------------------- 
 +# 4) Overschrijf-check 
 +# ----------------------------
 if [[ -e "$DST" ]]; then if [[ -e "$DST" ]]; then
   echo   echo
Regel 529: Regel 691:
   read -r -p "Overschrijven? (y/N): " ans   read -r -p "Overschrijven? (y/N): " ans
   case "${ans:-N}" in   case "${ans:-N}" in
-    y|Y|yes|YES) +    y|Y|yes|YES) echo "Oké, ik overschrijf het bestand." ;; 
-      echo "Oké, ik overschrijf het bestand." +    *) echo "Afgebroken. Geen wijzigingen gedaan."exit 0 ;;
-      ;; +
-    *) +
-      echo "Afgebroken. Geen wijzigingen gedaan." +
-      exit 0 +
-      ;;+
   esac   esac
 fi 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
 echo "Kopieer:" echo "Kopieer:"
 echo "  Bron : $SRC" echo "  Bron : $SRC"
 echo "  Doel : $DST" echo "  Doel : $DST"
 +echo "  (Schrijf eerst naar partial en hernoem bij succes)"
 echo echo
  
-Kopie met pv + size voor nette ETA +TMP_DST="${DST}.partial.$$" 
-pv -"$(stat -c%s "$SRC")" "$SRC"$DST"+ 
 +cleanup() { 
 +  Ruim partial op als we falen/stoppen. 
 +  # (Als destination read-only werd vlak voor mv, laten we hem soms bewust staan) 
 +  if [[ -"$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
 echo "Klaar. Resultaat:" echo "Klaar. Resultaat:"
 ls -lh "$DST" ls -lh "$DST"
 +
 </code> </code>
  
publiek/ltfs_en_tape.1764921984.txt.gz · Laatst gewijzigd: door admin

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki