Reduce the system calls performed by the "file" module

when using "state: link", and particularly when using
"force: yes".

Symbolic link resolution can be expensive. In our case,
the symbolic links are legacy links to automounts, and
the "file" task was causing all of the legacy links to
be traversed and mounted on every host every time the
task executed, even when the links were correct and there
was nothing to do.

This change avoids the system calls that perform the
symbolic link resolution by taking advantage of the short
circuit behaviur of the boolean "and" operator. The code
behaviour is unchanged except that it no longer performs
unnecessary system calls.

As it turns out, this change is not sufficient to fully
solve the symbolic link resolution problem, as the "file"
module still performs a stat() at the end of execution to
provide the caller with information about the file.
However, this change is very simple, it will eliminate
unnecessary system calls in a number of use cases, and it
gets the "file" module closer to the desired end result.
pull/20617/head
Mark Mielke 8 years ago committed by Toshio Kuratomi
parent 9db1cfebbc
commit b4a1542670

@ -246,7 +246,7 @@ def main():
module.fail_json(msg='src and dest are required for creating links') module.fail_json(msg='src and dest are required for creating links')
# original_basename is used by other modules that depend on file. # original_basename is used by other modules that depend on file.
if os.path.isdir(b_path) and state not in ("link", "absent"): if state not in ("link", "absent") and os.path.isdir(b_path):
basename = None basename = None
if params['original_basename']: if params['original_basename']:
basename = params['original_basename'] basename = params['original_basename']
@ -362,7 +362,7 @@ def main():
elif state in ('link', 'hard'): elif state in ('link', 'hard'):
if os.path.isdir(b_path) and not os.path.islink(b_path): if not os.path.islink(b_path) and os.path.isdir(b_path):
relpath = path relpath = path
else: else:
b_relpath = os.path.dirname(b_path) b_relpath = os.path.dirname(b_path)
@ -370,7 +370,7 @@ def main():
absrc = os.path.join(relpath, src) absrc = os.path.join(relpath, src)
b_absrc = to_bytes(absrc, errors='surrogate_or_strict') b_absrc = to_bytes(absrc, errors='surrogate_or_strict')
if not os.path.exists(b_absrc) and not force: if not force and not os.path.exists(b_absrc):
module.fail_json(path=path, src=src, msg='src file does not exist, use "force=yes" if you really want to create the link: %s' % absrc) module.fail_json(path=path, src=src, msg='src file does not exist, use "force=yes" if you really want to create the link: %s' % absrc)
if state == 'hard': if state == 'hard':

Loading…
Cancel
Save