Determina la dimensione di un dispositivo a blocchi


Risposte:


73

fdisknon capisce il layout di partizione utilizzato dal mio Mac con Linux, né qualsiasi altro formato di partizione non PC. (Sì, c'è mac-fdiskper le vecchie tabelle delle partizioni Mac e gdiskper la più recente tabella delle partizioni GPT, ma quelle non sono le uniche altre configurazioni di partizioni là fuori.)

Dato che il kernel ha già scansionato i layout delle partizioni quando il dispositivo a blocchi è entrato in servizio, perché non chiederlo direttamente?

$ cat / proc / partitions
nome minore # blocchi principali

   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

Questo non funziona per cose come le unità CD
Ganesh Sittampalam,

2
E riporta anche solo nomi "nativi". Su un server con iSCSI e / o multipath e / o LVM ottieni un sacco di dispositivi sd * e dm- * ma di solito devi cercare il link simbolico di quello a cui sei realmente interessato (es. A / dev / mapper / * one)
Luke404

2
I valori riportati qui sono multipli di 1 KiB che può essere un settore (512 byte) troppo piccolo.
Lekensteyn,

1
Questo mi è stato utile. Ho finito per fareawk '/sd[a-z]$/{printf "%s %8.2f GiB\n", $NF, $(NF-1) / 1024 / 1024}' /proc/partitions
suprjami il

173

blockdev --getsize64 /dev/sda restituisce la dimensione in byte.

blockdev --getsz /dev/sda restituisce dimensioni in settori a 512 byte.

Obsoleto: blockdev --getsize /dev/sdarestituisce le dimensioni nei settori.

blockdev fa parte di util-linux .


4
purtroppo ha bisogno del potere del superutente
heinrich5991

6
@ heinrich5991 non hai scelta. Un utente normale non può accedere direttamente a un dispositivo a blocchi ("lettura non elaborata"), il che è positivo per la sicurezza.
Totor

@Totor Certo, ma ci sono risposte a questa domanda specifica che non richiedono alcun diritto di superutente.
heinrich5991,

2
@ heinrich5991 quando lavori con filesystem dovresti chiedere a statfs () e agli amici. Ancora più importante, si dovrebbe non assume alcuna relazione diretta tra la dimensione del dispositivo a blocchi e totale / utilizzabile / efficacia / libero / qualunque spazio sul file system.
Luke404

2
La manpage su linux.die.net/man/8/blockdev dice che --getsizeè obsoleta e suggerisce --getszsettori coerenti a 512 byte. Se --getsizedeve essere usato, suppongo che --getssdovrebbe essere usato anche per assicurarsi che la dimensione del settore sia quella che ti aspetti.
mwfearnley,

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

Questo ti dà le sue dimensioni in blocchi da 512 byte.


9
@ heinrich5991 Come puoi essere sicuro che la dimensione del blocco del dispositivo sia sempre di 512 byte?
Totor,

5
La dimensione del settore è sempre di 512 byte in base alla fonte . Per il futuro, sto cercando di documentare questa interfaccia .
Lekensteyn,

Grazie per averlo chiarito. Ho notato che c'è anche un / sys / class / block / sda / queue / logical_block_size. Non ero sicuro se avrei dovuto usarlo o la costante 512.
Edward Falk il

33

Questo semplice codice. Impossibile trovare alcuna documentazione, ma lo fa egregiamente:

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

Correzione: in realtà ti dà la dimensione in SETTORI. Modificalo e voterò.
JCCyC,

8
@JCCyC: BLKGETSIZE64restituisce la dimensione in byte. Vedere le linux/fs.hnote "restituisce la dimensione del dispositivo in byte". Si noti che BLKGETSIZE(no "64") lo restituisce "/ 512".
Thanatos

Ho elaborato un campione più completo in parte basato su questo su stackoverflow.com/a/48490543/446106 . Per utilizzare lo snippet qui sopra, filedeve essere un descrittore di file (ad es. Da open()) e file_size_in_bytesdovrebbe essere un size_t.
mwfearnley,

(In realtà, file_size_in_bytesdovrebbe essere un tipo a 64 bit, quindi dovrebbe essere unsigned long long.)
mwfearnley,

16

Che ne dite di:

fdisk -l

Questo ti darà un elenco di tutti i tuoi dischi con le rispettive capacità, utilizzo e altro.


3
Provalo con sudo, altrimenti non stampa nulla.
Alfe,

10

blockdev --getsize /dev/sda


Utilizzare con sudo, altrimenti si ottiene Permission denied.
Wimateeka,

9

lsblk fornisce le informazioni che stai cercando, inclusi i tipi di dispositivo e i mountpoint (se presenti), con una vista ad albero e in un formato leggibile dall'uomo.

Tipo di dispositivo significa che funziona per le unità CD, come richiesto da Ganesh Sittampalam.

Per ottenere solo le dimensioni di un determinato dispositivo in byte:

lsblk -rbno SIZE /dev/block-device

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

o se usi bash o qualsiasi altra shell simile a POSIX i cui operatori aritmetici lavorano con numeri interi a 64 bit, non hai nemmeno bisogno di chiamare bc

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

indica la dimensione in byte.

La chiamata a cate forcella (eccetto bash) può essere ottimizzato via con bash, ksh93e zshcon:

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

5

Non c'è bisogno di ioctl in C. Basta cercare fino alla fine del file e ottenere la dimensione (in byte) in questo modo:

/* 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 stai cercando la dimensione del disco rigido, avrai bisogno dei privilegi di root per aprire il file e cercare fino alla fine.
Edward Falk,

5

Il blockdev (8) ha una risposta diversa? Opzioni --getsze deprecati --getsizenon sono gli stessi.

  • BLKSSZGET ( blockdev --getss) è per le dimensioni del settore fisico e
  • BLKBSZGET ( blockdev --getbsz) è per la dimensione del settore logico.
echo $(($(blockdev --getsize64 /dev/sda)/$(blockdev --getss /dev/sda)))

In realtà, penso che tu abbia quelli invertiti. (A meno che il mio sistema non abbia blocchi fisici da 512 byte e blocchi logici da 4096 byte.)
Edward Falk,

2
Bene, mi sono reso conto che block/ioctl.cin Linux il kernel contiene commenti fuorvianti. BLKPBSZGET (nota la P) ottiene la dimensione del settore fisico, BLKSSZGET ottiene la dimensione del settore logico e BLKBSZGET (o BLKBSZGET_32 in block/compat_ioctl.c) ottiene la dimensione dell'unità di allocazione del file system (cluster). Le dimensioni del settore logico e fisico differiscono quando si utilizza Advanced Format 512e. ( 512e @ WP )
Palec,

@Palec Commento più consapevole tra tutte le risposte e commenti a questa domanda.
Irfan Latif,

5

Innanzitutto, i miei ringraziamenti a tutti coloro che hanno contribuito. Ho imparato alcune cose utili.

Tuttavia, la mia esperienza è che la maggior parte di queste risposte sono in qualche modo incomplete, almeno per quanto riguarda i CD e i DVD, in particolare per quanto riguarda se sono disponibili per gli utenti normali piuttosto che limitati al superutente.
Questo si basa su test sul mio Linux Mageia 2.

I comandi destinati al superutente sono sempre accessibili da un utente normale prefissandoli con /sbin/, o talvolta con / usr / sbin /. Ora potrebbero funzionare o meno per un normale utente.

Molti potrebbero funzionare, per un utente normale, per un DVD sull'unità DVD, anche quando non è montato, mentre non funzioneranno per un disco rigido (di nuovo se richiamato come utente normale).

Ad esempio /sbin/fdisk -l /dev/cdromfunzionerà sul mio sistema e fornirà la "geometria" del DVD nell'unità ... che apparentemente è per lo più senza senso. Ma fornisce la dimensione del DVD in byte e in settori e una dimensione del settore corretta (di 2048 byte come al solito per il DVD).

Lo stesso vale /usr/sbin/gdisk -l /dev/cdrom, che danno solo la dimensione in settori di 2048 byte.

altri esempi (come utente non root, normale)

$ /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
...

Questo funziona per l'unità DVD, qui chiamata sr0, poiché il dispositivo è effettivamente /dev/sr0, /dev/cdromessendo solo un collegamento simbolico ad essa. La dimensione è data in pezzi di 1k.

Allo stesso modo, come normale utente, il comando

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

fornirà la dimensione di un DVD sul dispositivo /dev/sr0, in blocchi di 512 byte (così come la dimensione di un altro disco, anche se non montato). Tuttavia cat /sys/class/block/cdrom/sizenon funzionerà perché causa / dev / cdrom è solo un collegamento simbolico

Il comando df, suggerito da alcuni, fornisce le dimensioni delle partizioni montate, non di interi dischi. Inoltre, per un CD o un DVD montato offre una dimensione inferiore a quella effettiva del CD / DVD. Più precisamente, ci sono due dimensioni distinte che potrebbero interessare:

  • le dimensioni complessive del dispositivo, incluso ciò che viene utilizzato per la sua organizzazione interna. In genere questa è la dimensione del file ottenuto se viene copiato intero con il comando dd;
  • la dimensione dello spazio disponibile (possibilmente solo in modalità di sola lettura) per l'utente quando è montato, che è sempre inferiore. Questa è la dimensione indicata dal comando df.

uptick per $ / sbin / blockdev --getss / dev / cdrom # dimensioni del settore DVD
peterretief

Dici 512k ma intendi solo settori da 512 byte.
Tom Hale,

3

Un blocco è una sequenza di bit o byte con una lunghezza fissa, ovvero 512 byte, 4kB, 8kB, 16kB, 32kB ecc.

blockdev --getbsz partition

Esempio

# blockdev --getbsz /dev/sda1 
4096

Quindi la dimensione del blocco di questo file system è di 4kB.

Analogia: numero di bottiglie in cassette.
inserisci qui la descrizione dell'immagine


Questa è la risposta corretta
Karl Morrison,

1

Se stai usando Node.js, puoi usare questo componente aggiuntivo nativo per ottenere dimensioni del dispositivo a blocchi, dimensioni del settore fisico e dimensioni del settore logico (con supporto per FreeBSD, Linux, macOS e Windows). Ha anche alcuni altri aiutanti per fare IO diretto:

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


0

È /sys/block/sda/sizein blocchi? In tal caso quale?

BLKGETSIZE ioctl presenta lo stesso problema in unità di 512 anziché BLKSSZGET . BLKGETSIZE64 risolve questa ambiguità. Il conteggio dei blocchi reali è 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 */
}

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


1
Abuso di asserzione: se disabiliti le asserzioni, i tuoi effetti collaterali necessari non accadranno più.
Alfe,


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

mostrerà l'output in KB

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

bash può fare calcoli in linea: echo $(( $(blockdev ...)/1024 )). Si noti inoltre, --getbszfornisce la dimensione del blocco, non la dimensione del dispositivo.
mwfearnley,


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

Lo trovo molto utile di tutti quegli strumenti standard o voci proc


-3
df -k | grep /dev/sda

ti darà la dimensione in KB (primo numero), nonché lo spazio utilizzato (secondo numero) e lo spazio disponibile (terzo numero)


5
Questo è solo se il filesystem è montato.
lfaraone,

2
Non si tratta di bloccare lo spazio del dispositivo, ti darà lo spazio usato e utilizzabile dei filesystem montati che si trovano su / dev / sda. Che dire dello spazio non partizionato? E se hai più partizioni?
kbyrd,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.