
Estaba leyendo el manual de chattr
mi máquina Linux ( kali4-amd64
) cuando vi esto en la lista de definiciones de atributos de archivo:
A directory with the 'P' attribute set will enforce a hierarchical
structure for project id's. This means that files and directory created in
the directory will inherit the project id of the directory, rename
operations are constrained so when a file or directory is moved into
another directory, that the project id's much match. In addition, a hard
link to file can only be created when the project id for the file and the
destination directory match.
Personalmente no sé qué es una "identificación de proyecto" cuando se trata de Linux/UNIX, y al buscar mucho en Google tampoco obtengo resultados, así que espero que alguien aquí pueda ayudarme.
Respuesta1
Lo que estás preguntando es parte del concepto de cuotas de proyecto. Las cuotas de proyectos son una forma de gestionarcuota de disco. Un tipo de sistema de archivos particular puede o no admitir identificaciones de proyecto. Concentrémonos en ext4 y comencemos con man 8 tune2fs
:
-O [^]feature[,...]
Establezca o borre las características (opciones) indicadas del sistema de archivos en el sistema de archivos. […][…]
project
Habilite el seguimiento de ID del proyecto. Esto se utiliza para el seguimiento de la cuota del proyecto.
quota
Habilite los inodos de cuota del sistema de archivos interno.[…]
-Q quota-options
Establece la función de 'cuota' en el superbloque y trabaja en los archivos de cuota para el tipo de cuota determinado. Las opciones de cuota podrían ser una o más de las siguientes:
[^]usrquota
Establece/borra el inodo de cuota de usuario en el superbloque.
[^]grpquota
Establece/borra el inodo de cuota de grupo en el superbloque.
[^]prjquota
Establece/borra el inodo de cuota del proyecto en el superbloque.
Puede habilitar estas opciones en un sistema de archivos existente:
tune2fs -O project,quota /your/device
(o proporcionárselos mke2fs
al crear un nuevo sistema de archivos). Luego habilite la cuota del proyecto (posiblemente con cuota de usuario y/o cuota de grupo si lo desea):
tune2fs -Q prjquota /your/device
Móntalo:
mount /your/device /the/mountpoint
Ahora puede administrar cuotas con herramientas como setquota
y quota
(tenga en cuenta que las versiones antiguas (-ish) de las herramientas pueden carecer de la -P
opción que maneja las cuotas del proyecto). Tradicionalmente, limitaría la cantidad de espacio en disco que puede utilizar el usuario o grupo. Con la cuota de proyecto puedes hacer esto para "proyectos", independientemente de los usuarios y grupos que participen.
Funciona así. Primero colóquese en el punto de montaje y cree algunos directorios:
cd /the/mountpoint
mkdir foo bar baz
Habilite la jerarquía de proyectos en ellos:
chattr +P foo bar baz
Asígnalos a dos proyectos diferentes:
chattr -p 123 foo # 123 is an arbitrary number, project id
chattr -p 5 bar baz # so is 5, the point is they are different
Crea archivos dentro de:
echo "lorem ipsum" > foo/file1
echo "lorem ipsum" > bar/file2
echo "lorem ipsum" > baz/file3
Ahora invoca:
lsattr -pR .
y verás (entre otras) líneas como esta:
123 --------------e---P ./foo/file1
5 --------------e---P ./bar/file2
5 --------------e---P ./baz/file3
lo que significa file1
pertenece al proyecto con id 123
y pertenece al proyecto con id . Si define cuotas para estos proyectos (es decir, limita la cantidad de espacio en disco que los proyectos pueden usar), cada archivo afectará el consumo de cuota de su proyecto respectivo.file2
file3
5
Ahora lo que citaste tiene mucho sentido:
Los archivos y el directorio creados en el directorio heredarán la identificación del proyecto del directorio.
En nuestro ejemplo, file1
heredó la identificación del proyecto de foo
. Si crea más archivos/directorios, foo
también heredarán la identificación. Esto le permite a usted (y a otros usuarios) trabajar en el proyecto en su directorio designado, mientras que los archivos que cree cuentan automáticamente para la cuota respectiva.
Solo se puede crear un vínculo físico al archivo cuando la identificación del proyecto para el archivo y el directorio de destino coinciden.
ln ./baz/file3 ./foo/
fracasará (inténtelo) pero ln ./baz/file3 ./bar/
tendrá éxito. El sistema operativo no le permitirá "incrustar" fácilmente un archivo que pertenece a un proyecto (y debe permanecer así porque la ruta de origen no está desvinculada) en un directorio de proyecto diferente. Se permite vincular un archivo dentro de su proyecto.
cuando un archivo o directorio se mueve a otro directorio, la identificación del proyecto debe coincidir
Creo que esto es bastante engañoso. mv
hará su trabajo incluso si las identificaciones no coinciden. El punto es que si invocas
mv baz/file3 foo/
la herramienta primero intentará ubicar rename(2)
el archivo en la nueva ruta, esto fallará (como ln
ocurre arriba). Normalmente o dentro del mismo proyecto tendría éxito y el nombre original desaparecería. Aparentemente, este comportamiento es de lo que se trata "la identificación del proyecto debe coincidir".
Pero mv
no saldrá todavía. Es como moverse entre sistemas de archivos: después de mv
no poder cambiar el nombre, vuelve al modo copiar+eliminar. En efecto, crea unaCopiar(con un nuevo número de inodo) en el directorio de destino. En nuestro caso, la copia hereda la identificación del proyecto foo
(como lo haría cualquier archivo nuevo en este directorio), por lo que afecta el consumo de cuota del proyecto 123
. A continuación, se desvincula la ruta original. Esto puede afectar el consumo de cuota del proyecto 5
; o no: los enlaces duros o los descriptores de archivos abiertos harán que el inodo y los datos originales sobrevivan.
Tenga en cuenta que es algo sorprendente: se crea un archivo nuevo, los enlaces duros antiguos (si los hay) no están vinculados al archivo nuevo, los descriptores de archivo que apuntan al archivo antiguo no tienen nada que ver con el nuevo; como si la operación de movimiento se realizara entre sistemas de archivos.
Hay una manera de cambiar mv
el nombre en lugar de copiar+eliminar. Si asigna manualmente el archivo original al proyecto de destino
chattr -p 123 baz/file3
entonces mv baz/file3 foo/
realmente lo moverá sin copiarlo, sin romper los enlaces físicos (si los hay). Pero tenga en cuenta que el número de proyecto pertenece al inodo (no a la ruta, ni al nombre, ni a la entrada del directorio), por lo que chattr -p
afecta a todos los enlaces físicos.
Entonces, si necesita mover un archivo grande (es decir, datos detrás de algún inodo, no solo uno de muchos enlaces físicos) a otro proyecto, cambiar el proyecto y luego moverlo le ahorrará copias innecesarias.