dslreports logo
 
    All Forums Hot Topics Gallery
spc
uniqs
2

Bill_MI
Bill In Michigan
MVM
join:2001-01-03
Royal Oak, MI

Bill_MI to leibold

MVM

to leibold

Re: Why ever use a hard link?

I see... it doesn't list it it finds it! Find's man page has a newer -samefile option, too. You don't need the inode number, just the file.

Thanks much!

koitsu
MVM
join:2002-07-16
Mountain View, CA
Humax BGW320-500

koitsu

MVM

For a real-world situation where hard links are used, FreeBSD's /rescue directory is one such place. I apologise in advance for the big fat post, but I wanted to make sure Bill_MI See Profile got the full picture. inode number is in the furthest left column.

$ ls -l -i /rescue
total 670768
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 [
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 atacontrol
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 atmconfig
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 badsect
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 bsdlabel
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 bunzip2
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 bzcat
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 bzip2
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 camcontrol
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 cat
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 ccdconfig
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 chflags
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 chgrp
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 chio
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 chmod
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 chown
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 chroot
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 clri
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 cp
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 csh
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 date
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 dd
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 devfs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 df
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 dhclient
 98690 -r-xr-xr-x    1 root      wheel        9973 Oct 25 01:26 dhclient-script
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 disklabel
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 dmesg
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 dump
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 dumpfs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 dumpon
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 echo
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 ed
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 ex
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 expr
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 fastboot
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 fasthalt
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 fdisk
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 fsck
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 fsck_4.2bsd
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 fsck_ffs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 fsck_msdosfs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 fsck_ufs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 fsdb
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 fsirand
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 gbde
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 geom
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 getfacl
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 glabel
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 gpart
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 groups
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 gunzip
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 gzcat
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 gzip
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 halt
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 head
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 hostname
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 id
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 ifconfig
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 init
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 kenv
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 kill
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 kldconfig
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 kldload
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 kldstat
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 kldunload
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 ldconfig
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 link
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 ln
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 ls
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 lzcat
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 lzma
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 md5
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mdconfig
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mdmfs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mkdir
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mknod
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mount
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mount_cd9660
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mount_msdosfs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mount_nfs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mount_ntfs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mount_nullfs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mount_udf
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mount_unionfs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mt
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 mv
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 nc
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 newfs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 newfs_msdos
 98689 -r-xr-xr-x    1 root      wheel        1152 Oct 25 01:26 nextboot
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 nos-tun
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 pgrep
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 ping
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 ping6
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 pkill
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 ps
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 pwd
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 rcorder
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 rcp
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 rdump
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 realpath
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 reboot
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 red
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 rescue
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 restore
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 rm
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 rmdir
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 route
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 routed
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 rrestore
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 rtquery
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 rtsol
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 savecore
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 sed
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 setfacl
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 sh
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 spppcontrol
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 stty
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 swapon
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 sync
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 sysctl
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 tail
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 tar
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 tcsh
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 tee
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 test
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 tunefs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 umount
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 unlink
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 unlzma
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 unxz
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 vi
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 whoami
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 xz
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 xzcat
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 zcat
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 zfs
100027 -r-xr-xr-x  137 root      wheel     4949600 Oct 25 01:26 zpool
 

Note that the "total disk space used" shown in ls here is not quite true, and it's understandable why -- ls counts the disk usage on a per-file basis (i.e. doesn't have the brains to figure out "oh, most of these point to one single inode"). This is where du flags come in handy:

$ du -s /rescue
4916    /rescue
$ du -s -l /rescue
670772  /rescue
 

Some man page snippets that are relevant so you'll understand (you probably already know -s though):

     -l      If a file has multiple hard links, count its size multiple times.
             The default behavior of du is to count files with multiple hard
             links only once.  When the -l option is specified, the hard link
             checks are disabled, and these files are counted (and displayed)
             as many times as they are found.
 
     -s      Display an entry for each specified file.  (Equivalent to -d 0)
 

Bill_MI
Bill In Michigan
MVM
join:2001-01-03
Royal Oak, MI
TP-Link Archer C7
Linksys WRT54GS
Linksys WRT54G v4

2 edits

Bill_MI

MVM

I don't mind a bit, Thanks! Anyone else, be my guest. :-)

