@@ -238,25 +238,46 @@ def hash_timestamp(afile):
238
238
return md5hex
239
239
240
240
241
- def _on_cifs ( fname ):
242
- """ Checks whether a PATH is on a CIFS filesystem mounted in a POSIX
243
- host (i.e., has the " mount" command) .
241
+ def _generate_cifs_table ( ):
242
+ """Construct a reverse-length ordered list of mount points that
243
+ fall under a CIFS mount.
244
244
245
- CIFS shares are how Docker mounts Windows host directories into containers.
246
- CIFS has partial support for symlinks that can break, causing misleading
247
- errors, so this test is used to disable them on such systems.
245
+ This precomputation allows efficient checking for whether a given path
246
+ would be on a CIFS filesystem.
247
+
248
+ On systems without a ``mount`` command, or with no CIFS mounts, returns an
249
+ empty list.
248
250
"""
249
251
exit_code , output = subprocess .getstatusoutput ("mount" )
250
252
# Not POSIX
251
253
if exit_code != 0 :
252
- return False
254
+ return []
253
255
254
256
# (path, fstype) tuples, sorted by path length (longest first)
255
- paths_types = sorted ((line .split ()[2 :5 :2 ] for line in output .splitlines ()),
256
- key = lambda x : len (x [0 ]),
257
- reverse = True )
257
+ mount_info = sorted ((line .split ()[2 :5 :2 ] for line in output .splitlines ()),
258
+ key = lambda x : len (x [0 ]),
259
+ reverse = True )
260
+ cifs_paths = [path for path , fstype in mount_info if fstype == 'cifs' ]
261
+ if cifs_paths == []:
262
+ return []
263
+
264
+ return [mount for mount in mount_info
265
+ if any (mount [0 ].startswith (path ) for path in cifs_paths )]
266
+
267
+
268
+ _cifs_table = _generate_cifs_table ()
269
+
270
+
271
+ def on_cifs (fname ):
272
+ """ Checks whether a PATH is on a CIFS filesystem mounted in a POSIX
273
+ host (i.e., has the "mount" command).
274
+
275
+ CIFS shares are how Docker mounts Windows host directories into containers.
276
+ CIFS has partial support for symlinks that can break, causing misleading
277
+ errors, so this test is used to disable them on such systems.
278
+ """
258
279
# Only the first match counts
259
- for fspath , fstype in paths_types :
280
+ for fspath , fstype in _cifs_table :
260
281
if fname .startswith (fspath ):
261
282
return fstype == 'cifs'
262
283
return False
@@ -314,7 +335,7 @@ def copyfile(originalfile, newfile, copy=False, create_new=False,
314
335
hashmethod = config .get ('execution' , 'hash_method' ).lower ()
315
336
316
337
# Don't try creating symlinks on CIFS
317
- if _on_cifs (newfile ):
338
+ if copy is False and on_cifs (newfile ):
318
339
copy = True
319
340
320
341
# Existing file
0 commit comments