Updated to remove out-of-date info, add a new entry (on firewall
[rsync-web.git] / faqbody.html
1 <table><tr><td><ul>
2 <li><a href="#1">Read-only file system</a><br>
3 <li><a href="#2">copies every file</a><br>
4 <li><a href="#3">is your shell clean</a><br>
5 <li><a href="#4">memory usage</a><br>
6 <li><a href="#5">out of memory</a><br>
7 </ul></td><td>&nbsp;&nbsp;&nbsp;&nbsp;</td><td><ul>
8 <li><a href="#6">rsync through a firewall</a><br>
9 <li><a href="#7">rsync and cron</a><br>
10 <li><a href="#8">rsync: Command not found</a><br>
11 <li><a href="#9">spaces in filenames</a><br>
12 <li><a href="#10">HP compile</a><br>
13 </ul></td></tr></table>
14
15 <h3><a name=1>Read-only file system</a></h3>
16
17 <p>If you get "Read-only file system" as an error when sending to a rsync
18 daemon then you probably forgot to set "read only = no" for that module.
19
20 <hr>
21 <h3><a name=2>copies every file</a></h3>
22
23 <p>Some people occasionally report that rsync copies every file when they
24 expect it to copy only a small subset. In most cases the explanation is
25 that you forgot to include the --times (-t) option in the original copy,
26 so rsync is forced to check every file to see if it has changed (because
27 the modified time and size do not match).
28
29 <p>If you think that rsync is erroneously copying every file then look at
30 the stats produced with -v and see if rsync is really sending all the data. 
31
32 <hr>
33 <h3><a name=3>is your shell clean</a></h3>
34
35 <p>The "is your shell clean" message and the "protocol mismatch" message
36 are usually caused by having some sort of program in your .cshrc, .profile,
37 .bashrc or equivalent file that writes a message every time you connect
38 using a remote-shell program (such as ssh or rsh).  Data written in this
39 way corrupts the rsync data stream. rsync detects this at startup and
40 produces those error messages.  However, if you are using rsync-daemon
41 syntax (host::path or rsync://) without using a remote-shell program (no
42 --rsh or -e option), there is not remote-shell program involved, and the
43 problem is probably caused by an error on the daemon side (so check the
44 daemon logs).
45
46 <p>A good way to test if your remote-shell connection is clean is to try
47 something like this (use ssh or rsh, as appropriate):
48
49 <blockquote><pre>ssh remotemachine /bin/true &gt; test.dat</pre></blockquote>
50
51 <p>That should create a file called test.dat with nothing in it. If
52 test.dat is not of zero length then your shell is not clean.  Look at the
53 contents of test.dat to see what was sent. Look at all the startup files on
54 remotemachine to try and find the problem.
55
56 <hr>
57 <h3><a name=4>memory usage</a></h3>
58
59 <p>Yes, rsync uses a lot of memory. The majority of the memory is used to
60 hold the list of files being transferred. This takes about 100 bytes per
61 file, so if you are transferring 800,000 files then rsync will consume
62 about 80M of memory. It will be higher if you use -H or --delete.
63
64 <p>To fix this requires a major rewrite of rsync, which my or may not
65 happen.
66
67 <hr>
68 <h3><a name=5>out of memory</a></h3>
69
70 <p>The usual reason for "out of memory" when running rsync is that you are
71 transferring a _very_ large number of files.  The size of the files doesn't
72 matter, only the total number of files.
73
74 <p>As a rule of thumb you should expect rsync to consume about 100 bytes
75 per file in the file list. This happens because rsync builds a internal
76 file list structure containing all the vital details of each file.  rsync
77 needs to hold structure in memory because it is being constantly traversed.
78
79 <p>A future version of rsync could be built with an improved protocol that
80 transfers files in a more incremental fashion, which would require a lot
81 less memory.  Unfortunately, such an rsync does not yet exist.
82
83 <hr>
84 <h3><a name=6>rsync through a firewall</a></h3>
85
86 <p>If you have a setup where there is no way to directly connect two
87 machines for an rsync transfer, there are several ways to use the firewall
88 machine to act as an intermediary in the transfer.
89
90 <h4>Method 1</h4>
91
92 <p>Use ssh to access the intermediary system and have it ssh into the
93 actual target machine.
94
95 <p>To effect this extra ssh hop, you'll need to configure a authorization
96 method that does not involve any user interaction (such as prompting for a
97 password).  The easiest way to do this is to setup an ssh key (see the
98 ssh-key manpage).  You can encrypt this key (which requires a passphrase to
99 unlock it) as long as you have ssh-agent forwarding enabled -- this allows
100 the ssh connection between the intermediary system and the target machine
101 to authorize without a passphrase prompt because the authorization
102 information is coming from your local machine via the ssh protocol (which
103 has the benefit of not making intra-system logins password-less in
104 general).  Another solution is to configure host-based authentication,
105 which makes all logins between authorized machines automatically authorized
106 (which may or may not be something that you are comfortable with).
107
108 <p>You should then test that the forwarded ssh connection works without a
109 prompt by running a command like this:
110
111 <blockquote><pre>ssh inter ssh target uptime</pre></blockquote>
112
113 <p>If you get a password/passphrase prompt to get into the intermediary
114 system that's fine, but the extra hop need to occur without any extra user
115 interaction.
116
117 <p>Once that's done, you can do an rsync copy like this (one pull, one
118 push):
119
120 <blockquote><pre>rsync -av --rsync-path="ssh target rsync" inter:/source/ /dest/
121 rsync -av --rsync-path="ssh target rsync" /source/ inter:/dest/</pre></blockquote>
122
123 <p>These commands looks like they are copying to/from the "inter" host, but the 
124 remote-rsync command that we it to run performs the extra hop to the real
125 target system and runs the rsync command there.
126
127 <h4>Method 2</h4>
128
129 <p>Install and configure an rsync daemon on the target and use an ssh
130 tunnel to reach the rsync sever.
131
132 <p>Installing the rsync daemon is beyond the scope of this document, but
133 see the rsyncd.conf manpage for more information.  Keep in mind that you
134 don't need to be root to run an rsync daemon as long as you don't use a
135 protected port.
136
137 <p>Once your rsync daemon is up and running, you build an ssh tunnel
138 through your intermediary system like this:
139
140 <blockquote><pre>ssh -fN -l userid_on_inter -L 8873:target:8873 inter</pre></blockquote>
141
142 <p>What this does is cause a connection to port 8873 on the local system to
143 turn into a connection from the intermediary system to the target machine
144 on port 8873.  (Port 8873 was chosen instead of the normal 873 port number
145 because it does not require root privileges--use whatever port number you
146 like.)  The -N option tells ssh not to run a command on the remote system,
147 which works with modern ssh versions (you can run a sleep command if -N
148 doesn't work).  The -f option tells ssh to put the command in the
149 background after any password/passphrase prompts.
150
151 <p>Now when an rsync command is executed with a daemon-mode command-line
152 syntax to the local machine, the conversation is directed to the target
153 system.  For example:
154
155 <blockquote><pre>rsync -av --port 8873 localhost::module/source dest/
156 rsync -av rsync://localhost:8873/module/source dest/</pre></blockquote>
157
158 <hr>
159 <h3><a name=7>rsync and cron</a></h3>
160
161 <p>On some systems (notably SunOS4) cron supplies what looks like a socket
162 to rsync, so rsync thinks that stdin is a socket. This means that if you
163 start rsync with the --daemon switch from a cron job you end up rsync
164 thinking it has been started from inetd. The fix is simple&mdash;just
165 redirect stdin from /dev/null in your cron job.
166
167 <hr>
168 <h3><a name=8>rsync: Command not found</a></h3>
169
170 <p>This error is produced when the remote shell is unable to locate the rsync
171 binary in your path. There are 3 possible solutions:
172
173 <ol>
174
175 <li>install rsync in a "standard" location that is in your remote path. 
176
177 <li>modify your .cshrc, .bashrc etc on the remote machine to include the path
178 that rsync is in
179
180 <li>use the --rsync-path option to explicitly specify the path on the
181 remote machine where rsync is installed
182
183 </ol>
184
185 <p>You may echo find the command:
186
187 <blockquote><pre>ssh host 'echo $PATH'</pre></blockquote>
188
189 <p>for determining what your remote path is.
190
191 <hr>
192 <h3><a name=9>spaces in filenames</a></h3>
193
194 <p>Can rsync copy files with spaces in them?
195
196 <p>Short answer: Yes, rsync can handle filenames with spaces.
197
198 <p>Long answer: 
199
200 <p>Rsync handles spaces just like any other unix command line application.
201 Within the code spaces are treated just like any other character so a
202 filename with a space is no different from a filename with any other
203 character in it.
204
205 <p>The problem of spaces is in the argv processing done to interpret the
206 command line.  As with any other unix application you have to escape spaces
207 in some way on the command line or they will be used to separate arguments. 
208
209 <p>It is slightly trickier in rsync (and other remote-copy programs like
210 scp) because rsync sends a command line to the remote system to launch the
211 peer copy of rsync (this assumes that we're not talking about daemon mode,
212 which is not affected by this problem because no remote shell is involved
213 in the reception of the filenames).  The command line is interpreted by the
214 remote shell and thus the spaces need to arrive on the remote system
215 escaped so that the shell doesn't split such filenames into multiple
216 arguments.
217
218 <p>For example:
219
220 <blockquote><pre>rsync -av host:'a long filename' /tmp/</pre></blockquote>
221
222 <p>This is usually a request for rsync to copy 3 files from the remote
223 system, "a", "long", and "filename" (the only exception to this is for a
224 system running a shell that does not word-split arguments in its commands,
225 and that is exceedingly rare).  If you wanted to request a single file with
226 spaces, you need to get some kind of space-quoting characters to the remote
227 shell that is running the remote rsync command.  The following commands
228 should all work:
229
230 <blockquote><pre>rsync -av host:'"a long filename"' /tmp/
231 rsync -av host:'a\ long\ filename' /tmp/
232 rsync -av host:a\\\ long\\\ filename /tmp/</pre></blockquote>
233
234 <p>You might also like to use a '?' in place of a space as long as there
235 are no other matching filenames than the one with spaces (since '?' matches
236 any character):
237
238 <blockquote><pre>rsync -av host:a?long?filename /tmp/</pre></blockquote>
239
240 <p>As long as you know that the remote filenames on the command line
241 are interpreted by the remote shell then it all works fine. 
242
243 <hr>
244 <h3><a name=10>HP compile</a></h3>
245
246 <p>For HPUX apparently you need to add the option -Ae to the CFLAGS. Edit
247 the Makefile and change CFLAGS to:
248
249 <blockquote><pre>CFLAGS=-Ae -O</pre></blockquote>
250
251 <hr>
252