วิธีการทั่วไปในการดีบักรอบการสั่งซื้อใน systemd


23

ฉันรู้ต่อไปด้ายและคาดคะเนคำตอบของมัน ยกเว้นคำตอบไม่ใช่คำตอบในความหมายทั่วไป มันบอกว่าปัญหาเกิดขึ้นในกรณีใดกรณีหนึ่ง แต่ไม่ใช่โดยทั่วไป

คำถามของฉันคือ: มีวิธีการแก้ปัญหาการสั่งวงจรในลักษณะทั่วไป ? เช่นมีคำสั่งที่จะอธิบายวงจรและสิ่งที่เชื่อมโยงหน่วยหนึ่งไปยังอีก?

ตัวอย่างเช่นฉันมีการติดตามในjournalctl -b(โปรดละเว้นวันที่ระบบของฉันไม่มี RTC ที่จะซิงค์เวลาด้วย):

Jan 01 00:00:07 host0 systemd[1]: Found ordering cycle on sysinit.target/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on local-fs.target/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on cvol.service/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on basic.target/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on sockets.target/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on dbus.socket/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on sysinit.target/start
Jan 01 00:00:07 host0 systemd[1]: Breaking ordering cycle by deleting job local-fs.target/start
Jan 01 00:00:07 host0 systemd[1]: Job local-fs.target/start deleted to break ordering cycle starting with sysinit.target/start

โดยที่ cvol.service (อันที่แนะนำและแบ่งวงจร) คือ:

[Unit]
Description=Mount Crypto Volume
After=boot.mount
Before=local-fs.target

