SSD Nodes Learn 🎉 VPS $5.50/மாதம் முதல்
கல்வி வழிகாட்டிகள் Matt Connorஆல் Matt Connor · புதுப்பிக்கப்பட்டது 2026-08-16

systemd service Type: simple, forking, notify விளக்கம்

உங்கள் service active என்று காட்டியும் daemon இயங்கவில்லையா? simple, forking, notify மற்றும் oneshot ஆகிய Type அமைப்புகளின் வேறுபாடுகளை அறிந்து சரியான main PID-ஐ கண்டறியுங்கள்.

செயல்முறை (process) நின்ற பிறகும் systemd ஏன் ஒரு unit-ஐ active என்று காட்டுகிறது

systemd service unit என்பது systemd எதை முதன்மைச் செயல்முறை (main process) என்று கருதுகிறதோ, அது உயிருடன் இருக்கும் வரை active நிலையிலேயே இருக்கும். [Service] பகுதியில் உள்ள Type= என்பது அந்த முதன்மைச் செயல்முறை எது என்பதைத் தீர்மானிக்கிறது. தவறான மதிப்பைத் தேர்வு செய்தால், நீங்கள் கவனிக்க வேண்டிய daemon உள்ளே இறந்துவிட்டாலும், systemd ஒரு shell wrapper-ஐயோ அல்லது குறுகிய காலம் இயங்கும் parent process-ஐயோ கவனித்துக் கொண்டிருக்கும். அந்த unit, தான் கவனிக்கச் சொல்லப்பட்ட செயல்முறையைப் பற்றிய உண்மையான தகவலையே உங்களுக்குத் தெரிவிக்கிறது.

restart policy-ஐ மாற்றுவது இங்கே உதவாது. முதன்மைச் செயல்முறை வெளியேறும்போதுதான் Restart= செயல்படும். எனவே, முதன்மை PID (process identifier) இன்னும் இயங்கிக்கொண்டிருக்கும் ஒன்றிற்குச் சொந்தமாக இருக்கும் வரை Restart=always ஒருபோதும் இயங்காது. முதலில் Type=-ஐச் சரிசெய்யவும். முதன்மைச் செயல்முறை உண்மையாகவே வெளியேறிய பிறகு systemd என்ன செய்ய வேண்டும் என்பது ஒரு தனி முடிவாகும்; அது Restart= மற்றும் RestartSec= கையேட்டில் விளக்கப்பட்டுள்ளது.

Type= என்பது எதனைத் தீர்மானிக்கிறது

ஒவ்வொரு Type= மதிப்பும் ஒரே நேரத்தில் இரண்டு கேள்விகளுக்குப் பதிலளிக்கிறது. systemd எப்போது இந்த unit தொடங்கப்பட்டதாகக் கருத வேண்டும், மற்றும் இதில் முதன்மையான process எது என்பதுதான் அவை.

முதல் பதில் வரிசைப்படுத்துதலை (ordering) கட்டுப்படுத்துகிறது. உங்கள் unit-ஐ After=-ல் குறிப்பிடும் ஒரு unit, systemd உங்கள் unit-ஐத் தொடங்கியதாக அறிவிக்கும் வரை காத்திருக்கும். மிக விரைவாக "started" என்று அறிவிக்கும் ஒரு Type=, உங்கள் service தயாராகும் முன்பே அதனுடன் தொடர்புடைய பிற unit-களை இயங்கச் செய்துவிடும்.

இரண்டாவது பதில் கண்காணிப்பைக் (supervision) கட்டுப்படுத்துகிறது. ஒரு unit உருவாக்கும் ஒவ்வொரு process-ஐயும் systemd ஒரு cgroup-க்குள் (control group) வைக்கிறது. இது process-களைக் குழுவாக்கி, அவற்றைக் கட்டுப்படுத்தவும் ஒரே நேரத்தில் நிறுத்தவும் உதவும் ஒரு kernel வசதியாகும். இந்த cgroup மூலமே systemctl stop சுத்தம் செய்யும் பணிகளைச் செய்கிறது: KillMode= இயல்பாகவே control-group என்று இருப்பதால், ஒரு unit-ஐ நிறுத்தும்போது அதிலுள்ள அனைத்து process-களுக்கும் signal அனுப்பப்படும். Main PID என்பது இதைவிடக் குறுகிய எல்லை கொண்டது. இது அந்த unit-ன் முடிவைத் தீர்மானிக்கும் ஒரே process ஆகும்; இதன் exit status-தான் அந்த unit-ன் முடிவாகக் கருதப்படும். cgroup-ஐ main PID என்று தவறாகப் புரிந்துகொள்வதே குழப்பங்களுக்குக் காரணமாகிறது.

