Determinar o tamanho de um dispositivo de bloco


Respostas:


73

fdisknão entende o layout da partição usada pelo meu Mac executando o Linux, nem qualquer outro formato de partição que não seja o PC. (Sim, existem mac-fdiskpara tabelas de partições antigas do Mac e gdiskpara tabelas de partições GPT mais recentes, mas esses não são os únicos outros layouts de partição disponíveis.)

Como o kernel já examinou os layouts de partição quando o dispositivo de bloco entrou em serviço, por que não perguntar diretamente?

$ cat / proc / partitions
nome principal #blocks menor

   8 16 390711384 sdb
   8 17 514079 sdb1
   8 18 390194752 sdb2
   8 32 976762584 sdc
   8 33 514079 sdc1
   8 34 976245952 sdc2
   8 0 156290904 sda
   8 1 514079 sda1
   8 2 155774272 sda2
   8 48 1465138584 sdd
   8 49 514079 sdd1
   8 50 1464621952 sdd2

Isso não funciona para coisas como unidades de CD
Ganesh Sittampalam

2
E também informa apenas nomes "nativos". Em um servidor com iSCSI e / ou multipath e / ou LVM, você obtém vários dispositivos sd * e dm- *, mas geralmente você precisa procurar o link simbólico do que realmente está interessado (por exemplo, a / dev / mapper / * one)
Luke404

2
Os valores relatados aqui são múltiplos de 1 KB, que podem ser um setor (512 bytes) muito pequeno.
Lekensteyn

1
Isso foi útil para mim. Acabei fazendoawk '/sd[a-z]$/{printf "%s %8.2f GiB\n", $NF, $(NF-1) / 1024 / 1024}' /proc/partitions
suprjami

173

blockdev --getsize64 /dev/sda retorna tamanho em bytes.

blockdev --getsz /dev/sda retorna tamanho em setores de 512 bytes.

Descontinuado: blockdev --getsize /dev/sdaretorna o tamanho em setores.

O blockdev faz parte do util-linux .


4
infelizmente precisa de energia superusuário
heinrich5991

6
@ heinrich5991 você não tem escolha. Um usuário normal não pode acessar um dispositivo de bloco diretamente ("leitura bruta"), o que é bom para segurança.
Totor 23/05

@ Motor Claro, mas ainda existem respostas para essa pergunta específica que não exigem direitos de superusuário.
heinrich5991 23/05

2
@ heinrich5991 ao trabalhar com sistemas de arquivos, você deve perguntar ao statfs () e aos amigos. Mais importante, você não deve assumir nenhuma relação direta entre o tamanho do dispositivo de bloco e o espaço total / utilizável / efetivo / livre / qualquer espaço no sistema de arquivos.
precisa saber é o seguinte

2
A página de manual em linux.die.net/man/8/blockdev diz que --getsizeestá obsoleta e sugere --getszsetores consistentes de 512 bytes. Se --getsizedeve ser usado, acho --getssque também deve ser usado para garantir que o tamanho do setor seja o que você espera.
Mwfearnley

35
cat /sys/class/block/sda/size

Isso fornece seu tamanho em blocos de 512 bytes.


9
@ heinrich5991 Como você pode ter certeza de que o tamanho do bloco do dispositivo é sempre 512 bytes?
Totor 26/05

5
O tamanho do setor é sempre 512 bytes, de acordo com a fonte . Para o futuro, estou tentando documentar essa interface .
Lekensteyn

Obrigado por deixar isso claro. Notei que também há um / sys / class / block / sda / queue / logic_block_size. Eu não tinha certeza se deveria usar isso, ou a constante 512.
Edward Falk

33

Este código simples. Não foi possível encontrar nenhuma documentação, mas funciona bem:

#include <linux/fs.h>
...
ioctl(file, BLKGETSIZE64, &file_size_in_bytes);

Correção: na verdade, você obtém o tamanho em SETORES. Edite e eu votarei.
JCCyC

8
@JCCyC: BLKGETSIZE64retorna o tamanho em bytes. Veja linux/fs.h, que observa "retornar o tamanho do dispositivo em bytes". Observe que BLKGETSIZE(sem "64") retorna "/ 512".
Thanatos

Elaborei uma amostra mais completa, parcialmente baseada nisso, em stackoverflow.com/a/48490543/446106 . Para usar o snippet acima aqui, fileprecisa ser um descritor de arquivo (por exemplo, from open()) e file_size_in_bytesdeve ser a size_t.
precisa saber é o seguinte

(Na verdade, file_size_in_bytesdeve ser um tipo de 64 bits, por isso deve ser unsigned long long.)
mwfearnley

16

E se:

fdisk -l

Isso fornecerá uma lista de todos os seus discos com a respectiva capacidade, uso e muito mais.


3
Experimente com sudo, caso contrário, apenas imprime nada.
Alfe

10

blockdev --getsize /dev/sda


Use com sudo, caso contrário você recebe Permission denied.
Wimateeka

