CS 111 Scribe notes • March 24, 2013
- Spencer Brett
- Jeremy Haugen
Problem with symbolic links
In Emacs, let's say you're editing /etc/passwd
.
While the Emacs buffer contents are not equal to the file contents, Emacs creates a symbolic link:
/etc/.#passwd
with contents:
eggert@penguin.z:9371
This acts as a locking mechanism and contains info about Emacs as well as a process ID (9371).
Questions:
What can go wrong?
- non-Emacs editors (aside: Emacs stat("/etc/passwd") before rewriting, st_mtime...)
- Emacs crashes (workaround: kill(9371, 0)) (failures possible)
- Emacs loops while holding the lock (workaround: Emacs can steal the lock)
- Suppose
/etc/.#passwd
already exists for some other reason
If it is a regular file /etc/.#passwd/
, don't lock. (we hope this is the case).
- Another application removes the lock file or changes what it points to. (This messes up Emacs)
- You haven't changed buffer yet; Someone else locks it. (stat... as in 1.)
- File name base (after last slash) ≥ 254 bytes. (workaround: same as 4.)
- Different Emacses on different hosts can interoperate. (lnxsrv03.seas.ucla.edu vs. lnxsrv01.seas.ucla.edu)
- MS-Windows makes symlinks hard (ie. Programs need "create symbolic links" privileges) (workaround: use regular files)
Alternatives to using symlinks for lock files
fcntl(fc,F_SETLK,...)
(POSIX) not in Windows, postdates Emacs, didn't work with NFS until NFSv4.
- Use regular files for locks
-Peformance?
- fctl has 3 system calls
open(".#file")
read(fd,buf,bufsize)
close()
- Only 1 system call(atomic) for symbolic links:
symlink(".#file",buf,bufsize)
$ ln -s 'eggert@27' foo
$ ln foo bar
- You cannot change contents of a symlink
- You cannot change foo to change bar
Symbolic links are directory entries.
Advantages: fewer disk accesses.
Disadvantages: no hard links to symlinks.
Security issues with symbolic links
Attacker (eggert) Victim
$ ln -s ~eggert/data /tmp/foo umask 077
$ touch ~eggert/data sort -o /tmp/foo
$ chmod 777 ~eggert/data uniq /tmp/foo
$ cat ~eggert/data rm /tmp/foo
File name resolution
open("a/b/c/foo",O_RDONLY)...
$ ls -l a/b ... a/b->x/y
Suppose a/b goes to x/y
Steps: per process working directory
- get this process's working directory D from process table
- get 1st file name component C
- look up C in D (if none, we fail errno==ENOENT)
- you now have inode #I
- is it a directory? errno==ENOTDIR
- is it a symlink?
- No: errno==EPERM
- Yes: substitute symlink contents for name
- Set D=I and repeat from step 2
Problems?
- If contents start with a / (root directory vs. working directory)
- symlink loop (fix: counter of # symlinks traversed. Limit is 20. errno==ELOOP).
System calls
chdir("foo")
to change working directory.
chroot("bar")
to change root directory.
Example Code:
main.c
#include <unistd.h>
int main (int argc, char ** argv) {
chdir(argv[1]);
}
Call
$ gcc main.c -o mcd
$ ./mcd /tmp
$ cat foo
/home/eggert/playpen/usr/bin/passwd
/home/eggert/playpen/etc/passwd
chroot("/home/eggert/playpen");
system("/usr/bin/su");
Link Counts and Hard Links
- bug in system:
- removed link but forgot to decrement link count
- => file system will leak blocks
- bug: decrement link count, without removing directory entry
- => file system has dangling ptr (undefinded behavior).
- link can't overflow
loops of hardlinks no hardlinks to directories
Brief look at other file system problems
GPFS (an example big-machine file system)
120 PetaBytes from about 200,000 hard drives (600 GB hard drives for performance)
- stripes: blocks of data over multiple disks
- distributed metadata
- directories live in a file system
- efficient directory indexing
- distributed locking
- grab 10,000,000 images of physics experiment X
- name the files (exp1.img, exp2.img... exp10000000.img)
- file system stays live during maintenance
- to look up an entry O(N) operation where N is the number of directory entries in this directory
magic-gpfs-clone /gpfs /gpfs-feb25
cd /gpfs-Feb25
tar -cf /dev/tape .