Type=simple என்பது binary இயங்குவதற்கு முன்பே தொடங்கப்பட்டதாக அறிக்கை செய்கிறது

Type=simple என்பது ExecStart= அமைக்கப்பட்டு, Type= மற்றும் BusName= ஆகிய இரண்டும் இல்லாதபோது இயல்பாக அமையும் அமைப்பாகும். systemd ஒரு process-ஐ உருவாக்கி, அந்த unit உடனடியாகத் தொடங்கிவிட்டதாகக் கருதி, அந்த process-ஐ முதன்மை PID-ஆகக் கொள்கிறது. service binary இயங்குவதற்கு முன்பே, அடுத்தடுத்த unit-கள் உடனடியாகத் தொடங்கத் தொடங்கிவிடும்.

இந்தக் கடைசி விவரம் ஒரு பொதுவான ஆச்சரியத்தை விளக்குகிறது. ExecStart= பாதையில் உள்ள எழுத்துப் பிழை (typo) ஒரு start job-ஐ வெற்றிகரமாக முடிக்கும், ஆனால் binary இயங்கத் தவறியவுடன் தோல்வி ஏற்படும். systemd அந்தச் சூழலை exit code 203-ஆகப் பதிவு செய்கிறது. அதன் சொந்த அட்டவணை இதை EXEC என்று அழைப்பதோடு, service binary-ஐ இயக்கத் தவறியதற்கான தோல்வி என்றும் வரையறுக்கிறது. எனவே, systemctl start எந்தப் பிழையும் இன்றித் திரும்புவது, உங்கள் binary அங்கு உள்ளது என்பதற்குச் சான்றாகாது.

முன்புறத்தில் (foreground) தங்கி, தன்னைத்தானே பின்புலத்திற்கு (background) மாற்றிக்கொள்ளாத நிரல்களுக்கு simple-ஐப் பயன்படுத்தவும். இது நவீன daemons மற்றும் நீங்கள் எழுதும் பெரும்பாலான நிரல்களுக்குப் பொருந்தும்.

Type=exec என்பது நிரல் தொடங்கும் வரை காத்திருக்கிறது

Type=exec என்பது simple-ன் மேம்படுத்தப்பட்ட ஒரு நிலையாகும். fork மற்றும் binary-ன் இயக்கம் ஆகிய இரண்டும் வெற்றிகரமாக முடிந்த பின்னரே, அந்த unit தொடங்கப்பட்டதாக systemd கருதும். binary கோப்பு இல்லையென்றாலோ அல்லது User=-ஐத் தீர்க்க முடியாவிட்டாலோ, அது வெற்றிகரமாகத் தொடங்கியதாகக் காட்டாமல், தொடக்கப் பணியிலேயே (start job) தோல்வியைச் சுட்டிக்காட்டும்.

Type=exec ஆனது systemd 240 பதிப்பில் அறிமுகப்படுத்தப்பட்டது, எனவே தற்போதுள்ள அனைத்து server distribution-களிலும் இது உள்ளது. ஆகஸ்ட் 2026 நிலவரப்படி, Ubuntu 24.04-ல் systemd 255-ம், Debian 13-ல் systemd 257-ம் உள்ளன. உங்கள் பதிப்பை systemctl --version மூலம் சரிபார்க்கவும்.

இதன் விளைவாகத் தொடக்கத்தில் ஒரு கூடுதல் synchronization படி தேவைப்படும். ஆனால், systemctl start-லிருந்து துல்லியமான exit status-ஐப் பெற முடியும் என்பது இதன் நன்மையாகும். foreground-ல் இயங்கும் நிரல்களுக்கு, simple-க்கு பதிலாக exec-ஐப் பயன்படுத்துவது சிறந்தது.

Type=forking மற்றும் முதன்மை PID தொலைந்து போதல்

Type=forking, ExecStart=-ல் உள்ள process ஒரு child-ஐ உருவாக்கிவிட்டு, திட்டமிட்டபடி வெளியேறும் என்பதை systemd-க்குத் தெரிவிக்கிறது. அந்த முதல் process வெளியேறும் வரை systemd காத்திருந்து, அதன் பிறகே unit தொடங்கப்பட்டதாகக் கருதும். எஞ்சியிருக்கும் child-தான் daemon ஆகும்.