[Service]
Type=oneshot
RemainAfterExit=no
ExecStart=/usr/bin/cryptsetup open /dev/*** cvol --key-file /boot/***

[Install]
WantedBy=home.mount
WantedBy=root.mount
WantedBy=usr-local.mount

ตาม journalctl cvol.service ต้องการ basic.service ยกเว้นว่าไม่อย่างน้อยก็ไม่ชัด มีคำสั่งที่จะแสดงให้เห็นว่าลิงค์นี้มาจากไหน? และโดยทั่วไปแล้วจะมีคำสั่งซึ่งจะหารอบและแสดงที่แต่ละลิงค์ในรอบเกิด?

คำตอบ:


20

มีคำสั่งที่จะแสดงให้เห็นว่าลิงค์นี้มาจากไหน?

สิ่งที่ใกล้เคียงที่สุดที่คุณสามารถทำได้คือsystemctl show -p Requires,Wants,Requisite,BindsTo,PartOf,Before,After cvol.serviceซึ่งจะแสดงรายการการพึ่งพา (ผล) สำหรับหน่วยที่กำหนด

มีคำสั่งซึ่งจะหารอบและแสดงที่แต่ละลิงค์ในวงจรมา?

สำหรับความรู้ของฉันไม่มีคำสั่งดังกล่าว ที่จริงแล้ว systemd ไม่มีสิ่งใดที่จะช่วยในการดีบักรอบการสั่งซื้อ (ถอนหายใจ)

ตาม journalctl cvol.service ต้องการ basic.service ยกเว้นว่าไม่อย่างน้อยก็ไม่ชัด

ครั้งแรกที่การพึ่งพาความต้องการ ( Wants=, Requires=, BindsTo=ฯลฯ ) มีความเป็นอิสระของการอ้างอิงการสั่งซื้อ ( Before=และAfter=) สิ่งที่คุณเห็นที่นี่คือวงจรการสั่งซื้ออ้างอิงคือไม่มีอะไรเกี่ยวข้องWants=ฯลฯ

ประการที่สองมีจำนวน "การอ้างอิงเริ่มต้น" ที่สร้างขึ้นระหว่างหน่วยของบางประเภท พวกเขาถูกควบคุมโดยDefaultDependencies=คำสั่งใน[Unit]ส่วน (ซึ่งถูกเปิดใช้งานโดยค่าเริ่มต้น )

โดยเฉพาะอย่างยิ่งเว้นแต่คำสั่งนี้ถูกปิดใช้งานอย่างชัดเจน.serviceหน่วยใด ๆ ที่ได้รับโดยนัยRequires=basic.targetและการAfter=basic.targetอ้างอิงซึ่งเป็นสิ่งที่คุณเห็น นี้ถูกบันทึกไว้ในsystemd.service (5)


คำสั่งที่คุณยกมานั้นทำงานได้อย่างสมบูรณ์และเผยให้เห็นการพึ่งพาบนพื้นฐานเป้าหมาย มันเป็นความอัปยศที่ชุดเครื่องมือสำหรับ systemctl ขาดไป แต่ก็ดีมันเป็นโครงการใหม่
galets

2
@galets: ตัดสินจากประสบการณ์ของฉันมีตัวอย่างการขาดแคลนน้อยมาก ... บางทีสักวันหนึ่งฉันจะเพิ่มความฟุ้งซ่านของผู้รายงานวัฏจักรเพิ่มข้อมูลที่มีประโยชน์บางอย่างลงในบันทึก ในขณะเดียวกันที่จริงคุณอาจใช้systemd-analyze verify UNITเพื่อตรวจสอบความถูกต้องของหน่วย เบื้องหลังคำสั่งนี้จะสร้างอินสแตนซ์ systemd เสมือนและพยายามโหลด UNIT ที่กำหนดให้เป็นธุรกรรมเริ่มต้น (ราวกับว่ามันเป็นdefault.target) สิ่งนี้จะไม่เปิดเผยข้อมูลใหม่ (เทียบกับบันทึก) แต่อย่างน้อยคุณไม่ต้องรีบูตโดยใช้หน่วยที่เปิดใช้งานเพื่อดูว่ามันล้มเหลวหรือไม่
intelfx

คำขอ systemd สำหรับการปรับปรุง (RFE): เพิ่มการฟุ่มเฟื่อยของนักข่าววงจร
adrelanos

20

คุณสามารถเห็นภาพวงจรที่มีคำสั่งsystemd-analyze verify, systemd-analyze dotและGraphViz dotเครื่องมือ:

systemd-analyze verify default.target |&
perl -lne 'print $1 if m{Found.*?on\s+([^/]+)}' |
xargs --no-run-if-empty systemd-analyze dot |
dot -Tsvg >cycle.svg

คุณควรเห็นสิ่งนี้:

ป้อนคำอธิบายรูปภาพที่นี่

ที่นี่คุณสามารถดูวงจร: c.service->b.service->a.service->c.service

Color legend: 
    black     = Requires
    dark blue = Requisite
    dark grey = Wants
    red       = Conflicts
    green     = After

ลิงค์:


systemd-analyze verifyไม่มีอยู่ที่นี่ในการติดตั้งเดเบียน 8
sjas

@sjas, systemd-analyze verify ใช้ได้v216ตั้งแต่ systemd-verifyความพยายาม มันมีอยู่หรือไม่
Evgeny Vereshchagin


1
systemd-analyze verify default.targetตัวมันเองทำหน้าที่ได้ดีในการแสดงลูป ...
Gert van den Berg

0

ขั้นตอนที่ 1: เรียกใช้คำสั่งการตรวจสอบสำหรับ default.target

systemd-analyze verify default.target

ขั้นตอนที่ 2: สังเกตว่าบริการหรือเป้าหมายใดที่กล่าวถึงในข้อความ"systemd การทำลายวงจรการสั่งซื้อโดยการลบงาน"และแสดงรายการการพึ่งพาที่สมบูรณ์

systemctl show -p Requires,Wants,Requisite,BindsTo,PartOf,Before,After <service or target name mentioned in the "breaking cycle" message>

ขั้นตอนที่ 3: ดูกลุ่ม "after" และ "before" ภายในเซอร์วิสหรือไฟล์เป้าหมายมักกำหนดไว้

/lib/systemd/system

และค้นหาบริการหรือเป้าหมายที่รู้จักกันดีว่ามีความต่อเนื่อง แต่อยู่ในลำดับขาออกสำหรับบริการนี้

ตัวอย่าง:

dbus.service

มักจะเป็นตลาด"หลังจาก"

multi-user.target

แต่"ก่อนหน้า"

sockets.target

การพึ่งพาดังกล่าวสามารถสังเกตได้ง่ายโดยการโทร

systemctl list-dependencies default.target

อย่างไรก็ตามหากไฟล์

/lib/systemd/system/dbus.service

มีบรรทัดที่ชอบ:

Before=multi-user.target

หรือ

After=sockets.target

หรือทั้งสองอย่างพร้อมกันหมายถึง dbus.service ถูกกำหนดขาออกและมันทำให้เกิดวงจรที่ไม่มีที่สิ้นสุด

การรักษาง่าย - เปลี่ยนคำว่า"หลังจาก"เป็น"ก่อน"และในทางกลับกันหากจำเป็น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.