Pude modificar el ctime con dos métodos diferentes:
- Cambiando el kernel para que
ctime
coincide con elmtime
- Escribir un script de shell simple (pero complicado).
Primer método:cambiar el kernel.
Ajusté solo unas pocas líneas en KERNEL_SRC/fs/attr.c
Esta modificación actualiza ctime para que coincida con mtime siempre que mtime esté "definido explícitamente".
Hay muchas formas de "definir explícitamente" el mtime, por ejemplo:
En Linux:
touch -m --date="Wed Jun 12 14:00:00 IDT 2013" filename
En Java (usando Java 6 o 7, y presumiblemente otros):
long newModificationTime = TIME_IN_MILLIS_SINCE_EPOCH;
File myFile = new File(myPath);
newmeta.setLastModified(newModificationTime);
Aquí está el cambio a KERNEL_SRC/fs/attr.c
en el notify_change
función:
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) Esta línea, sin comentarios, actualizaría el ctime a la hora actual del reloj al cambiar el archivo. No queremos eso, ya que queremos establecer el ctime nosotros mismos. Por lo tanto, comentamos esta línea. (Esto no es obligatorio)
(2) Este es realmente el quid de la solución. El notify_change
La función se ejecuta después de que se haya cambiado un archivo, donde los metadatos de tiempo deben actualizarse. Si no se especificó mtime, entonces mtime se establece en la hora actual. De lo contrario, si mtime se estableció en un valor específico, también establecemos ctime y atime en ese valor.
Segundo método:secuencia de comandos de shell simple (pero hacky).
Breve explicación:
- Cambia la hora del sistema a tu hora objetivo
- Realice un chmod en el archivo, el archivo ctime ahora refleja el tiempo objetivo
- Revertir la hora del 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"
Ejecute esto de la siguiente manera:./changectime.sh MYFILE
El ctime del archivo ahora reflejará el tiempo en el archivo.
Por supuesto, probablemente no desee el archivo con permisos 777. Asegúrese de modificar este script según sus necesidades antes de usarlo.
Adaptando esta respuesta a tu 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");
Dudo que veamos un método conveniente en la API estándar de Java para hacer esto, ya que ni Linux (man touch ) ni Windows (GetFileTime función en MSDN) dan fácil acceso a este campo. Las llamadas al sistema nativo solo dan acceso a la creación/acceso/modificación de marcas de tiempo, al igual que Java.