இதில் உள்ள சிக்கல் அடையாளப்படுத்துதல் ஆகும். systemd தொடங்கிய process முடிந்துவிட்டதால், எஞ்சியிருப்பவற்றில் எது முதன்மையானது என்பதை அது கண்டறிய வேண்டும். PIDFile=-ஐ daemon எழுதும் கோப்பாக அமைக்கவும்; இது வழக்கமாக /run-க்குக் கீழ் இருக்கும் ஒரு பாதையாகும். இதிலிருந்து systemd PID-ஐ வாசிக்கும். அந்த PID இந்த service-க்குச் சொந்தமானதா என்பதையும் systemd சரிபார்க்கும். எனவே, தொடர்பில்லாத ஒரு process-ஐக் குறிக்கும் பழைய கோப்பு நிராகரிக்கப்படும்.

PIDFile= இல்லையென்றால், GuessMainPID= பொருந்தும், இது இயல்பாகவே yes என்று இருக்கும். service ஒரே ஒரு process-ஆக நிலைபெற்றால் மட்டுமே இந்த ஊகம் நம்பகமானது. கையேடு இதன் வரம்பைத் தெளிவாகக் கூறுகிறது: daemon ஒன்றுக்கு மேற்பட்ட process-களைக் கொண்டிருந்தால், இந்த ஊகம் தவறாகலாம், மேலும் தோல்வியைக் கண்டறியும் வசதி வேலை செய்யாது. ஒரு unit-ன் முதன்மை PID 0 என்று முடிவடையலாம், அதாவது systemd-ஆல் கண்காணிக்க எதுவுமே இருக்காது என்று அர்த்தம்.

fork செய்யும் பெரும்பாலான daemon-களில் அவற்றை foreground-ல் வைத்திருக்கும் ஒரு switch இருக்கும். அந்த switch-ஐ Type=exec-உடன் பயன்படுத்தவும், மேலும் PIDFile= வரியை நீக்கவும். குறைவான நகரும் பாகங்கள் இருந்தால், PID-ஐ இழப்பதற்கான வாய்ப்புகளும் குறையும்.

Type=oneshot என்பது முடிவடையும் பணிகளுக்கானது

Type=oneshot ஒரு process இயங்கி முடிவடையும் வரை காத்திருக்கும். அந்த process வெளியேறிய பிறகுதான் systemd அந்த unit-ஐ 'started' நிலைக்குக் கொண்டுவரும். எனவே, மற்றொரு unit சார்ந்திருக்கும் பணிகளுக்கு oneshot சரியான அமைப்பாகும். ஒரு unit-ல் Type= அல்லது ExecStart= குறிப்பிடப்படாதபோது, இதுவே இயல்பான (default) அமைப்பாகக் கருதப்படுகிறது.

oneshot-க்கு இரண்டு தனித்துவமான செயல்பாடுகள் உள்ளன. இது மட்டுமே ஒன்றுக்கும் மேற்பட்ட ExecStart= வரிகளை ஏற்கும், மேலும் அந்த வரிகள் வரிசைக்கிரமமாக இயங்கும். இதன் start timeout இயல்பாகவே முடக்கப்பட்டிருக்கும், எனவே oneshot நீண்ட நேரம் இயங்கினால், நீங்கள் TimeoutStartSec=-ஐ அமைக்காவிட்டால் அது காலவரையின்றி காத்திருக்கும்.

