docs: def start(self):
          '''
          Turn on the master server components
          '''
          self._pre_flight()
          log.info('salt-master is starting as user \'%s\'', salt.utils.user.get_user())
  
          enable_sigusr1_handler()
          enable_sigusr2_handler()
  
          self.__set_max_open_files()
  
          # Reset signals to default ones before adding processes to the process
          # manager. We don't want the processes being started to inherit those
          # signal handlers
          with salt.utils.process.default_signals(signal.SIGINT, signal.SIGTERM):
  
              # Setup the secrets here because the PubServerChannel may need
              # them as well.
              SMaster.secrets['aes'] = {
                  'secret': multiprocessing.Array(
                      ctypes.c_char,
                      salt.utils.stringutils.to_bytes(
                          salt.crypt.Crypticle.generate_key_string()
                      )
                  ),
                  'reload': salt.crypt.Crypticle.generate_key_string
              }
              log.info('Creating master process manager')
              # Since there are children having their own ProcessManager we should wait for kill more time.
              self.process_manager = salt.utils.process.ProcessManager(wait_for_kill=5)
              pub_channels = []
              log.info('Creating master publisher process')
              log_queue = salt.log.setup.get_multiprocessing_logging_queue()
              for _, opts in iter_transport_opts(self.opts):
                  chan = salt.transport.server.PubServerChannel.factory(opts)
                  chan.pre_fork(self.process_manager, kwargs={'log_queue': log_queue})
                  pub_channels.append(chan)
  
              log.info('Creating master event publisher process')
              self.process_manager.add_process(salt.utils.event.EventPublisher, args=(self.opts,))
  
              if self.opts.get('reactor'):
                  if isinstance(self.opts['engines'], list):
                      rine = False
                      for item in self.opts['engines']:
                          if 'reactor' in item:
                              rine = True
                              break
                      if not rine:
                          self.opts['engines'].append({'reactor': {}})
                  else:
                      if 'reactor' not in self.opts['engines']:
                          log.info('Enabling the reactor engine')
                          self.opts['engines']['reactor'] = {}
  
              salt.engines.start_engines(self.opts, self.process_manager)
  
              # must be after channels
              log.info('Creating master maintenance process')
              self.process_manager.add_process(Maintenance, args=(self.opts,))
  
              if self.opts.get('event_return'):
                  log.info('Creating master event return process')
                  self.process_manager.add_process(salt.utils.event.EventReturn, args=(self.opts,))
  
              ext_procs = self.opts.get('ext_processes', [])
              for proc in ext_procs:
                  log.info('Creating ext_processes process: %s', proc)
                  try:
                      mod = '.'.join(proc.split('.')[:-1])
                      cls = proc.split('.')[-1]
                      _tmp = __import__(mod, globals(), locals(), [cls], -1)
                      cls = _tmp.__getattribute__(cls)
                      self.process_manager.add_process(cls, args=(self.opts,))
                  except Exception:
                      log.error('Error creating ext_processes process: %s', proc)
  
              if HAS_HALITE and 'halite' in self.opts:
                  log.info('Creating master halite process')
                  self.process_manager.add_process(Halite, args=(self.opts['halite'],))
  
              # TODO: remove, or at least push into the transport stuff (pre-fork probably makes sense there)
              if self.opts['con_cache']:
                  log.info('Creating master concache process')
                  self.process_manager.add_process(salt.utils.master.ConnectedCache, args=(self.opts,))
                  # workaround for issue #16315, race condition
                  log.debug('Sleeping for two seconds to let concache rest')
                  time.sleep(2)
  
              log.info('Creating master request server process')
              kwargs = {}
              if salt.utils.platform.is_windows():
                  kwargs['log_queue'] = log_queue
                  kwargs['log_queue_level'] = salt.log.setup.get_multiprocessing_logging_level()
                  kwargs['secrets'] = SMaster.secrets
  
              self.process_manager.add_process(
                  ReqServer,
                  args=(self.opts, self.key, self.master_key),
                  kwargs=kwargs,
                  name='ReqServer')
  
              self.process_manager.add_process(
                  FileserverUpdate,
                  args=(self.opts,))
  
              # Fire up SSDP discovery publisher
              if self.opts['discovery']:
                  if salt.utils.ssdp.SSDPDiscoveryServer.is_available():
                      self.process_manager.add_process(salt.utils.ssdp.SSDPDiscoveryServer(
                          port=self.opts['discovery']['port'],
                          listen_ip=self.opts['interface'],
                          answer={'mapping': self.opts['discovery'].get('mapping', {})}).run)
                  else:
                      log.error('Unable to load SSDP: asynchronous IO is not available.')
                      if sys.version_info.major == 2:
                          log.error('You are using Python 2, please install "trollius" module to enable SSDP discovery.')
  
          # Install the SIGINT/SIGTERM handlers if not done so far
          if signal.getsignal(signal.SIGINT) is signal.SIG_DFL:
              # No custom signal handling was added, install our own
              signal.signal(signal.SIGINT, self._handle_signals)
  
          if signal.getsignal(signal.SIGTERM) is signal.SIG_DFL:
              # No custom signal handling was added, install our own
              signal.signal(signal.SIGTERM, self._handle_signals)
  
          self.process_manager.run()