systemd Type= simple, forking, notify: योग्य पर्याय
unit active असूनही daemon बंद का दिसतो ते समजा. simple, exec, forking, oneshot आणि notify मधून योग्य Type= निवडा आणि खरा main PID शोधा.
systemd प्रक्रिया बंद झाल्यानंतरही unit सक्रिय असल्याचे का दाखवते
systemd service unit मध्ये systemd ने main process म्हणून ओळखलेली एकमेव प्रक्रिया जिवंत असेपर्यंत ती active राहते. कोणती प्रक्रिया main process मानायची हे Type= मधील [Service] ठरवते. चुकीचे मूल्य निवडल्यास systemd shell wrapper किंवा अल्पकाळ टिकणाऱ्या parent प्रक्रियेवर लक्ष ठेवते, तर तुम्हाला आवश्यक असलेला daemon त्याच unit मध्ये बंद होतो. systemd ला ज्या प्रक्रियेवर लक्ष ठेवण्यास सांगितले आहे, तिच्याबद्दल unit अचूक स्थिती दाखवत असते.
restart policy बदलल्याने ही समस्या सुटणार नाही. main process बंद झाल्यावरच Restart= कार्य करते. त्यामुळे main PID (process identifier) अजूनही चालू असलेल्या प्रक्रियेचा असल्यास Restart=always कधीच कार्यान्वित होत नाही. आधी Type= दुरुस्त करा. main process प्रत्यक्षात बंद झाल्यानंतर systemd काय करते, हा स्वतंत्र निर्णय आहे. त्यासाठी Restart= आणि RestartSec= वरील मार्गदर्शक पहा.
Type= नेमके काय ठरवते
प्रत्येक Type= value एकाच वेळी दोन प्रश्नांची उत्तरे देते. systemd या unit ला सुरू झालेले कधी मानू शकते, आणि मुख्य process कोणता आहे.
पहिले उत्तर ordering नियंत्रित करते. After= मध्ये तुमच्या unit चे नाव देणारी unit systemd तुमची unit सुरू झाल्याचे घोषित करेपर्यंत थांबते. "started" खूप लवकर कळवणारा Type= dependent units ना तुमची service विनंत्यांना प्रतिसाद देण्यापूर्वीच सुरू होऊ देतो.
दुसरे उत्तर supervision नियंत्रित करते. unit ने सुरू केलेला प्रत्येक process systemd cgroup (control group) मध्ये ठेवते. ही processes एकत्रितपणे मर्यादित आणि बंद करता यावीत यासाठी processes चे गट करणारी kernel सुविधा आहे. systemctl stop cleanup करण्यासाठी cgroup वापरते: KillMode= चे default control-group असते, त्यामुळे unit थांबवताना तिच्या आत असलेल्या प्रत्येक process ला signal पाठवला जातो. मुख्य PID अधिक मर्यादित असतो. तो एकच process असतो; तो process बंद झाल्यावर unit समाप्त होते आणि त्याचा exit status unit चा result बनतो. cgroup ला main PID समजून वाचल्यापासून हा गोंधळ सुरू होतो.
Type=simple binary चालवण्यापूर्वीच सेवा सुरू झाल्याचे दाखवते
Type=simple हे default असते, जेव्हा ExecStart= सेट केलेले असते आणि Type= किंवा BusName= यांपैकी काहीही उपस्थित नसते. systemd process तयार करते, unit लगेच सुरू झाल्याचे मानते आणि त्या process ला मुख्य PID म्हणून हाताळते. सेवा binary प्रत्यक्षात execute होण्यापूर्वीच पुढील units सुरू होतात.
शेवटचा तपशील एका सामान्य अनपेक्षित परिस्थितीचे कारण स्पष्ट करतो. ExecStart= path मध्ये typo असला, तरी start job यशस्वी झाल्याचे दिसते. Execution अयशस्वी झाल्यावर क्षणभराने failure दिसतो. systemd ही स्थिती exit code 203 सह नोंदवते. त्याच्या स्वतःच्या तक्त्यात याला EXEC असे नाव दिले आहे आणि सेवा binary execute करण्यात अपयश अशी त्याची व्याख्या केली आहे. त्यामुळे systemctl start error शिवाय परत आल्याने तुमचे binary अस्तित्वात आहे हे सिद्ध होत नाही.
Foreground मध्ये राहणाऱ्या आणि स्वतःला background मध्ये न हलवणाऱ्या program साठी simple वापरा. यात आधुनिक daemons पैकी बहुतेक आणि तुम्ही स्वतः लिहिलेली जवळजवळ कोणतीही सेवा येते.
Type=exec प्रत्यक्षपणे प्रोग्राम सुरू होईपर्यंत प्रतीक्षा करते
Type=exec हे simple सारखेच आहे, परंतु त्यात आणखी एक टप्पा आहे. fork आणि binary चे execution दोन्ही यशस्वी झाल्यानंतरच systemd unit सुरू झाली असे मानते. binary उपलब्ध नसल्यास किंवा User= चे आता निराकरण करता येत नसल्यास start job स्वतःच अयशस्वी होते. यामुळे सुरुवातीला यशस्वी झाल्याचे दाखवून काही क्षणांनी शांतपणे अयशस्वी होण्याची स्थिती टळते.
Type=exec systemd 240 मध्ये आले. त्यामुळे सध्याच्या प्रत्येक server distribution मध्ये ते उपलब्ध आहे. August 2026 पर्यंत Ubuntu 24.04 मध्ये systemd 255 आणि Debian 13 मध्ये systemd 257 उपलब्ध आहे. तुमची आवृत्ती systemctl --version ने तपासा.
यासाठी सुरू करताना एक अतिरिक्त synchronisation टप्पा लागतो. त्याचा फायदा म्हणजे systemctl start कडून प्रामाणिक exit status मिळतो. Foreground program साठी simple ऐवजी exec वापरणे पसंत करा.
Type=forking आणि मुख्य PID कसा हरवतो
Type=forking systemd ला सांगते की ExecStart= मधील प्रक्रिया child प्रक्रिया fork करेल आणि त्यानंतर जाणीवपूर्वक बाहेर पडेल. systemd त्या पहिल्या प्रक्रियेच्या बाहेर पडण्याची वाट पाहते आणि त्यानंतरच unit सुरू झाल्याचे मानते. मागे राहिलेली child प्रक्रिया daemon असते.
अडचण ओळख निश्चित करण्याची असते. systemd ने सुरू केलेली प्रक्रिया संपलेली असल्यामुळे, उरलेल्या प्रक्रियांपैकी मुख्य प्रक्रिया कोणती आहे हे systemd ला ठरवावे लागते. PIDFile= मध्ये daemon लिहित असलेली फाइल द्या. सामान्यतः हा /run अंतर्गत असलेला path असतो. त्यानंतर systemd त्या फाइलमधून PID वाचते. त्या फाइलमधील PID आधीपासून या सेवेचा भाग असलेल्या प्रक्रियेकडे निर्देश करतो का, हेही systemd तपासते. त्यामुळे असंबंधित प्रक्रियेचे नाव असलेली stale फाइल स्वीकारली जात नाही.
PIDFile= नसल्यास GuessMainPID= लागू होते आणि त्याची default value yes असते. सेवा एका प्रक्रियेत स्थिरावते तेव्हाच हा अंदाज विश्वासार्ह असतो. Manual मध्ये ही मर्यादा स्पष्टपणे दिली आहे: daemon मध्ये एकापेक्षा जास्त प्रक्रिया असल्यास अंदाज चुकीचा ठरू शकतो आणि failure detection काम करणे थांबवते. Unit चा मुख्य PID 0 देखील होऊ शकतो. याचा अर्थ systemd कडे supervise करण्यासाठी कोणतीही प्रक्रिया उरत नाही.
Fork करणाऱ्या बहुतेक daemons मध्ये त्यांना foreground मध्ये ठेवणारा switch देखील असतो. तो switch Type=exec सोबत वापरा आणि PIDFile= ही line काढून टाका. घटकांची संख्या कमी असल्यामुळे PID हरवण्याचे मार्गही कमी होतात.
पूर्ण होऊन बाहेर पडणाऱ्या कामासाठी Type=oneshot
Type=oneshot प्रक्रियेने चालून बाहेर पडणे अपेक्षित असते. प्रक्रिया बाहेर पडल्यानंतरच systemd युनिट सुरू झाल्याचे मानते. त्यामुळे दुसऱ्या युनिटने ज्याची वाट पाहणे आवश्यक आहे, अशा कोणत्याही कामासाठी oneshot हा योग्य प्रकार आहे. युनिटमध्ये Type= किंवा ExecStart= यापैकी काहीही निर्दिष्ट केलेले नसल्यास हाच सूचित default असतो.
oneshot शी संबंधित दोन वर्तन विशेष आहेत. एकापेक्षा अधिक ExecStart= ओळी स्वीकारणारा हा एकमेव प्रकार आहे. त्या ओळी क्रमाने चालवल्या जातात. याचा start timeout देखील default ने disabled असतो. त्यामुळे अडकलेला oneshot स्वतः TimeoutStartSec= सेट करेपर्यंत अनिश्चित काळ प्रतीक्षा करतो.
प्रक्रिया बाहेर पडल्यानंतर युनिट inactive स्थितीत परतते. RemainAfterExit=yes कोणतीही प्रक्रिया चालू नसतानाही त्याला active ठेवते. या पृष्ठाच्या सुरुवातीला वर्णन केलेल्या लक्षणाची ही जाणीवपूर्वक केलेली आवृत्ती आहे. युनिटचे काम एखादी स्थिती तयार करून ठेवणे, सतत काहीतरी चालू ठेवणे नव्हे, असेल तेव्हा हे योग्य असते. उदाहरणार्थ, firewall ruleset लोड करणे किंवा container stack सुरू करणे. रीबूटनंतर परत सुरू होणाऱ्या Docker Compose stack मागील पद्धत हीच आहे. युनिट compose command चालवते, बाहेर पडते आणि त्याने सुरू केलेले containers त्याच्यापेक्षा जास्त काळ चालू राहत असल्यामुळे active राहते. schedule कडून सुरू केले जाणारे काम देखील oneshot युनिटचेच असते. हे cron ऐवजी systemd timer वर job चालवण्याच्या पद्धतीचे दुसरे अंग आहे.
Type=notify वापरल्याने सेवा तयार झाल्याचे सांगू शकते
Type=notify निर्णय सेवेवर सोपवते. Unix socket वर प्रक्रिया NOTIFY_SOCKET environment variable मधून मिळालेल्या path वर READY=1 पाठवेपर्यंत systemd start job सुरू ठेवते. C interface sd_notify(3) आहे आणि अनेक servers त्याला आधीपासून support करतात.
"is it started" या प्रश्नाचे हे अचूक उत्तर आहे. simple आणि exec सेवा configuration वाचण्यापूर्वी किंवा listening socket उघडण्यापूर्वीच started असल्याचे कळवतात. त्यामुळे dependent unit खूप लवकर सुरू होऊ शकते आणि तिचे पहिले connection fail होऊ शकते. notify मध्ये सेवा स्वतः तयार असल्याचे सांगते त्याच क्षणी ती started असल्याचे कळवले जाते.
systemd हा message फक्त main process कडून स्वीकारते. NotifyAccess=main याचा अर्थ हाच आहे आणि Type=notify हे त्याचा संकेत देते. Message child किंवा helper कडून येत असल्यास NotifyAccess=all सेट करा. Shell script systemd-notify --ready call करू शकते. मात्र ते स्वतंत्र short-lived process म्हणून चालते. त्यामुळे NotifyAccess=all आवश्यक असते आणि message पाठवणारा process आधीच exit झालेला असल्यास systemd ला तो message कोणाकडून आला हे कदाचित ठरवता येणार नाही. Protocol स्वतः implement करणारी सेवा अधिक विश्वासार्ह असते.
या विषयाशी संबंधित आणखी दोन settings माहिती असणे उपयुक्त आहे. systemd 253 पासून उपलब्ध असलेले Type=notify-reload हेच handshake reloads साठी लागू करते. त्यामुळे signal पाठवल्यानंतर लगेच return होण्याऐवजी सेवा reload पूर्ण झाल्याचे कळवल्यावर systemctl reload return करते. WatchdogSec= notifying service ला ठरावीक interval ने keep-alive message पाठवण्यास सांगते. Deadline चुकल्यास systemd त्याला failure मानते.
Type=dbus आणि Type=idle
Type=dbus ही सेवा system आणि desktop सेवा परस्परांशी संवाद साधण्यासाठी वापरत असलेल्या message bus, म्हणजे D-Bus वर नाव नोंदवेपर्यंत प्रतीक्षा करते. यासाठी BusName= आवश्यक आहे आणि BusName= सेट केल्यावर ते default होते. बस नावाची प्रत्यक्ष नोंदणी करणाऱ्या सेवेसाठीच याचा वापर करा.
Type=idle हे simple प्रमाणेच कार्य करते. मात्र queued jobs dispatch होईपर्यंत program चालवण्यास विलंब करते आणि हा विलंब जास्तीत जास्त five seconds असतो. Boot वेळी console output status messages मध्ये मिसळू नये यासाठी हे उपलब्ध आहे. हे ordering tool नाही आणि सामान्य service मध्ये याचा वापर करू नये.
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 9101systemd shell ला मुख्य PID म्हणून नोंदवते. exporter foreground मध्ये चालू असताना shell जिवंत राहते. server बंद पडल्यास shell ला त्याची जाणीव होत नाही. त्यामुळे मुख्य PID अजूनही जिवंत असतो, unit अजूनही active असते आणि Restart= कडे कारवाई करण्यासाठी काहीही नसते. दोन्ही प्रक्रिया संपूर्ण काळ unit च्या cgroup मध्ये असतात. त्यामुळे systemctl stop अजूनही cleanup योग्य प्रकारे करते. बिघडलेली गोष्ट supervision आहे; cleanup नाही.
ही दुरुस्ती unit मध्ये प्रत्यक्षात किती दीर्घकाळ चालणाऱ्या प्रक्रिया आहेत यावर अवलंबून असते.
एकच प्रक्रिया असल्यास, shell च्या जागी ती प्रक्रिया सुरू करा.
#!/bin/bash
export APP_ENV=production
exec /opt/app/bin/server --config /etc/app.yamlexec shell च्या जागी दिलेला program सुरू करते आणि तोच PID कायम ठेवते. त्यामुळे systemd ने नोंदवलेला PID आता daemon चा असतो. त्याहून चांगले म्हणजे wrapper काढून टाका. Environment= आणि EnvironmentFile= variables पुरवतात, तर ExecStartPre= setup step पुरवते. त्यामुळे systemd daemon थेट सुरू करू शकते आणि त्याचा PID सुरुवातीपासूनच अचूकपणे ओळखू शकते.
दोन प्रक्रिया असल्यास, कोणताही एक PID संपूर्ण unit चे प्रतिनिधित्व करत नाही. त्या दोन स्वतंत्र units मध्ये विभाजित करा आणि After= व Wants= वापरून त्यांचा क्रम निश्चित करा. प्रत्येक प्रक्रियेसाठी एक unit ही systemd चांगल्या प्रकारे supervise करू शकणारी रचना आहे. तसेच प्रत्येक प्रक्रियेला स्वतःचे restart behaviour मिळवण्याचा हा एकमेव मार्ग आहे.
ExitType=cgroup मध्ये होणारे बदल
ExitType= हे systemd 250 मध्ये जोडले गेले. डीफॉल्ट मूल्य 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 संपूर्ण process group च्या स्थितीनुसार चालते.
यामुळे काय सुटत नाही, हे स्पष्टपणे समजून घ्या. ExitType=cgroup मुळे किमान एक process जिवंत असेपर्यंत unit active राहते. त्यामुळे दोन daemon धारण करणारी unit त्यांपैकी एक बंद झाल्यानंतरही active राहते. यामुळे launcher ची समस्या सुटते. मात्र एकाच unit ला अनेक स्वतंत्र process साठी supervisor बनवले जात नाही. ExitType= हे Type=oneshot सोबत वापरता येत नाही.
संसाधनांचे accounting देखील cgroup मध्येच नोंदवले जाते. त्यामुळे MemoryMax= आणि CPUQuota= सारख्या मर्यादा unit ने सुरू केलेल्या प्रत्येक process वर लागू होतात. मुख्य PID विषयी Type= काय सांगते, यावर त्याचा परिणाम होत नाही. या विषयाचा दुसरा भाग systemd वापरून सेवेची memory आणि CPU मर्यादित करणे येथे आहे.
systemd प्रत्यक्षात कोणत्या प्रक्रियेवर लक्ष ठेवते हे कसे शोधावे
तुम्ही डीबग करत असलेल्या unit वर हे टप्प्याटप्प्याने करा. आधी systemd ने काय लोड केले ते वाचा. त्यानंतर ते काय track करते ते वाचा. शेवटी त्याची तुलना process table शी करा.
systemctl cat app.service
systemctl show -p Type,ExitType,GuessMainPID,PIDFile,MainPID,RemainAfterExit app.servicesystemctl cat unit file आणि त्याला लागू होणारे सर्व drop-in एकत्र दाखवते. त्यामुळे तुम्ही संपादित केल्याचे आठवत असलेली file नव्हे, तर systemd ने प्रत्यक्षात लोड केलेली configuration वाचत आहात. systemctl show तुम्ही स्पष्टपणे नोंदवलेली नसलेली defaults यांसह effective values दाखवते. पुढे जाण्यापूर्वी MainPID चे value नोंदवा.
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 line systemd ज्या एकमेव process वर देखरेख ठेवते तिचे वर्णन करते. या दोन्ही गोष्टी एकत्र वाचा. MainPID चे value 0 असल्यास systemd कडे देखरेख ठेवण्यासाठी कोणतीही process नाही. cgroup मध्ये तुमचा daemon असतानाही MainPID shell कडे resolve होत असल्यास, वर वर्णन केलेली wrapper स्थिती आहे. अपेक्षेपेक्षा अधिक processes असलेला cgroup असल्यास launcher किंवा forking daemon वापरला जात आहे.
systemctl status app.service
journalctl -u app.service -bsystemctl status state line आणि cgroup tree एकत्र दाखवते. त्यामुळे दोन्ही प्रश्नांची उत्तरे अनेकदा एकाच वेळी मिळतात. journalctl -u ला -b सह केवळ या boot पुरते मर्यादित केल्यास, systemd ने त्या unit साठी नोंदवलेल्या start आणि stop events, तसेच त्याने पाहिलेले exit codes दिसतात. daemon स्वतःच्या log file मध्ये लिहित असल्यास ती file देखील वाचा, कारण systemd पर्यंत पोहोचलेली माहितीच ते नोंदवू शकते.
तुम्ही Type= बदलल्यास reload आणि restart करा.
systemd-analyze verify /etc/systemd/system/app.service
sudo systemctl daemon-reload
sudo systemctl restart app.servicesystemd-analyze verify file parse करते आणि स्वीकारता न येणाऱ्या settings कळवते. daemon-reload systemd ला disk वरील unit files पुन्हा वाचण्यास सांगते. बदललेले Type= आधीपासून चालू असलेल्या unit ला लागू होत नाही. त्यामुळे restart आवश्यक आहे; तो ऐच्छिक नाही.
त्यानंतर बदलाची चाचणी करा. systemd-cgls मधून तुम्हाला प्रत्यक्ष महत्त्वाच्या असलेल्या process चा PID घ्या आणि तिला kill करा. लगेच systemctl is-active app.service चालवा. Type= योग्य असल्यास unit active state मधून बाहेर पडते. ती active राहिल्यास systemd अजूनही दुसऱ्या कशावर तरी लक्ष ठेवत आहे.
कोणता systemd service Type= वापरावा
- foreground मध्ये सुरू राहणारा प्रोग्राम:
Type=exec. - readiness notification ला समर्थन देणारा प्रोग्राम:
Type=notify; तसेच reload ची पुष्टीही करत असल्यासnotify-reload. - background मध्ये जाण्याचा आग्रह धरणारा daemon:
PIDFile=सहType=forking, किंवाType=execसह त्याचा foreground पर्याय. - काम करून बाहेर पडणारी script:
Type=oneshot; स्थिती शिल्लक ठेवणे हा उद्देश असल्यासRemainAfterExit=yesदेखील वापरा. - child processes सुरू ठेवून स्वतः बाहेर पडणारा launcher:
ExitType=cgroupसहType=simple.
तृतीय-पक्ष daemon साठी कोणता पर्याय आवश्यक आहे याची खात्री नसल्यास, प्रथम त्यासोबत आलेली unit file वाचा. वितरणाने पुरवलेल्या unit वर systemctl cat चालवल्यास upstream ने निवडलेला Type= दिसतो. हा पर्याय तुमच्या स्वतःच्या निवडीपेक्षा अधिक लोकांनी तपासलेला असतो.
FAQ
माझे systemd unit प्रक्रिया बंद झाल्यानंतरही active का राहते?
कारण systemd मुख्य प्रक्रिया म्हणून ज्या प्रक्रियेला मानते ती अजूनही चालू असते. systemd unit च्या cgroup मधील प्रत्येक प्रक्रियेऐवजी सेवेसाठी Type= नुसार निवडलेल्या एका PID वर लक्ष ठेवते. Type=simple वापरून सुरू केलेली wrapper script हे याचे नेहमीचे कारण आहे: shell हा मुख्य PID असतो. त्यामुळे shell ने background मध्ये सुरू केलेला daemon बंद झाला तरी unit active राहते. systemctl show -p MainPID app.service चालवा. त्यानंतर systemd-cgls --unit=app.service वापरून unit चे cgroup सूचीबद्ध करा आणि दोन्हींची तुलना करा.
Type=simple आणि Type=exec यांच्यात काय फरक आहे?
Type=simple मध्ये systemd ने प्रक्रिया तयार करताच unit सुरू झाल्याचे मानले जाते. Binary execute होण्यापूर्वीच हे घडते. त्यामुळे ExecStart= मधील चुकीचा path असला तरी start job यशस्वी झाल्याचे दिसते आणि त्यानंतर failure येतो. Type=exec मध्ये execution यशस्वी होईपर्यंत प्रतीक्षा केली जाते. त्यामुळे failure स्वतः start job कडून नोंदवला जातो. दोन्ही प्रकारांमध्ये तीच प्रक्रिया मुख्य PID म्हणून मानली जाते. Type=exec साठी systemd 240 किंवा त्यानंतरची आवृत्ती आवश्यक आहे.
Type=forking सोबत PIDFile= अजूनही आवश्यक आहे का?
होय, daemon PIDFile लिहित असल्यास ते आवश्यक आहे. ते नसल्यास systemd GuessMainPID= वर अवलंबून राहते. हा अंदाज असतो आणि एका प्रक्रियेत स्थिरावणाऱ्या सेवेसाठीच तो विश्वसनीय असतो. अंदाज चुकीचा ठरल्यास किंवा लावता न आल्यास त्या unit साठी failure detection आणि automatic restarting काम करणे थांबवतात. PIDFile= मध्ये daemon लिहित असलेला अचूक path द्या. हा path सामान्यतः /run अंतर्गत असतो.
RemainAfterExit=yes कधी वापरावे?
Unit चा उद्देश प्रक्रिया चालू ठेवणे नसून system state बदलणे असेल तेव्हा ते वापरावे. Firewall rules लोड करणारे किंवा container stack सुरू करणारे Type=oneshot unit काम पूर्ण होताच बंद होते. RemainAfterExit=yes नसल्यास unit inactive होते. त्यामुळे systemctl stop कडे थांबवण्यासाठी काहीही राहत नाही आणि ExecStop= cleanup चालवण्याचीही कोणतीही संधी राहत नाही. RemainAfterExit=yes असल्यास कोणतीही प्रक्रिया नसतानाही unit active राहते. या परिस्थितीत हेच अपेक्षित असते.
Type= बदलण्यासाठी daemon-reload आवश्यक आहे का?
होय. त्यासोबत unit restart करणेही आवश्यक आहे. systemctl daemon-reload मुळे systemd disk वरील unit files पुन्हा वाचते. मात्र चालू instance सुरू होताना वापरलेले Type= कायम ठेवते. चाचणी करण्यापूर्वी sudo systemctl daemon-reload आणि त्यानंतर sudo systemctl restart app.service चालवा. अन्यथा तुम्ही अजूनही जुन्या supervision behaviour वर लक्ष ठेवत असाल.