Process வெளியேறிய பிறகு, அந்த unit 'inactive' நிலைக்குத் திரும்பும். RemainAfterExit=yes, எந்த process-ம் இயங்காத நிலையிலும் அந்த unit-ஐ active நிலையில் வைத்திருக்கும். இந்தப் பக்கத்தின் தொடக்கத்தில் குறிப்பிடப்பட்ட அறிகுறியின் திட்டமிட்ட வடிவம் இதுவே. ஒரு unit-ன் பணி ஏதேனும் ஒன்றை இயங்க வைப்பதாக இல்லாமல், ஒரு நிலையை (state) உருவாக்குவதாக இருக்கும்போது இது சரியான அணுகுமுறையாகும்; உதாரணமாக, firewall ruleset-ஐ ஏற்றுவது அல்லது container stack-ஐத் தொடங்குவது. reboot-க்குப் பிறகு மீண்டும் வரும் Docker Compose stack-ன் பின்னணியில் இந்த முறைதான் உள்ளது. இதில் unit, compose command-ஐ இயக்கிவிட்டு வெளியேறிவிடும், ஆனால் அது தொடங்கிய containers தொடர்ந்து இயங்குவதால் அந்த unit 'active' நிலையிலேயே இருக்கும். ஒரு schedule மூலம் தூண்டப்படும் பணிகளுக்கும் oneshot unit பயன்படுத்தப்படுகிறது; இது cron-க்கு பதிலாக systemd timer-ல் ஒரு பணியை இயக்குதல் என்பதன் மற்றொரு பகுதியாகும்.

Type=notify என்பது service தயாராகிவிட்டதை அதுவே தெரிவிக்கும்படி செய்கிறது.

Type=notify முடிவெடுக்கும் பொறுப்பை service-க்கே மாற்றுகிறது. process ஆனது NOTIFY_SOCKET environment variable-ல் உள்ள பாதையில் ஒரு Unix socket வழியாக READY=1 செய்தியை அனுப்பும் வரை, systemd அந்த start job-ஐத் திறந்து வைத்திருக்கும். இதற்கான C interface sd_notify(3) ஆகும், பல servers இதை ஏற்கனவே ஆதரிக்கின்றன.

"இது தொடங்கப்பட்டுவிட்டதா" என்ற கேள்விக்கு இதுவே சரியான பதில். simple மற்றும் exec ஆகியவை service அதன் configuration-ஐப் படிப்பதற்கு முன்போ அல்லது listening socket-ஐத் திறப்பதற்கு முன்போ "தொடங்கப்பட்டது" என்று தெரிவித்துவிடும். இதனால், அதைச் சார்ந்திருக்கும் unit மிக விரைவாகத் தொடங்கி, முதல் connection-ஐ ஏற்படுத்த முடியாமல் தோல்வியடையலாம். notify, service தானாகவே தயாராகிவிட்டதாகக் கூறும் தருணத்தில் மட்டுமே "தொடங்கப்பட்டது" என்று தெரிவிக்கும்.

systemd இந்தச் செய்தியை main process-லிருந்து மட்டுமே ஏற்கும், இதையே NotifyAccess=main குறிக்கிறது, மேலும் Type=notify இதை உறுதிப்படுத்துகிறது. ஒருவேளை இந்தச் செய்தி child process அல்லது helper மூலம் வந்தால், NotifyAccess=all-ஐ அமைக்க வேண்டும். ஒரு shell script systemd-notify --ready-ஐ அழைக்கலாம், ஆனால் அது குறுகிய காலமே இயங்கும் தனி process என்பதால், அதற்கு NotifyAccess=all தேவைப்படுகிறது. மேலும், அனுப்பிய process ஏற்கனவே முடிந்துவிட்டதால், அந்தச் செய்தியை systemd-ஆல் அடையாளம் காண முடியாமல் போகலாம். இந்த protocol-ஐ நேரடியாகப் பேசும் service மிகவும் நம்பகமானது.

இதனுடன் தொடர்புடைய இரண்டு அமைப்புகளைத் தெரிந்துகொள்வது பயனுள்ளது. Type=notify-reload (systemd 253 முதல் கிடைக்கிறது) இதே handshake முறையை reload-களுக்கும் நீட்டிக்கிறது. எனவே, signal அனுப்பப்பட்டவுடன் திரும்புவதற்குப் பதிலாக, reload முடிந்துவிட்டதாக service தெரிவிக்கும்போது systemctl reload திரும்பும். WatchdogSec=, ஒரு notifying service-ஐ குறிப்பிட்ட கால இடைவெளியில் keep-alive செய்தியை அனுப்பச் சொல்கிறது; ஒருவேளை அந்த காலக்கெடு தவறினால், systemd அதைத் தோல்வியாகக் கருதும்.

Type=dbus மற்றும் Type=idle

