Symlinks are abused and misused far too often. I have seen it most often in storage. Let’s say project A is funded and they buy a few servers and some storage.

The storage is mounted on all the servers as /projectA/featureA and life goes on. Eventually they need to buy more storage. The storage they have is perfectly fine, they just want to add. They need to decide where to place the storage for a new feature, B. The could mount the storage at /projectA/featureB.

However, since the project started the business has made a decision they will mount all storage in /storage/mount#. They wanted to achieve a global name space so storage could be moved from server to server without local path dependencies. Projects will have to use the storage in /storage. The newly purchased storage is mounted in /storage/mount1 as it’s the first storage purchased after the new mount policy came into affect.

Of course, the application developers do not like the fact they have half their storage in /projectA/featureA and the other half in /storage/mount1. They have the UNIX team create a symbolic link from /projectA/featureB to /storage/mount1. Perfect they think! Now they can always reference /projectA/..!

A few months later the project is a success! The business asks them for features X, Y, and Z. Each time requiring the purchase of more storage. Now they have five mounts:

/projectA/featureA
/projectA/featureB -> /storage/mount1
/projectA/featureX -> /storage/mount2
/projectA/featureY -> /storage/mount3
/projectA/featureZ -> /storage/mount4

Of course by this time, the project name has changed five times and it’s called ProjectF, but everyone remembers it used to be called ProjectA and that is why the data exists in /projectA. Usage is continuing to increase and they decide to buy 50 more servers. The UNIX engineer who created the initial symbolic links is long gone and the new engineer has no idea these local dependencies exist. The servers are built and have all the correct storage mounted /projectA/featureA and /storage/mount1-4. The operations team starts the applications on the servers and heads home for the night.

The next morning there are all kinds of complaints about the project’s website returning all kinds of errors! After some investigation they find that the symbolic links from /projectA/feature[BXYZ] do not exist. Frantically they create these links and service is stored.

If you find yourself creating symbolic links for a production application, take a breather. Think about this decision.

4 Responses to “symlinks are the Devil and Other Reasons Why You Should Reconsider Using Them”

  1. Matt Simmons Says:

    I’m actively thinking about doing something like this in production, to allow me to shard my dataset.

    Right now, I’ve got a directory tree that’s currently at 800GB and growing continuously. I very much want to break this apart, because I’m constantly creating new LUNs to grow the filesystem to account for growth, but adding them to the logical volume is creating a string of pearls that I don’t want to break.

    My solution sounds very much like your example, in that there will be /mnt/fs/1, /mnt/fs/2, etc, each of which will be 500GB, and each of the directories that currently lives on the 800GB volume will be on one of the /mnt/fs/#, and symlinked to its original position.

    This will allow us to grow the size of the dataset without growing the filesystem, it gives me more flexibility if one particular client grows exceptionally, and decreases catastrophic loss if one of the underlying LUNs fails or is otherwise unavailable.

    Given the requirement that all client folders are available under the original directory, and the size of the dataset, I don’t see another solution to the problem, other than continuing to do what I’ve been doing, and that’s making me very, very nervous.

  2. Maxim Says:

    I’m not arguing with you about how this is ugly, but simply documenting it might have helped, too :P

  3. Peter Lewis Says:

    On NFS, I’ve done something similar, but overcame a lot of the symlink management issues by using a combination of automount and having the symbolic links on one of the mounts.

    Example:
    /mnt/linkpool/a -> /mnt/a
    /mnt/linkpool/b -> /mnt/b

    the autmount line is something like
    /mnt/* servername:/export/&

    The & registers the name as a variable and the * expands it.

  4. I’m here to shard data and chew bubblegum… | Standalone Sysadmin Says:

    [...] should also say that Bash Cures Cancer thinks this is a terrible [...]

Leave a Reply

If Wordpress eats your comment (shell output, loops, ex..) brock (at) gmail dot com.