Other LSBLK(8) Command for FreeBSD

Hi,

as we all know there is no single command to show storage devices on FreeBSD system. Some grep(1) the dmesg(8) command, some check /var/run/dmesg.boot file, some try camcontrol(8) command and so on ... as I struggle to create any empathy for Linux systems I really like the lsblk(8) command and I always missed in in the FreeBSD land. As I got a free afternoon I started to write one from scratch and after several hours it works on my systems as designed. Below You will find the attached lsblk(8) implementation with BSD license and example outputs. As this is implementation from scratch we may come with better then lsblk name ... I hear your propositions ;)

If you have time, please test it on your systems and report bugs so I will be able to fix them.

It's attached to this thread as lsblk.sh.txt file as files with .sh extension are not allowed on this forum.

As this forum configuration CODE tags are useless (only up to two consecutive spaces allowed) check attached screenshot for formatted output -
lsblk.sh.examples.png also displayed below.

3071



Regards,
vermaden
 

Attachments

  • lsblk.sh.examples.png
    lsblk.sh.examples.png
    43.3 KB · Views: 5,591
  • lsblk.sh.txt
    lsblk.sh.txt
    17.3 KB · Views: 1,923

I think its fixed, but please test again, use the script from the first post.

another sample.
How about letting caller specify $SUDO ?

Thanks, its the same BUG, I assumed the output of camcontrol devlist to always be like (passX,devY) or (devY,passX) but sometimes (not on my boxes) its only (passX) so it was easy to fix.

Code:
# camcontrol devlist
<LSILOGIC Logical Volume 3000>     at scbus0 target 2 lun 0 (pass0,da0)
<TEAC DV-28SL 1.0A>                at scbus2 target 0 lun 0 (pass1,cd0)
<AMI Virtual CDROM 1.00>           at scbus4 target 0 lun 0 (cd1,pass2)
<AMI Virtual Floppy 1.00>          at scbus5 target 0 lun 0 (pass3)

About the sudo ... You may as well remove it, it just make convenient way to use it as regular user as camcontrol requires UID 0 to show anything.

Whichout sudo it will be like that:

Code:
PATH=${PATH}:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin

# OUTPUT
printf "%-14s %7s %4s %-18s %12s %s\n" DEVICE MA:MI SIZE TYPE LABEL MOUNT
( atacontrol list 2> /dev/null \
  | grep '<' \
  | awk '{print $2}'

  camcontrol devlist 2> /dev/null \
  | grep -E -o "\(.*,.*\)" \
  | tr -d '(,)' \
  | grep -v ses \
  | sed -E 's|pass[0-9]+||g' \
  | tr -d ' '
) \
  | sort -n \
  | while read DEV
  do
  PREFIX=""


Now fits into 80 columns terminal.


Regards,
vermaden
 
ada0 SSD and da0 USB stick show up nicely, but an MMC SD card containing Raspberry Pi image (MBR MSDOSBOOT & UFS rootfs) does not.
Maybe this could the mechanism to pick up those odd devices:
Code:
hopo # sysctl -a|grep mmc
kern.disks: da0 mmcsd0 ada0 cd0

Thanks,
Juha
 

Attachments

@juha

Great idea! ;)

Added, atacontrol is still needed for acdX devices but camcontrol is not needed anymore. Download latest version from the first post and try again.
 
Getting there, ada0, da0 still ok and mmcsd0 also shown, but some funny extra.
Also, mountpoints are always -, even when
Code:
hopo # mount
/dev/ada0p2 on / (ufs, local, soft-updates)
devfs on /dev (devfs, local)
/dev/gpt/TIKKU_3 on /mnt (ufs, local, soft-updates)
 

Attachments

Much improved, but there are still minor issues.
Code:
jrm@awarnach18 ~ % lsblk
DEVICE           MA:MI SIZE TYPE                      LABEL MOUNT
cd0               0:53    - -                             - <UNMOUNTED>
cd1               0:64    - -                             - <UNMOUNTED>
da0               0:54  68G MBR                           - -
  da0s1           0:55  68G freebsd                       - -
    <FREE>         -:- 512M -                             - -
    0:e           512M freebsd -                   <UNMOUNTED>
    da0s1b        0:57 4.0G freebsd-swap                  - SWAP
    da0s1a        0:56  63G freebsd-ufs                   - /
    <FREE>         -:- 9.6M -                             - -
    da0s1a        0:56 9.6M freebsd-ufs                   - /
  <FREE>           -:- 395K -                             - -