Type=dbus என்பது, system மற்றும் desktop சேவைகள் தங்களுக்குள் தொடர்புகொள்ளப் பயன்படுத்தும் D-Bus-ல், ஒரு சேவை தனது பெயரைப் பதிவு செய்யும் வரை காத்திருக்கும். இதற்கு BusName= தேவைப்படுகிறது, மேலும் BusName= அமைக்கப்பட்டவுடன் இதுவே இயல்புநிலை (default) அமைப்பாக மாறுகிறது. ஒரு சேவை உண்மையில் bus பெயரைப் பதிவு செய்தால் மட்டுமே இதைப் பயன்படுத்தவும்.

Type=idle என்பது simple போன்றே செயல்படும், ஆனால் இது வரிசையில் உள்ள பணிகள் (queued jobs) முடிவடையும் வரை நிரலை இயக்குவதைத் தாமதப்படுத்தும்; இதற்கு ஐந்து வினாடிகள் கால வரம்பு உண்டு. boot-ன் போது வெளியாகும் console தகவல்கள், status செய்திகளுடன் கலந்துவிடாமல் இருக்கவே இது உருவாக்கப்பட்டது. இது ஒரு வரிசைப்படுத்தும் கருவி (ordering tool) அல்ல, மேலும் சாதாரண சேவைகளில் இதைப் பயன்படுத்தக்கூடாது.

wrapper script ஏன் systemd-ஐ தவறான PID-ல் நிறுத்துகிறது

அறிகுறிகளை உருவாக்கும் கட்டமைப்பு இதோ.

[Service]
Type=simple
ExecStart=/opt/app/run.sh
#!/bin/bash
export APP_ENV=production
/opt/app/bin/server --config /etc/app.yaml &
/opt/app/bin/exporter --port 9101

systemd, shell-ஐ முதன்மை PID-ஆகப் பதிவு செய்கிறது. exporter foreground-ல் இயங்கும்போது shell உயிர்ப்புடன் இருக்கும். server செயலிழந்தால், shell அதை கவனிக்காது; எனவே முதன்மை PID இன்னும் உயிர்ப்புடன் இருக்கும், unit இன்னும் active நிலையிலேயே இருக்கும், மேலும் Restart= செயல்படுவதற்கு எதுவும் இருக்காது. இரண்டு process-களும் unit-ன் cgroup-லேயே இருப்பதால், systemctl stop இன்னும் சரியாகவே cleanup செய்யும். மேற்பார்வை (supervision) மட்டுமே பாதிக்கப்பட்டுள்ளது, cleanup அல்ல.

இந்தத் தீர்வு, அந்த unit-ல் எத்தனை நீண்டகால process-கள் உள்ளன என்பதைப் பொறுத்தது.

ஒரே ஒரு process இருந்தால், shell-க்கு பதிலாக அதை மாற்றவும்.

#!/bin/bash
export APP_ENV=production
exec /opt/app/bin/server --config /etc/app.yaml

exec, shell-ஐ குறிப்பிட்ட நிரலால் (program) இடமாற்றம் செய்து அதே PID-ஐ வைத்திருக்கும், எனவே systemd பதிவு செய்த PID இப்போது daemon-க்கு உரியதாகிவிடும். இன்னும் சிறப்பாக, wrapper-ஐ நீக்கிவிடவும். Environment= மற்றும் EnvironmentFile= மாறிகளை (variables) கொண்டு செல்லும், ExecStartPre= setup படியைக் கையாளும்; எனவே systemd நேரடியாக daemon-ஐத் தொடங்கி, அதன் PID-ஐத் துல்லியமாக அறிய முடியும்.

இரண்டு process-கள் இருந்தால், எந்த ஒரு PID-ம் அந்த unit-ஐ முழுமையாகப் பிரதிநிதித்துவப்படுத்தாது. அவற்றை இரண்டு தனித்தனி unit-களாகப் பிரித்து, After= மற்றும் Wants= மூலம் வரிசைப்படுத்தவும். ஒரு process-க்கு ஒரு unit என்ற அமைப்பையே systemd சிறப்பாக மேற்பார்வையிடும்; ஒவ்வொரு process-க்கும் தனித்தனி restart முறையை அமைப்பதற்கான ஒரே வழி இதுதான்.

ExitType=cgroup மாற்றங்கள் என்றால் என்ன

ExitType= என்பது systemd 250-ல் சேர்க்கப்பட்டது. இதன் default மதிப்பு main ஆகும்: main process முடிவடையும் போது, அந்த unit நிறுத்தப்பட்டதாகக் கருதப்படும். ExitType=cgroup-ஐப் பயன்படுத்தினால், அதன் cgroup-ல் ஏதேனும் ஒரு process உயிருடன் இருக்கும் வரை அந்த unit இயங்குவதாகவே கருதப்படும்.

