1 votos

¿Por qué el sleepimage y el swapfile están llenos de ceros?

Si miro el contenido de sleepimage o swapfile en /var/vm , me parece que es sólo 1,07G de bytes nulos. Yo esperaría que contengan datos reales, o si no se están utilizando que sean un archivo 0B. He comprobado unas cuantas versiones de SO diferentes y he verificado que esto es así desde la 10.9 hasta la 11.6, así que dudo que sea algo particular de una configuración o sistema de archivos determinado.

1voto

Paul Lindner Puntos 986

Decidí indagar un poco en el código fuente del kernel y tengo una respuesta aproximada, pero aún no está 100% claro. Si echas un vistazo a IOHibernateIO.cpp dentro del IOHibernateSystemPostWake se ve la siguiente llamada (nota: ligeramente diferente para 10.11+, pero se acaba llamando a la misma función)

    if (kFSOpened == gFSState)
    {
    // invalidate & close the image file
    gIOHibernateCurrentHeader->signature = kIOHibernateHeaderInvalidSignature;
    if ((fileRef = gIOHibernateFileRef))
    {
        gIOHibernateFileRef = 0;
        IOSleep(TRIM_DELAY);
        kern_close_file_for_direct_io(fileRef,
#if DISABLE_TRIM
                       0, 0, 0, 0, 0);
#else
                       0, (caddr_t) gIOHibernateCurrentHeader, 
                       sizeof(IOHibernateImageHeader),
                       0,
                       gIOHibernateCurrentHeader->imageSize);
#endif
    }
    gFSState = kFSIdle;
    }
    return (kIOReturnSuccess);

Es importante, DISABLE_TRIM se define como 0, por lo que acabamos llamando a kern_close_file_for_direct_io cuya firma es la siguiente:

void
kern_close_file_for_direct_io(struct kern_direct_file_io_ref_t * ref,
                  off_t write_offset, caddr_t addr, vm_size_t write_length,
                  off_t discard_offset, off_t discard_end)

y cuya aplicación parece emitir primero un DKIOCUNMAP ioctl para los extensiones que pertenecen al archivo de hibernación, luego copia write_length bytes de la dirección de memoria addr en el archivo. Si miramos un poco hacia atrás, gIOHibernateCurrentHeader se pone a cero en la memoria después de escribir la imagen de hibernación durante IOHibernateSystemSleep .

Esto nos lleva a unas cuantas conclusiones, así como a unas cuantas preguntas persistentes:

  • Efectivamente, este parece ser el comportamiento previsto, y puedo ver un DKIOCUNMAP que se emite dentro de vm_compressor_backing_file.c por lo que asumo que algo similar ocurre con los archivos de intercambio también.

  • Sin embargo, no sé qué significa esto para el espacio ocupado físicamente en el disco. En el caso de APFS esto es trivial ya que soporta archivos dispersos (por lo que incluso si el archivo es realmente 1,7G de bytes nulos no importará), pero ¿qué pasa con HFS+? Tengo entendido que el DKIOCUNMAP ioctl se traduce efectivamente en el comando TRIM de las SSD para limpiar los bloques usados:

El método doUnmap fue introducido como reemplazo del método doDiscard. Realiza una función similar, que es liberar los bloques de disco que no son utilizados por el sistema de archivos. A diferencia del método doDiscard, que es capaz de liberar sólo una serie de bloques de disco físicamente contiguos, el método doUnmap recibe un array que contiene uno o más rangos de bloques de disco que ya no están en uso. Un proceso del espacio de usuario puede realizar esta acción enviando el ioctl DKIOCUNMAP.

lo que parece implicar que, a pesar de que el nivel del sistema de archivos piensa que el tamaño del archivo es de 1,7G, ninguno de esos extents apunta realmente a bloques válidos en el disco, y por lo tanto el tamaño físico del archivo es mucho menor. Esto también explicaría por qué son 1,7G de ceros, ya que asumo que el controlador del SSD al recibir el comando de recorte podría implementar RZAT (devolver ceros después del recorte). Esta hipótesis se podría comprobar probando esto en un disco giratorio y viendo si se devuelven datos.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X