6

I want to capture all disks that do not have a filesystem ( all disks that mkfs not runs on them )

I tried the below, but still gives the OS ( sda ).

What is the best approach with lsblk or other command to capture all disks that are without filesystem?

  lsblk -f | egrep -v "xfs|ext3|ext4"
  NAME             FSTYPE      LABEL UUID                                   
  MOUNTPOINT
 fd0
  sda
 └─sda2           LVM2_member       v0593a-KiKU-9emb-STbx-ByMz-S95k-jChr0m
 ├─vg00-lv_swap swap              1beb675f-0b4c-4225-8455-e876cafc5756   
 [SWAP]
 sdg
 sdh
 sdi
 sdj
 sdk
 sr0
Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
yael
  • 12,598
  • 51
  • 169
  • 303

4 Answers4

5
lsblk -o NAME,FSTYPE -dsn

This will print a list of block devices that are not themselves holders for partitions (they do not have a partition table). The detected file system type is in the second column. If its blank there is no recognized file system.

So to get the output you want in one command

lsblk -o NAME,FSTYPE -dsn | awk '$2 == "" {print $1}'
jdwolf
  • 4,887
  • 1
  • 13
  • 28
  • This is good unless you've got ZFS pools with ZVOLs on them. e.g. on one of my systems, some of the block devices your `lsblk ... | awk ...` command lists are `zd128p[123]`. They're actually partitions 1-3 of /dev/zd128 (which happens to be `/dev/zvol/volumes/freebsd`, my freebsd VM's disk image). There are other ZVOL devices which it lists, too (including a few centos, debian, and ubuntu VMs). BTW `file -s /dev/zd128p3` reports `/dev/zd128p3: Unix Fast File system [v2] (little-endian) last mounted on [.....]`. I'm not sure if this would happen with LVM volumes too - it's been a while. – cas Dec 23 '17 at 07:35
  • @cas the above command only recognizes containers in the case of block devices that are part of a partition table. As far as I know that concept doesn't extend to a fs volume. Also it would skip block devices without a partition table that are in containers. Maybe I shouldn't assume the op doesn't want that? but such devices are ambiguous whether you'd want a file system on them or a partition table. – jdwolf Dec 23 '17 at 08:05
  • my comment really wasn't about containers or VMs (i.e. the fact that my ZVOLs are mostly used for VMs isn't relevant). ZFS ZVOLs **are** block devices, just like any other - that's their entire purpose. The kernel recognises them as block devices, and they can be formatted with filesystems, as several of mine were - but your command still listed them as unformatted block devices. This is a problem with `lsblk` not recognising the filesystem on a formatted ZVOL block device...btw, `blkid` recognises them and detects the fs type. – cas Dec 23 '17 at 08:13
  • @cas NVM. lsblk handles LVM volumes just fine. Any PVs partitions or not are considered holders. – jdwolf Dec 23 '17 at 08:14
  • @cas the term "container" was misspoken. I meant holders which means block devices where there is a partitions or volumes on it. Or in other words where the kernel is using it to derive other block devices. – jdwolf Dec 23 '17 at 08:18
  • @cas "your command still listed them as unformatted block devices." by this you mean the zvols or the PVs that make up the zvols? The latter is not surprising while the former would suggest a bug. I also just confirmed lsblk detects fs on LVM LVs. – jdwolf Dec 23 '17 at 08:21
  • The ZVOLs themselves, which is why I made the comment. I thought your `lsblk ... | awk ...` command was neat (+1) and tried it on one of my systems which had a bunch of ZVOLs on it, which is why I noticed the problem. ZVOLs are block devices in every respect, so there's no good reason why `lsblk` should fail to work correctly with them....i.e. a bug. – cas Dec 23 '17 at 08:24
  • BTW, one of my ZVOL devices is for a centos VM. Centos uses LVM by default when you install it. `blkid` recognises that it is an LVM2_member (`/dev/zd144p2: UUID="ZJiDZk-wy9h-Yxe1-Gexz-7QRY-Pkme-ANlqK6" TYPE="LVM2_member" PARTUUID="000a4cc5-02"`, while `lsblk` doesn't. I also created a new ZVOL with `zfs create -V 5GB volumes/junk`, partitioned it with fdisk, then formatted it with mkfs.ext4. again, `blkid` recognises it for an ext4 formatted partition, `lsblk` doesn't. – cas Dec 23 '17 at 08:29
  • @cas can you please show me your approach to capture disks without fs? – yael Dec 24 '17 at 19:07
  • @yael They don't as far as I know? They are pointing out that lsblk (presumably on BSD) does not properly show file system type of a ZFS volume. While I have confirmed that LVM volumes (on Linux) are correctly recognized. – jdwolf Dec 24 '17 at 19:31
  • i don't. I was pointing out that `lsblk` (on linux, not freebsd) doesn't work correctly with **all** valid linux block devices - ZFS for sure, possibly others. I don't like relying on things that have unknown failure modes so if I really needed a list of unformatted block devices, I'd probably use `blkid` rather than `lsblk`....and maybe use `file -s` as well (either to verify what `blkid` told me, or as a secondary attempt to identify anything that blkid couldn't). – cas Dec 25 '17 at 00:49
0

In my opinion, the best option is FDISK. syntax:

fdisk -l | grep -i ^disk
0

You can use parted utility for listing all disks,whether they have filesystems or not:

sudo parted

and then type "print free".

It will print all partitioned as well as non-partitioned drives.

enter image description here

0

The following one-liner seems to work. It prints all block device names except those which have a TYPE, PTTYPE, LABEL, or PARTLABEL. The last two on the grounds that something with a label is likely to be in use already.

This seems to me to be a much better approach than using grep -v to exclude a list of filesystem types known at this moment in time.

blkid | awk -F': ' '!/ ((PT)?TYPE|(PART)?LABEL)="[^"]+"/ {print $1}'

Note: the list of block devices produced by this are NOT in any way guaranteed not to be in use, just that they don't have any of the commonly used markers that in-use block devices have. They're probably not in use, but without spending significantly more time researching the issue I'm extremely reluctant to even suggest that it is any kind of guaranteed list.

On one of my ZFS On Linux boxes, it produces the following output:

# blkid | awk -F': ' '!/ ((PT)?TYPE|(PART)?LABEL)="[^"]*"/ {print $1}'
/dev/sdb9

This is correct for that system. /dev/sdb9 IS an unformatted, unused partition. It's an 8MB partition at the end of a disk which is used in a single-disk ZFS pool (this is a home machine for testing stuff and I needed its mirror drive for something else and haven't got around to replacing it yet)


BTW, blkid takes significantly longer to run than lsblk. It does a lot more work trying to identify what kind of block device it's looking at.

This is probably only noticeable on servers with hundreds of drives/lvm members/zvols and other block devices.

For example, on one of my medium-sized servers (with 362 block devices of various kinds), blkid takes about 2 minutes to run, while lsblk takes about 0.09 seconds. On another, much smaller, system with only 39 block devices (the home testing box mentioned above), blkid takes 0.16 seconds while lsblk takes 0.01 seconds.

If you need to run this repeatedly and the run-time is too long, you can always cache blkdid's output in a tmpfile for a short time. e.g. if the cache either doesn't exist or is older than, say, 30 minutes then generate the cache file (blkid > /path/to/blkid.cache) and use that as the input to awk or whatever.

cas
  • 1
  • 7
  • 119
  • 185