9

lsblk fornece as informações que você está procurando, incluindo tipos de dispositivos e pontos de montagem (se houver), com uma exibição em árvore e em um formato legível por humanos.

Tipo de dispositivo significa que ele funciona para unidades de CD, conforme solicitado por Ganesh Sittampalam.

Para obter apenas o tamanho de um dispositivo específico em bytes:

lsblk -rbno SIZE /dev/block-device

7
echo "`cat /sys/class/block/sda2/size`*512" | bc

ou se você usa o bash ou qualquer outro shell semelhante ao POSIX, cujos operadores aritméticos trabalham com números inteiros de 64 bits, você nem precisa chamar bc

echo "$((512*$(cat /sys/class/block/sda2/size)))"

dá o tamanho em bytes.

A chamada para catgarfo e (exceto para bash) pode ser otimizado afastado com bash, ksh93e zshcom:

echo "$((512*$(</sys/class/block/sda2/size)))"

5

Não há necessidade de ioctl em C. Basta procurar o final do arquivo e obter o tamanho (em bytes) dessa maneira:

/* define this before any #includes when dealing with large files: */
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

// ...
int fd = open("/dev/sda", O_RDONLY);
off_t size = lseek(fd, 0, SEEK_END);
// Now size is the size of the file, in bytes, or -1 on error.
// lseek(fd, 0, SEEK_SET) to get back to the start of the file.

Se você está procurando o tamanho da unidade de disco bruto, precisará de privs raiz para abrir o arquivo e procurar o final.
Edward Falk

5

O blockdev (8) tem uma resposta diferente? Opções --getsze obsoletas --getsizenão são as mesmas.

  • BLKSSZGET ( blockdev --getss) é para o tamanho do setor físico e
  • BLKBSZGET ( blockdev --getbsz) é para o tamanho do setor lógico.
echo $(($(blockdev --getsize64 /dev/sda)/$(blockdev --getss /dev/sda)))

Na verdade, acho que você reverteu. (A menos que meu sistema tem blocos físicos de 512 bytes e blocos lógicos de 4096 bytes.)
Edward Falk

2
Bem, eu percebi que block/ioctl.cno Linux a fonte do kernel contém comentários enganosos. BLKPBSZGET (observe que P) obtém o tamanho do setor físico, BLKSSZGET obtém o tamanho lógico do setor e BLKBSZGET (ou BLKBSZGET_32 in block/compat_ioctl.c) obtém o tamanho da unidade de alocação do sistema de arquivos (cluster). O tamanho do setor lógico e físico é diferente quando o Advanced Format 512e é usado. ( 512e @ WP )
Palec

@Palec Comentário mais esclarecido entre todas as respostas e comentários a esta pergunta.
Irfan Latif

5

Primeiro, meus agradecimentos a todos que contribuíram. Eu aprendi algumas coisas úteis.

Ainda assim, minha experiência é que a maioria dessas respostas é um tanto incompleta, pelo menos no que diz respeito a CD e DVDs, principalmente se eles estão disponíveis para usuários normais e não restritos ao superusuário.
Isso é baseado em testes no meu Linux Mageia 2.

Os comandos destinados ao superusuário sempre podem ser acessados ​​por um usuário normal, prefixando-o com /sbin/, ou às vezes com / usr / sbin /. Agora eles podem ou não funcionar para um usuário normal.

Muitos podem funcionar, para um usuário normal, para um DVD na unidade de DVD, mesmo quando não estiver montado, enquanto não funcionarão para um disco rígido (novamente quando invocados como usuário normal).

Por exemplo /sbin/fdisk -l /dev/cdrom, funcionará no meu sistema e fornecerá a "geometria" do DVD na unidade ... o que aparentemente é basicamente um absurdo. Mas ele fornece o tamanho do DVD em bytes e em setores, e um tamanho de setor correto (de 2048 bytes, como é habitual no DVD).

O mesmo vale para /usr/sbin/gdisk -l /dev/cdrom, que fornece apenas o tamanho em setores de 2048 bytes.

outros exemplos (como usuário normal, não root)

$ /sbin/blockdev --getss /dev/cdrom   # DVD sector size
2048
$ /sbin/blockdev --getsize64 /dev/cdrom  # DVD byte size
5453316096

$ cat /proc/partitions  # see below
...
   8        8  416027241 sda8
  11        0    5325504 sr0
   8       16 1465138584 sdb
...

Isso funciona para a unidade de DVD, aqui chamada sr0, já que o dispositivo é realmente /dev/sr0, /dev/cdromsendo apenas um link simbólico para ele. O tamanho é dado em pedaços de 1k.

Da mesma forma, como usuário normal, o comando

$ cat /sys/class/block/sr0/size
10651008

fornecerá o tamanho de um DVD no dispositivo /dev/sr0, em pedaços de 512 bytes (assim como o tamanho de outro disco, mesmo que não esteja montado). No entanto cat /sys/class/block/cdrom/size, não funcionará porque / dev / cdrom é apenas um link simbólico

