Como determinar se um sistema de arquivos linux pertence ou não a um sistema em execução

2

Eu preciso escrever um programa que receba um dispositivo de bloco como entrada, como / dev / sda1, e tenha que executar um conjunto de operações, dependendo de o sistema de arquivos estar ou não em execução no momento.

Assumiremos que a entrada sempre terá uma árvore de diretórios do Linux correta, o único que eu preciso saber é se existe uma estrutura de diretório ou arquivo / s específico que possa determinar com segurança se o sistema interno está sendo executado. Quero dizer, se o sistema de arquivos contém a raiz de um sistema que está ligado.

Ele deve funcionar para qualquer sistema de arquivos ou versão do kernel do Linux.

Obrigado!

    
por jlledom 12.01.2013 / 21:55

2 respostas

0

Eu escrevi uma função que retorna 1 se o argumento for o dispositivo raiz, 0 se não for e um valor negativo para erro:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

static int
root_check(const char *disk_dev)
{
        static const char  root_dir[] = "/";
        struct stat        root_statb;
        struct stat        dev_statb;

        if (stat(root_dir, &root_statb) != 0)
        {
                perror(root_dir);
                return -1;
        }
        if (!S_ISDIR(root_statb.st_mode))
        {
                fprintf(stderr, "Error: %s is not a directory!\n", root_dir);
                return -2;
        }
        if (root_statb.st_ino <= 0)
        {
                fprintf(stderr, "Warning: %s inode number is %d; "
                                "unlikely to be valid.\n",
                                        root_dir, root_statb.st_ino);
        }
        else if (root_statb.st_ino > 2)
        {
                fprintf(stderr, "Warning: %s inode number is %d; "
                                "probably not a root inode.\n",
                                        root_dir, root_statb.st_ino);
        }
        if (stat(disk_dev, &dev_statb) != 0)
        {
                perror(disk_dev);
                return -1;
        }
        if (S_ISBLK(dev_statb.st_mode))
                /* That's good. */ ;
        else if (S_ISCHR(dev_statb.st_mode))
        {
                fprintf(stderr, "Warning: %s is a character-special device; "
                                "might not be a disk.\n", disk_dev);
        }
        else
        {
                fprintf(stderr, "Warning: %s is not a device.\n", disk_dev);
                return(0);
        }
        if (dev_statb.st_rdev == root_statb.st_dev)
        {
                printf("It looks like %s is the root file system (%s).\n",
                                        disk_dev, root_dir);
                return(1);
        }
        // else
        printf("(It looks like %s is NOT the root file system.)\n", disk_dev);
        return(0);
}

Os dois primeiros testes são basicamente verificações de sanidade: se stat("/", …) falhar ou " / " não for um diretório, seu sistema de arquivos está quebrado. Os testes st_ino são uma espécie de tiro no escuro. AFAIK, números de inodes nunca devem ser negativos ou nulos. Historicamente (pelo que me refiro a 30 anos atrás), o diretório-raiz sempre teve o inode número 1. Isso ainda pode ser verdade para alguns tipos de * nix (alguém ouviu falar de “Minix”?), E pode ser verdade para o especial sistemas de arquivos, como /proc , e para sistemas de arquivos Windows (FAT), mas a maioria dos sistemas Unix e Unix-like contemporâneos parecem usar o inode número 1 para rastrear blocos ruins, empurrando a raiz para o inode número 2.

S_ISBLK é verdadeiro para "dispositivos de bloco", como /dev/sda1 , em que a saída de ls -l começa com " b ". Da mesma forma, S_ISCHR é verdadeiro para "dispositivos de caractere", em que a saída de ls -l começa com " c ". (Você pode ocasionalmente ver nomes de disco como /dev/rsda1 ; o " r " significa "raw". Dispositivos de disco brutos às vezes são usados para fsck e backup, mas não para montagem.) Todo inode tem st_dev , que diz em qual sistema de arquivos esse inode está. Os inodes para dispositivos também têm st_rdev campos, que dizem quais dispositivos eles são . (Os dois números separados por vírgulas que você vê no lugar do tamanho do arquivo quando você ls -l um dispositivo são os dois bytes de st_rdev .)

Assim, o truque é ver se o st_rdev do dispositivo de disco corresponde ao st_dev do diretório raiz; ou seja, o dispositivo especificado é aquele em que “ / ” está ativado?

    
por 20.04.2013 / 00:14
0

Você pode verificar se o dispositivo está montado e onde:

awk -v device=/dev/sda1 ' $1 == device {print $2}' /proc/mounts

Isso não detecta dispositivos usados por um subsistema do kernel, como mdraid ou LVM. Estes são visíveis através de /sys/class/block/sda1/holders (esse diretório contém um link simbólico para o item de mapeador de dispositivo que usa o dispositivo).

    
por 14.01.2013 / 02:10