Now that made me instantly think of the "busybox" in OpenWrt where most executables are *symbolic* links to the same file. I think this embedded Linux is squashfs which may not have inodes. Flash wants to be tiny so there must be a reason they use -s.

So I looked in my own Ubuntu /bin and instantly saw a file with 3 links. Sorted by inode number and Voila!

ls -il /bin | sort
(excerpt)
1182125 -rwxr-xr-x 1 root root  326800 2012-10-03 14:30 dbus-daemon
1182157 -rwxr-xr-x 1 root root    3642 2011-12-12 17:40 bzgrep
1182158 -rwxr-xr-x 1 root root    2140 2011-12-12 17:40 bzdiff
1182245 -rwxr-xr-x 3 root root   31176 2011-12-12 17:40 bunzip2
1182245 -rwxr-xr-x 3 root root   31176 2011-12-12 17:40 bzcat
1182245 -rwxr-xr-x 3 root root   31176 2011-12-12 17:40 bzip2
1182246 -rwxr-xr-x 1 root root    1297 2011-12-12 17:40 bzmore
1182260 -rwsr-xr-x 1 root root   31384 2011-02-11 15:42 fusermount
1182261 -rwxr-xr-x 1 root root   14712 2011-02-11 15:42 ulockmgr_server
 

Not familiar with BSD /rescue but will look it up next opportunity.
EDIT: I see what they're doing! Creating the most survivable, smallest footprint, of recovery tools.

koitsu
MVM
join:2002-07-16
Mountain View, CA
Humax BGW320-500

koitsu

MVM

I'ma regular contributor to the TomatoUSB firmware, so I have more than enough familiarity with Busybox.

squashfs is partially the reason Busybox is used this way. To clarify, squashfs supports both hardlinks and symlinks. Further proof is in this incorrect problem report. Hardlinks could have been used just as effectively -- and in some firmwares they are used instead of symlinks. What I do not know is what the compression level difference is between a symlink and a hardlink with squashfs. It varies based on inode type (dir vs. file vs. symlink vs. hardlink vs. FIFO etc.), so there may be an advantage compression-wise to using symlinks over hardlinks.

From the Busybox perspective it doesn't matter though -- the main busybox binary itself parses argv[0] and iterates over a large array of strings, comparing against the effective calling command was. Rather than get into the parsing semantics, it works like this: if you symlink or hardlink "poop" to the busybox binary, and you run the "poop" command, the busybox binary compares the command you run to argv[0] and if it finds a match, it runs the code associated for that command. If there is no match, I believe busybox spits back some error like "unsupported command".

This is exactly what FreeBSD's /rescue/rescue does too, it's just done (implemented) differently internally -- the binaries you see that are hard linked to /rescue/rescue are not "custom versions" like what you find with Busybox -- they are the real deal.

So there's a single binary on the system that handles lots of commands. Why is it done this way? That has to do with saving space on a filesystem like squashfs, quite simply. Remember: Busybox "markets" itself for embedded environments or where space is very limited.

{opinion}
Other than that, Busybox is just a total piece of utter junk. I cannot even begin to explain to you the amount of bugs and brokenness that are in this suite. I think my bug list, personally experienced, is up to 40 or 50 by now, and I have fixed my own share of catastrophic bugs in that junkpile more than once (my favourites usually consist of file descriptor leakage, i.e. someone not calling close() but repeatedly calling open()). A colleague of mine personally knows a developer who quit the Busybox team after several years, simply because of how utterly horrible the code was that was being pushed out. That fellow now works on something called Toybox. Any time I see Busybox used somewhere I become wary and scared.
{/opinion}
quote:
EDIT: I see what they're doing! Creating the most survivable, smallest footprint, of recovery tools.
More or less, you got it. I wouldn't use the word "survivable" though -- it's just about saving space in environments where space is not as freely available as, say, a 250GB hard disk.

Bill_MI
Bill In Michigan
MVM
join:2001-01-03
Royal Oak, MI
TP-Link Archer C7
Linksys WRT54GS
Linksys WRT54G v4

Bill_MI

MVM

I'm no developer but played in the OpenWrt build environment and busybox was a constant chatter of discussion. I ran into differences with sed that made me not attempt some cable/dsl modem parameter logging on OpenWrt. I still run my build of Whiterussian 0.9 on my main router, the blazing fast and modern WRT54G v4 using the 2.4 kernel and Broadcom binary blobs.