6

I understand the reasoning why nearly every unix version doesn't allow hard-linking of directories (in fact HFS+ on OS X is the only one I know, but even that isn't made easy to do yourself). However, all file-systems in theory support hard-linked directories, as all directories contain at least one extra hard-link to itself, plus extra hard-links in sub-directories pointing back to their parent.

Now, I realise that hard-linking can be dangerous if misused, as it can create cyclical structures that few programs will check for, and thus become stuck in an infinite loop. However, I was hoping to use hard-links to create a Time Machine style backup that can work for any unix. I don't believe that this kind of structure would be dangerous, as the links simply point to previous backups; there should be no risk of cyclical linking. In my case I'm currently just using rsync to create hard-links to existing files, but this slow and wasteful, particularly with very large backups and especially if I already know which directories are unchanged.

With this in mind, is there any way to force the creation of directory hard-links on unix variants? ln is presumably no good as this is the place that many unix flavours put their restricts upon in order to prevent hard-linking directories, and ln versions that support hard-linked directories specifically state that the operation is likely to fail. But for someone who knows the risks, and knows that their use-case is safe, is there any way to actually create the link anyway? Ideally for a shell script, but if I need to compile a small program to do it then I suppose I could.

3
  • Short answer: No. The reason it fails is the kernel prohibits it.
    – derobert
    May 9, 2013 at 16:38
  • 2
    Don't do it as anything other than an intellectual curiosity. You will break the filesystem.
    – Chris Down
    May 10, 2013 at 9:12
  • 1
    I think that what you are looking for is a revision control system: e.g. mercurial or sub-version. Jul 15, 2016 at 18:21

4 Answers 4

5

Don't do this. If you want to have a backup system using hard links to save space, better to use rsync with --link-dest, which will hard link files appropriately to save space, without causing the problems that this causes (that is, hard linking between directories is a corruption of the filesystem, and will cause it to report wrong inode counts + fail fsck + generally have unknown semantics due to not being a DAG).

11
  • 2
    Which will cause it to fail fsck. Pass 2: Checking directory structure Entry 'bar' in / (2) is a link to directory /foo (12). Clear<y>? Also leaves a wrong ref count in the inode (later fsck message)
    – derobert
    May 9, 2013 at 16:34
  • @derobert I don't know what you were expecting...
    – Chris Down
    May 9, 2013 at 17:11
  • 2
    Well, I wasn't expecting the wrong inode count. But the point is, OP actually wants to use this, not just do it as an intellectual curiosity. And this is clearly not a sane backup strategy. Or even half-sane. So that comment is to make sure OP is aware of that.
    – derobert
    May 9, 2013 at 18:53
  • @derobert Ah, my eyes skipped to "for someone who knows the risks" and eschewed the rest, so I didn't see what they were actually planning to do with it. Yes, in which case, basically don't do it. I added an alternative.
    – Chris Down
    May 10, 2013 at 6:52
  • 1
    +1 for rsync --link-dest, which is exactly the right solution for this backup scenario. Sep 15, 2013 at 17:02
3

If you are unable to use debugfs interactively, you can pipe to it and use sed to remove the prompt and echoed-back command from its output.

echo 'link /foo /bar' | debugfs -w [device] | sed '$s/debugfs:  $//' | sed '1d'
1
  • AFAIK, debugfs is not a utility available on "every Unix".
    – Kusalananda
    Jan 3, 2017 at 8:17
2

You can use debugfs to do this. With the filesystem not mounted, do debugfs -w /dev/device_name. Then, at the debugfs prompt, use the link command the same way you would use ln if hard links to directories were normally possible. (e.g. link /original_dir /new_link) The link command in debugfs, unlike ln and the link system call, allows hard links to directories to be created. Once you're done, just type quit.

However, as other people have mentioned, DO NOT actually do this. It will cause problems. I'm just saying this because you asked how to forcibly create a directory hard link, and that's how you do it.

0

Directories should never have extra hard links to them. Sure, you can create them, but that is a serious corruption of the filesystem.

The reason is that directories must always form a tree structure, else it is impossible to traverse them sanely to clean up. Yes, it will work fine for now. But the next time you have to run fsck(8) for any reason, it probably won't do its work, or at best just delete one of the spurious links.

No, this is not theory. A Ultrix system long ago here got a few directories hardlinked by some glitch. Cleaning that up by editing the filessytem was no fun.

3
  • It should still be a tree-structure, for example /Backups/2013-05-10/foo and /Backups/2013-05-11/foo pointing to the same inode. While things like searches may traverse both not recognising they're the same, it shouldn't cause any issues otherwise, though I suppose unix isn't equipped to delete hard-linked directories either (rm -R would delete the contents of both directories for example).
    – Haravikk
    May 13, 2013 at 10:35
  • 1
    @Haravikk, that isn't a tree, it's a DAG. And it has to be strictly a tree.
    – vonbrand
    May 13, 2013 at 10:55
  • Even so, the only reasons that seem to be against doing it are that unix programs (such as fsck) wouldn't support it properly, and that you can create loops. But assuming I could simply ignore links that fsck doesn't like, rather than letting it "fix" them, and that I know my structure couldn't result in loops, then I don't see any reason not to do it. As I say, Time Machine does this and it works extremely well because of there is no chance of looping.
    – Haravikk
    Jul 6, 2013 at 15:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .