日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

systemd wsl 测试笔记

發布時間:2024/1/8 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 systemd wsl 测试笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • systemd 簡介
    • WSL systemd
    • systemctl
    • journalctl
    • hello service
    • Sleep 與 Timeout 測試
    • Requires 測試
    • After 測試

systemd 簡介

Linux 從關閉到運行, 完整的啟動和啟動過程有三個主要部分:

  • 硬件啟動(Hardware boot): 初始化系統硬件
  • Linux 引導(Linux boot): 加載 Linux 內核,然后加載 systemd
  • Linux 啟動(Linux startup): systemd為主機做好生產性工作的準備

systemd 是一個軟件套件, 充當系統和服務管理器, 軟件平臺, 以及作為應用程序和內核之間的粘合劑. 一般作為 PID 1 運行, 是引導期間啟動的第一個進程, 也是關機期間終止的最后一個進程. 常見的發行版 Arch Linux, Debian, Ubuntu, Dedora 等都啟用了 systemd.

  • System and Service Manager (systemd.io)
  • systemd/systemd: The systemd System and Service Manager (github.com), 目前最新的版本為v252
  • systemd - Wikipedia

流傳較廣的一個 systemd architecture 的簡化示意圖 (Learning to love systemd | Opensource.com)

但 systemd 主要作者的 Peottering 說過 systemd 的開發是 never finished, never complete, but tracking progress of technology, 因此組件或架構也在不斷變化著, 如現在的12種Unit類型:

  • .service
  • .socket
  • .device (automatically initiated by systemd)
  • .mount
  • .automount
  • .swap
  • .target
  • .path
  • .timer (which can be used as a cron-like job scheduler)
  • .snapshot
  • .slice (used to group and manage processes and resources)
  • .scope (used to group worker processes, isn’t intended to be configured via unit files)

查看 systemd 版本

$ systemd --version systemd 245 (245.4-4ubuntu3.18) +PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid

WSL systemd

WSL默認使用 init 作為系統和服務管理器, 使用 pstree 命令查看進程樹:

$ pstree init─┬─init───{init}├─init───init───bash───pstree└─{init}

這里 init 是 Linux 內核啟動時創建的第一個進程(PID 1)

$ ps ax | grep init1 ? Sl 0:00 /init8 ? Ss 0:00 /init9 ? S 0:00 /init100 pts/0 S+ 0:00 grep --color=auto init

WSL 從0.76.6 預覽版及更高版本開始支持手動開啟 systemd, 即把 systemd 作為 PID 1, 讓 init 進程成為 systemd 的子進程. 先在 PowerShell 中查看當前WSL的版本

# wsl update > wsl --version WSL 版本: 1.0.3.0 內核版本: 5.15.79.1 WSLg 版本: 1.0.47 MSRDC 版本: 1.2.3575 Direct3D 版本: 1.606.4 DXCore 版本: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp Windows版本: 10.0.22623.1037

WSL 版本: 1.0.3.0 支持手動開啟 systemd, 編輯WSL系統中的 /etc/wsl.conf 文件添加[boot]選項來啟用 systemd:

$ sudo vi /etc/wsl.conf [boot] systemd=true

然后就可以 PowerShell 中關掉 WSL

> wsl --shutdown

重新打開 WSL, 會發現啟動變慢了一些, 因為現在除了 init 進程, 還要開一堆 systemd 的進程, 啟動后, 發現 systemd 已經是 PID 1 了, 而 init 進程成了 systemd 的子進程

$ pstree systemd─┬─ModemManager───2*[{ModemManager}]├─NetworkManager───2*[{NetworkManager}]├─accounts-daemon───2*[{accounts-daemon}]├─agetty├─anacron───sh───run-parts───mlocate───flock───updatedb.mlocat├─atd├─avahi-daemon───avahi-daemon├─cron├─cups-browsed───2*[{cups-browsed}]├─cupsd───dbus├─dbus-daemon├─gdm3───2*[{gdm3}]├─init─┬─init───{init}│ ├─init───init───bash───pstree│ ├─login───bash│ └─{init}├─2*[kerneloops]├─networkd-dispat├─polkitd───2*[{polkitd}]├─rsyslogd───3*[{rsyslogd}]├─rtkit-daemon───2*[{rtkit-daemon}]├─snapd───21*[{snapd}]├─3*[snapfuse]├─sshd├─switcheroo-cont───2*[{switcheroo-cont}]├─systemd─┬─(sd-pam)│ ├─dbus-daemon│ └─pulseaudio───2*[{pulseaudio}]├─systemd-journal├─systemd-logind├─systemd-network├─systemd-resolve├─systemd-udevd├─udisksd───4*[{udisksd}]├─unattended-upgr───{unattended-upgr}├─whoopsie───2*[{whoopsie}]└─wpa_supplicant

但用 ps ax 命令發現 PID 1 是 /sbin/init, 這是什么套娃操作?

$ ps axPID TTY STAT TIME COMMAND1 ? Ss 0:00 /sbin/init2 ? Sl 0:00 /init5 ? Sl 0:00 plan9 --control-socket 6 --log-level 4 --server-fd 7 --pipe-fd 9 --log-truncate51 ? S<s 0:06 /lib/systemd/systemd-journald77 ? Ss 0:00 /lib/systemd/systemd-udevd

systemctl

systemctl 是 控制systemd系統和服務管理器的主要工具.

常見 Unit 的概念:

  • LOAD = Reflects whether the unit definition was properly loaded. 反映Unit是否正確加載: loaded 或 not-found
  • ACTIVE = The high-level unit activation state, i.e. generalization of SUB. 高級Unit活動狀態: active, inactive 或 failed
  • SUB = The low-level unit activation state, values depend on unit type. 低級Unit活動狀態, 值取決于Unit類型: running, dead, exited, waiting, mounted, plugged, listening, failed, active等

常用命令

# 列出正在運行的Unit, systemctl list-units 或者直接 systemctl# 列出所有Unit systemctl list-units --all # 列出加載失敗的Unit, 類型為12種里面的service systemctl list-units --failed --type=service # 列出所有ACTIVE 狀態為 inactive 的Unit systemctl list-units --all --state=inactive# 啟動服務 systemctl start xxx.service # 停止服務 systemctl stop xxx.service # 重啟服務(熱啟動) systemctl restart xxx.service # 重載服務(冷啟動) systemctl reload xxx.service # 查看狀態 systemctl status xxx# 使能(創建符號鏈接, 開機啟動) systemctl enable xxx # 禁止(刪除符號鏈接) systemctl disable xxx # 查看是否使能 systemctl is-enabled xxx

journalctl

systemd 日志配置文件為 /etc/systemd/journald.conf, 可以直接查看或者通過以下命令查看

$ systemd-analyze cat-config systemd/journald.conf

可以通過修改配置文件來設置 是否永久存儲日志, 最大的文件大小/數量/時間, 最大的行數, 指定日志級別 等

日志默認的保存目錄是 /var/log/journal/(持久性存儲persistent) 或 /run/log/journal(易失性存儲volatile) , 里面默認存的是二進制日志以節省空間, 除了記錄日志本身外, 還會記錄大量元數據, 可以用 journalctl 工具查看日志文本, 然后再配合其它命令篩選, 查詢或導出

journalctl, Query the journal. 用于查詢日志

# 從舊到新打印系統日志 journalctl --system 或者 journalctl # 從新到舊 journalctl -r# 打印當前用戶的日志, 一般開機自啟程序當前用戶指的root journalctl --user# 查看指定服務的日志 journalctl -u xxx# 查看指定服務的日志, 不分頁 journalctl --no-paper -u xxx# 持續跟蹤指定服務的日志 journalctl -f -u xxx journalctl -f -u xxx -u yyy# 查看日志占用磁盤空間 journalctl --disk-usage# 按照 大小 數量 時間 設置/清理日志 1G 1years journalctl--vacuum-size=BYTES Reduce disk usage below specified size--vacuum-files=INT Leave only the specified number of journal files--vacuum-time=TIME Remove journal files older than specified time# 驗證日志文件的完整性 journalctl --verify# 查看某個時間段的日志, --since today 或者 journalctl --since "2023-01-05 16:50:00" --until "2023-01-05 16:51:00"# 查看本次啟動后的日志, -b 或 journalctl --boot # 查看記錄的過往啟動的簡明信息, 如 -9~0 journalctl -list-boots # 查看上次啟動的日志 journalctl --boot=-1 # 查看最新的10行日志 journalctl --boot --lines=10# 日志級別 # 0 emerg Emerge系統不可用 # 1 alert Alert必須立即采取行動 # 2 crit Crit緊急情況 # 3 err Err非緊急的錯誤 # 4 warning Warnning警告 # 5 notice Notice普通但值得注意的事件 # 6 info Info信息 # 7 debug Debug調試# 指定日志級別查看 journalctl -p err --lines=10 journalctl -p 3 -u xxx.service # 查看上次啟動的err信息 journalctl -b -1 -p err # 查看上次啟動的err信息的最后10行 journalctl -b -1 -p err -n 10# json 輸出 journalctl -b -u xxx.service -o json journalctl -b -u xxx.service -o json-pretty# 查看內核日志, 和 dmesg 打印出的類似 journalctl -k

hello service

systemd 常見的兩個目錄:

  • /etc/systemd/system/, systemd默認從這里讀取配置文件, 但用 ls -la 可以看出, 里面的service基本都是符號鏈接, 指向 /lib/systemd/system, 但直接把配置文件.service 放在這個目錄也是可以的
  • /lib/systemd/system, 可以放置真正的配置文件

下面給出一個簡單的service示例, 1s打印一次

$ sudo vi /lib/systemd/system/hello.service [Unit] Description=Hello World Service After=network.target[Service] Type=simple ExecStart=/bin/bash -c 'while true; do echo "Hello World"; sleep 1; done' Restart=on-failure[Install] WantedBy=multi-user.target

可以直接運行

$ sudo systemctl status hello.service# 因為是后臺進程, 默認終端無顯示, dmeg里也沒有, 可以用status $ sudo systemctl status hello.service ● hello.service - Hello World ServiceLoaded: loaded (/lib/systemd/system/hello.service; disabled; vendor preset: enabled)Active: active (running) since Thu 2023-01-05 15:12:53 CST; 36s agoMain PID: 1508 (bash)Tasks: 2 (limit: 38477)Memory: 864.0KCGroup: /system.slice/hello.service├─1508 /bin/bash -c while true; do echo "Hello World"; sleep 1; done└─1560 sleep 1Jan 05 15:13:20 U20 bash[1508]: Hello World Jan 05 15:13:21 U20 bash[1508]: Hello World Jan 05 15:13:22 U20 bash[1508]: Hello World Jan 05 15:13:23 U20 bash[1508]: Hello World

得益于配置文件里寫了 Restart=on-failure, 假設我們不小心殺掉了進程, systemd 會幫我們重新拉起來

# PID號參考上方 Main PID: 1508 (bash) $ sudo kill -9 1508# 可以看到進程被重新拉了起來, PID號已經變了 $ sudo systemctl status hello ● hello.service - Hello World ServiceLoaded: loaded (/lib/systemd/system/hello.service; disabled; vendor preset: enabled)Active: active (running) since Thu 2023-01-05 15:18:03 CST; 1s agoMain PID: 1854 (bash)Tasks: 2 (limit: 38477)Memory: 948.0KCGroup: /system.slice/hello.service├─1854 /bin/bash -c while true; do echo "Hello World"; sleep 1; done└─1856 sleep 1Jan 05 15:18:03 U20 systemd[1]: Started Hello World Service. Jan 05 15:18:03 U20 bash[1854]: Hello World Jan 05 15:18:04 U20 bash[1854]: Hello World# 持續跟蹤服務 $ journalctl -f -u hello

如果系統關掉, 重新打開, 服務并不在運行

$ sudo systemctl status hello.service ● hello.service - Hello World ServiceLoaded: loaded (/lib/systemd/system/hello.service; disabled; vendor preset: enabled)Active: inactive (dead)

可以使用 enable 來創建符號鏈接, 因為配置文件中 WantedBy=multi-user.target, 會創建鏈接到 /etc/systemd/system/multi-user.target.wants, 而 sudo systemctl status multi-user.target 可以看到是開機啟動的, 那么 hello.service 再下次系統啟動時會連帶著起來.

$ sudo systemctl enable hello.service Created symlink /etc/systemd/system/multi-user.target.wants/hello.service → /lib/systemd/system/hello.service.

再次重啟系統, 就可以看到服務開機啟動了

$ sudo systemctl status hello ● hello.service - Hello World ServiceLoaded: loaded (/lib/systemd/system/hello.service; enabled; vendor preset: enabled)Active: active (running) since Thu 2023-01-05 15:29:56 CST; 17s agoMain PID: 372 (bash)Tasks: 2 (limit: 38477)Memory: 768.0KCGroup: /system.slice/hello.service├─372 /bin/bash -c while true; do echo "Hello World"; sleep 1; done└─949 sleep 1Jan 05 15:30:04 U20 bash[372]: Hello World Jan 05 15:30:05 U20 bash[372]: Hello World

小結一下

# 編寫配置文件, vi 或者 nano編輯器的 sudo systemctl edit --force --full xxx.service sudo vi /lib/systemd/system/xxx.service # 立即運行服務 sudo systemctl start xxx # 設置開機啟動(創建符號鏈接到 yyy.target.wants 或 yyy.target.requires) sudo systemctl enable xxx

