Inotify attiva una notifica quando viene avviata una scrittura o quando è stata completata?


12

Immagina due processi, un lettore e uno scrittore, che comunicano tramite un normale file su un ext3 fs. Reader ha un IN_MODIFYcontrollo inotify sul file. Writer scrive 1000 byte nel file, in una singola write()chiamata. Reader ottiene l'evento inotify e chiama fstatil file. Cosa vede Reader?

  1. C'è qualche garanzia che Reader possa recuperare almeno 1000 per st_sizeil file? Dai miei esperimenti, sembra di no.

  2. C'è qualche garanzia che Reader possa effettivamente read()1000 byte?

Questo sta accadendo in una casella associata I / O seriamente. Ad esempio, sarmostra un tempo di attesa di circa 1 secondo. Nel mio caso il Reader è in realtà in attesa 10 secondi DOPO ottenere l'evento inotify prima di chiamare state ottenere risultati troppo piccoli.

Quello che avevo sperato era che l'evento inotify non fosse consegnato fino a quando il file non fosse pronto. Ciò che sospetto stia effettivamente accadendo è che l'evento inotify si attiva DURANTE la write()chiamata in Writer e che i dati siano effettivamente disponibili per altri processi sul sistema ogni volta che si presenta pronto. In questo caso, 10s non è abbastanza tempo.

Immagino che sto solo cercando la conferma che il kernel effettivamente implementa inotifica il modo in cui sto indovinando. Inoltre, se ci sono opzioni, possibilmente, per modificare questo comportamento?

Infine, qual è il punto di inotificare, dato questo comportamento? Sei ridotto a eseguire il polling del file / directory comunque, dopo aver ottenuto l'evento, fino a quando i dati non saranno effettivamente disponibili. Potrebbe anche farlo tutto il tempo, e dimenticare di inotificare.

*** MODIFICARE ** * * Va bene, come spesso accade, il comportamento che sto vedendo ha davvero senso, ora che capisco cosa sto davvero facendo. ^ _ ^

In realtà sto rispondendo a un evento IN_CREATE sulla directory in cui risiede il file. Quindi sto effettivamente stat () 'il file in risposta alla creazione del file, non necessariamente l'evento IN_MODIFY, che potrebbe arrivare più tardi.

Ho intenzione di cambiare il mio codice in modo che, una volta ricevuto l'evento IN_CREATE, mi iscriverò a IN_MODIFY sul file stesso e non tenterò effettivamente di leggere il file finché non avrò l'evento IN_MODIFY. Mi rendo conto che c'è una piccola finestra lì in cui potrei perdere una scrittura sul file, ma questo è accettabile per la mia applicazione, perché nel caso peggiore, il file verrà chiuso dopo un numero massimo di secondi.


È possibile utilizzare una pipe anziché un file. Vedi man mknod
daniel kullmann l'

È necessario utilizzare un file normale per disporre di un buffer di più terabyte tra i due processi. Anche per preservare i dati nel buffer al riavvio.
Todd ha liberato l'

Risposte:


5

Da quello che vedo nel sorgente del kernel , inotify si accende solo dopo che una scrittura è stata completata (cioè la tua ipotesi è sbagliata). Dopo l'attivazione della notifica, si verificano solo altre due cose sys_write, la funzione che implementa il writesyscall: impostazione di alcuni parametri dello scheduler e aggiornamento della posizione sul descrittore di file. Questo codice è stato simile fino al 2.6.14 . Al momento dell'attivazione della notifica, il file ha già le sue nuove dimensioni.

Controlla cose che potrebbero andare storte:

  • Forse il lettore sta ricevendo vecchie notifiche, dalla precedente scrittura.
  • Se il lettore chiama state poi chiama reado viceversa, potrebbe succedere qualcosa nel mezzo. Se continui ad aggiungere file, la statprima chiamata garantisce che sarai in grado di leggere così lontano, ma è possibile che siano stati scritti più dati al momento della chiamata del lettore read, anche se non ha ancora ricevuto la notifica di inotify.
  • Solo perché lo scrittore chiama writenon significa che il kernel scriverà il numero richiesto di caratteri. Ci sono pochissime circostanze in cui le scritture atomiche sono garantite fino a qualsiasi dimensione. Ogni writechiamata è garantita atomica, tuttavia: ad un certo punto i dati non sono ancora stati scritti, quindi all'improvviso sono stati scritti n byte, dove n è il valore restituito della writechiamata. Se si osserva un file parzialmente scritto, significa che ha writerestituito meno dell'argomento size.

Strumenti utili per indagare su ciò che sta accadendo includono:

  • strace -tt
  • il sottosistema auditd

Grazie per le idee. Ho appena rivisto il codice e in effetti sto solo controllando -1 come valore di ritorno da scrivere per il caso di errore. Quindi, può darsi che non stia ottenendo il valore restituito da write indicando che tutti i dati sono stati scritti. Tuttavia, quando guardo il file dopo il fatto, so che tutti i "1000" byte sono stati effettivamente scritti, perché il file è in buona forma, cioè è costituito da record interi e coerenti. Quindi il primo record non viene parzialmente scritto.
Todd ha liberato il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.