概述

systemd即为system daemon,是linux下的一种init软件,由Lennart Poettering带头开发,并在LGPL 2.1及其后续版本许可证下开源发布,开发目标是提供更优秀的框架以表示系统服务间的依赖关系,并依此实现系统初始化时服务的并行启动,同时达到降低Shell的系统开销的效果,最终代替现在常用的System V与BSD风格init程序。
与多数发行版使用的System V风格init相比,systemd采用了以下新技术:

  1. 采用Socket激活式与总线激活式服务,以提高相互依赖的各服务的并行运行性能;
  2. 用Cgroups代替PID来追踪进程,以此即使是两次fork之后生成的守护进程也不会脱离systemd的控制。

配置

配置内核启用systemd支持

Gentoo Linux --->
        Support for init systems, system and service managers --->
                [*] systemd

链接mtab文件,解决挂载错误

    ln -sf /proc/self/mounts /etc/mtab

修改/boot/grub/grub.cfg


    init=/usr/lib/systemd/systemd       使用systemd引导
    linux /kernel-3.10.32-gentoo root=/dev/sda9 ro rootflags=subvol=rootfs rootfstype=btrfs quiet systemd.show_status=1

processor type and features
    [*] built-in kernel command line
        () Built-in kernel command string

可以用内建字符串,也可以用grub写参数

quiet选项会隐藏内核信息和systemd信息,所以需要显示的加上’systemd.show_status=1’这个参数
现在的内核参数,先加quiet后加systemd.show_status=1,会隐藏内核参数只显示systemd日志

设置主机名称

    hostnamectl set-hostname <HOSTNAME>

设置编码

    localectl set-locale LANG=en_US.utf8

设置键盘(似乎可以忽略)

    localectl set-keymap us
    localectl set-x11-keymap us

设置时区时间

    timedatectl set-timezone Asia/Shanghai
    timedatectl set-time "xx-xx-xx xx:xx:xx"

set-time写入的时间会连同写入BIOS时钟,每次开机系统始终也是从BIOS里读取

添加/删除服务

    systemctl enable dhcpcd
    systemctl enable slim
    
    systemctl disable slim

启动/停止服务

    systemctl start dhcpcd
    systemctl stop dhcpcd
systemd会在内部维护一个服务的当前状态,如果已经认定服务启动(停止)的
那么,ExecStart(ExecStop)后边的命令则不会被执行

iptables 服务设置

gentoo stable分支还没有给iptables添加systemd的支持.
这个只能手动操作了,bugs上边好像有专门的讨论
方法没研究太明白,所以直接用自己的笨办法,每次启动加载iptables配置
iptables的~x86分支已经添加了systemd支持

添加服务文件
    vim /usr/lib/systemd/system/iptables.service
    [Unit]
    Description=iptables
    Before=network.target
    
    [Service]
    Type=forking
    RemainAfterExit=yes
    ExecStart=/bin/bash /usr/lib/systemd/system/iptables_script.sh start
    ExecStop=/bin/bash /usr/lib/systemd/system/iptables_script.sh stop
    KillMode=process
    
    [Install]
    WantedBy=multi-user.target
添加配置脚本
   vim usr/lib/systemd/system/iptables_script.sh
   function start()
   {
        #iptables xxx
   }
   
   function stop()
   {
        #iptables xxx
   }
   
   case "$1" in
   start)
      start
   ;;
   stop)
      stop
   ;;
   *)
      echo "Usage: $0 {start|stop}"
   esac
添加服务并启动
   systemctl enable iptables
   systemctl state iptables

添加自定义模块

vim /etc/modules-load.d/xxx.conf
#名字最好有标志性的意义
vim /etc/modules-load.d/virtualbox.conf
vboxdrv
vboxnetflt
vboxnetadp

每个模块名称占一行

优化启动速度

启动时间分析

systemd包含丰富的启动过程性能分析功能.

    systemd-analyze 
    time            显示启动耗时(默认参数,可以省略)
    blame           显示单个服务的具体启动耗时
    critical-chain  启动链耗时分析
    plot            生成svg矢量图

及由上边的几个参数,可以很方便的查看系统中哪个服务拖慢了系统启动
systemd-analyze plot > plot.svg 可以导出svg图片,更直观的显示启动过程耗时