如果更改了配置文件想要重啟服務

# 配置文件修改需要 reload units, 但還不會打斷之前服務的運行 sudo systemctl daemon-reload # 重啟服務 sudo systemctl restart xxx

如果想要徹底停止并刪掉服務

# 停止當前的運行 sudo systemctl stop xxx # 禁止開機自啟(刪掉符號鏈接) sudo systemctl disable xxx # 刪掉配置文件 sudo rm -f /lib/systemd/system/xxx.service

Sleep 與 Timeout 測試

服務配置文件中 Restart=on-failure 的默認超時時間是 90s, 也就是 90s 內不返回結果就會認為失敗了, 特別是調試的時候, 經常會直接 sleep 一段時間再啟動, 如GNSS冷啟動超級慢, 有時候 sleep 超過了 90s, sleep 的位置不對會出問題, 下面就演示一下

$ sudo vi /lib/systemd/system/hellox.service [Unit] Description=Hello World Service After=network.target[Service] Type=simple ExecStartPre=/bin/sleep 100 ExecStart=/bin/bash -c 'while true; do echo "Hellox"; sleep 1; done' Restart=on-failure[Install] WantedBy=multi-user.target

運行測試發現一直失敗, 顯示 Failed with result 'timeout'

$ sudo systemctl daemon-reload $ sudo systemctl restart hellox$ journalctl -f -u hellox Jan 05 17:38:04 U20 systemd[1]: hellox.service: start-pre operation timed out. Terminating. Jan 05 17:38:04 U20 systemd[1]: hellox.service: Control process exited, code=killed, status=15/TERM Jan 05 17:38:04 U20 systemd[1]: hellox.service: Failed with result 'timeout'. Jan 05 17:38:04 U20 systemd[1]: Failed to start Hellox Service. Jan 05 17:38:04 U20 systemd[1]: hellox.service: Scheduled restart job, restart counter is at 1. Jan 05 17:38:04 U20 systemd[1]: Stopped Hellox Service. Jan 05 17:38:04 U20 systemd[1]: Starting Hellox Service...Jan 05 17:39:34 U20 systemd[1]: hellox.service: start-pre operation timed out. Terminating. Jan 05 17:39:34 U20 systemd[1]: hellox.service: Control process exited, code=killed, status=15/TERM Jan 05 17:39:34 U20 systemd[1]: hellox.service: Failed with result 'timeout'. Jan 05 17:39:34 U20 systemd[1]: Failed to start Hellox Service. Jan 05 17:39:35 U20 systemd[1]: hellox.service: Scheduled restart job, restart counter is at 2. Jan 05 17:39:35 U20 systemd[1]: Stopped Hellox Service. Jan 05 17:39:35 U20 systemd[1]: Starting Hellox Service...

如果確實非要 sleep, 有下面幾種解決辦法

  • 刪掉 ExecStartPre=/bin/sleep 100, 把 sleep 100 放到 ExecStart=/bin/bash -c 'sleep 100; while true; do echo "Hellox"; sleep 1; done', 建議用這種方法, restart 服務會立即返回
  • 修改超時時間, 如修改為120s, TimeoutSec=120, 或者不限制 TimeoutSec=0, 這會導致 restart 的時候卡ExecStartPre=/bin/sleep 100 這個100s, 所以不太建議這種方法, 可以使用 --no-block 參數規避
  • sudo systemctl --no-block restart hellox, 讓systemctl跳過等待, 也就沒有Timeout了, 比較危險, 慎用
  • sleep 往往并不靠譜, 建議不用, 可以試試 After 或者 Requires, 或者修改程序

Requires 測試

本服務啟動時, Requires后面的服務也會同時被啟動(不會因為sleep遲滯), Requires后的服務失敗, 本服務也會終止

修改 hellox.service, 讓 hello.service 成為 hellox 的 Requiers

$ sudo vi /lib/systemd/system/hellox.service [Unit] Description=Hellox Service Requires=hello.service[Service] Type=simple ExecStart=/bin/bash -c 'while true; do echo "Hellox"; sleep 1; done' Restart=on-failure[Install] WantedBy=multi-user.target

此時 hello.service 沒有運行, 啟動 hellox, 發現hello也被同時啟動了

