tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

⎇ main recipes/smartmontools.toml TOML · 111 siq'ikuna · 6.8 KB Ñawpa willay ch'uya

salud del disco: smartmontools, y el hueco que no era de espacio 57d556969 · Sergio ·

1# smartmontools 7.5 — SMART: preguntarle a un disco si se está muriendo.
2#
3# ══ POR QUÉ ENTRA ══════════════════════════════════════════════════════════════════════════════
4# `censo-distro.py` marca «discos y salud del equipo» **4 de 4 ausente**, con el comentario «nada
5# que avise de un disco muriéndose». Y en este proyecto eso no es hipotético: la memoria del repo
6# tiene documentados un disco de 5,9 G que **al llenarse no se degrada, se cae entero**, 19 G de
7# montones muertos, y un «0 fallan» que era mentira porque no quedaban inodos para escribir el
8# `.fail`. Todo eso es espacio; **la salud del hardware no la mira nadie**.
9#
10# Un disco con sectores reasignados en aumento avisa días antes de morir — pero sólo si alguien
11# pregunta. `smartctl` es quien pregunta.
12#
13# ══ CUESTA UNA RECETA: TODAS SUS DEPS SON OPCIONALES ═══════════════════════════════════════════
14# Medido sobre su `configure.ac`: sus únicas deps externas son `AC_CHECK_LIB` de `cap`, `systemd`,
15# `selinux` y `usb` — **las cuatro opcionales**, y ninguna hace falta para lo que importa (hablar
16# ATA/SCSI/NVMe por ioctl). El tarball del release trae `configure` generado, así que tampoco
17# necesita autotools.
18#
19# ══ LAS PERILLAS ═══════════════════════════════════════════════════════════════════════════════
20#   --without-libsystemd    no hay systemd en esta distro; es para que `smartd` notifique por él
21#   --without-libcap-ng     `libcap-ng` no está en el corpus. Lo que se pierde es que `smartd`
22#                           suelte capacidades al arrancar — relevante sólo para el daemon
23#   --without-selinux       no hay SELinux acá
24#   --without-libusb        los puentes USB-SATA. Sin esto no se lee el SMART de un disco externo
25#                           por USB; los internos (ATA/SCSI/NVMe) van por ioctl y no lo necesitan.
26#                           **Se dice porque es la limitación que alguien va a notar**
27#   --with-nvme-devicescan  que `smartd`/`smartctl --scan` encuentren los NVMe, que es lo que tiene
28#                           esta clase de máquina. Sin esto hay que nombrar el dispositivo a mano
29#   --without-update-smart-drivedb  el script que BAJA la base de datos de modelos desde internet.
30#                           No en una distro que se construye entera desde fuente y sin red
31#
32# ⚠ `--with-initscriptdir=no` y `--without-systemdsystemunitdir`: el init de esta distro es `arje`,
33# no systemd ni sysvinit, así que instalar un script de arranque ajeno sería basura en la imagen.
34# `smartd` se declara en `arje` cuando alguien decida vigilar discos de forma continua; hoy lo que
35# cierra el hueco es `smartctl`, que se invoca a mano.
36name    = "smartmontools"
37version = "7.5"
38license = "GPL-2.0-or-later"
39
40[source]
41tarball = "https://sourceforge.net/projects/smartmontools/files/smartmontools/7.5/smartmontools-7.5.tar.gz/download"
42sha256  = "690b83ca331378da9ea0d9d61008c4b22dde391387b9bbad7f29387f2595f76e"
43
44[build]
45# Sus deps son todas opcionales y ninguna se enciende ⇒ no hay dep shared-only que fuerce dinámico.
46# (La regla: `link` tiene que coincidir con lo que publican las deps de la receta — ver la nota de
47# `recipes/gdb.toml`, donde `gmp`/`mpfr` son sólo `.so` y el estático falló.)
48compiler = "zig-cc"
49target   = "x86_64-linux-musl"
50link     = "static"
51flags    = []
52
53[build.phases]
54configure = '''
55set -e
56[ -f ./configure ] || { echo "smartmontools: el tarball no trae ./configure" >&2; exit 1; }
57./configure --build=$CBUILD --host=$CHOST --prefix=/usr --sysconfdir=/etc \
58  --without-libsystemd --without-libcap-ng --without-selinux --without-libusb \
59  --with-nvme-devicescan \
60  --without-update-smart-drivedb \
61  --with-initscriptdir=no --without-systemdsystemunitdir
62'''
63compile = 'make -j"$(nproc)"'
64# ⚠ EL GUARDIÁN LO EJECUTA Y LE PIDE LA BASE DE DATOS DE MODELOS.
65#
66# `smartctl` sin `drivedb.h` compilada adentro **arranca igual** y pierde lo que lo hace útil: los
67# nombres y los umbrales específicos de cada modelo de disco. Daría atributos crudos numerados sin
68# saber qué significan — sellado, con contenido, y sin la función que promete.
69#
70# No se intenta consultar un disco de verdad: el sandbox va con `--unshare-all` y sin `/dev`
71# propio, así que pedirlo haría fallar un build correcto (el error que ya pagué cinco veces hoy).
72# Lo que sí se puede comprobar es que el binario arranque y que la base de datos esté dentro.
73install = '''
74set -e
75make install DESTDIR=/out
76for b in smartctl smartd; do
77  [ -x "/out/usr/sbin/$b" ] || [ -x "/out/usr/bin/$b" ] || { echo "smartmontools: falta $b" >&2; find /out -maxdepth 4 -type f -perm -u+x >&2; exit 1; }
78done
79SC=$(find /out -name smartctl -type f -perm -u+x | head -1)
80# Ejecución y truncado SEPARADOS: el estado de una tubería es el del último comando.
81sal=$("$SC" --version 2>&1) || { echo "smartmontools: smartctl no arranca" >&2; printf '%s\n' "$sal" >&2; exit 1; }
82printf '%s\n' "$sal" | head -1 | grep -qE 'smartctl 7\.5' || { echo "smartmontools: --version inesperado: $(printf '%s\n' "$sal" | head -1)" >&2; exit 1; }
83
84# La base de datos de modelos: es lo que traduce «atributo 5» a «sectores reasignados». Sin ella
85# `smartctl` arranca y devuelve números crudos sin nombre — sellado y sin la función que promete.
86#
87# ⚠ **EL ANCLA SALE DE LEER SU FUENTE, no de suponer el formato.** Mi primera versión contaba
88# «líneas que empiezan por letra» de `-P showall`, que es frágil y podía rechazar un build correcto.
89# `knowndrives.cpp:showallpresets()` imprime una línea literal al final:
90#
91#     pout("Total number of entries  :%5u\n" …, knowndrives.size(), …)
92#
93# ⇒ se lee ESE número, que es exactamente el tamaño de la base compilada. Y de paso: esa función
94# devuelve `errcnt`, o sea que sale ≠ 0 **sólo** si la base tiene errores de sintaxis — otra cosa
95# que vale saber antes de tratar su estado como «no arrancó».
96db=$("$SC" -P showall 2>&1) || true
97n=$(printf '%s\n' "$db" | sed -n 's/^Total number of entries *: *\([0-9]\+\).*/\1/p' | head -1)
98[ -n "$n" ] || {
99  echo "smartmontools: -P showall no imprimió la línea 'Total number of entries' — el formato cambió o la base no se compiló" >&2
100  printf '%s\n' "$db" | tail -5 >&2
101  exit 1
102}
103[ "$n" -gt 50 ] || {
104  echo "smartmontools: la base de modelos trae $n entrada(s) — esperaba más de 50; smartctl daría atributos crudos numerados sin saber qué significan" >&2
105  exit 1
106}
107echo "smartmontools: $(printf '%s\n' "$sal" | head -1) · smartctl + smartd · $n entrada(s) de drivedb"
108'''
109
110[deps]
111build = ["make", "pkgconf"]