O comando df, sugerido por alguns, fornece o tamanho de partições montadas, não de discos inteiros. Além disso, para um CD ou DVD montado, ele fornece menos do que o tamanho real do CD / DVD. Mais precisamente, existem dois tamanhos distintos nos quais podemos interessar:

  • o tamanho geral do dispositivo, incluindo o que é usado para sua organização interna. Normalmente, esse é o tamanho do arquivo obtido se ele for copiado inteiro com o comando dd;
  • o tamanho do espaço disponível (possivelmente apenas no modo somente leitura) para o usuário quando ele estiver montado, o que é sempre menor. Esse é o tamanho indicado pelo comando df.

uptick para o tamanho do setor $ / sbin / blockdev --getss / dev / cdrom # DVD
peterretief

Você diz 512k, mas apenas setores de 512 bytes.
Tom Hale #

3

Um bloco é uma sequência de bits ou bytes com um comprimento fixo, ou seja, 512 bytes, 4kB, 8kB, 16kB, 32kB etc.

blockdev --getbsz partition

Exemplo

# blockdev --getbsz /dev/sda1 
4096

Portanto, o tamanho do bloco desse sistema de arquivos é de 4kB.

Analogia: número de garrafas em caixas.
insira a descrição da imagem aqui


Essa é a resposta correta.
Karl Morrison

1

Se você estiver usando o Node.js, poderá usar este complemento nativo para obter o tamanho do dispositivo de bloco, o tamanho do setor físico e o tamanho do setor lógico (com suporte para FreeBSD, Linux, macOS e Windows). Ele também tem alguns outros auxiliares para fazer E / S diretas:

https://github.com/ronomon/direct-io


0

Está /sys/block/sda/sizeno tamanho do bloco? Se sim, qual?

O ioctl BLKGETSIZE tem o mesmo problema que em unidades de 512 em vez de BLKSSZGET . BLKGETSIZE64 resolve essa ambiguidade. A contagem real de blocos é BLKGETSIZE64 / BLKSSZGET .

/*BINFMTC:
http://lkml.indiana.edu/hypermail/linux/kernel/0105.2/0744.html
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <assert.h>

int main(int argc, char **argv)
{
        int fd;
        long blk=0L;
        long ssz=0L;
        long long oct=0LL;

        if((fd=open(argv[1],O_RDONLY))<0) { perror(argv[1]); exit(1); }
        if(ioctl(fd,BLKGETSIZE,&blk)<0) { perror("BLKGETSIZE"); exit(1); }
        if(ioctl(fd,BLKSSZGET,&ssz)<0) { perror("BLKSSZGET"); exit(1); }
        if(ioctl(fd,BLKGETSIZE64,&oct)<0) { perror("BLKGETSIZE64"); exit(1); }
        if(close(fd)<0) { perror("close"); exit(1); }
        printf("BLKGETSIZE=%ld BLKSSZGET=%ld BLKGETSIZE64=%lld BLKGETSIZE64/BLKSSZGET=%ld SIZEGB=%f #%f\240GiB\n\n",\
blk,ssz,oct,(long)(oct/(long long)ssz),(double)oct/1000000000.0,(double)oct/1073741824.0);

        fflush(stdout); /* before exec */

        execl("/bin/bash","bash","-c",\
"for i in \
/sys/block/?d?/{size,alignment_offset,?d??/size,?d??/alignment_offset,queue/*block*,queue/*sector*}; \
do test -f \"$i\" && echo \"$i: $(<$i)\"; done"\
,NULL);

        exit(127);
        return 127; /* not reached */
}

Veja http://lkml.indiana.edu/hypermail/linux/kernel/0105.2/0744.html


1
Abuso de afirmação: se você desabilitar as afirmações, seus efeitos colaterais necessários não acontecerão mais.
Alfe


0
echo "`blockdev --getbsz /dev/sdc`/1024"|bc

mostrará a saída em KB

[root@veritas datadg2]# echo "`blockdev --getbsz /dev/sdc`/1024"|bc
4
[root@veritas datadg2]#

festa pode fazer cálculos em linha: echo $(( $(blockdev ...)/1024 )). Observe também, --getbszfornece o tamanho do bloco, não o tamanho do dispositivo.
Mwfearnley


-1
fdisk -l /dev/sda | grep -m1 ^Disk | awk '{print $3 " " $4}'

Acho muito útil do que todas essas ferramentas padrão ou entradas de proc


-3
df -k | grep /dev/sda

fornecerá o tamanho em KB (primeiro número), bem como o espaço usado (segundo número) e o espaço disponível (terceiro número)


5
Isso é apenas se o sistema de arquivos estiver montado.
Lfaraone 22/06/2009

2
Não se trata de espaço no dispositivo de bloco, ele fornecerá espaço usado e utilizável de sistemas de arquivos montados que estejam em / dev / sda. E o espaço não particionado? E se você tiver várias partições?
Kbyrd
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.