1193323Sed<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
2193323Sed        "http://www.w3.org/TR/html4/loose.dtd">
3193323Sed
4193323Sed<html>
5193323Sed
6193323Sed<head>
7193323Sed
8193323Sed<title>Postfix and NFS</title>
9193323Sed
10193323Sed<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
11193323Sed<link rel='stylesheet' type='text/css' href='postfix-doc.css'>
12193323Sed
13193323Sed</head>
14280031Sdim
15280031Sdim<body>
16193323Sed
17193323Sed<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix and NFS</h1>
18193323Sed
19249423Sdim<hr>
20218893Sdim
21193323Sed<h2> Postfix support status for NFS </h2>
22193323Sed
23193323Sed<p> What is the status of support for Postfix on NFS? The answer
24195098Sedis that Postfix itself is supported when you use NFS, but there is
25280031Sdimno promise that an NFS-related problem will promptly receive a
26280031SdimPostfix workaround, or that a workaround will even be possible.
27280031Sdim</p>
28280031Sdim
29296417Sdim<p> That said, Postfix will in many cases work very well on NFS,
30296417Sdimbecause Postfix implements a number of workarounds (see below).
31280031SdimGood NFS implementations seldom if ever give problems with Postfix,
32280031Sdimso Wietse recommends that you spend your money wisely.  </p>
33195098Sed
34280031Sdim<h2> Postfix file locking and NFS </h2>
35194612Sed
36280031Sdim<p> For the Postfix mail queue, it does not matter how well NFS
37280031Sdimfile locking works. The reason is that you cannot share Postfix
38280031Sdimqueues among multiple running Postfix instances. You can use NFS
39193323Sedto switch a Postfix mail queue from one NFS client to another one,
40288943Sdimbut only one NFS client can access a Postfix mail queue at any
41288943Sdimparticular point in time. </p>
42234353Sdim
43288943Sdim<p> For mailbox file sharing with NFS, your options are to use
44280031Sdim<b>fcntl</b> (kernel locks), <b>dotlock</b> (<i>username</i>.lock
45193323Sedfiles), to use both locking methods simultaneously, or to switch
46288943Sdimto maildir format. The maildir format uses one file per message and
47280031Sdimneeds no file locking support in Postfix or in other mail software.
48288943Sdim</p>
49193323Sed
50288943Sdim<p> Many sites that use mailbox format play safe and use both locking
51288943Sdimmethods simultaneously. </p>
52249423Sdim
53193323Sed<blockquote>
54276479Sdim<pre>
55234353Sdim/etc/postfix/main.cf:
56280031Sdim    virtual_mailbox_lock = fcntl, dotlock
57280031Sdim    mailbox_delivery_lock = fcntl, dotlock
58280031Sdim</pre>
59193323Sed</blockquote>
60193323Sed
61195098Sed<h2> Postfix NFS workarounds </h2>
62195098Sed
63195098Sed<p> The list below summarizes the workarounds that exist for running
64234353SdimPostfix on NFS as of the middle of 2003. As a reminder, Postfix
65218893Sdimitself is still supported when it runs on NFS, but there is no
66288943Sdimpromise that an NFS-related problem will promptly receive a Postfix
67288943Sdimworkaround, or that a workaround will even be possible.  </p>
68276479Sdim
69276479Sdim<ul>
70195098Sed
71276479Sdim<li> <p> Problem: when renaming a file, the operation may succeed
72276479Sdimbut report an error anyway<sup>[1]</sup>. </p>
73276479Sdim
74276479Sdim<p> Workaround: when rename(old, new) reports an error, Postfix
75276479Sdimchecks if the new name exists and the old name is gone. If the check
76288943Sdimsucceeds, Postfix assumes that the rename() operation completed
77288943Sdimnormally.  </p>
78276479Sdim
79276479Sdim<li> <p> Problem: when creating a directory, the operation may succeed
80276479Sdimbut report an error anyway<sup>[1]</sup>. </p>
81195098Sed
82276479Sdim<p> Workaround: when mkdir(new) reports an EEXIST error, Postfix
83276479Sdimchecks if the new name resolves to a directory. If the check succeeds,
84276479SdimPostfix assumes that the mkdir() operation completed normally.  </p>
85276479Sdim
86276479Sdim<li> <p> Problem: when creating a hardlink to a file, the operation
87288943Sdimmay succeed but report an error anyway<sup>[1]</sup>. </p>
88288943Sdim
89288943Sdim<p> Workaround: when link(old, new) fails, Postfix compares the
90288943Sdimdevice and inode number of the old and new files. When the two files
91195098Sedare identical, Postfix assumes that the link() operation completed
92195098Sednormally. </p>
93193323Sed
94195340Sed<li> <p> Problem: when creating a dotlock (<i>username</i>.lock)
95195340Sedfile, the operation may succeed but report an error anyway<sup>[1]</sup>.
96193323Sed</p>
97195098Sed
98234353Sdim<p> Workaround: in this case, the only safe action is to back off
99193323Sedand try again later.  </p>
100288943Sdim
101288943Sdim<li> <p> Problem: when a file server's "time of day" clock is not
102288943Sdimsynchronized with the client's "time of day" clock, email deliveries
103288943Sdimare delayed by a minute or more.  </p>
104276479Sdim
105193323Sed<p> Workaround: Postfix explicitly sets file time stamps to avoid
106276479Sdimdelays with new mail (Postfix uses "last modified" file time stamps
107276479Sdimto decide when a queue file is ready for delivery).  </p>
108276479Sdim
109276479Sdim</ul>
110276479Sdim
111288943Sdim<p> <sup>[1]</sup> How can an operation succeed and report an error
112276479Sdimanyway? </p>
113276479Sdim
114276479Sdim<p> Suppose that an NFS server executes a client request successfully,
115276479Sdimand that the server's reply to the client is lost.  After some time
116195098Sedthe client retransmits the request to the server.  Normally, the
117276479Sdimserver remembers that it already completed the request (it keeps a
118276479Sdimlist of recently-completed requests and replies), and simply
119276479Sdimretransmits the reply. </p>
120276479Sdim
121276479Sdim<p> However, when the server has rebooted or when it has been very
122288943Sdimbusy, the server no longer remembers that it already completed the
123276479Sdimrequest, and repeats the operation.  This causes no problems with
124276479Sdimfile read/write requests (they contain a file offset and can therefore
125276479Sdimbe repeated safely), but fails with non-idempotent operations. For
126193323Sedexample, when the server executes a retransmitted rename() request,
127193323Sedthe server reports an ENOENT error because the old name does not
128193323Sedexist; and when the server executes a retransmitted link(), mkdir()
129193323Sedor create() request, the server reports an EEXIST error because the
130193323Sedname already exists. </p>
131
132<p> Thus, successful, non-idempotent, NFS operations will report
133false errors when the server reply is lost, the client retransmits
134the request, and the server does not remember that it already
135completed the request.  </p>
136
137</body>
138</html>
139