文前说明
作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。
本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。
分析整理的版本为 Ovirt 3.4.5 版本。
命令使用方式:Usage: /etc/init.d/ovirt-engine {start|stop|status|restart}
if __name__ == '__main__':
service.setupLogger()
d = Daemon()
d.run()
根据参数打开系统日志
logger = logging.getLogger('ovirt')
logger.propagate = False
if os.environ.get('OVIRT_SERVICE_DEBUG', '0') != '0':
logger.setLevel(logging.DEBUG)
else:
logger.setLevel(logging.INFO)
启动守护进程
usage=_('usage: %prog [options] start'),
def _daemon(self):
self.logger.debug('daemon entry pid=%s', os.getpid())
self.logger.debug('background=%s', self._options.background)
os.umask(0o022)
self.daemonSetup()
self._daemonReady()
......
- 设置启动参数
......
parser.add_option(
'-d', '--debug',
dest='debug',
action='store_true',
default=False,
help=_('debug mode'),
)
parser.add_option(
'--pidfile',
dest='pidfile',
default=None,
metavar=_('FILE'),
help=_('pid file to use'),
)
parser.add_option(
'--background',
dest='background',
action='store_true',
default=False,
help=_('Go into the background'),
)
parser.add_option(
'--systemd',
dest='systemd',
default='simple',
choices=['simple', 'notify'],
help=_('Systemd type simple|notify'),
)
parser.add_option(
'--redirect-output',
dest='redirectOutput',
action='store_true',
default=False,
help=_('Redirect output of daemon'),
)
......
- 整个服务启动的过程,就是 JBOSS 模块加载的过程
self._executable = os.path.join(
java.Java().getJavaHome(),
'bin',
'java',
)
jbossModulesJar = os.path.join(
self._config.get('JBOSS_HOME'),
'jboss-modules.jar',
)
- 加载参数检测
self._checkInstallation(
pidfile=self.pidfile,
jbossModulesJar=jbossModulesJar,
)
self.check(
name=self._config.get('JBOSS_HOME'),
directory=True,
)
self.check(
name=jbossModulesJar,
)
# Check the required engine directories and files:
self.check(
os.path.join(
self._config.get('ENGINE_USR'),
'services',
),
directory=True,
)
self.check(
self._config.get('ENGINE_CACHE'),
directory=True,
writable=True,
)
self.check(
self._config.get('ENGINE_TMP'),
directory=True,
writable=True,
mustExist=False,
)
self.check(
self._config.get('ENGINE_LOG'),
directory=True,
writable=True,
)
self.check(
name=os.path.join(
self._config.get("ENGINE_LOG"),
'host-deploy',
),
directory=True,
writable=True,
)
for log in ('engine.log', 'console.log', 'server.log'):
self.check(
name=os.path.join(self._config.get("ENGINE_LOG"), log),
mustExist=False,
writable=True,
)
if pidfile is not None:
self.check(
name=pidfile,
writable=True,
mustExist=False,
)
日志根据不同的需求,配置不同的日志文件:engine.log、console.log、server.log。
- 创建运行所需的目录,设置 700 权限
self._tempDir = service.TempDir(self._config.get('ENGINE_TMP'))
self._tempDir.create()
self._jbossRuntime = service.TempDir(self._config.get('JBOSS_RUNTIME'))
self._jbossRuntime.create()
self._setupEngineApps()
jbossTempDir = os.path.join(
self._jbossRuntime.directory,
'tmp',
)
jbossConfigDir = os.path.join(
self._jbossRuntime.directory,
'config',
)
javaModulePath = self._linkModules(
os.path.join(
self._jbossRuntime.directory,
'modules',
),
'%s:%s' % (
self._config.get('ENGINE_JAVA_MODULEPATH'),
os.path.join(
self._config.get('JBOSS_HOME'),
'modules',
),
),
)
os.mkdir(jbossTempDir)
os.mkdir(jbossConfigDir)
os.chmod(jbossConfigDir, 0o700)
- 创建 jboss_runtime 目录,包含 tmp、config、modules 子目录
cd /var/lib/ovirt-engine/jboss_runtime
[root@localhost jboss_runtime]# ll
total 16
drwx------. 3 ovirt ovirt 4096 Jul 3 12:04 config
drwxr-xr-x. 2 ovirt ovirt 4096 Jul 3 12:04 deployments
drwxr-xr-x. 4 ovirt ovirt 4096 Jul 3 12:03 modules
drwxr-xr-x. 5 ovirt ovirt 4096 Jul 3 12:03 tmp
- 根据模板生成配置文件,设置 600 权限
jbossBootLoggingFile = self._processTemplate(
template=os.path.join(
os.path.dirname(sys.argv[0]),
'ovirt-engine-logging.properties.in'
),
dir=jbossConfigDir,
)
jbossConfigFile = self._processTemplate(
template=os.path.join(
os.path.dirname(sys.argv[0]),
'ovirt-engine.xml.in',
),
dir=jbossConfigDir,
mode=0o600,
)
- 设置模块启动参数信息
self._engineArgs.extend([
# The name or the process, as displayed by ps:
'ovirt-engine',
# Virtual machine options:
'-server',
'-XX:+TieredCompilation',
'-Xms%s' % self._config.get('ENGINE_HEAP_MIN'),
'-Xmx%s' % self._config.get('ENGINE_HEAP_MAX'),
'-XX:PermSize=%s' % self._config.get('ENGINE_PERM_MIN'),
'-XX:MaxPermSize=%s' % self._config.get(
'ENGINE_PERM_MAX'
),
'-Djava.net.preferIPv4Stack=true',
'-Dsun.rmi.dgc.client.gcInterval=3600000',
'-Dsun.rmi.dgc.server.gcInterval=3600000',
'-Djava.awt.headless=true',
])
# Add extra system properties provided in the configuration:
for engineProperty in shlex.split(
self._config.get('ENGINE_PROPERTIES')
):
if not engineProperty.startswith('-D'):
engineProperty = '-D' + engineProperty
self._engineArgs.append(engineProperty)
# Add extra jvm arguments provided in the configuration:
for arg in shlex.split(self._config.get('ENGINE_JVM_ARGS')):
self._engineArgs.append(arg)
# Add arguments for remote debugging of the java virtual machine:
engineDebugAddress = self._config.get('ENGINE_DEBUG_ADDRESS')
if engineDebugAddress:
self._engineArgs.append(
(
'-Xrunjdwp:transport=dt_socket,address=%s,'
'server=y,suspend=n'
) % (
engineDebugAddress
)
)
# Enable verbose garbage collection if required:
if self._config.getboolean('ENGINE_VERBOSE_GC'):
self._engineArgs.extend([
'-verbose:gc',
'-XX:+PrintGCTimeStamps',
'-XX:+PrintGCDetails',
])
# Add arguments for JBoss:
self._engineArgs.extend([
'-Djava.util.logging.manager=org.jboss.logmanager',
'-Dlogging.configuration=file://%s' % jbossBootLoggingFile,
'-Dorg.jboss.resolver.warning=true',
'-Djboss.modules.system.pkgs=org.jboss.byteman',
'-Djboss.modules.write-indexes=false',
'-Djboss.server.default.config=ovirt-engine',
'-Djboss.home.dir=%s' % self._config.get(
'JBOSS_HOME'
),
'-Djboss.server.base.dir=%s' % self._config.get(
'ENGINE_USR'
),
'-Djboss.server.data.dir=%s' % self._config.get(
'ENGINE_VAR'
),
'-Djboss.server.log.dir=%s' % self._config.get(
'ENGINE_LOG'
),
'-Djboss.server.config.dir=%s' % jbossConfigDir,
'-Djboss.server.temp.dir=%s' % jbossTempDir,
'-Djboss.controller.temp.dir=%s' % jbossTempDir,
'-jar', jbossModulesJar,
'-mp', javaModulePath,
'-jaxpmodule', 'javax.xml.jaxp-provider',
'org.jboss.as.standalone',
'-c', os.path.basename(jbossConfigFile),
])
- 创建 JBOSS 启动发布模块目录
deploymentsDir = os.path.join(
self._jbossRuntime.directory,
'deployments',
)
os.mkdir(deploymentsDir)
- 与项目中的发布模块映射为链接
for engineAppDir in shlex.split(self._config.get('ENGINE_APPS')+ " " + self._config.get('TERMINAL_APPS')):
self.logger.debug('Deploying: %s', engineAppDir)
if not os.path.isabs(engineAppDir):
engineAppDir = os.path.join(
self._config.get('ENGINE_USR'),
engineAppDir,
)
if not os.path.exists(engineAppDir):
self.logger.warning(
_(
"Application directory '{directory}' "
"does not exist, it will be ignored"
).format(
directory=engineAppDir,
),
)
continue
engineAppLink = os.path.join(
deploymentsDir,
os.path.basename(engineAppDir),
)
os.symlink(engineAppDir, engineAppLink)
with open('%s.dodeploy' % engineAppLink, 'w'):
pass
[root@localhost deployments]# pwd
/var/lib/ovirt-engine/jboss_runtime/deployments
[root@localhost deployments]# ll
total 16
lrwxrwxrwx. 1 ovirt ovirt 34 Jul 3 12:03 engine.ear -> /usr/share/ovirt-engine/engine.ear
-rw-r--r--. 1 ovirt ovirt 10 Jul 3 11:30 engine.ear.deployed
lrwxrwxrwx. 1 ovirt ovirt 54 Jul 3 12:03 ovirt-engine-reports.war -> /var/lib/ovirt-engine-reports/ovirt-engine-reports.war
-rw-r--r--. 1 ovirt ovirt 24 Jul 3 12:03 ovirt-engine-reports.war.deployed
lrwxrwxrwx. 1 ovirt ovirt 67 Jul 3 12:03 rhev.ear -> /usr/share/ovirt-engine/branding/rhev-1.brand/applications/rhev.ear
-rw-r--r--. 1 ovirt ovirt 8 Jun 19 08:00 rhev.ear.deployed
- 创建 modules 目录,将运行 JBOSS 模块的依赖建立链接关系
def _linkModules(self, directory, modulePath):
"""
Link all the JBoss modules into a temporary directory.
This required because jboss tries to automatically update
indexes based on timestamp even if there is no permission to do so.
"""
modifiedModulePath = []
for index, element in enumerate(modulePath.split(':')):
modulesTmpDir = os.path.join(
directory,
'%02d-%s' % (
index,
'-'.join(element.split(os.sep)[-2:]),
),
)
modifiedModulePath.append(modulesTmpDir)
# For each directory in the modules directory create the
# same in the temporary directory and populate with symlinks
# pointing to the original files (excluding indexes):
for parentDir, childrenDirs, childrenFiles in os.walk(element):
parentTmpDir = os.path.join(
modulesTmpDir,
os.path.relpath(
parentDir,
element
),
)
if not os.path.exists(parentTmpDir):
os.makedirs(parentTmpDir)
for childFile in childrenFiles:
if childFile.endswith('.index'):
continue
os.symlink(
os.path.join(parentDir, childFile),
os.path.join(parentTmpDir, childFile)
)
return ':'.join(modifiedModulePath)
[root@localhost main]# pwd
/var/lib/ovirt-engine/jboss_runtime/modules/00-ovirt-engine-modules/com/mchange/c3p0/main
[root@localhost main]# ll
total 8
lrwxrwxrwx. 1 ovirt ovirt 62 Jul 3 12:03 c3p0.jar -> /usr/share/ovirt-engine/modules/com/mchange/c3p0/main/c3p0.jar
lrwxrwxrwx. 1 ovirt ovirt 64 Jul 3 12:03 module.xml -> /usr/share/ovirt-engine/modules/com/mchange/c3p0/main/module.xml