Έλεγχος για rotation log αρχείου
Giorgos Keramidas
keramida at ceid.upatras.gr
Wed Sep 16 15:35:57 EEST 2009
On Wed, 16 Sep 2009 14:34:22 +0300, George Notaras <gnot at g-loaded.eu> wrote:
> Giorgos Keramidas wrote:
>> Αν προσέξεις τις διαφορές σε inode και size του finfo('foo') και του
>> fdinfo(fd) θα δεις ότι είναι πια εύκολο να καταλάβεις ότι έχει αλλάξει
>> το αρχείο στο δίσκο και πρέπει να το κάνεις reopen.
>>
>> Αν έχει αλλάξει το i-node έγινε rename, οπότε μπορείς να συνεχίσεις από
>> το offset 0 ξανανοίγοντας το αρχείο.
>>
>> Αν έχει το ίδιο i-node αλλά διαφορετικό μέγεθος, μάλλον έγινε truncate
>> in place. Σε αυτή την περίπτωση έχεις την επιλογή είτε να αρχίσεις από
>> την αρχή πάλι ή να περιμένεις μέχρι να ξεπεράσει σε μέγεθος το offset
>> που είχες διαβάσει τελευταία φορά.
>
> Αν και η ιδέα του Ρικούδη για το pipe με έβαλε σε σκέψεις, μάλλον θα
> προχωρήσω με αυτούς του ελέγχους. Μέχρι τώρα προσπαθούσα χωρίς την
> stat(), παρά μόνο με read(), tell() και seek() να ανιχνεύσω το
> rotation, κάτι μάλλον αδύνατο.
Η αλήθεια είναι ότι κι η stat() έχει το δικό της σετ από «προβλήματα»,
αφού δε σου εγγυάται κανείς ότι δε θα γίνει κάτι σαν:
Το Πρόγραμμά Σου Κάποιος άλλος
| |
| |
+-- fd = os.open(path) |
| |
| +-- rename(path, path2)
| |
| |
+-- stat(path) |
| |
| |
| +-- rename(path2, path)
| |
| |
v v
now now
Σε αυτό το σημείο εσύ «πιστεύεις» ότι το αρχείο άλλαξε, αλλά μετά το
δεύτερο rename() το "path" αναφέρεται πάλι στο ίδιο ακριβώς i-node.
Επειδή αυτό είναι μια κάπως παθολογική περίπτωση, μπορείς να προσθέσεις
ένα ακόμα έλεγχο *αφού* ξανανοίξεις το αρχείο, κι αν όντως είναι το ίδιο
με το αρχικό file πριν τα 2 rename() calls, να ελέγξεις αν έχει ακόμα
μέγεθος >= αρχικό μέγεθος και να κάνεις seek εκεί που ήσουνα αρχικά.
Αλλά τώρα πια ξεφεύγουμε από το τι είναι ένα "log file tail mode" και τι
πρέπει να κάνει το tail-like πρόγραμμα και ασχολούμαστε με γενικότερα
stat()-based race conditions, με τα οποία οποιοδήποτε πρόγραμμα μπορεί
να την πατήσει.
More information about the Linux-greek-users
mailing list