Code:
jrm@bravo ~ % lsblk
DEVICE           MA:MI SIZE TYPE                      LABEL MOUNT
ada0              0:63 466G GPT                           - -
  <FREE>           -:- 3.0K -                             - -
  ada0p1          0:65 512K freebsd-boot             gpboot -
  <FREE>           -:- 492K -                             - -
  ada0p2          0:67 466G freebsd-ufs            gprootfs -
  <FREE>           -:- 3.5K -                             - -
ada1              0:6a 149G MBR                           - -
  ada1s1          0:71 149G freebsd                       - -
gpart: No such geom: ada1s1.
  <FREE>           -:-  10M -                             - -
 
It looks good on the cluster node (awarnach18), but the old laptop (bravo) still has the gpart: No such geom: ada1s1. line.
 
Code:
jrm@bravo ~ % sh -x ./lsblk
+ PATH=.:/home/jrm/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/usr/bin:/bin:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
+ which sudo
+ SUDO=sudo
+ printf '%-14s %7s %4s %-18s %12s %s\n' DEVICE MA:MI SIZE TYPE LABEL MOUNT
DEVICE           MA:MI SIZE TYPE                      LABEL MOUNT
+ sort -n
+ sudo atacontrol list
+ read DEV
+ grep '<'
+ awk '{print $2}'
+ sysctl -n kern.disks
+ tr ' ' '\n'
+ PREFIX=''
+ gpart show ada0
+ gpart show ada0
+ tr -d '=>'
+ read LINE
+ [ '34  976773101  ada0  GPT  (466G)' = '' ]
+ [ '' = '' ]
+ ls -l /dev/ada0
+ awk 'END{print $5}'
+ tr x :
+ MA_MI=0:63
+ [ 0:63 = 0, ]
+ echo '34  976773101  ada0  GPT  (466G)'
+ grep -E -o '\(.*\)'
+ tr -d '()'
+ SIZE=466G
+ [ 466G = '' ]
+ echo '34  976773101  ada0  GPT  (466G)'
+ awk '{print $4}'
+ TYPE=GPT
+ printf '%-14s %7s %4s %-18s %12s %s\n' ada0 0:63 466G GPT - -
ada0              0:63 466G GPT                           - -
+ echo '34  976773101  ada0  GPT  (466G)'
+ grep -q GPT
+ PREFIX=p
+ continue
+ read LINE
+ [ '34          6        - free -  (3.0K)' = '' ]
+ [ p = '' ]
+ echo '34          6        - free -  (3.0K)'
+ grep -q -- '- free -'
+ echo '34          6        - free -  (3.0K)'
+ grep -E -o '\(.*\)'
+ tr -d '()'
+ SIZE=3.0K
+ printf '  %-12s %7s %4s %-18s %12s %s\n' '<FREE>' -:- 3.0K - - -
  <FREE>           -:- 3.0K -                             - -
+ continue
+ read LINE
+ [ '40       1024     1  freebsd-boot  (512K)' = '' ]
+ [ p = '' ]
+ echo '40       1024     1  freebsd-boot  (512K)'
+ grep -q -- '- free -'
+ echo '40       1024     1  freebsd-boot  (512K)'
+ grep -E -o '\(.*\)'
+ tr -d '()'
+ SIZE=512K
+ echo '40       1024     1  freebsd-boot  (512K)'
+ awk '{print $3}'
+ NAME=1
+ echo '40       1024     1  freebsd-boot  (512K)'
+ awk '{print $4}'
+ TYPE=freebsd-boot
+ [ freebsd-boot = !0 ]
+ [ ada0 != 1 ]
+ NAME=ada0p1
+ gpart list ada0
+ grep -A 256 'Name: ada0p1'
+ grep -m 1 label:
+ awk '{print $2}'
+ LABEL=gpboot
+ [ gpboot = '' ]
+ MOUNT=-
+ [ freebsd-boot = freebsd-zfs ]
+ ls -l /dev/ada0p1
+ awk 'END{print $5}'
+ tr x :
+ MA_MI=0:65
+ [ 0:65 = 0, ]
+ printf '  %-12s %7s %4s %-18s %12s %s\n' ada0p1 0:65 512K freebsd-boot gpboot -
  ada0p1          0:65 512K freebsd-boot             gpboot -
