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

Windows: DST timestamp "fix" (bug 18078) marks ~90% of library as changed after every clock change; freezes server when triggered by a folder browse

Aperta
#1,707 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@pupvogel ci sta già lavorando.

Dal 25/10/2026.

  • #1708 di @pupvogel — aperta

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
45/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
perl, sqlite

Direzione di ricerca

The bug is in Slim/Utils/Scanner/Local.pm around line 209 in rescan, and Slim/Utils/Misc.pm findAndScanDirectoryTree. Read those subs and the tracks/scanned_files schema. Reproduce by toggling metainformation.lastRescanTimeIsDST on Windows, then verify only actually changed files are re-read and folder browse doesn't block server. Done: no global shift, scan counts match real changes.

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

Descrizione

Describe the bug

This morning my Windows Lyrion server froze while streaming music.
Turns out the issue is related to the daylight saving time change last night (reported before as #824 but closed as stale).
My AI traced it to two interacting things:

  1. Perl's stat() on Windows (LMS ships Perl 5.32.1, MSWin32-x64-multi-thread, gcc build on the Microsoft C runtime) reports mtime one hour off for files whose modification date lies in the other DST half of the year. Right now (standard time) a file saved in July reads 3600 s early, a file saved in November reads correctly; in summer it is the reverse. This is the old CRT _stat behaviour; a single global offset cannot describe it.
  2. Slim::Utils::Scanner::Local::rescan (bug 18078 block, Local.pm ~line 209) compensates by shifting every row: UPDATE tracks SET timestamp = timestamp ± 3600. That is only correct for rows whose stored value was itself affected by the CRT error at the time of the last scan; for every other row it introduces a one-hour mismatch. In addition the persistent scanned_files table is not shifted at all.

Net effect: after the shift, scanned_files.timestamp doesn't match tracks.timestamp for most rows, so almost every file lands in the changed set and gets its tags re-read.

Worse, the block also runs in the in-process rescan that Slim::Utils::Misc::findAndScanDirectoryTree triggers when a client browses the music folder (Scanner::Local->rescan($path, { no_async => 1, recursive => 0 })). If that is the first scan after the clock change, tracks get shifted while the scanned_files rows from the previous full scan are not, the changed query returns essentially every track under the folder, and the server re-reads them synchronously. Today that froze my server for good: port 9000 stopped answering, players stalled, the Windows service hung in STOP_PENDING until perl.exe was killed, and the isScanning flag survived in the DB and had to be cleared with abortscan.

[26-10-25 09:30:59.9909] Slim::Utils::Scanner::Local::rescan (180) Discovering audio files in D:\la musique 'pop'\platten
[26-10-25 09:31:00.4055] Slim::Utils::Scanner::Local::__ANON__ (216) DST has changed since last scan - fix timestamps in tracks table
[26-10-25 09:31:01.0025] Slim::Utils::Scanner::Local::deleteTracks (407) Removing deleted audio files (0)
[26-10-25 09:31:01.0026] Slim::Utils::Scanner::Local::updateTracks (574) Rescanning changed audio files (59479)

To Reproduce

  1. Windows, NTFS, library whose files carry modification dates from both halves of the year, last full scan done before a DST change.
  2. Let the clock change happen (or set metainformation.lastRescanTimeIsDST to the opposite of the current state).
  3. Either run "Look for new and changed media" → nearly every file is reported as changed and re-read (see numbers below), or
  4. browse the music folder from a client (iPeng, Material, ...) → the same re-read runs inside the server process and blocks it.

Expected behavior

Only files that actually changed are re-read. A folder browse never performs a library-sized synchronous rescan inside the server.

Measurements (after the DST block had run, before the files were re-read)

Sample of 1,500 random local tracks, real_mtime − tracks.timestamp (real mtime read via the Win32 API):

offset share of resolvable tracks file dates Perl stat vs real mtime
+3600 s ~72 % winter-dated (Nov 2017 …) equal
+7200 s ~15 % summer-dated (Jul 2001, Apr 2003, May 2010) Perl reads 3600 s early
0 ~13 % winter-dated (Nov 2009) equal

External scanner run right afterwards (scanner.pl --rescan, three media dirs):

09:56:06 Discovering audio files in D:\la musique 'pop'\platten
09:56:30 Removing deleted audio files (2)
09:56:30 Rescanning changed audio files (50422)
10:04:20 Scanning new audio files (0)
10:04:20 Discovering audio files in D:\la musique 'pop'\unorg
10:04:38 Removing deleted audio files (1)
10:04:39 Rescanning changed audio files (6350)
10:06:48 Discovering audio files in D:\la musique 'pop'\kinder
10:06:49 Rescanning changed audio files (666)
10:07:07 Scanning new audio files (0)

57,438 files re-read, 3 files actually deleted, 0 new, 0 actually changed, 11 minutes. Afterwards a sample of 300 random tracks shows perl stat mtime == tracks.timestamp for all 300, i.e. the re-read merely rewrote what the shift had broken.

System Information

  • OS: Windows 11 Pro 10.0.26300, LMS running as the squeezesvc service
  • Hardware: x86_64 (Ryzen 9 9950X), library on an internal NTFS volume
  • Web skin: Default
  • Browser: Chrome
  • LMS Version: 9.1.1 (1779815526), Perl 5.32.1 MSWin32-x64-multi-thread
  • Players: Squeezebox3, iPeng (the browse that triggered the in-process scan came from iPeng), SqueezeLite
  • Library: ~57,000 local files, SQLite, dbhighmem on

Additional context / suggestions

  • The blanket ±3600 shift cannot be correct given the CRT behaviour. Options: (a) read mtime through the Win32 API (Win32API::File GetFileTime, or Win32::UTCFileTime) so the value is DST-independent and drop the shift; or (b) at minimum shift scanned_files too, so the in-process path does not see a global mismatch.
  • findAndScanDirectoryTree should not run a potentially library-sized synchronous rescan in the server; cap the changed set or hand off to the external scanner above some threshold.
  • Consider resetting isScanning on server start when no scanner process exists.

Happy to test a patch; I can reproduce on demand by toggling the DST flag in metainformation.

Lingua principale
Perl
Stelle
1.8k
Fork
386
Merge medio
2g 4h
PR unite (30g)
15

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

  • Nessun Dockerfile né file Docker Compose
  • Nessun modello di pull request
  • Nessuna 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 LMS-Community/slimserver

Tutte le issue di LMS-Community/slimserver

Issue simili

Altre issue su Perl

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.