2011-04-01 20 views
5

Me gustaría saber qué entrada en/dev un archivo está en Por ejemplo, si/dev/sdc1 está montado en/media/disk, y pedir/media /. disk/foo.txt, me gustaría obtener/dev/sdc como respuesta.Linux de programación: el dispositivo que un archivo está en

Usando stat llame al sistema en ese archivo Obtendré su partición mayor y menores números (8 y 33, para sdc1). Ahora necesito obtener el dispositivo "raíz" (sdc) o su principal/menor de eso. ¿Existe alguna función de biblioteca o función de biblioteca que pueda utilizar para vincular una partición a su dispositivo principal? ¿O mejor aún, para obtener ese dispositivo directamente del archivo?

brw-rw---- 1 root floppy 8, 32 2011-04-01 20:00 /dev/sdc 
brw-rw---- 1 root floppy 8, 33 2011-04-01 20:00 /dev/sdc1 

¡Gracias de antemano!

Respuesta

8

La versión rápida y sucia: df $file | awk 'NR == 2 {print $1}'.

Programado ... bueno, hay una razón por la que comencé con la versión rápida y sucia. No hay forma portátil de obtener programáticamente la lista de sistemas de archivos montados. (getmntent() obtiene fstab entradas, lo cual no es lo mismo.) Además, ni siquiera se puede analizar la salida de mount(8) de manera confiable; en Unixes diferentes, el punto de montaje puede ser el primero o el último elemento. La forma más portátil de hacer esto termina siendo ... el análisis df de salida (e incluso eso es dudoso, como notó con el número de partición). Por lo que está de vuelta a la solución de la envoltura rápido y sucio de todos modos, a menos que usted quiere realizar el desplazamiento /dev y busque los dispositivos de bloque a juego con major(st_rdev) (major() ser de sys/types.h).

Si se restringe a este Linux, puede utilizar /proc/mounts para obtener la lista de sistemas de archivos montados. Otros Unixes específicos se pueden optimizar de manera similar: por ejemplo, en OS X y creo que FreeBSD, puede usar sysctl() en el árbol vfs para obtener puntos de montaje. En el peor, se puede encontrar y utilizar el archivo de cabecera apropiada para descifrar lo que el archivo de la tabla de montaje es (y sí, incluso que varía: en Solaris es /etc/mnttab, en muchos otros sistemas Es /etc/mtab, algunos sistemas ponen en /var/run en lugar de /etc, y en muchos Linuxes es inexistente o un enlace simbólico al /proc/mounts). Y su formato es diferente en prácticamente todos los sistemas operativos tipo Unix.

+0

Gracias, pero me gustaría achive esto utilizando únicamente las llamadas System/Library. Además, su sugerencia es darme el número de partición ;-) – Grieih

+0

@Grieih: +1 a esto porque nunca ha especificado que desea esto en C-code. PD al agregar '-F '[0-9]'' se eliminará el número de partición – SiegeX

+1

@Greih: ver actualización. Fui con eso por una razón, desafortunadamente. – geekosaur

2

Lo que se busca es imposible - no hay conexión 1: 1 entre un archivo de dispositivo de bloque y la partición se está describiendo.

considerar:

  1. puede crear varios archivos de dispositivo de bloque con diferentes nombres (pero los mismos números mayor y menor) y son indistinguibles (N: 1)

  2. Se puede utilizar una bloquear archivo de dispositivo como un argumento para montar para montar una partición y luego eliminar el archivo de dispositivo de bloque dejando la partición montada. (0: 1)

De modo que no hay forma de hacer lo que desee excepto en algunos casos específicos y restringidos.

1

número mayor le dirá qué dispositivo es: 3 - IDE en primera controladora, 22 - IDE en segundo controlador y 8 para SCSI.

El número menor le indicará el número de partición y, para dispositivos IDE, si es unidad principal o secundaria.Este cálculo es diferente para IDE y SCSI.

Para IDE es: x * 64 + p, x es el número de unidad en el controlador (0 o 1) y p es partición

Para SCSI es: y * 16 + p, donde y es la unidad número y p es la partición

3

La información que desea existe en sysfs que expone el árbol del dispositivo Linux. Esto modela las relaciones entre los dispositivos en el sistema y, como usted está tratando de determinar un dispositivo de disco padre desde una partición, este es el lugar para buscar. No sé si existen reglas duras y rápidas en las que pueda confiar para evitar que su código se rompa con versiones futuras del kernel, pero los desarrolladores del núcleo intentan mantener sysfs como una interfaz estable.

Si mira /sys/dev/block/<major>:<minor>, verá que se trata de un enlace simbólico con los componentes de la cola como block/<disk-device-name>/<partition-device-name>. Si tuviera que realizar una llamada al sistema readlink(2), podría analizar el destino del enlace para obtener el nombre del dispositivo de disco. Con cáscara (ya que es más fácil de expresar de esta manera, pero hacerlo en C será bastante fácil):

$ echo $(basename $(dirname $(readlink /sys/dev/block/8:33))) 
sdc 

Como alternativa, puede tomar ventaja de la anidación de directorios de partición en los directorios del disco (de nuevo con cáscara, pero a partir de C, su un open(2), read(2) y close(2)):

$ cat /sys/dev/block/8:33/../dev 
8:32 

Esto supone PUESTA mayor: menor es en realidad para una partición, no algún otro tipo de dispositivo no anidada.

Cuestiones relacionadas