+ [ freebsd-boot = freebsd ]
+ read LINE
+ [ '1064        984        - free -  (492K)' = '' ]
+ [ p = '' ]
+ echo '1064        984        - free -  (492K)'
+ grep -q -- '- free -'
+ echo '1064        984        - free -  (492K)'
+ grep -E -o '\(.*\)'
+ tr -d '()'
+ SIZE=492K
+ printf '  %-12s %7s %4s %-18s %12s %s\n' '<FREE>' -:- 492K - - -
  <FREE>           -:- 492K -                             - -
+ continue
+ read LINE
+ [ '2048  976771080     2  freebsd-ufs  (466G)' = '' ]
+ [ p = '' ]
+ echo '2048  976771080     2  freebsd-ufs  (466G)'
+ grep -q -- '- free -'
+ echo '2048  976771080     2  freebsd-ufs  (466G)'
+ grep -E -o '\(.*\)'
+ tr -d '()'
+ SIZE=466G
+ echo '2048  976771080     2  freebsd-ufs  (466G)'
+ awk '{print $3}'
+ NAME=2
+ echo '2048  976771080     2  freebsd-ufs  (466G)'
+ awk '{print $4}'
+ TYPE=freebsd-ufs
+ [ freebsd-ufs = !0 ]
+ [ ada0 != 2 ]
+ NAME=ada0p2
+ gpart list ada0
+ grep -A 256 'Name: ada0p2'
+ grep -m 1 label:
+ awk '{print $2}'
+ LABEL=gprootfs
+ [ gprootfs = '' ]
+ MOUNT=-
+ [ freebsd-ufs = freebsd-zfs ]
+ ls -l /dev/ada0p2
+ awk 'END{print $5}'
+ tr x :
+ MA_MI=0:67
+ [ 0:67 = 0, ]
+ printf '  %-12s %7s %4s %-18s %12s %s\n' ada0p2 0:67 466G freebsd-ufs gprootfs -
  ada0p2          0:67 466G freebsd-ufs            gprootfs -
+ [ freebsd-ufs = freebsd ]
+ read LINE
+ [ '976773128          7        - free -  (3.5K)' = '' ]
+ [ p = '' ]
+ echo '976773128          7        - free -  (3.5K)'
+ grep -q -- '- free -'
+ echo '976773128          7        - free -  (3.5K)'
+ grep -E -o '\(.*\)'
+ tr -d '()'
+ SIZE=3.5K
+ printf '  %-12s %7s %4s %-18s %12s %s\n' '<FREE>' -:- 3.5K - - -
  <FREE>           -:- 3.5K -                             - -
+ continue
+ read LINE
+ [ '' = '' ]
+ continue
+ read LINE
+ read DEV
+ PREFIX=''
+ gpart show ada1
+ gpart show ada1
+ tr -d '=>'
+ read LINE
+ [ '63  312581745  ada1  MBR  (149G)' = '' ]
+ [ '' = '' ]
+ ls -l /dev/ada1
+ awk 'END{print $5}'
+ tr x :
+ MA_MI=0:6a
+ [ 0:6a = 0, ]
+ echo '63  312581745  ada1  MBR  (149G)'
+ grep -E -o '\(.*\)'
+ tr -d '()'
+ SIZE=149G
+ [ 149G = '' ]
+ echo '63  312581745  ada1  MBR  (149G)'
+ awk '{print $4}'
+ TYPE=MBR
+ printf '%-14s %7s %4s %-18s %12s %s\n' ada1 0:6a 149G MBR - -
ada1              0:6a 149G MBR                           - -
+ echo '63  312581745  ada1  MBR  (149G)'
+ grep -q GPT
+ echo '63  312581745  ada1  MBR  (149G)'
+ grep -q MBR
+ PREFIX=s
+ continue
+ read LINE
+ [ '63  312560577     1  freebsd  [active]  (149G)' = '' ]
+ [ s = '' ]
+ echo '63  312560577     1  freebsd  [active]  (149G)'
+ grep -q -- '- free -'
+ echo '63  312560577     1  freebsd  [active]  (149G)'
+ grep -E -o '\(.*\)'
+ tr -d '()'
+ SIZE=149G
+ echo '63  312560577     1  freebsd  [active]  (149G)'
+ awk '{print $3}'
+ NAME=1
+ echo '63  312560577     1  freebsd  [active]  (149G)'
+ awk '{print $4}'
+ TYPE=freebsd
+ [ freebsd = !0 ]
+ [ ada1 != 1 ]
+ NAME=ada1s1
+ gpart list ada1
+ grep -A 256 'Name: ada1s1'
+ grep -m 1 label:
+ awk '{print $2}'
+ LABEL=''
+ [ '' = '' ]
+ LABEL=-
+ MOUNT=-
+ [ freebsd = freebsd-zfs ]
+ ls -l /dev/ada1s1
+ awk 'END{print $5}'
+ tr x :
+ MA_MI=0:71
+ [ 0:71 = 0, ]
+ printf '  %-12s %7s %4s %-18s %12s %s\n' ada1s1 0:71 149G freebsd - -
  ada1s1          0:71 149G freebsd                       - -
