I worked through hard versus symbolic links by inspecting inodes and link counts with ls -i and stat. Symlinks enabled atomic configuration swaps (the current-release pointer pattern) while hard links shared data without duplication.

Objective & Context

Links are how Linux references the same data from multiple paths. This lab clarifies that hard links share an inode (same data, multiple names) while symlinks are pointers to a path, then applies symlinks for zero-downtime config and release switching.

Learning Objectives

  • Explain the difference between hard links and symbolic links using inodes.
  • Create hard links and verify shared inodes and link counts with ls -li.
  • Create symbolic links and inspect their targets with stat and readlink.
  • Identify dangling symlinks and clean them up safely.
  • Perform an atomic release switch with ln -sfn for zero-downtime deploys.

Environment & Prerequisites

Prerequisites

  • Any Linux shell with GNU coreutils (ln, ls, stat are preinstalled everywhere).
  • A filesystem that supports hard links for step 1 (ext4, xfs, btrfs all qualify; FAT and most network mounts do not).
  • Sample files to link and a scratch directory such as ~/lab/links.
  • Basic familiarity with ls -l output from the file management lab.

Step-by-Step Execution

1. Compare inodes of a hard link

echo hello > file.txt && ln file.txt hard.txt && ls -li file.txt hard.txt

Expected output:

524301 -rw-r--r-- 2 taki taki 6 2026-06-17 09:12 file.txt
524301 -rw-r--r-- 2 taki taki 6 2026-06-17 09:12 hard.txt

What this teaches: Identical inode numbers prove both names point to the same data blocks; the link count of 2 shows two directory entries reference that inode. Deleting one name only decrements the count, and the data survives until the count reaches zero.

2. Create a symlink and inspect it

ln -s /srv/releases/v2 /srv/current && stat /srv/current

Expected output:

  File: /srv/current -> /srv/releases/v2
  Size: 15              Blocks: 0          IO Block: 4096   symbolic link

What this teaches: stat reveals a symlink is its own tiny file holding a path string (Size 15, Blocks 0); readlink -f resolves the full chain to the real target.

3. Atomic release switch

ln -sfn /srv/releases/v3 /srv/current

Expected output:

(no output on success; verify with: readlink /srv/current)
/srv/releases/v3

What this teaches: The -n flag stops ln from dereferencing an existing symlink to a directory, and -f replaces it; together they swap the pointer atomically so readers never see a half-updated path. This needs sudo when /srv is root-owned.

How It Works

A Unix filesystem separates names from data. The inode holds the data blocks, permissions, and timestamps; a directory is just a table mapping names to inode numbers. A hard link adds another name for the same inode, so both names are equal peers and the data survives until the last name is removed and the last open descriptor closes.

A symbolic link is a different object entirely: a small file whose content is a path string. The kernel resolves it at open time, which means symlinks can point across filesystems and to directories, but also means they break (dangle) when the target moves. Tools like readlink and stat -c %N expose the link layer so you can tell names apart from data.

The atomic swap works because renaming a symlink is a single filesystem operation. ln -sfn creates the new link and renames it over the old one in one step, so a web server reading /srv/current either gets the old release or the new one, never a missing path. This is the same mechanism behind zero-downtime deployment tools.

Validation & Testing

Delete the original name of a hard-linked file and confirm the data survives via the other name; repoint a symlink and confirm consumers see the new target atomically. Pass criteria: hard links share an inode and survive original deletion; symlink swap is instantaneous.

Troubleshooting

SymptomLikely causeFix
ln reports invalid cross-device linkHard links cannot span filesystemsUse a symbolic link instead, or keep both names on the same mount
Symlink shows as red/dangling in lsIts target was moved or deletedRecreate the target or repoint with ln -sfn; find dangling links with find -xtype l
ln -sf followed the old link into a directoryWithout -n, ln dereferences a symlink that points to a directoryAlways use ln -sfn for the atomic swap pattern
Hard link edits appear in both names unexpectedlyThat is correct behavior: both names share one inodeCopy (cp) instead of linking when you need independent files
readlink shows a relative path that resolves wronglyRelative symlinks resolve from the link's directory, not your cwdPrefer absolute targets for system paths like /srv/current
Too many levels of symbolic links errorSymlinks form a loop pointing at each otherBreak the cycle by removing one link and repointing it correctly
Advanced: Troubleshooting
  • Cross-filesystem hard link fails: hard links cannot span filesystems; use a symlink.
  • Dangling symlink: the target moved or was deleted; recreate or repoint.
  • Non-atomic swap: use ln -sfn to replace a symlink in one step.

Key Results

  • Demonstrated shared-inode behaviour of hard links with link counts.
  • Implemented zero-downtime release switching with atomic symlink swaps.
  • Distinguished symlink path-pointers from inode-sharing hard links.
  • Avoided data duplication for shared references via hard links.

Key Takeaways

  • Hard links are extra names for one inode; symlinks are path pointers stored as tiny files.
  • Same inode plus a link count above 1 identifies hard-linked names.
  • Symlinks can cross filesystems and point to directories; hard links cannot.
  • ln -sfn swaps a symlink atomically, which enables zero-downtime releases.
  • Relative symlink targets resolve from the link's own directory.

Practice Challenges

Challenge 1: Prove shared data

Goal: create a hard link, append text through one name, and show it appears through the other; then delete the original and show the data survives.

Hint: compare inode numbers with ls -li.

Challenge 2: Hunt dangling links

Goal: find every broken symlink under /etc and /srv, then decide for each whether to repoint or remove it.

Hint: find has a -xtype l test for this exact job.