I've tracked down the blocking use of randomness in cloud-init's python
module initialization.  There are several nonblocking calls to
getrandom(), which I believe should be fine; then a blocking call in the
multiprocessing module.

# PYTHONHASHSEED=1 gdb --args /usr/bin/python3-dbg /usr/bin/cloud-init init
GNU gdb (Ubuntu 8.0.1-0ubuntu1) 8.0.1
[...]
(gdb) break getrandom
Breakpoint 1 at 0x420b90
(gdb) python
>import sys
>sys.path.append('/usr/share/doc/python3.6/examples/gdb')
>import libpython
>end
(gdb) run
Starting program: /usr/bin/python3-dbg /usr/bin/cloud-init init
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, getrandom (buffer=buffer@entry=0x7fffffff8140,
    length=length@entry=2496, flags=flags@entry=1)
    at ../sysdeps/unix/sysv/linux/getrandom.c:30
[...]
(gdb) cont 4
Will ignore next 3 crossings of breakpoint 1.  Continuing.
[...]
-------+
ci-info: | Route |  Destination  |    Gateway    |     Genmask     | Interface |
 Flags |
ci-info: +-------+---------------+---------------+-----------------+-----------+
-------+
ci-info: |   0   |    0.0.0.0    | 192.168.122.1 |     0.0.0.0     |    ens3   |
   UG  |
ci-info: |   1   | 192.168.122.0 |    0.0.0.0    |  255.255.255.0  |    ens3   |
   U   |
ci-info: |   2   | 192.168.122.1 |    0.0.0.0    | 255.255.255.255 |    ens3   |
   UH  |
ci-info: +-------+---------------+---------------+-----------------+-----------+
-------+
/usr/lib/python3.6/logging/config.py:85: ResourceWarning: unclosed file <_io.Tex
tIOWrapper name='/var/log/cloud-init.log' mode='a' encoding='UTF-8'>
  _install_loggers(cp, handlers, disable_existing_loggers)

Breakpoint 1, getrandom (buffer=buffer@entry=0x7ffff21b7340,
    length=length@entry=32, flags=flags@entry=0)
    at ../sysdeps/unix/sysv/linux/getrandom.c:30
30      in ../sysdeps/unix/sysv/linux/getrandom.c
(gdb) py-bt
Traceback (most recent call first):
  0x7ffff6b66b20
  File "/usr/lib/python3.6/multiprocessing/process.py", line 307, in __init__
    self._config = {'authkey': AuthenticationString(os.urandom(32)),
  File "/usr/lib/python3.6/multiprocessing/process.py", line 320, in <module>
    _current_process = _MainProcess()
  <built-in method exec of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  <built-in method __import__ of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1017, in _handle_fromlist
  File "/usr/lib/python3.6/multiprocessing/context.py", line 5, in <module>
    from . import process
  <built-in method exec of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  <built-in method __import__ of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1017, in _handle_fromlist
  File "/usr/lib/python3.6/multiprocessing/__init__.py", line 16, in <module>
    from . import context
  <built-in method exec of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "/usr/lib/python3.6/concurrent/futures/process.py", line 53, in <module>
    import multiprocessing
  <built-in method exec of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "/usr/lib/python3.6/concurrent/futures/__init__.py", line 17, in <module>
    from concurrent.futures.process import ProcessPoolExecutor
  <built-in method exec of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "/usr/lib/python3.6/asyncio/base_events.py", line 17, in <module>
    import concurrent.futures
  <built-in method exec of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "/usr/lib/python3.6/asyncio/__init__.py", line 21, in <module>
    from .base_events import *
  <built-in method exec of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "/usr/lib/python3/dist-packages/jinja2/asyncsupport.py", line 13, in 
<module>
    import asyncio
  <built-in method exec of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "/usr/lib/python3/dist-packages/jinja2/__init__.py", line 77, in 
_patch_async
    from jinja2.asyncsupport import patch_all
  File "/usr/lib/python3/dist-packages/jinja2/__init__.py", line 81, in <module>
    _patch_async()
  <built-in method exec of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "/usr/lib/python3/dist-packages/cloudinit/templater.py", line 23, in 
<module>
    import jinja2
  <built-in method exec of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  <built-in method __import__ of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1017, in _handle_fromlist
  File 
"/usr/lib/python3/dist-packages/cloudinit/config/cc_update_etc_hosts.py", line 
52, in <module>
    from cloudinit import templater
  <built-in method exec of module object at remote 0x7ffff6bb9cd8>
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  0x7ffff6bbf580
  File "/usr/lib/python3/dist-packages/cloudinit/importer.py", line 15, in 
import_module
    __import__(module_name)
  File "/usr/lib/python3/dist-packages/cloudinit/importer.py", line 35, in 
find_module
    mod = import_module(full_path)
  File "/usr/lib/python3/dist-packages/cloudinit/stages.py", line 751, in 
_fixup_modules
    mod_name, ['', type_utils.obj_name(config)], ['handle'])
  File "/usr/lib/python3/dist-packages/cloudinit/stages.py", line 818, in 
run_section
    mostly_mods = self._fixup_modules(raw_mods)
  File "/usr/lib/python3/dist-packages/cloudinit/cmd/main.py", line 107, in 
run_module_section
    (which_ran, failures) = mods.run_section(full_section_name)
  File "/usr/lib/python3/dist-packages/cloudinit/cmd/main.py", line 416, in 
main_init
    return (init.datasource, run_module_section(mods, name, name))
  File "/usr/lib/python3/dist-packages/cloudinit/cmd/main.py", line 638, in 
status_wrapper
    ret = functor(name, args)
  File "/usr/lib/python3/dist-packages/cloudinit/util.py", line 2238, in 
log_time
    ret = func(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/cloudinit/cmd/main.py", line 829, in main
    get_uptime=True, func=functor, args=(name, args))
  File "/usr/bin/cloud-init", line 11, in <module>
    load_entry_point('cloud-init==17.1', 'console_scripts', 'cloud-init')()
(gdb) 

We have the option to set the authkey to a different value post-
initialization, but there's no way to avoid using entropy when importing
this module.

** Also affects: python3.6 (Ubuntu)
   Importance: Undecided
       Status: New

** Changed in: python3.6 (Ubuntu)
       Status: New => Triaged

** Changed in: cloud-init (Ubuntu)
       Status: Incomplete => Triaged

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1727358

Title:
  cloud-init is slow to complete init on minimized images

To manage notifications about this bug go to:
https://bugs.launchpad.net/cloud-init/+bug/1727358/+subscriptions

-- 
ubuntu-bugs mailing list
ubuntu-bugs@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to