[Service]
Type=simple
ExitType=cgroup
ExecStart=/opt/app/launcher

இது ஒரு குறிப்பிட்ட சிக்கலைத் தீர்க்கிறது. உண்மையான பணியைத் தொடங்கிவிட்டு வெளியேறும் ஒரு launcher, ExitType=main-ன் கீழ் இயங்கினால், systemd அந்த unit-ஐ நிறுத்திவிட்டு மற்ற process-களைக் கொன்றுவிடும். ExitType=cgroup-ஐப் பயன்படுத்தினால், அந்த unit முழு குழுவையும் கண்காணிக்கும்.

இது எதைத் தீர்க்காது என்பதில் தெளிவாக இருக்கவும். ExitType=cgroup என்பது குறைந்தது ஒரு process இருக்கும் வரை unit-ஐ active நிலையில் வைத்திருக்கும், எனவே இரண்டு daemons-ஐக் கொண்ட ஒரு unit-ல் ஒன்று இறந்தாலும் அது active-ஆகவே இருக்கும். இது launcher சிக்கலை மட்டுமே சரிசெய்கிறது. இது ஒரு unit-ஐ பல சுதந்திரமான process-களின் supervisor-ஆக மாற்றாது. ExitType=-ஐ Type=oneshot-உடன் இணைக்கவும் முடியாது.

வளக் கணக்கீடு (resource accounting) cgroup-லேயே நடைபெறுகிறது, எனவே Type= main PID பற்றி என்ன கூறினாலும், MemoryMax= மற்றும் CPUQuota= போன்ற வரம்புகள் அந்த unit உருவாக்கிய அனைத்து process-களுக்கும் பொருந்தும். இது குறித்த கூடுதல் விவரங்களை systemd மூலம் ஒரு service-ன் memory மற்றும் CPU-ஐக் கட்டுப்படுத்துதல் பகுதியில் காணலாம்.

systemd உண்மையில் கண்காணிக்கும் process-ஐக் கண்டறிவது எப்படி

நீங்கள் பிழைத்திருத்தம் (debug) செய்யும் unit-ல் வரிசையாக இதைப் பின்பற்றவும். systemd எதை ஏற்றியது என்பதைப் படித்து, அது எதைக் கண்காணிக்கிறது என்பதைப் பார்த்து, அதை process table-உடன் ஒப்பிடவும்.

systemctl cat app.service
systemctl show -p Type,ExitType,GuessMainPID,PIDFile,MainPID,RemainAfterExit app.service

systemctl cat என்பது unit file-ஐ அதன் மீது பொருந்தும் அனைத்து drop-in கோப்புகளுடனும் சேர்த்து அச்சிடும். எனவே, நீங்கள் திருத்தியதாக நினைக்கும் கோப்பை விட, systemd உண்மையில் எதை ஏற்றுகிறதோ அதையே நீங்கள் வாசிக்கிறீர்கள். systemctl show என்பது நீங்கள் குறிப்பிடாத defaults உட்பட, நடைமுறையில் உள்ள மதிப்புகளை அச்சிடும். அடுத்த கட்டத்திற்குச் செல்லும் முன் MainPID-ன் மதிப்பைக் குறித்துக்கொள்ளவும்.

systemd-cgls --unit=app.service
ps -o pid,ppid,stat,etime,args -p "$(systemctl show -p MainPID --value app.service)"

systemd-cgls என்பது unit-ன் cgroup-ல் உள்ள அனைத்து process-களையும் பட்டியலிடும். ps வரிசையானது systemd கண்காணிக்கும் ஒற்றை process-ஐ விவரிக்கும். இரண்டையும் சேர்த்து வாசிக்கவும். MainPID-ன் மதிப்பு 0 எனில், systemd-யிடம் கண்காணிக்க எந்த process-ம் இல்லை என்று அர்த்தம். cgroup-ல் உங்கள் daemon இருக்கும்போது, MainPID ஒரு shell-ஐக் காட்டினால், அது மேலே குறிப்பிட்ட wrapper சூழலாகும். நீங்கள் எதிர்பார்த்ததை விட அதிகமான process-கள் cgroup-ல் இருந்தால், அங்கு ஒரு launcher அல்லது forking daemon சம்பந்தப்பட்டிருக்கிறது என்று பொருள்.