$ sudo systemctl stop hello hellox $ sudo systemctl daemon-reload $ sudo systemctl start hellox $ journalctl -f -u hello -u hellox Jan 05 18:59:46 U20 systemd[1]: Started Hello World Service. Jan 05 18:59:46 U20 systemd[1]: Started Hellox Service. Jan 05 18:59:46 U20 bash[2535]: Hello World Jan 05 18:59:46 U20 bash[2536]: Hellox Jan 05 18:59:47 U20 bash[2535]: Hello World Jan 05 18:59:47 U20 bash[2536]: Hellox

終止 hello, 發現 hellox 也被牽連終止了. (反過來不會)

$ sudo systemctl stop hello $ journalctl -f -u hello -u hellox Jan 05 19:00:53 U20 bash[2558]: Hellox Jan 05 19:00:53 U20 bash[2557]: Hello World Jan 05 19:00:53 U20 systemd[1]: Stopping Hello World Service... Jan 05 19:00:53 U20 systemd[1]: Stopping Hellox Service... Jan 05 19:00:53 U20 systemd[1]: hello.service: Succeeded. Jan 05 19:00:53 U20 systemd[1]: Stopped Hello World Service. Jan 05 19:00:53 U20 systemd[1]: helloy.service: Succeeded. Jan 05 19:00:53 U20 systemd[1]: Stopped Hellox Service.

After 測試

配置文件中的 After 表示該服務在什么服務啟動之后再啟動, 其它服務在啟動中或者未啟動完成則本服務等待, 典型應用如:

  • 許多程序需要聯網才能使用, 可以等到網絡服務啟動后再啟動
  • ros應用 依賴 roscore , 可以在roscore服務啟動后再啟動ros應用
  • 很多日志以時間為log名, 但是嵌入式系統等很多沒有后備電池, 需要通過GNSS或者網絡NTP, PTP等授時后, 系統時間才會準確, 其它的服務可以等待時間同步的服務完成后再開始運行

修改 hellox.service, 在 hello.service 啟動之后再啟動, 即 After=hello.service

$ sudo vi /lib/systemd/system/hellox.service [Unit] Description=Hellox Service After=hello.service[Service] Type=simple ExecStart=/bin/bash -c 'while true; do echo "Hellox"; sleep 1; done' Restart=on-failure[Install] WantedBy=multi-user.target

現在 hello.service 沒有運行, 先啟動 hellox:

$ sudo systemctl start hellox# 發現可以直接運行 $ sudo systemctl status hellox ● hellox.service - Hellox ServiceLoaded: loaded (/lib/systemd/system/hellox.service; disabled; vendor preset: enabled)Active: active (running) since Thu 2023-01-05 15:47:16 CST; 4s agoMain PID: 1328 (bash)Tasks: 2 (limit: 38477)Memory: 796.0KCGroup: /system.slice/hellox.service├─1328 /bin/bash -c while true; do echo "Hellox"; sleep 1; done└─1333 sleep 1Jan 05 15:47:16 U20 systemd[1]: Started Hellox Service. Jan 05 15:47:16 U20 bash[1328]: Hellox Jan 05 15:47:17 U20 bash[1328]: Hellox# 停掉hellox sudo systemctl stop hellox

修改 hello.service, 加上89s的延時

$ sudo vi /lib/systemd/system/hello.service [Unit] Description=Hello World Service After=network.target[Service] Type=simple ExecStartPre=/bin/sleep 89 ExecStart=/bin/bash -c 'while true; do echo "Hello World"; sleep 1; done' Restart=on-failure[Install] WantedBy=multi-user.target

把 hello.service 先運行起來, 然后趁著89s還沒有走完, 運行 hellox.service發現 hellox.service被卡住直到 hello.service 啟動完

$ sudo systemctl start hello # 另一個窗口 $ sudo systemctl start hellox$ journalctl -f -u hello -u hellox Jan 05 19:08:30 U20 systemd[1]: Starting Hello World Service... Jan 05 19:09:59 U20 systemd[1]: Started Hello World Service. # 89s后hello起來了 Jan 05 19:09:59 U20 bash[2981]: Hello World Jan 05 19:09:59 U20 systemd[1]: Started Hellox Service. # hellox 在這里起來了 Jan 05 19:09:59 U20 bash[2983]: Hellox Jan 05 19:10:00 U20 bash[2981]: Hello World Jan 05 19:10:00 U20 bash[2983]: Hellox Jan 05 19:10:01 U20 bash[2981]: Hello World

兩個服務都enable, 然后重啟系統, 也能看到類似的效果. 按名字順序, helloy 的PID在hello的后面, 但如果調換兩個service的內容(讓hello中After=helloy, 讓helloy去sleep 89), 就沒有After的效果了.

總結

以上是生活随笔為你收集整理的systemd wsl 测试笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。