Gentoo Archives: gentoo-user

From: Alan McKinnon <alan.mckinnon@×××××.com>
To: gentoo-user@l.g.o
Subject: Re: [gentoo-user] Atomically swap directories
Date: Sun, 22 Jul 2012 15:23:33
Message-Id: 20120722172132.597a5e72@khamul.example.com
In Reply to: Re: [gentoo-user] Atomically swap directories by Michael Mol
1 On Sun, 22 Jul 2012 10:59:46 -0400
2 Michael Mol <mikemol@×××××.com> wrote:
3
4 > On Sun, Jul 22, 2012 at 9:53 AM, Florian Philipp
5 > <lists@×××××××××××.net> wrote:
6 > > Hi list!
7 > >
8 > > This is more a general POSIX question but I guess here I have the
9 > > best chance to get a definite answer.
10 > >
11 > > If I want to replace a file with another file without removing the
12 > > first one and without having a moment in time at which the file
13 > > name does not exist, I can use the following sequence:
14 > >
15 > > # swap $file1 with $file2 on the same file system
16 > > dir=$(dirname "$file1")
17 > > tmp=$(mktemp -u -d "$dir") # [1]
18 > > ln "$file1" "$tmp"
19 > > mv "$file2" "$file1"
20 > > mv "$tmp" "$file2"
21 > >
22 > > This works because mv does not affect the hardlink to $file1 and a
23 > > rename operation on a single file system is atomic. This is a handy
24 > > procedure when you have a background process which occasionally
25 > > opens $file1 and you don't want it to fail just because of bad
26 > > timing.
27 > >
28 > > Now my question is: How can I do a similar thing for a directory? I
29 > > cannot usually create hardlinks on directories (are there file
30 > > systems where this actually works?) and I cannot use mv to
31 > > overwrite one directory with another.
32 > >
33 > > The only idea I currently have is to create a level of indirection
34 > > via symlinks and then atomically overwrite the symlink. Is there
35 > > any other way?
36 >
37 > I'd be very, very wary of doing something like this without knowing
38 > exactly what programs might be accessing files inside the folder
39 > you're swapping out. In order to avoid a race where some poor process
40 > winds up with open file handles to some content in both your old and
41 > new folders, you'd really need a way to:
42 >
43 > 1) lock the folder so no programs can gain new handles on it or any
44 > file or folder inside
45 > 2) wait until all other open file handles to the folder and its
46 > contents are closed
47 > 3) swap out the folder
48 > 4) unlock
49 >
50 > (1) might be doable with flock() on a parent directory.
51 > (2) you'll need to use fuser to find the processes which have open
52 > handles and get them to release them.
53 > (3) mv a a_tmp; mv b a; mv a_tmp b
54 > (4) flock -u
55 >
56
57
58 I'd argue that what the OP wants is fundamentally impossible - there is
59 no such thing to my knowledge as a directory locking mechanism that is
60 guaranteed to always work in all cases - it would have to be
61 kernel-based to do that and I've personally never heard of such a
62 mechanism.
63
64 The fact is, that directory operations are not atomic wrt the directory
65 contents, and the OP needs to find a different way to solve his problem.
66
67 As for the OPs question re: hard-linking directories, Linux never allows
68 this as a user action - it can cause un-solveable loops when traversing
69 directory trees. Most other Unixes have the same rule for the same
70 reason. Some do allow it; but I forget which ones and I'm too lazy on a
71 Sunday afternoon to Google it :-)
72
73 The kernel is of course perfectly able to hard-link directories - it
74 has to to be able to create . and .. at all, but that code only runs as
75 part of what mkdir does. In all other cases the kernel is hard-coded to
76 just refuse to do it.
77
78 --
79 Alan McKinnon
80 alan.mckinnon@×××××.com

Replies

Subject Author
Re: [gentoo-user] Atomically swap directories Florian Philipp <lists@×××××××××××.net>