@@ -238,25 +238,45 @@ 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 ()),
257
+ mount_info = sorted ((line .split ()[2 :5 :2 ] for line in output .splitlines ()),
256
258
key = lambda x : len (x [0 ]),
257
- reverse = True )
259
+ cifs_paths = [path for path , fstype in mount_info ]
260
+ if cifs_paths == []:
261
+ return []
262
+
263
+ return [mount for mount in mount_info
264
+ if any (mount [0 ].startswith (path ) for path in cifs_paths )]
265
+
266
+
267
+ _cifs_table = _generate_cifs_table ()
268
+
269
+
270
+ def on_cifs (fname ):
271
+ """ Checks whether a PATH is on a CIFS filesystem mounted in a POSIX
272
+ host (i.e., has the "mount" command).
273
+
274
+ CIFS shares are how Docker mounts Windows host directories into containers.
275
+ CIFS has partial support for symlinks that can break, causing misleading
276
+ errors, so this test is used to disable them on such systems.
277
+ """
258
278
# Only the first match counts
259
- for fspath , fstype in paths_types :
279
+ for fspath , fstype in _cifs_table :
260
280
if fname .startswith (fspath ):
261
281
return fstype == 'cifs'
262
282
return False
@@ -314,7 +334,7 @@ def copyfile(originalfile, newfile, copy=False, create_new=False,
314
334
hashmethod = config .get ('execution' , 'hash_method' ).lower ()
315
335
316
336
# Don't try creating symlinks on CIFS
317
- if _on_cifs (newfile ):
337
+ if copy is False and on_cifs (newfile ):
318
338
copy = True
319
339
320
340
# Existing file
0 commit comments