systemctl status app.service
journalctl -u app.service -b

systemctl status என்பது state வரிசையையும் cgroup மரத்தையும் ஒன்றாக அச்சிடும், எனவே இது பெரும்பாலும் இரண்டு கேள்விகளுக்கும் ஒரே நேரத்தில் பதிலளிக்கும். -b உடன் இந்த boot-க்கு மட்டும் மட்டுப்படுத்தப்பட்ட journalctl -u, systemd அந்த unit-க்காகப் பதிவு செய்த start மற்றும் stop நிகழ்வுகளையும், அது கண்ட exit codes-களையும் காட்டும். daemon தனது சொந்த log கோப்பில் எழுதினால், அதையும் வாசிக்கவும்; ஏனெனில் systemd தனக்குக் கிடைத்த தகவல்களை மட்டுமே பதிவு செய்ய முடியும்.

நீங்கள் Type=-ஐ மாற்றும்போது, reload மற்றும் restart செய்யவும்.

systemd-analyze verify /etc/systemd/system/app.service
sudo systemctl daemon-reload
sudo systemctl restart app.service

systemd-analyze verify கோப்பைப் பகுப்பாய்வு செய்து, ஏற்றுக்கொள்ள முடியாத அமைப்புகளைத் தெரிவிக்கும். daemon-reload என்பது systemd-ஐ disk-லிருந்து unit கோப்புகளை மீண்டும் படிக்கச் செய்யும். மாற்றப்பட்ட Type= ஏற்கனவே இயங்கிக்கொண்டிருக்கும் unit-க்கு உடனடியாகப் பொருந்தாது, எனவே restart செய்வது கட்டாயமாகும், விருப்பத்தேர்வு அல்ல.

பின்பு மாற்றத்தைச் சோதிக்கவும். systemd-cgls மூலம் நீங்கள் கவனிக்க வேண்டிய process-ன் PID-ஐ எடுத்து அதை kill செய்யவும். உடனடியாக systemctl is-active app.service-ஐ இயக்கவும். Type= சரியாக இருந்தால், அந்த unit active நிலையிலிருந்து வெளியேறும். அது இன்னும் active நிலையிலேயே இருந்தால், systemd வேறொன்றைக் கண்காணித்துக் கொண்டிருக்கிறது என்று அர்த்தம்.

எந்த systemd service Type=-ஐ நீங்கள் பயன்படுத்த வேண்டும்

  • foreground-ல் இயங்கும் ஒரு நிரல்: Type=exec.
  • readiness notification-ஐ ஆதரிக்கும் ஒரு நிரல்: Type=notify, மற்றும் அது reloads-ஐயும் உறுதிப்படுத்தினால் notify-reload.
  • background-க்குச் செல்ல விரும்பும் ஒரு daemon: PIDFile= உடன் Type=forking, அல்லது அதன் foreground switch-உடன் Type=exec.
  • வேலை செய்துவிட்டு வெளியேறும் ஒரு script: Type=oneshot, மேலும் state-ஐ அப்படியே விட்டுச் செல்வது நோக்கமாக இருந்தால் RemainAfterExit=yes.
  • அதன் children தொடர்ந்து இயங்கும்போது வெளியேறும் ஒரு launcher: ExitType=cgroup உடன் Type=simple.

ஒரு third party daemon-க்கு எது தேவை என்பதில் உங்களுக்குத் தெளிவு இல்லையென்றால், முதலில் அதன் packaged unit file-ஐப் படிக்கவும். விநியோகஸ்தர் வழங்கிய unit-ல் systemctl cat-ஐ இயக்குவது, upstream தேர்ந்தெடுத்த Type=-ஐக் காட்டும்; அந்தத் தேர்வு உங்களை விட அதிகமான மக்களால் சோதிக்கப்பட்டது.

FAQ

process இறந்த பிறகும் எனது systemd unit ஏன் active நிலையிலேயே உள்ளது?