+ [ freebsd = freebsd ]
+ gpart show ada1s1
+ grep -v '=>'
+ read BSDLINE
gpart: No such geom: ada1s1.
+ read LINE
+ [ '312560640      21168        - free -  (10M)' = '' ]
+ [ s = '' ]
+ echo '312560640      21168        - free -  (10M)'
+ grep -q -- '- free -'
+ echo '312560640      21168        - free -  (10M)'
+ grep -E -o '\(.*\)'
+ tr -d '()'
+ SIZE=10M
+ printf '  %-12s %7s %4s %-18s %12s %s\n' '<FREE>' -:- 10M - - -
  <FREE>           -:-  10M -                             - -
+ continue
+ read LINE
+ [ '' = '' ]
+ continue
+ read LINE
+ read DEV
 
jrm, have you checked that the slice ada1s1 has been initialized with the BSD disklabel? If it's not the gpart show ada1s1 would correctly show "no such geom".
 
That laptop is at home now and it's booted into FreeBSD on the fist disk. IIRC, the second disk has a vanilla DragonFly installation (i.e., I didn't drop down to a console to manually prepare the disk). I'll investigate when I return home.
 
Happy here now, except field MOUNT. Partly my fault, haven't labeled the active / filesystem.
Existing labels show up here and there under /dev
Code:
hopo $ ls -l /dev/*/MSDOSBOOT /dev/*/rootfs /dev/*/TIKKU_3
crw-r-----  1 root  operator  0xc7 Apr 26 14:50 /dev/gpt/TIKKU_3
crw-r-----  1 root  operator  0xb0 Apr 26 11:49 /dev/msdosfs/MSDOSBOOT
crw-r-----  1 root  operator  0xb6 Apr 26 11:49 /dev/ufs/rootfs
 

Attachments

That laptop is at home now and it's booted into FreeBSD on the fist disk. IIRC, the second disk has a vanilla DragonFly installation (i.e., I didn't drop down to a console to manually prepare the disk). I'll investigate when I return home.

I think you need to load the geom_part_bsd64 kernel module for GEOM to understand the DragonFlyBSD disklabel.

# kldload geom_part_bsd64
 
Better again: ada0p2 MOUNT / shows up correct, and MOUNT SWAP are coherent, but those oddball mountpoints are still -
Code:
/dev/ada0p2 on / (ufs, local, soft-updates)
devfs on /dev (devfs, local)
/dev/gpt/TIKKU_3 on /mnt/a (ufs, local, soft-updates)
/dev/ufs/rootfs on /mnt/b (ufs, local, soft-updates, nfsv4acls)
/dev/msdosfs/MSDOSBOOT on /mnt/c (msdosfs, local)
 

Attachments

Try now please.

BTW, which FreeBSD this is? I do not have /dev/msdosfs directory while FAT32 labeled pendrive is in my box right now ...
 
I will try the updates momentarily.

On line 177 (current code I have) you could redirect standard error to /dev/null, to remove the gpart: No such geom: ada1s1. line.
Code:
if [ "${TYPE}" = "freebsd" -a "${PREFIX}" != "p" ]
  then
    gpart show "${NAME}" 2> /dev/null \
    ...
 
Back
Top