From a4373a898e65604f58299c947882f50294dd813f Mon Sep 17 00:00:00 2001 From: Timmy Keller Date: Mon, 2 Sep 2024 08:44:38 -0500 Subject: various changes over time --- misc/diskhealth | 46 ++++++++++++++++++++++++ misc/mkmount | 18 ++++++++++ misc/mountimg | 42 ++++++++++++++++++++++ misc/verifoo | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 216 insertions(+) create mode 100755 misc/diskhealth create mode 100755 misc/mkmount create mode 100755 misc/mountimg create mode 100755 misc/verifoo (limited to 'misc') diff --git a/misc/diskhealth b/misc/diskhealth new file mode 100755 index 0000000..5cce07b --- /dev/null +++ b/misc/diskhealth @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 + +import subprocess +import json +from pprint import pprint + +smart_result = subprocess.run(["sudo", "smartctl", "-Aij", "/dev/sda"], capture_output=True, text=True) + +smart_result = json.loads(smart_result.stdout) + +sector_size = smart_result["logical_block_size"] + +from typing import NamedTuple +class RawValue(NamedTuple): + value: int + string: str + +class Flags(NamedTuple): + value: int + string: str + prefailure: bool + updated_online: bool + performance: bool + error_rate: bool + event_count: bool + auto_keep: bool + +class SmartAttribute(NamedTuple): + id: int + name: str + value: int + worst: int + thresh: int + when_failed: str + flags: dict + raw: dict + +attributes = {} + +for attr in smart_result["ata_smart_attributes"]["table"]: + attr_l = SmartAttribute(**attr) + attributes[attr_l.id] = attr_l + +if 241 in attributes: + lbas_written = attributes[241].raw["value"] + print((lbas_written * sector_size) / 10**12) diff --git a/misc/mkmount b/misc/mkmount new file mode 100755 index 0000000..b23d85b --- /dev/null +++ b/misc/mkmount @@ -0,0 +1,18 @@ +#!/bin/sh + +set -e + +mpdir="/run/media/$USER" +mkdir -p "$mpdir" + +mp="$1" + +if [ -z "$mp" ]; then + mp="$(mktemp -d "$mpdir/XXXXXX")" +else + mp="$mpdir/$mp" + [ -f "$mp" ] && echo "Error: $mp already exists" && exit 1 + mkdir -p "$mp" +fi + +echo "$mp" diff --git a/misc/mountimg b/misc/mountimg new file mode 100755 index 0000000..efe886c --- /dev/null +++ b/misc/mountimg @@ -0,0 +1,42 @@ +#!/bin/sh + +set -e + +die() { echo "$(basename "$0"): $1" && exit 1 ; } + +# file check +! [ "$1" ] && die "No file was specified" +! [ -f "$1" ] && die "$1 is not a file" +# mountpoint check +! [ "$2" ] && die "No mountpoint was specified" +! [ -d "$2" ] && die "Mountpoint $2 is not a directory" +[ "`ls -A "$2"`" ] && die "Mountpoint $2 is not empty" +# check disk image validity +! fdisk -lu "$1" 2>&1 | grep -m1 "\s*Start\s*End" >/dev/null && die "File $1 is not a disk image" + +# get sectorsize +#sectorsize=$(fdisk -lu "$1" | grep -m1 '^Units:' | cut -d' ' -f8) # Sector size is 8th word +sectorsize=512 + +# get partition num, if there is more than one part, interactively if not available +# TODO check if there is no partitions +partition="$3" +if [ -z "$partition" ]; then + fdisk -o Size,Type,Name -lu "$1" | awk '!f{print $0};f>0{print " " f-1 ") " $0; f++};f==-1{print "Part " $0;f=1};/^$/{f=-1}' + + printf "\nChoose partition number to mount: " + read partition +fi + +# check if part num valid +[ -z "${partition##*[!0-9]*}" ] && die "Illegal number: '$partition'" + +# get offset from fdisk +fdisk_ignore_lines=9 # ignore first 9 lines of output +offset=$(fdisk -o Start -l "$1" | sed $(( fdisk_ignore_lines + partition ))'q;d' ) + +# check if that produced a valid offset +[ -z "$offset" ] && die "Partition $partition does not exist" + +# try to mount +mount -o loop,offset=$(( offset * sectorsize )) "$1" "$2" && echo "Successfully mounted" || die "Error mounting" diff --git a/misc/verifoo b/misc/verifoo new file mode 100755 index 0000000..34089cb --- /dev/null +++ b/misc/verifoo @@ -0,0 +1,110 @@ +#!/bin/sh + +help() { +cat << HELPDOC +usage: $(basename "$0") [options] [file]... + +OPTIONS: + -h, --help show this menu + -c, --check read and verify checksums from file + -r, --recursive produce a checksum for all files in a directory recursively + --recursive-sum produce a checksum for a directory. sensitive to filenames + --recursive-sum-nopath produce a checksum for a directory. not sensitive to filenames/placement + -s, --silent produce no output to stderr + -v, --verbose output a progress bar of hash progress if pv is avaliable (wip) + +MODES: + -S, --sha use sha1sum for checksums + -M, --md5 use md5sum for checksums + -X, --xxh use xxhsum for checksums (default if avaliable with sha1sum as fallback) +HELPDOC +} + +# set defaults +cat="pv -F'%r_[%b]_[%t]_[%e]_%p'" +! command -v pv >/dev/null && cat=cat + +hash=xxhsum +! command -v xxhsum >/dev/null && hash=sha1sum + +hashfiles="" +verbose=1 +recursive="" +outputfile="" + +while true; do + case "$1" in + -c|--check) [ -n "$2" ] && hashfiles="$hashfiles $2" && shift ;; + -s|--silent) verbose=0 ;; + -v|--verbose) verbose=2 ;; + --recursive|-r) recursive=3 ;; + --recursive-sum) recursive=2 ;; + --recursive-sum-nopath) recursive=1 ;; + -S|--sha) hash=sha1sum ;; + -M|--md5) hash=md5sum ;; + -X|--xxh) hash=xxhsum ;; + -h|--help) help; exit 0 ;; + -*) help; exit 1 ;; + *) break ;; + esac + shift +done + +case $verbose in + 0) cat=cat ;; + 1) cat=cat ;; +esac + +# run hash +while [ -n "$1" ]; do + if [ -d "$1" ]; then # is directory + # check if using -r flag + case "$recursive" in + 1) + # get hash of all files, sort hashes, hash hashes + # TODO make pv work in this mode + + #catd="$cat" + #if [ $verbose -ge 2 ] && [ "$catd" != "cat" ]; then + # total_files=$(du -a "$1" | wc -l) + # catd="pv -l -s$total_files -F'[%b/$total_files]_[%t]_[%e]_%p'" + #fi + #sum=`find "$1" -type f -print0 | xargs -r0 $hash | $catd | cut -d' ' -f1 | sort | $hash | cut -d' ' -f1` 2>/dev/null + sum=`find "$1" -type f -print0 | xargs -r0 $hash | cut -d' ' -f1 | sort | $hash | cut -d' ' -f1` 2>/dev/null + echo "r/$sum $1" + ;; + 2) + # hash sorted filenames + # sort all filenames w/ full path and hash + # hash those sums together + # `tar -c -f - "$1" | $hash` is a good idea but it doesn't work since changes to the fs affect tar + filehash=`find "$1" -type f -print0 | sort -z | xargs -r0 $cat | $hash | cut -d' ' -f1` + pathhash=`find "$1" -printf "%P\0" | sort -z | $hash | cut -d' ' -f1` + sum=`printf "$filehash$pathhash" | $hash | cut -d' ' -f1` + echo "p/$sum $1" + ;; + 3) + # sort files and hash each one in sequence + # TODO make pv work in this mode + find "$1" -type f -print0 | sort -z | xargs -r0 $hash + ;; + *) + [ $verbose -ge 1 ] && echo "-r not specified for directory $1. Exiting" + exit 1 + ;; + esac + else # is file + if ! [ -f "$1" ]; then + [ $verbose -gt 1 ] && echo "File $1 does not exist. Exiting" + exit 1 + fi + files="$1" + + while [ -f "$2" ]; do + files="$files\0$2" + shift + done + printf "$files" | xargs -r0 $hash + fi + shift +done -- cgit v1.2.3