[m-dev.] avoiding symlinks to ..

Zoltan Somogyi zoltan.somogyi at runbox.com
Thu Oct 19 19:59:40 AEDT 2017


At the moment, the make actions that write_deps_file.m generates
for the install_ints and install_grade_hdrs targets generate symlinks to "..",
the parent directory. This has the effect of making the target directory
of an install uncopyable with scp, because scp does not copy symlinks;
it copies *what the symlink points to* instead. With a symlink from e.g.
Mercury to "..", it copies all of .., which includes Mercury, which includes ..,
and so on ad infinitum (until you run your target machine's disk out of space).

There are ways around this, including using rsync and tar, but it still
surprises me every few months, when I happen to forget about this
problem and use scp to back up my laptop to my iMac.

Would anyone object if I changed the make actions to avoid generating
symlinks to ".."? What I propose is that instead of the current directory
layout scheme, which looks like this:

a directory for a grade such as asm_fast.gc containing
    the .opt and .trans_opt files for all library modules
    a directory named Mercury which contains
        a symlink named opts to ..
        a symlink names trans_opts to ..

we construct something like this:

a directory for a grade such as asm_fast.gc containing
    a directory named opts containing
          the .opt files for all library modules
    a directory named trans_opts containing
          the .trans_opt files for all library modules
    for each library module m, a symlink from $m.opt to opts/$m.opts
    for each library module m, a symlink from $m.transopt to trans_opts/$m.trans_opt
    a directory named Mercury which contains
         a symlink named opts to ../opts
         a symlink named trans_opts to ../trans_opts

And likewise for the other directory structures containing symlinks to parent.

When one runs scp on this, the target will be significantly bigger than the source,
because scp replaces each symlink with the target, but since no target contains
further symlinks, at least the target will be *finite* in size.

The disadvantage of this scheme is that ordinary lookups, of .int* files as well as
.*opt files, will have to follow an extra symlink. This cost shouldn't have to paid often;
Unix/Linux kernels have a cache specifically for filename to inode# translation,
and the cost has to be paid only when a filename is put into this cache.

Do people think this is a cost worth paying? My answer is "yes".

Zoltan.


More information about the developers mailing list