Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

DisksService.getDisks wakes spun-down array disks via systeminformation.diskLayout()

Aperta
#2,018 0 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
65/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
linux, typescript
Ambito
api, backend

Direzione di ricerca

Start in api/src/unraid-api/graph/resolvers/disks/disks.service.ts at getDisks(), then compare its diskLayout() path with getTemperature() and the WebUI's SmartInfo.php behavior. Exercise /graphql with { disks { id } } against standby disks; done means identity is returned without waking them and smartStatus remains unknown for disks that are still asleep.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Environment

Unraid OS Version: 7.3.1

Are you using a reverse proxy? No (tested directly against the LAN IP and via the LAN hostname; reproduction does not involve any proxy).

Pre-submission Checklist

  • I have verified that my Unraid OS is up to date
  • I have tested this issue by accessing my server directly (not through a reverse proxy)
  • This is not an Unraid Connect related issue (if it is, please submit via the support form instead)

Issue Description

Querying { disks { ... } } over the unraid-api GraphQL endpoint spins up array drives that were in standby. The resolver populates each Disk via systeminformation.diskLayout(), which itself shells out to smartctl --xall per device without the -n standby flag. Modern large HDDs (Seagate Exos ≥16 TB, WD Gold ≥16 TB, etc.) treat the resulting ATA IDENTIFY / READ LOG as a wake-up signal and leave standby.

Note that the same file's getTemperature(device) already does the right thing on line 104:

const { stdout } = await execa('smartctl', ['-n', 'standby', '-A', '-j', device]);

— exactly the call shape we need everywhere else in this resolver.

The relevant code in api/src/unraid-api/graph/resolvers/disks/disks.service.ts:378:

async getDisks(): Promise<Disk[]> {
    const partitions = await blockDevices().then((devices) =>
        devices.filter((device) => device.type === 'part')
    );
    const arrayDisks = this.configService.get<ArrayDisk[]>('store.emhttp.disks', []);
    const { data } = await batchProcess(await diskLayout(), async (disk) =>
        this.parseDisk(disk, partitions, arrayDisks)
    );
    return data;
}

The official WebUI (/usr/local/emhttp/plugins/dynamix/include/SmartInfo.php) already avoids this: identity comes from cached disks.ini populated by emhttpd at boot, and any smartctl invocation passes -n standby. That is why opening Main on the WebUI never wakes drives but a GraphQL { disks { ... } } does.

Steps to Reproduce

  1. Spin down the array disks via the WebUI or hdparm -y /dev/sdX.
  2. Confirm they are sleeping: smartctl -n standby -i /dev/sdXDevice is in STANDBY mode.
  3. Issue a minimal GraphQL query through /graphql:
    { disks { id } }
    
  4. Re-check the larger drives: smartctl -n standby -i /dev/sdX.
  5. The ≥16 TB drives that reported STANDBY mode in step 2 now report Power mode. Field selection in the query is irrelevant — even { disks { id } } is enough because the resolver fully populates each disk via diskLayout() before returning.

Expected Behavior

GraphQL queries against disks (and downstream queries that touch the same resolver, e.g. array.disks hardware enrichment) should not transition any drive out of standby. Identity fields (vendor, model, serialNum, firmwareRevision, interfaceType) should be served from cached state, and smartStatus should be probed only for drives that are already spinning — matching the WebUI's behavior.

Actual Behavior

Test data from one server (mixed array, single query of { disks { id } } from a fully spun-down baseline):

Disk Model Size After { disks { id } }
/dev/sda WDC WD160EDGZ 16 TB Spun up
/dev/sdb WDC WD180EDGZ (parity) 18 TB Spun up
/dev/sdd WDC WD30NPRZ 3 TB Still standby
/dev/sde WDC WD40EZRX 4 TB Still standby
/dev/sdf WDC WD180EDGZ 18 TB Spun up
/dev/sdg ST16000NM000J 16 TB Spun up
/dev/sdh ST16000NM000J 16 TB Spun up

Pattern: large modern drives wake on any ATA command; older smaller drives ignore it. Consistent with current Seagate / WD firmware behavior.

Additional Context

Suggested fix. Replace diskLayout() with a custom enumeration that mirrors the WebUI strategy:

  • Use lsblk -d -J -O for identity (or this.configService.get('store.emhttp.devices') for array-mapped disks). All sysfs-backed, no SMART access.
  • Use smartctl -n standby -H -j /dev/sdX per disk for smartStatus. Honor exit_status: 2 as "standby — status unknown".
  • Keep blockDevices() for partitions.
  • parseDisk does not need to change — it already accepts the shape lsblk produces.

Reference implementation. I have implemented this exact pattern as a runtime monkey-patch in u-manager-companion (function patch_disks_service_bundle) and verified on the same server that:

  • { disks { ... } } returns the full record (vendor / serial / firmware / interfaceType) and smartStatus: "UNKNOWN" for spun-down disks.
  • No drive in standby transitions to active.
  • Latency drops from several seconds to <500 ms because we no longer wait on smartctl --xall for every device.

Happy to open a PR with the upstream version of the same change.

Lingua principale
TypeScript
Stelle
113
Fork
22
Merge medio
10h 40m
PR unite (30g)
13

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di unraid/api

Tutte le issue di unraid/api

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.