وزن: 3
توضیحات: داوطلبان باید قادر به مدیریت SysVinit runlevel یا systemd boot target سیستم باشند. این هدف شامل تغییر به حالت تک کاربره (single user mode)، خاموش کردن یا ریبوت کردن سیستم است. داوطلبان باید بتوانند قبل از تعویض runlevels / boot targets به کاربران هشدار داده و فرآیندها را به درستی متوقف کنند. این هدف همچنین شامل تنظیم SysVinit runlevel یا systemd boot target پیشفرض است. همچنین شامل آگاهی از Upstart به عنوان جایگزینی برای SysVinit یا systemd است.
حوزههای کلیدی دانش:
- تنظیم runlevel یا boot target پیشفرض
- جابجایی بین runlevels / boot targets از جمله حالت تک کاربره (single user mode)
- خاموش کردن (Shutdown) و ریبوت (reboot) از خط فرمان
- هشدار به کاربران قبل از تعویض runlevels / boot targets یا سایر رویدادهای مهم سیستم
- متوقف کردن صحیح فرآیندها (processes)
اصطلاحات و ابزارهای کاربردی:
- /etc/inittab
- shutdown
- init
- /etc/init.d/
- telinit
- systemd
- systemctl
- /etc/systemd/
- /usr/lib/systemd/
- wall
در درس قبلی توالی بوت سیستم در لینوکس را توضیح دادیم، سپس با Sysv، Upstart و systemd به عنوان مدیران سرویسهای مختلف در دنیای لینوکس آشنا شدیم. در این درس یاد میگیریم که چگونه با استفاده از این مدیران سرویس، کنترل سرویسهای سیستم لینوکس خود را به دست بگیریم.
بیایید با SysV شروع کنیم. SysV چیزی نیست جز تعداد زیادی اسکریپت اجرایی که پس از فرآیند init اجرا میشوند. چگونه میتوانیم تعریف کنیم که کدام سرویس باید هنگام شروع به کار کامپیوتر اجرا شود؟ خوشحالم که پرسیدید. به نظر میرسد که فایلهای پیکربندی متنی حجیمی مورد نیاز باشد، اینجاست که runlevels وارد بازی میشوند.
یک runlevel یکی از حالتهایی است که یک سیستمعامل مبتنی بر یونیکس در آن اجرا میشود. هر runlevel دارای تعداد معینی از سرویسهای متوقف شده یا شروع شده است که به کاربر اجازه میدهد رفتار ماشین را کنترل کند. runlevels از نیاز به ویرایش دستی چند فایل بزرگ جلوگیری میکنند.
به طور سنتی، هفت runlevel وجود دارد که از صفر تا شش شمارهگذاری شدهاند. و تفاوتهایی بین سیستمهای مبتنی بر Debian و RedHat وجود دارد:
| Runlevel | Debian | RedHat |
|---|---|---|
| 0 | Halt | Halt |
| 1 | Single User Mode | Single User Mode |
| 2 | Full,Multi-User,GUI | Multi-User, No Net |
| 3 | Nothing | Multi-User, with Net, No GUI |
| 4 | Nothing | Not used |
| 5 | Nothing | Full,Multi-User,GUI |
| 6 | Reboot | Reboot |
CentOS 5 آخرین نسخهای بود که از SysV استفاده کرد و از CentOS 7 به بعد از Systemd استفاده میشود.
برای یافتن runlevel فعلی و قبلی، از دستور runlevel استفاده میشود:
[root@centos5-1 ~]# runlevel
N 5
در خروجی بالا، حرف ‘N’ نشان میدهد که runlevel از زمان بوت شدن سیستم تغییر نکرده است. و 5 runlevel فعلی است.
اکنون که درباره runlevelها میدانیم، چگونه میتوانیم بین آنها جابجا شویم؟ خب کافی است به 'init' بگویید که چه runlevelی میخواهید.
telinit برای تغییر runlevel سیستم SysV استفاده میشود.
telinit RUNLEVEL
بیایید آن را روی یک ماشین CentOS 5 امتحان کنیم:
[root@centos5-1 ~]# runlevel
N 5
[root@centos5-1 ~]# telinit 3
و سیستم به runlevel 3 میرود، بیایید به runlevel 5 برگردیم:
[root@centos5-1 ~]# telinit 5
init (به عنوان یک دستور) یک مقداردهی اولیه کنترل فرآیند مانند telinit است.
[root@centos5-1 ~]# init 3
{% hint style="info" %}
telinit ابزار کوچکتری است که به init اطلاع میدهد چه زمانی نیاز به تغییر runlevel دارد. بنابراین میتوانیم از "telinit" استفاده کنیم تا به init بگوییم (tell init) که نیاز به تعویض runlevel دارد. telinit در واقع به دستور init لینک شده است و امکان استفاده از دستور init به جای آن وجود دارد اما توصیه نمیشود.
[root@centos5-1 ~]# ls -l /sbin/telinit
lrwxrwxrwx 1 root root 4 Aug 26 23:20 /sbin/telinit -> init
{% endhint %}
چندین راه برای تغییر runlevelها وجود دارد. برای ایجاد یک تغییر دائمی، میتوانیم /etc/inittab را ویرایش کرده و سطح پیشفرضی را که در بالا دیدیم تغییر دهیم.
پس از بوت شدن هسته لینوکس، برنامه init فایل /etc/inittab را میخواند تا رفتار هر runlevel را تعیین کند. مگر اینکه کاربر مقدار دیگری را به عنوان پارامتر بوت هسته تعیین کند، سیستم تلاش میکند وارد (شروع) runlevel پیشفرض شود (CentOS 5).
[root@centos5-1 ~]# cat /etc/inittab
#
# inittab This file describes how the INIT process should set up
# the system in a certain run-level.
#
# Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
# Modified for RHS Linux by Marc Ewing and Donnie Barnes
#
# Default runlevel. The runlevels used by RHS are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
id:5:initdefault:
# System initialization.
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
# When our UPS tells us power has failed, assume we have a few minutes
# of power left. Schedule a shutdown for 2 minutes from now.
# This does, of course, assume you have powerd installed and your
# UPS connected and working correctly.
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"
# If power was restored before the shutdown kicked in, cancel it.
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
# Run xdm in runlevel 5
x:5:respawn:/etc/X11/prefdm -nodaemon
runlevel پیشفرض از ورودی id: در /etc/inittab تعیین میشود. نحوه تنظیم runlevelها به طور پیشفرض و نحوه پیکربندی آنها تا حدی به توزیع خاصی که در حال اجرا هستید بستگی دارد.
فرمت هر خط در فایل inittab به صورت زیر است:
id:runlevel:action:process
در اینجا شرح این فیلدها آمده است:
- id (کد شناسایی) – شامل توالی یک تا چهار کاراکتر است که عملکرد آن را شناسایی میکند.
- runlevels – runlevelهایی را لیست میکند که این ورودی برای آنها اعمال میشود.
- action – کدهای خاص در این فیلد به init میگویند که چگونه با فرآیند برخورد کند. مقادیر ممکن عبارتند از: initdefault، sysinit، boot، bootwait، wait و respawn.
- process – دستور یا اسکریپتی را که باید اجرا شود تعریف میکند.
اکنون بیایید ببینیم SysV چگونه مفهوم run levelها را پیادهسازی میکند.
دایرکتوری /etc/init.d شامل اسکریپتهایی است که توسط ابزارهای init سیستم V (SysVinit) استفاده میشوند.
[root@centos5-1 ~]# ls /etc/init.d/
acpid hidd netconsole rpcidmapd
anacron httpd netfs rpcsvcgssd
atd ip6tables netplugd saslauthd
auditd ipmi network sendmail
autofs iptables NetworkManager single
avahi-daemon irda nfs smartd
avahi-dnsconfd irqbalance nfslock sshd
bluetooth iscsi nscd svnserve
conman iscsid ntpd syslog
cpuspeed killall oddjobd vmware-tools
crond krb524 pand vmware-tools-thinprint
cups kudzu pcscd vncserver
cups-config-daemon ldap portmap wdaemon
dnsmasq lvm2-monitor psacct wpa_supplicant
dund mcstrans rawdevices xfs
firstboot mdmonitor rdisc ypbind
functions mdmpd readahead_early yum-updatesd
gpm messagebus readahead_later
haldaemon microcode_ctl restorecond
halt multipathd rpcgssd
همانطور که گفتیم، در SysV، برنامه init اولین فرآیندی است که اجرا میشود و متعاقباً برخی از سرویسهای زیرساختی شروع میشوند. فایلهای موجود در /etc/init.d اسکریپتهای شل (shell scripts) هستند که به دستورات start، stop، restart و (در صورت پشتیبانی) reload برای مدیریت یک سرویس خاص پاسخ میدهند. اما SysV چگونه تعیین میکند که کدام سرویسها در داخل /etc/init.d باید بر اساس runlevel پیشفرض شروع یا متوقف شوند؟ بیایید یک تصویر ترسیم کنیم:
SysV از گروهبندی استفاده میکند. اسکریپتهای هر runlevel گروهبندی شده و در /etc/rc{runlevel}.d/ قرار میگیرند که در آن runlevel همان شماره runlevel است.
از آنجایی که بسیاری از سرویسها ممکن است در runlevelهای مختلف وجود داشته باشند، فایلهای اسکریپت واقعی در /etc/init.d نگه داشته میشوند و /etc/rc{runlevel}.d/ فقط به موارد مورد نیاز اشاره (point) میکنند.
[root@centos5-1 etc]# ls | grep rc.
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
rc.d
rc.local
rc.sysinit
بیایید به عنوان مثال نگاهی به rc.5 بیندازیم:
[root@centos5-1 etc]# ls -l rc5.d/
total 288
lrwxrwxrwx 1 root root 17 Aug 26 23:21 K01dnsmasq -> ../init.d/dnsmasq
lrwxrwxrwx 1 root root 24 Aug 26 23:21 K02avahi-dnsconfd -> ../init.d/avahi-dnsconfd
lrwxrwxrwx 1 root root 24 Aug 26 23:23 K02NetworkManager -> ../init.d/NetworkManager
lrwxrwxrwx 1 root root 17 Aug 26 23:23 K02oddjobd -> ../init.d/oddjobd
lrwxrwxrwx 1 root root 16 Aug 26 23:20 K05conman -> ../init.d/conman
lrwxrwxrwx 1 root root 19 Aug 26 23:21 K05saslauthd -> ../init.d/saslauthd
lrwxrwxrwx 1 root root 17 Aug 26 23:20 K05wdaemon -> ../init.d/wdaemon
lrwxrwxrwx 1 root root 16 Aug 26 23:20 K10psacct -> ../init.d/psacct
lrwxrwxrwx 1 root root 15 Aug 26 23:21 K15httpd -> ../init.d/httpd
lrwxrwxrwx 1 root root 18 Aug 26 23:22 K15svnserve -> ../init.d/svnserve
lrwxrwxrwx 1 root root 13 Aug 26 23:23 K20nfs -> ../init.d/nfs
lrwxrwxrwx 1 root root 14 Aug 26 23:23 K24irda -> ../init.d/irda
<output has been truncated>
lrwxrwxrwx 1 root root 23 Aug 26 23:20 S00microcode_ctl -> ../init.d/microcode_ctl
lrwxrwxrwx 1 root root 22 Aug 26 23:28 S03vmware-tools -> ../init.d/vmware-tools
lrwxrwxrwx 1 root root 25 Aug 26 23:20 S04readahead_early -> ../init.d/readahead_early
lrwxrwxrwx 1 root root 15 Aug 26 23:23 S05kudzu -> ../init.d/kudzu
lrwxrwxrwx 1 root root 16 Aug 26 23:20 S07iscsid -> ../init.d/iscsid
lrwxrwxrwx 1 root root 19 Aug 26 23:19 S08ip6tables -> ../init.d/ip6tables
lrwxrwxrwx 1 root root 18 Aug 26 23:19 S08iptables -> ../init.d/iptables
lrwxrwxrwx 1 root root 18 Aug 26 23:21 S08mcstrans -> ../init.d/mcstrans
lrwxrwxrwx 1 root root 17 Aug 26 23:21 S10network -> ../init.d/network
lrwxrwxrwx 1 root root 16 Aug 26 23:20 S11auditd -> ../init.d/auditd
lrwxrwxrwx 1 root root 21 Aug 26 23:21 S12restorecond -> ../init.d/restorecond
lrwxrwxrwx 1 root root 16 Aug 26 23:21 S12syslog -> ../init.d/syslog
lrwxrwxrwx 1 root root 18 Aug 26 23:19 S13cpuspeed -> ../init.d/cpuspeed
lrwxrwxrwx 1 root root 20 Aug 26 23:21 S13irqbalance -> ../init.d/irqbalance
lrwxrwxrwx 1 root root 15 Aug 26 23:20 S13iscsi -> ../init.d/iscsi
lrwxrwxrwx 1 root root 17 Aug 26 23:21 S13portmap -> ../init.d/portmap
lrwxrwxrwx 1 root root 17 Aug 26 23:23 S14nfslock -> ../init.d/nfslock
lrwxrwxrwx 1 root root 19 Aug 26 23:21 S15mdmonitor -> ../init.d/mdmonitor
<output has been truncated>
هر اسکریپت در هر runlevel با عملکردهای شروع (startup) یا خاموش کردن (shutdown) خود اجرا میشود، بسته به اینکه آن runlevel در حال بالا رفتن (going up) یا پایین آمدن (going down) باشد. S به معنای اسکریپت شروعکننده (starting) و K نشان میدهد که یک اسکریپت متوقفکننده (killing) است. ترتیب اقدامات با اعداد تعریف میشود. از دستور cat استفاده کنید تا ببینید داخل آن چیست:
[root@centos5-1 rc5.d]# cat S55sshd
#!/bin/bash
#
# Init file for OpenSSH server daemon
#
# chkconfig: 2345 55 25
# description: OpenSSH server daemon
#
# processname: sshd
# config: /etc/ssh/ssh_host_key
# config: /etc/ssh/ssh_host_key.pub
# config: /etc/ssh/ssh_random_seed
# config: /etc/ssh/sshd_config
# pidfile: /var/run/sshd.pid
# source function library
. /etc/rc.d/init.d/functions
# pull in sysconfig settings
[ -f /etc/sysconfig/sshd ] && . /etc/sysconfig/sshd
RETVAL=0
prog="sshd"
# Some functions to make the below more readable
KEYGEN=/usr/bin/ssh-keygen
SSHD=/usr/sbin/sshd
RSA1_KEY=/etc/ssh/ssh_host_key
RSA_KEY=/etc/ssh/ssh_host_rsa_key
DSA_KEY=/etc/ssh/ssh_host_dsa_key
PID_FILE=/var/run/sshd.pid
runlevel=$(set -- $(runlevel); eval "echo \$$#" )
do_rsa1_keygen() {
if [ ! -s $RSA1_KEY ]; then
echo -n $"Generating SSH1 RSA host key: "
rm -f $RSA1_KEY
if $KEYGEN -q -t rsa1 -f $RSA1_KEY -C '' -N '' >&/dev/null; then
chmod 600 $RSA1_KEY
chmod 644 $RSA1_KEY.pub
if [ -x /sbin/restorecon ]; then
/sbin/restorecon $RSA1_KEY.pub
fi
success $"RSA1 key generation"
echo
else
failure $"RSA1 key generation"
echo
exit 1
fi
fi
}
do_rsa_keygen() {
if [ ! -s $RSA_KEY ]; then
echo -n $"Generating SSH2 RSA host key: "
rm -f $RSA_KEY
if $KEYGEN -q -t rsa -f $RSA_KEY -C '' -N '' >&/dev/null; then
chmod 600 $RSA_KEY
chmod 644 $RSA_KEY.pub
if [ -x /sbin/restorecon ]; then
/sbin/restorecon $RSA_KEY.pub
fi
success $"RSA key generation"
echo
else
failure $"RSA key generation"
echo
exit 1
fi
fi
}
do_dsa_keygen() {
if [ ! -s $DSA_KEY ]; then
echo -n $"Generating SSH2 DSA host key: "
rm -f $DSA_KEY
if $KEYGEN -q -t dsa -f $DSA_KEY -C '' -N '' >&/dev/null; then
chmod 600 $DSA_KEY
chmod 644 $DSA_KEY.pub
if [ -x /sbin/restorecon ]; then
/sbin/restorecon $DSA_KEY.pub
fi
success $"DSA key generation"
echo
else
failure $"DSA key generation"
echo
exit 1
fi
fi
}
do_restart_sanity_check()
{
$SSHD -t
RETVAL=$?
if [ ! "$RETVAL" = 0 ]; then
failure $"Configuration file or keys are invalid"
echo
fi
}
start()
{
# Create keys if necessary
do_rsa1_keygen
do_rsa_keygen
do_dsa_keygen
cp -af /etc/localtime /var/empty/sshd/etc
echo -n $"Starting $prog: "
$SSHD $OPTIONS && success || failure
RETVAL=$?
[ "$RETVAL" = 0 ] && touch /var/lock/subsys/sshd
echo
}
stop()
{
echo -n $"Stopping $prog: "
if [ -n "`pidfileofproc $SSHD`" ] ; then
killproc $SSHD
else
failure $"Stopping $prog"
fi
RETVAL=$?
# if we are in halt or reboot runlevel kill all running sessions
# so the TCP connections are closed cleanly
if [ "x$runlevel" = x0 -o "x$runlevel" = x6 ] ; then
killall $prog 2>/dev/null
fi
[ "$RETVAL" = 0 ] && rm -f /var/lock/subsys/sshd
echo
}
reload()
{
echo -n $"Reloading $prog: "
if [ -n "`pidfileofproc $SSHD`" ] ; then
killproc $SSHD -HUP
else
failure $"Reloading $prog"
fi
RETVAL=$?
echo
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
reload)
reload
;;
condrestart)
if [ -f /var/lock/subsys/sshd ] ; then
do_restart_sanity_check
if [ "$RETVAL" = 0 ] ; then
stop
# avoid race
sleep 3
start
fi
fi
;;
status)
status -p $PID_FILE openssh-daemon
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|condrestart|status}"
RETVAL=1
esac
exit $RETVAL
و تمام این مکانها، مکانهایی بودند که SysV برای مدیریت اسکریپتها و runlevelها استفاده میکند. در سیستم Sysv میتوانیم سرویسها را با دستور service و دستور chkconfig مدیریت کنیم تا تعیین کنیم سرویسها چگونه و چه زمانی شروع شوند. بعداً در مورد آنها صحبت خواهیم کرد.
{% hint style="info" %} rc.local
اما در مورد /etc/rc.local چطور؟ این فایل پس از اجرای تمام اسکریپتهای دیگر سطح init اجرا میشود، بنابراین قرار دادن دستورات مختلفی که میخواهید هنگام راهاندازی اجرا شوند در آن امن است. همچنین این مکان خوبی برای قرار دادن اسکریپتهای "عیبیابی" (troubleshooting) است. اما فراموش نکنید که rc.local ممکن است در Upstart و Systemd به درستی کار نکند. قبل از استفاده در محیط عملیاتی (production)، آن را تست و جستجو کرده و پیکربندی لازم را انجام دهید. {% endhint %}
بیایید به موضوع خود برگردیم و با معادل runlevelها در systemd آشنا شویم. اگرچه /etc/inittab هنوز در سیستمهای Systemd وجود دارد اما بخشی از پیکربندی نیست، ما چیزی به نام "Targets" داریم.
مانند runlevelها، حالتهایی در سیستم systemd وجود دارد که سیستم ما میتواند در آنها اجرا شود، در systemd به runlevelها به عنوان "targets" اشاره میشود. "targets" به عنوان مجموعهای از سرویسها توصیف میشوند. به معادلها نگاه کنید:
┌─────────┬───────────────────┐
│Runlevel │ Target │
├─────────┼───────────────────┤
│0 │ poweroff.target │
├─────────┼───────────────────┤
│1 │ rescue.target │
├─────────┼───────────────────┤
│2, 3, 4 │ multi-user.target │
├─────────┼───────────────────┤
│5 │ graphical.target │
├─────────┼───────────────────┤
│6 │ reboot.target │
└─────────┴───────────────────┘
برای جابجایی بین Boot Targets از ابزار systemctl استفاده میکنیم.
Systemctl یک ابزار systemd است که مسئول کنترل سیستم systemd و مدیر سرویس (service manager) است. این ابزار میتواند کارهای زیادی انجام دهد اما آنچه ما در اینجا نیاز داریم و از آن استفاده میکنیم، تغییر boot targets است.
برای مشاهده boot target فعلی از دستور systemctl get-default استفاده کنید:
[root@centos7-1 ~]# systemctl get-default
graphical.target
برای تغییر target از دستور systemctl isolate xxxxx.target استفاده کنید، به عنوان مثال:
[root@centos7-1 ~]# systemctl isolate rescue.target
[root@centos7-1 ~]# systemctl isolate multi-user.target
برای تنظیم target پیشفرض، دستور systemctl set-default xxxxxx.target را اجرا کنید:
[root@centos7-1 ~]# systemctl set-default graphical.target
Removed symlink /etc/systemd/system/default.target.
Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/graphical.target.
اما systemd چگونه میداند چه کاری انجام دهد و چگونه کارها را انجام دهد؟ ما چیزی به نام "Unit" داریم. مفهوم "Unit Files" جایگزین اسکریپتهای init SysV برای سرویسها میشود.
انواع مختلفی از unit fileها وجود دارد و بهترین راه برای توصیف unit fileها این است که بگوییم "آن چیزی است که باید شروع شود". بله آن یک "چیز" است زیرا انواع مختلفی از unit fileها وجود دارد. هر unit file یک فایل متنی ساده است که یک واحد (unit)، کاری که انجام میدهد، آنچه باید قبل یا بعد از آن اجرا شود و سایر جزئیات را توصیف میکند.
Unit fileها میتوانند در چند مکان مختلف در سیستم شما ذخیره شوند. systemd به این ترتیب به دنبال فایلهای واحد سیستم میگردد:
- /etc/systemd/system: دایرکتوری ذخیره unit fileهایی که یک سرویس را گسترش میدهند. این دایرکتوری نسبت به unit fileهای واقع در هر جای دیگر سیستم اولویت دارد.
- /run/systemd/system: دایرکتوری مکان زمان اجرا (runtime) برای unit fileها است.
- /usr/lib/systemd/system: دایرکتوری مکان پیشفرضی است که unit fileها توسط پکیجها در آنجا نصب میشوند. Unit fileها در دایرکتوری پیشفرض نباید تغییر داده شوند.
Unit fileهای موجود در دایرکتوریهای قبلی، موارد بعدی را بازنویسی (override) میکنند. بیایید نگاهی به آنها بیندازیم:
[root@centos7-1 ~]# ls -l /etc/systemd/system
total 4
drwxr-xr-x. 2 root root 31 Oct 28 2017 basic.target.wants
drwxr-xr-x. 2 root root 31 Oct 28 2017 bluetooth.target.wants
lrwxrwxrwx. 1 root root 41 Oct 28 2017 dbus-org.bluez.service -> /usr/lib/systemd/system/bluetooth.service
lrwxrwxrwx. 1 root root 41 Oct 28 2017 dbus-org.fedoraproject.FirewallD1.service -> /usr/lib/systemd/system/firewalld.service
lrwxrwxrwx. 1 root root 44 Oct 28 2017 dbus-org.freedesktop.Avahi.service -> /usr/lib/systemd/system/avahi-daemon.service
lrwxrwxrwx. 1 root root 44 Oct 28 2017 dbus-org.freedesktop.ModemManager1.service -> /usr/lib/systemd/system/ModemManager.service
lrwxrwxrwx. 1 root root 46 Oct 28 2017 dbus-org.freedesktop.NetworkManager.service -> /usr/lib/systemd/system/NetworkManager.service
lrwxrwxrwx. 1 root root 57 Oct 28 2017 dbus-org.freedesktop.nm-dispatcher.service -> /usr/lib/systemd/system/NetworkManager-dispatcher.service
lrwxrwxrwx. 1 root root 36 Oct 28 2017 default.target -> /lib/systemd/system/graphical.target
drwxr-xr-x. 2 root root 87 Oct 28 2017 default.target.wants
drwxr-xr-x. 2 root root 38 Oct 28 2017 dev-virtio\x2dports-org.qemu.guest_agent.0.device.wants
lrwxrwxrwx. 1 root root 35 Oct 28 2017 display-manager.service -> /usr/lib/systemd/system/gdm.service
drwxr-xr-x. 2 root root 32 Oct 28 2017 getty.target.wants
drwxr-xr-x. 2 root root 65 Oct 28 2017 graphical.target.wants
drwxr-xr-x. 2 root root 4096 Oct 28 2017 multi-user.target.wants
drwxr-xr-x. 2 root root 26 Oct 28 2017 printer.target.wants
drwxr-xr-x. 2 root root 31 Oct 28 2017 remote-fs.target.wants
drwxr-xr-x. 2 root root 188 Oct 28 2017 sockets.target.wants
drwxr-xr-x. 2 root root 36 Oct 28 2017 spice-vdagentd.target.wants
drwxr-xr-x. 2 root root 26 Oct 28 2017 sssd.service.d
drwxr-xr-x. 2 root root 169 Oct 28 2017 sysinit.target.wants
drwxr-xr-x. 2 root root 44 Oct 28 2017 system-update.target.wants
drwxr-xr-x. 2 root root 29 Oct 28 2017 vmtoolsd.service.requires
[root@centos7-1 ~]# ls -l /run/systemd/system/
total 8
-rw-r--r-- 1 root root 17 Jan 2 2019 session-1.scope
drwxr-xr-x 2 root root 160 Jan 2 2019 session-1.scope.d
-rw-r--r-- 1 root root 17 Jan 2 2019 user-1000.slice
drwxr-xr-x 2 root root 120 Jan 2 2019 user-1000.slice.d
[root@centos7-1 ~]# ls /usr/lib/systemd/system
<output has been trancuated>
cryptsetup-pre.target runlevel0.target
cryptsetup.target runlevel1.target
ctrl-alt-del.target runlevel1.target.wants
cups-browsed.service runlevel2.target
cups.path runlevel2.target.wants
cups.service runlevel3.target
cups.socket runlevel3.target.wants
dbus-org.freedesktop.hostname1.service runlevel4.target
dbus-org.freedesktop.import1.service runlevel4.target.wants
dbus-org.freedesktop.locale1.service runlevel5.target
dbus-org.freedesktop.login1.service runlevel5.target.wants
dbus-org.freedesktop.machine1.service runlevel6.target
<output has been trancuated>
nfs-rquotad.service umount.target
nfs-secure.service upower.service
nfs-server.service usb_modeswitch@.service
nfs.service usbmuxd.service
nfs-utils.service user.slice
nss-lookup.target var-lib-nfs-rpc_pipefs.mount
nss-user-lookup.target vgauthd.service
ntpdate.service virt-guest-shutdown.target
ntpd.service virtlockd.service
numad.service virtlockd.socket
oddjobd.service virtlogd.service
packagekit-offline-update.service virtlogd.socket
packagekit.service vmtoolsd.service
paths.target wacom-inputattach@.service
plymouth-halt.service wpa_supplicant.service
plymouth-kexec.service zram.service
plymouth-poweroff.service
بیایید یکی از unit fileهای target را دنبال کنیم. ls -al *.target را امتحان کنید تا تمام فایلهای target را ببینید. به عنوان مثال default.target:
[root@centos7-1 ~]# ls -al /usr/lib/systemd/system/default.target
lrwxrwxrwx. 1 root root 16 Oct 28 2017 /usr/lib/systemd/system/default.target -> graphical.target
بیایید نگاهی به آن graphical.target بیندازیم:
[root@centos7-1 ~]# cat /usr/lib/systemd/system/graphical.target
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes
و آنچه نیاز دارد multi-user.target است، بیایید ببینیم:
[root@centos7-1 ~]# cat /usr/lib/systemd/system/multi-user.target
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes
و این به _basic.target _ نیاز دارد:
[root@centos7-1 ~]# cat /usr/lib/systemd/system/basic.target
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Basic System
Documentation=man:systemd.special(7)
Requires=sysinit.target
After=sysinit.target
Wants=sockets.target timers.target paths.target slices.target
After=sockets.target paths.target slices.target
در نهایت sysinit.target :
[root@centos7-1 ~]# cat /usr/lib/systemd/system/sysinit.target
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=System Initialization
Documentation=man:systemd.special(7)
Conflicts=emergency.service emergency.target
Wants=local-fs.target swap.target
After=local-fs.target swap.target emergency.service emergency.target
و sysinit.target به چیزی نیاز ندارد. به نظر میرسد که ما به بالاترین سطح هدف در درخت خود رسیدهایم و میتوانیم به عقب برگردیم.
استفاده از unit fileها در کنار مفهوم Targets باعث میشود Systemd در مقایسه با SysV انعطافپذیرتر باشد.
زمانهایی وجود دارد که چندین کاربر به یک کامپیوتر سرور متصل (log in) هستند و ما نیاز داریم، مثلاً سرور را برای انجام برخی کارهای نگهداری (maintenance) ریاستارت کنیم. البته، راه درست این است که به همه کسانی که متصل هستند در مورد فعالیت نگهداری اطلاع دهیم.
wall (مخفف write to all) یک ابزار خط فرمان یونیکس است که محتویات یک فایل یا ورودی استاندارد را به تمام کاربران متصل نمایش میدهد. معمولاً توسط root برای ارسال پیام خاموش شدن به تمام کاربران درست قبل از poweroff استفاده میشود.
wall [-n] [-t timeout] [-g group] [message | file]
OPTIONS
-n, --nobanner
Suppress the banner.
-t, --timeout timeout
Abandon the write attempt to the terminals after timeout
seconds. This timeout must be a positive integer. The
default value is 300 seconds, which is a legacy from the time
when people ran terminals over modem lines.
-g, --group group
Limit printing message to members of group defined as a group
argument. The argument can be group name or GID.
-V, --version
Display version information and exit.
-h, --help
Display help text and exit.
بیایید ارسال پیام "we are going down" را امتحان کنیم:
[root@centos5-1 ~]# wall "we are going down"
Broadcast message from root@centos6-1 (pts/1) (Sun Nov 11 00:46:58 2018):
we are going down
و user1 چه چیزی دریافت خواهد کرد:
[user1@centos5-1 ~]$
Broadcast message from root@centos6-1 (pts/1) (Sun Nov 11 00:46:58 2018):
we are going down
گزینهها ممکن است در برخی توزیعهای قدیمی کار نکنند.
shutdown - متوقف کردن (Halt)، خاموش کردن (power-off) یا ریبوت کردن ماشین
shutdown [OPTIONS...] [TIME] [WALL...]
OPTIONS
The following options are understood:
--help
Print a short help text and exit.
-H, --halt
Halt the machine.
-P, --poweroff
Power-off the machine (the default).
-r, --reboot
Reboot the machine.
-h
Equivalent to --poweroff, unless --halt is specified.
-k
Do not halt, power-off, reboot, just write wall message.
--no-wall
Do not send wall message before halt, power-off, reboot.
-c
Cancel a pending shutdown. This may be used cancel the effect of
an invocation of shutdown with a time argument that is not "+0"
or "now".
-t sec
Tell init to wait sec seconds between sending processes the warning
and the kill signal, before changing to another runlevel.
[TIME]
The time argument specifies when to perform the shutdown operation.
[WALL]
A message to be sent to all users, along with the standard shutdown notification.
shutdown کار خود را با ارسال سیگنال به فرآیند init انجام میدهد و از آن میخواهد runlevel را تغییر دهد. با توجه به عنوان قبلی، runlevel 0 برای halt کردن سیستم، runlevel 6 برای ریبوت کردن سیستم و runlevel 1 برای قرار دادن سیستم در حالتی استفاده میشود که وظایف مدیریتی در آن قابل انجام است (single-user mode).
root@ubuntu16-1:~# shutdown -r -t 15 +5 "Server will restart in 5 minutes. Please save your work."
Shutdown scheduled for Sun 2018-11-11 03:19:56 PST, use 'shutdown -c' to cancel.
root@ubuntu16-1:~# shutdown -c
ما میتوانیم یک رشته زمانی (که معمولاً برای ساعت/دقیقه به صورت “now” یا “hh:mm” است) را تعیین کنیم:
root@ubuntu16-1:~# shutdown -r 10:10 "Server will be rebooted at 10:10am"
Shutdown scheduled for Tue 2018-11-13 10:10:00 PST, use 'shutdown -c' to cancel.
root@ubuntu16-1:~# shutdown -c
{% hint style="info" %}
- halt قبل از ACPI (Advanced Configuration and Power Interface) استفاده میشد که امروزه برق را برای ما قطع میکند. این دستور سیستم را متوقف میکرد و سپس پیامی با مضمون "اکنون خاموش کردن برق بلامانع است" چاپ میکرد. در آن زمان به جای دکمه پاور کنترل شده توسط ACPI در کامپیوترهای مدرن، سوئیچهای فیزیکی روشن/خاموش وجود داشت.
- poweroff، طبیعتاً سیستم را متوقف کرده و سپس خاموش کردن برق توسط ACPI را فراخوانی میکند.
این روزها halt به اندازه کافی هوشمند است که اگر ACPI فعال باشد، به طور خودکار poweroff را فراخوانی کند. در واقع، آنها اکنون از نظر عملکردی معادل هستند. {% endhint %}
دستور reboot میتواند برای خاموش کردن یا ریبوت کردن لینوکس استفاده شود.
[root@centos7-1 ~]# reboot --help
reboot [OPTIONS...] [ARG]
Reboot the system.
--help Show this help
--halt Halt the machine
-p --poweroff Switch off the machine
--reboot Reboot the machine
-f --force Force immediate halt/power-off/reboot
-w --wtmp-only Don't halt/power-off/reboot, just write wtmp record
-d --no-wtmp Don't write wtmp record
--no-wall Don't send wall message before halt/power-off/reboot
برای ریبوت کردن لینوکس، فقط دستور reboot را مستقیماً بدون هیچ گزینهای فراخوانی کنید.
[root@centos7-1 ~]# reboot
این کار باعث خاموش شدن و راهاندازی مجدد ایمن (graceful) ماشین میشود. این همان اتفاقی است که وقتی روی restart در منوی خود کلیک میکنید، میافتد.
گزینه -f ماشین را به اجبار ریبوت میکند. این مشابه فشار دادن دکمه پاور روی CPU است. هیچ فرآیند خاموش شدنی صورت نمیگیرد. سیستم فوراً ریست میشود.
دستور بعدی دستور halt است. این دستور میتواند یک سیستم را خاموش کند اما گزینههای دیگری نیز دارد:
[root@centos7-1 ~]# halt --help
halt [OPTIONS...]
Halt the system.
--help Show this help
--halt Halt the machine
-p --poweroff Switch off the machine
--reboot Reboot the machine
-f --force Force immediate halt/power-off/reboot
-w --wtmp-only Don't halt/power-off/reboot, just write wtmp record
-d --no-wtmp Don't write wtmp record
--no-wall Don't send wall message before halt/power-off/reboot
دستور halt نیز دارای گزینه force است اما سعی کنید از آن استفاده نکنید، زیرا ممکن است سیستم شما را در حالتی ناپایدار (inconsistent) قرار دهد.
دستور دیگری دقیقاً مشابه دستور halt وجود دارد. این دستور همان کارها را انجام میدهد و همان گزینهها را میگیرد.
[root@centos7-1 ~]# poweroff --help
poweroff [OPTIONS...]
Power off the system.
--help Show this help
--halt Halt the machine
-p --poweroff Switch off the machine
--reboot Reboot the machine
-f --force Force immediate halt/power-off/reboot
-w --wtmp-only Don't halt/power-off/reboot, just write wtmp record
-d --no-wtmp Don't write wtmp record
--no-wall Don't send wall message before halt/power-off/reboot
و کار ما تمام شد.
.
.
.
Sources:
https://www.linuxjournal.com/article/1274
https://en.wikipedia.org/wiki/Runlevel
https://www.geeksforgeeks.org/run-levels-linux/
https://www.ostechnix.com/check-runlevel-linux/
https://geek-university.com/linux/etc-inittab/``https://developer.ibm.com/tutorials/l-lpic1-101-3/
https://www.liquidweb.com/kb/linux-runlevels-explained/
https://linux.die.net/man/8/telinit
https://askubuntu.com/questions/5039/what-is-the-difference-between-etc-init-and-etc-init-d
https://www.systutorials.com/239880/change-systemd-boot-target-linux/
https://www.tecmint.com/change-runlevels-targets-in-systemd/
https://fedoramagazine.org/systemd-getting-a-grip-on-units/
https://www.linode.com/docs/quick-answers/linux-essentials/what-is-systemd/
https://www.howtoforge.com/linux-wall-command/
https://en.wikipedia.org/wiki/Wall_(Unix)
http://man7.org/linux/man-pages/man1/wall.1.html
http://man7.org/linux/man-pages/man8/shutdown.8.html
https://www.computerhope.com/unix/ushutdow.htm
https://www.tecmint.com/shutdown-poweroff-halt-and-reboot-commands-in-linux/
https://www.binarytides.com/linux-command-shutdown-reboot-restart-system/
