1、neutron 启动命令为:
/usr/bin/python2.7 /usr/bin/neutron-server --config-file /etc/neutron/neutron.conf --log-file=/var/log/neutron/server.log --config-file /etc/neutron/plugins/ml2/ml2_conf.ini
其中cat /usr/bin/neutron-server
#!/usr/bin/python2.7
# PBR Generated from u'console_scripts'
import sys
from neutron.cmd.eventlet.server import main
if __name__ == "__main__":
sys.exit(main())
2、进入neutron代码中
- 首先是neutron/cmd/eventlet/server/__init__.py 的main函数
def main():
server.boot_server(_main_neutron_server)
- neutron/server/__init__.py,读取配置设置日志
def boot_server(server_func):
# the configuration will be read into the cfg.CONF global data structure
config.init(sys.argv[1:])
config.setup_logging()
config.set_config_defaults()
if not cfg.CONF.config_file:
sys.exit(_("ERROR: Unable to find configuration file via the default"
" search paths (~/.neutron/, ~/, /etc/neutron/, /etc/) and"
" the '--config-file' option!"))
try:
server_func()
except KeyboardInterrupt:
pass
except RuntimeError as e:
sys.exit(_("ERROR: %s") % e)
- neutron/cmd/eventlet/server/__init__.py 的_main_neutron_server函数
def _main_neutron_server():
if cfg.CONF.web_framework == 'legacy':
wsgi_eventlet.eventlet_wsgi_server()
else:
wsgi_pecan.pecan_wsgi_server()
- neutron/server/wsgi_pecan.py的pecan_wsgi_server函数
def pecan_wsgi_server():
LOG.info(_LI("Pecan WSGI server starting..."))
application = pecan_app.setup_app()
neutron_api = service.run_wsgi_app(application)
wsgi_eventlet.start_api_and_rpc_workers(neutron_api)
其中application得到是关于http请求的一些policy、context、quota等的检验关于pecan起restful api的例子可以查看
通过以下方法启动neutron-server监听端口及其wsgi应用
neutron_api = service.run_wsgi_app(application)
接下来开始加载neutron的plugins:
- neutron/server/wsgi_eventlet.py 的start_api_and_rpc_workers函数
def start_api_and_rpc_workers(neutron_api):
pool = eventlet.GreenPool()
api_thread = pool.spawn(neutron_api.wait)
try:
neutron_rpc = service.serve_rpc()
except NotImplementedError:
LOG.info(_LI("RPC was already started in parent process by "
"plugin."))
else:
rpc_thread = pool.spawn(neutron_rpc.wait)
plugin_workers = service.start_plugin_workers()
for worker in plugin_workers:
pool.spawn(worker.wait)
# api and rpc should die together. When one dies, kill the other.
rpc_thread.link(lambda gt: api_thread.kill())
api_thread.link(lambda gt: rpc_thread.kill())
pool.waitall()
其中neutron/service.py serve_rpc函数
def serve_rpc():
plugin = manager.NeutronManager.get_plugin()
service_plugins = (
manager.NeutronManager.get_service_plugins().values())
...
...
...
try:
# passing service plugins only, because core plugin is among them
rpc = RpcWorker(service_plugins)
...
...
...
launcher = common_service.ProcessLauncher(cfg.CONF, wait_interval=1.0)
launcher.launch_service(rpc, workers=cfg.CONF.rpc_workers)
if (cfg.CONF.rpc_state_report_workers > 0 and
plugin.rpc_state_report_workers_supported()):
rpc_state_rep = RpcReportsWorker([plugin])
LOG.debug('using launcher for state reports rpc, workers=%s',
cfg.CONF.rpc_state_report_workers)
launcher.launch_service(
rpc_state_rep, workers=cfg.CONF.rpc_state_report_workers)
return launcher
...
...
...
其中class NeutronManager(object)类的__init__函数中通过函数
self._load_service_plugins()从配置文件中得到service_plugins的值,并赋值给self.serivce_plugins
/etc/neutron/neutron.conf
[DEFAULT]
service_plugins=xxxx
回到start_api_and_rpc_workers函数接着即会启动相应配置文件的子进程数,执行wait操作