ஏனெனில் systemd முதன்மை process-ஆகக் கருதும் process இன்னும் இயங்கிக்கொண்டிருக்கிறது. unit-ன் cgroup-ல் உள்ள அனைத்து process-களையும் கவனிப்பதற்குப் பதிலாக, Type=-ன் படி தேர்ந்தெடுக்கப்பட்ட ஒரு குறிப்பிட்ட PID-ஐ மட்டுமே systemd கண்காணிக்கிறது. Type=simple மூலம் தொடங்கப்பட்ட wrapper script இதற்குப் பொதுவான காரணமாகும்: shell தான் முதன்மை PID-ஆக இருக்கும், எனவே shell பின்னணியில் தொடங்கிய daemon வெளியேறிய பிறகும் unit active நிலையிலேயே இருக்கும். systemctl show -p MainPID app.service-ஐ இயக்கவும், பின் systemd-cgls --unit=app.service மூலம் unit-ன் cgroup-ஐப் பட்டியலிட்டு இரண்டையும் ஒப்பிட்டுப் பார்க்கவும்.

Type=simple மற்றும் Type=exec ஆகியவற்றிற்கு இடையே உள்ள வேறுபாடு என்ன?

Type=simple-ல், binary இயக்கப்படுவதற்கு முன்பே, systemd process-ஐ உருவாக்கியவுடன் unit தொடங்கிவிட்டதாகக் கருதப்படும். எனவே ExecStart=-ல் தவறான path இருந்தால், start job வெற்றிகரமாக முடிந்ததாகக் காட்டிவிட்டு, பின் தோல்வியடையும். Type=exec, execution வெற்றிகரமாக முடியும் வரை காத்திருக்கும், எனவே தோல்வி start job-லேயே தெரிவிக்கப்படும். இவை இரண்டுமே ஒரே process-ஐ முதன்மை PID-ஆகக் கருதுகின்றன. Type=exec-க்கு systemd 240 அல்லது அதற்குப் பிந்தைய பதிப்பு தேவை.

Type=forking பயன்படுத்தும்போது PIDFile= இன்னும் தேவையா?

ஆம், daemon அதை எழுதும்போதெல்லாம் தேவை. அது இல்லையெனில், systemd GuessMainPID=-க்குத் திரும்பும்; இது ஒரு ஊகம் மட்டுமே, ஒரே ஒரு process-ஆகச் செயல்படும் service-களுக்கு மட்டுமே இது நம்பகமானது. ஊகம் தவறாகவோ அல்லது சாத்தியமற்றதாகவோ இருக்கும்போது, அந்த unit-க்கான தோல்வி கண்டறிதல் மற்றும் தானியங்கி மறுதொடக்கம் (automatic restarting) வேலை செய்யாது. PIDFile=-ஐ daemon எழுதும் சரியான path-க்குக் குறிவைக்கவும், இது பொதுவாக /run-ன் கீழ் இருக்கும்.

RemainAfterExit=yes-ஐ எப்போது பயன்படுத்த வேண்டும்?

ஒரு process-ஐத் தொடர்ந்து இயக்குவதை விட, system-ன் நிலையை மாற்றுவதே unit-ன் நோக்கமாக இருக்கும்போது இதைப் பயன்படுத்த வேண்டும். firewall விதிகளை ஏற்றும் அல்லது container stack-ஐத் தொடங்கும் ஒரு Type=oneshot unit, தனது வேலை முடிந்ததும் வெளியேறிவிடும். RemainAfterExit=yes இல்லையெனில், unit inactive நிலைக்குச் சென்றுவிடும்; இதனால் systemctl stop-க்கு நிறுத்த எதுவுமிருக்காது, மேலும் ExecStop= cleanup-ஐ இயக்க வழியும் இருக்காது. இதைச் சேர்த்தால், process-கள் இல்லாவிட்டாலும் unit active நிலையிலேயே இருக்கும், இதுவே இங்கு எதிர்பார்க்கப்படும் செயல்பாடு.

Type=-ஐ மாற்றினால் daemon-reload தேவையா?

ஆம், அத்துடன் unit-ஐ restart செய்வதும் அவசியம். systemctl daemon-reload, disk-ல் உள்ள unit கோப்புகளை மீண்டும் படிக்க systemd-ஐத் தூண்டும், ஆனால் இயங்கிக்கொண்டிருக்கும் instance தான் தொடங்கியபோது இருந்த Type=-ஐயே வைத்திருக்கும். சோதிப்பதற்கு முன் sudo systemctl daemon-reload-ஐ இயக்கி, பின் sudo systemctl restart app.service-ஐ இயக்கவும்; இல்லையெனில் நீங்கள் பழைய கண்காணிப்பு முறையையே கவனித்துக் கொண்டிருப்பீர்கள்.