另外可以使用bootchart2进行系统性能分析

emerge bootchart2
systemctl enable bootchart2

配置启动时间优化

对于systemd启动过程的优化,arch wiki里有一份介绍,
里边的内容大致总结下,就是这么几个方面

预读

systemd 自己实现了一个 readahead,可以用来提高开机效率.不过,效果会因内核版本和硬件情况而不同(极少数情况下还会变慢).开启 readahead:
systemctl enable systemd-readahead-collect.service systemd-readahead-replay.service

在虚拟机里测试了一下,启动速度反倒慢了2秒…暂时就没测试主机效果

精简内核

现在加载内核用掉了2秒,精简下内核应该还会缩短这个时间

更早的启动服务

这点是arch wiki里介绍的,暂时不理解

交错启动

有些硬件使用staggered spin-up,操作系统一个一个访问硬盘,以减少耗电。这会降低启动速度,大部分用户都不需要开启。检查是否开启:

    dmesg | grep SSS

如果没有查到,表示未启动。如果有显示,可以将libahci.ignore_sss=1 加入 kernel line 进行禁用。

避免重复挂载

mkinitcpio提供了 fsck 钩子,将启动加载配置中的 root 从 ro 修改为 rw 并删除 /etc/fstab 中的 root 挂载,可以避免重复挂载。挂载参数可以通过rootflags=[mount options…]设置。
删除 /etc/fstab 中的 API 文件系统,systemd 会自动挂载它们。下面命令可以获得这些 API 文件系统的列表:
pacman -Ql systemd | grep ‘.mount$’
/home等其他文件系统可以通过自定义挂载单元进行挂载。

利用systemd自动挂载

增加自动挂载参数noauto,comment=systemd.automount,这样fstab会将分区挂载延迟到第一次使用的时候.

vim /etc/fstab
/dev/sda9		/				btrfs		noauto,comment=systmed.automount,subvol=rootfs,inode_cache,space_cache,noatime,nodiratime,autodefrag,noacl,compress=lzo	0 1
更新内核到3.12以后,每次关机user@1000.service总会超时然后被kill,现在只有ntfs分区采用了自动挂载
精简输出信息

修改启动加载器内核参数中的 verbose 为 quiet 即可。对于某些用户,特别是 SSD 用户,TTY 的龟速实际上成为了性能瓶颈,精简输出信息实际上有利于提高性能。

禁用单用户关机/重启

vim /etc/polkit-1/rules.d/60-noreboot.rules 

    polkit.addRule(function(action, subject) {
      if (action.id.indexOf("org.freedesktop.login1.hibernate") == 0) {
        return polkit.Result.AUTH_ADMIN;
      }
    });
    
    polkit.addRule(function(action, subject) {
      if (action.id.indexOf("org.freedesktop.login1.power-off") == 0) {
        return polkit.Result.AUTH_ADMIN;
      }
    });
    
    polkit.addRule(function(action, subject) {
      if (action.id.indexOf("org.freedesktop.login1.reboot") == 0) {
        return polkit.Result.AUTH_ADMIN;
      }
    });
    
    polkit.addRule(function(action, subject) {
      if (action.id.indexOf("org.freedesktop.login1.suspend") == 0) {
        return polkit.Result.AUTH_ADMIN;
      }
    });

单用户电源管理

安装 polkit 后才可以一般用户身份使用电源管理。
如果你正登录在一个本地的systemd-logind用户会话,且当前没有其它活动的会话,那么以下命令无需root权限即可执行。否则(例如,当前有另一个用户登录在某个tty),systemd 将会自动请求输入root密码。

重启:

systemctl reboot

退出系统并停止电源:

systemctl poweroff

待机:

systemctl suspend

休眠:

systemctl hibernate

混合休眠模式(同时休眠到硬盘并待机):

systemctl hybrid-sleep

systemd 添加 capslock -> ctrl 映射脚本

此方法仅适用于ps2接口键盘

vim /lib/systemd/system/mykeymap.service
[Unit]
Description=Map Caps Lock to Ctrl

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/setkeycodes 0x3a 29
KillMode=none

[Install]
WantedBy=multi-user.target

相关链接

http://wiki.gentoo.org/wiki/Systemd#Installation
https://wiki.archlinux.org/index.php/systemd_(简体中文)