Gentoo Archives: gentoo-user

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

Attachments

File name MIME type
signature.asc application/pgp-signature