Sono stato in grado di modificare il ctime con due metodi diversi:
- Cambiando il kernel in modo che
ctime
corrisponde amtime
- Scrivere un semplice (ma confuso) script di shell.
1° metodo:cambiare il kernel.
Ho modificato solo poche righe in KERNEL_SRC/fs/attr.c
Questa modifica aggiorna ctime in modo che corrisponda a mtime ogni volta che mtime è "definito in modo esplicito".
Esistono molti modi per "definire esplicitamente" l'mtime, ad esempio:
In Linux:
touch -m --date="Wed Jun 12 14:00:00 IDT 2013" filename
In Java (usando Java 6 o 7, e presumibilmente altri):
long newModificationTime = TIME_IN_MILLIS_SINCE_EPOCH;
File myFile = new File(myPath);
newmeta.setLastModified(newModificationTime);
Ecco la modifica a KERNEL_SRC/fs/attr.c
nel notify_change
funzione:
now = current_fs_time(inode->i_sb);
//attr->ia_ctime = now; (1) Comment this out
if (!(ia_valid & ATTR_ATIME_SET))
attr->ia_atime = now;
if (!(ia_valid & ATTR_MTIME_SET)) {
attr->ia_mtime = now;
}
else { //mtime is modified to a specific time. (2) Add these lines
attr->ia_ctime = attr->ia_mtime; //Sets the ctime
attr->ia_atime = attr->ia_mtime; //Sets the atime (optional)
}
(1) Questa riga, non commentata, aggiornerebbe il ctime all'ora corrente in caso di modifica del file. Non lo vogliamo, dal momento che vogliamo impostare noi stessi il ctime. Pertanto, commentiamo questa riga. (Questo non è obbligatorio)
(2) Questo è veramente il nocciolo della soluzione. Il notify_change
La funzione viene eseguita dopo che un file è stato modificato, in cui i metadati dell'ora devono essere aggiornati. Se non è stato specificato mtime, allora mtime è impostato sull'ora corrente. Altrimenti, se mtime è stato impostato su un valore specifico, impostiamo anche ctime e atime su quel valore.
Secondo metodo:script di shell semplice (ma confuso).
Breve spiegazione:
- Modifica l'ora di sistema con l'ora target
- Esegui un chmod sul file, il file ctime ora riflette l'ora target
- Ripristina l'ora di sistema.
changectime.sh
#!/bin/sh
now=$(date)
echo $now
sudo date --set="Sat May 11 06:00:00 IDT 2013"
chmod 777 $1
sudo date --set="$now"
Eseguilo come segue:./changectime.sh MYFILE
Il ctime del file ora rifletterà l'ora nel file.
Ovviamente, probabilmente non vuoi il file con i permessi 777. Assicurati di modificare questo script in base alle tue esigenze prima di utilizzarlo.
Adattando questa risposta al tuo caso:
// Warning: Disk must be unmounted before this operation
String disk = "/dev/sda1";
// Update ctime
Runtime.getRuntime().exec("debugfs -w -R 'set_inode_field "+pathToMyFile+" ctime "+myCustomTime+"' "+disk);
// Drop vm cache so ctime update is reflected
Runtime.getRuntime().exec("echo 2 > /proc/sys/vm/drop_caches");
Dubito che vedremo un metodo conveniente nell'API Java standard per farlo, poiché né Linux (man touch ) né Windows (GetFileTime funzione su MSDN) consentono un facile accesso a questo campo. Le chiamate di sistema native danno solo accesso ai timestamp di creazione/accesso/modifica, così fa Java.