systemd चा इतिहास आणि तो का यशस्वी झाला
SysV init च्या मर्यादा, Upstart आणि launchd चे आधीचे प्रयत्न, चार वर्षांत distributions ने systemd का स्वीकारले आणि कोणते आक्षेप योग्य होते हे जाणून घ्या.
systemd का यशस्वी ठरण्यामागील कारण
systemd चा इतिहास SysV init करू शकत नसलेल्या दोन गोष्टींपासून सुरू होतो. SysV init (System V init, AT&T Unix कडून Linux ला मिळालेली startup प्रणाली) मध्ये एखादी सेवा कोणत्या घटकांवर अवलंबून आहे हे सांगण्याची कोणतीही पद्धत नव्हती. सेवा सुरू झाल्यानंतर तिच्याशी संबंधित कोणत्या processes आहेत हे ओळखण्याचीही त्यात पद्धत नव्हती. systemd ने shell script ला उपलब्ध नसलेल्या kernel features वापरून या दोन्ही समस्यांचे निराकरण केले: processes चा मागोवा घेण्यासाठी control groups आणि ordering साठी आधीच उघडलेले listening sockets. पुढील इतिहासात ही दोन्ही उत्तरे userland च्या इतर भागांत कशी पसरली हे दिसते. याच टप्प्यावर आक्षेप सुरू झाले. त्यांपैकी काही आक्षेप योग्य होते.
SysV init ने प्रत्यक्षात काय केले
SysV प्रणालीवर PID 1 (process ID 1, kernel सुरू करणारी पहिली process) ने /etc/inittab वाचले, runlevel निवडला आणि त्या runlevel साठीची scripts चालवली. या scripts /etc/init.d/ मध्ये होत्या. /etc/rc3.d/ मधील symbolic links मुळे कोणत्या scripts चालतील आणि कोणत्या क्रमाने चालतील हे ठरत असे. त्यामुळे /etc/rc3.d/S20nginx हे /etc/init.d/nginx कडे निर्देश करत असे आणि त्याला start हा argument देऊन चालवले जात असे.
#!/bin/sh
### BEGIN INIT INFO
# Provides: nginx
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
### END INIT INFO
case "$1" in
start)
start-stop-daemon --start --quiet --pidfile /run/nginx.pid \
--exec /usr/sbin/nginx
;;
stop)
start-stop-daemon --stop --quiet --retry TERM/30/KILL/5 \
--pidfile /run/nginx.pid
;;
esacS20nginx मधील 20 ही dependency नसून क्रमातील स्थिती आहे. त्याचा अर्थ ही script S19 नंतर आणि S21 आधी चालते. यामागचे कारण त्यातून समजत नाही. त्यामुळे त्याची पडताळणी करता येत नाही. तसेच एखाद्या मानवाने ते सुरक्षित असल्याचे ठरवल्याशिवाय परस्पर असंबंधित दोन scripts सुरक्षितपणे एकाच वेळी चालवता येत नाहीत.
rc program प्रत्येक script क्रमाने चालवत असे आणि ती पूर्ण होईपर्यंत थांबत असे. Network address मिळवण्यासाठी तीस सेकंद थांबणारी एखादी script संपूर्ण boot प्रक्रिया तीस सेकंदांसाठी अडवत असे. Network वापरत नसलेल्या services सुद्धा यामुळे थांबत असत.
त्या script च्या सुरुवातीला असलेले LSB (Linux Standard Base) header ही समस्या प्रणालीच्या आतून सोडवण्याचा प्रयत्न होता. 2011 मध्ये Debian 6.0 ने insserv ला default केले. ते प्रत्येक script मधील Required-Start वाचत असे, dependency graph तयार करत असे आणि symlinks चे क्रमांक पुन्हा ठरवत असे. त्यामुळे Debian स्वतंत्र scripts startpar सह एकाच वेळी चालवू शकत असे. यामुळे काही सुधारणा झाली, परंतु मूलभूत समस्या दूर झाली नाही. Dependency अजूनही script पूर्ण होण्यावरच आधारित होती. S20nginx ने 0 परत करणे म्हणजे shell function ने परतावा दिला आहे. त्याचा अर्थ nginx connections स्वीकारत आहे असा होत नाही.
इनिट स्क्रिप्ट कोणत्याही प्रकारे दुरुस्त करू शकत नसलेल्या पाच गोष्टी
- समांतर startup. फाइलनावानुसार केलेला क्रम मशीनवरील प्रत्येक सेवेसाठी एकूण क्रम ठरवतो. त्यामुळे boot होण्यास सर्व सेवांच्या कालावधीइतका एकत्रित वेळ लागतो.
- Readiness. start script daemon ला fork केल्यानंतर संपते; daemon विनंती हाताळू शकेल तेव्हा नाही. त्यामुळे पुढील script अनेकदा खूप लवकर सुरू होते.
- Supervision. daemon दोनदा fork करतो आणि त्याची parent process बंद होते. त्यामुळे daemon terminal पासून वेगळा होतो आणि त्याला PID 1 कडे पुन्हा parent केले जाते. init ला child process बंद झाल्याचे दिसते, पण जिवंत राहिलेल्या process शी त्याचा विश्वासार्ह दुवा राहत नाही.
- On-demand start. inetd (internet super-server) कनेक्शन आल्यावर daemon सुरू करू शकत होते. पण ते स्वतंत्र configuration file असलेली वेगळी system होती. तसेच boot वेळी इतर सर्व सेवांच्या क्रमाबाबत ते काहीही करत नव्हते.
- Resource control. init script मधून एखाद्या सेवेची memory किंवा CPU मधील तिची share मर्यादित करता येत नव्हती.
ulimitएका process वर लागू होत होते आणिniceफक्त scheduler वर परिणाम करत होते. त्यामुळे सेवेतील नियंत्रणाबाहेर गेलेली child process मशीनवरील इतर कोणत्याही process प्रमाणेच दिसत होती.
Supervision मधील ही उणीव रोजच्या कामात सर्वाधिक त्रासदायक ठरत होती. PID file हा त्यावरील तात्पुरता उपाय होता: daemon त्याचा process ID /run/nginx.pid मध्ये लिहित असे आणि stop function ती file वाचत असे. daemon ला hard kill केले, तर file तशीच राहायची. त्यानंतर kernel तोच क्रमांक दुसऱ्या कशाला तरी देत असे आणि start-stop-daemon --stop --pidfile त्या क्रमांकाचा मालक असलेल्या कोणत्याही process कडे signal पाठवत असे. stale PID file मुळे init script चुकीची process बंद करते.
launchd ने socket ची समस्या आधीच सोडवली
Apple ने 2005 मध्ये Mac OS X 10.4 मध्ये Dave Zarzycki यांनी लिहिलेले launchd सादर केले. एका प्रक्रियेने init, rc, xinetd, crond आणि watchdogd यांची जागा घेतली.
अनुकरण करण्यासारखी कल्पना म्हणजे socket activation. launchd प्रथम प्रत्येक listening socket तयार करते आणि त्यानंतर daemons सुरू करते. अद्याप सुरू न झालेल्या daemon शी client जोडला, तरी connection refused मिळत नाही. कारण daemon ने accept() कॉल करेपर्यंत kernel ते connection त्या socket च्या backlog queue मध्ये ठेवते. दोन daemons मधील क्रम आता एखाद्या व्यक्तीने घोषित करण्याची बाब राहत नाही. तो socket ठरवतो.
launchd ची रचना Mach IPC (inter-process communication) वर आधारित होती. Mach IPC हे Apple च्या XNU kernel चा भाग असून त्याला Linux मध्ये समतुल्य सुविधा नाही. हा code port करणे कधीही व्यवहार्य नव्हते. तरीही ही कल्पना पुढे आली.
Upstart मध्ये event हे कामाचे एकक बनले
Scott James Remnant यांनी लिहिलेले Canonical चे Upstart ऑक्टोबर 2006 मध्ये Ubuntu 6.10 मध्ये प्रसिद्ध झाले. Fedora 9 ते Fedora 14 पर्यंतच्या आवृत्त्यांमध्ये ते वापरले गेले. RHEL 6 आणि Chrome OS मध्येही ते वापरले गेले. त्याने runlevel ऐवजी event वापरला. कोणते events आल्यावर job सुरू आणि बंद करायचे, हे job मध्ये नमूद केले जात असे.
# /etc/init/example.conf
start on filesystem and net-device-up IFACE!=lo
stop on runlevel [!2345]
respawn
respawn limit 10 5
exec /usr/local/bin/exampledJob ची संख्या वाढल्यावर दोन समस्या दिसून आल्या. पहिली समस्या म्हणजे दिशेची होती. एखादे job “हे घडल्यावर मला सुरू करा” असे सांगते. त्यामुळे कोणते घटक कशावर अवलंबून आहेत, याची माहिती चुकीच्या file मध्ये राहते. एखाद्या service ला तिला आवश्यक असलेल्या घटकांची माहिती असते; पण पुढील वर्षी कोणत्या घटकाला तिची गरज भासेल, हे तिला माहीत असू शकत नाही. नवीन service जोडताना अनेकदा एखाद्या विद्यमान job मध्ये बदल करून त्याने नवीन event emit करणे आवश्यक असे.
दुसरी समस्या म्हणजे tracking ची होती. Upstart ने forking daemon चा मागोवा घेण्यासाठी fork() calls ची संख्या ptrace ने मोजली. हे expect fork किंवा expect daemon म्हणून configure केले जात असे. Forks ची संख्या चुकीची दिल्यास Upstart आधीच exit झालेल्या process चे supervision करत राहते किंवा आधीच झालेल्या fork ची प्रतीक्षा करत राहते. त्याचे लक्षण म्हणजे initctl start कोणतीही error न दाखवता hang होणे. Job file मधून असे का झाले, हे स्पष्ट करण्याचा कोणताही मार्ग उपलब्ध नसतो.
Upstart साठी contributors ना Canonical च्या contributor agreement वर स्वाक्षरी करणेही आवश्यक होते. ही engineering fault नव्हती; मात्र त्यावर कोण काम करेल, यावर त्याचा परिणाम झाला.
PID 1 चा पुनर्विचार, April 2010
30 April 2010 रोजी Lennart Poettering यांनी "PID 1 चा पुनर्विचार" नावाची पोस्ट प्रकाशित केली. Kay Sievers यांनी त्यांच्यासोबत या प्रकल्पावर काम केले. या मांडणीचे चार भाग होते.
- कमी गोष्टी सुरू करा. एखादी सेवा प्रत्यक्षात मागितली जाईपर्यंत अनेक सेवा थांबू शकतात.
- socket द्वारे क्रम सूचित करता येत असेल, तर तो क्रम स्वतंत्रपणे घोषित करू नका. सर्व sockets एकाच टप्प्यात उघडा आणि त्यानंतर सर्व काही एकाच वेळी सुरू करा.
- PID files ऐवजी control groups वापरून processes चा मागोवा घ्या.
- सेवा declarative file मध्ये वर्णन करा, जेणेकरून एकच वर्णन प्रत्येक distribution वर कार्य करेल.
त्या वर्षी पहिला release आला. Fedora 14 ने November 2010 मध्ये systemd हा पर्याय म्हणून उपलब्ध केला आणि Fedora 15 ने May 2011 मध्ये त्याला default केले.
cgroups मुळे supervision विश्वसनीय का झाले
cgroup (control group) हे processes चे गट तयार करण्यासाठी kernel चे वैशिष्ट्य आहे. ते 2008 मध्ये Linux 2.6.24 मध्ये समाविष्ट झाले. systemd प्रत्येक service ला स्वतंत्र cgroup मध्ये ठेवते. एखाद्या child ला त्याच्या parent चा cgroup वारशाने मिळतो. unprivileged process स्वतःला त्या cgroup मधून बाहेर हलवू शकत नाही. त्यामुळे double forking मुळे काहीही लपून राहत नाही. PID 1 कडे unit शी संबंधित processes चा अचूक संच नेहमी उपलब्ध असतो. service थांबवणे म्हणजे तिच्या cgroup मधील सर्व processes kill करणे. हेच default KillMode=control-group करते.
systemctl status हा group दाखवतो:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running) since Tue 2026-08-11 09:14:22 UTC; 3min ago
Main PID: 1042 (nginx)
Tasks: 3 (limit: 4653)
Memory: 6.1M (peak: 7.4M)
CGroup: /system.slice/nginx.service
├─1042 "nginx: master process /usr/sbin/nginx"
├─1043 "nginx: worker process"
└─1044 "nginx: worker process"stale PID file ची हीच संपूर्ण कारणमीमांसा आहे. stale होणारी कोणतीही file नसते, कारण ही यादी kernel state असते.
याच tree मध्ये limits देखील असतात, कारण cgroups tracking साठी वापरण्यापूर्वी accounting साठी तयार करण्यात आले होते. MemoryMax=, CPUQuota= आणि TasksMax= प्रत्येकी एका ओळीचे आहेत. एखाद्या service वर कठोर memory आणि CPU cap लावणे आज drop-in file द्वारे करता येते; 2009 मध्ये त्यासाठी कुणीही न लिहिलेल्या shell script मध्ये patch करावा लागला असता.
2011 ते 2015 दरम्यान प्रत्येक वितरणाने का बदल केला
- Fedora 15, May 2011.
- openSUSE 12.1, November 2011.
- Mageia 2, May 2012.
- Arch Linux, October 2012 पासून नवीन installations साठी default.
- RHEL 7, June 2014.
- SLES 12, October 2014.
- Debian 8, April 2015.
- Ubuntu 15.04, April 2015.
यामागची कारणे मुख्यतः साधी होती. त्यामुळे हा बदल जलद झाला.
- प्रत्येक distribution वर एकच unit file कार्य करते. त्यामुळे upstream projects ने
.servicefile वितरित करणे सुरू केले आणि distributions ने प्रत्येक package आणि प्रत्येक release साठी स्वतंत्र shell script maintain करणे थांबवले. - 2012 च्या आसपास ConsoleKit चे maintenance थांबल्यानंतर desktop session tracking
systemd-logindकडे हलवण्यात आले. GNOME ला logind आवश्यक होते. त्यामुळे systemd नसलेल्या distribution ला पर्याय शोधावा लागला. तो पर्यायelogindहोता. हे systemd मधील logind वेगळे काढून स्वतंत्रपणे maintain केलेले आहे. - Device manager असलेले udev April 2012 मध्ये systemd च्या source tree मध्ये merge करण्यात आले. udev वितरित करणाऱ्या distributions आता systemd च्या repository चा मागोवा घेत होत्या. त्याला प्रतिसाद म्हणून Gentoo ने
eudevfork केले. - Containers मुळे process tracking आणि प्रत्येक service साठी limits अधिक महत्त्वाच्या ठरल्या, कारण दोन्ही cgroup ची features आहेत. Container process वर कोणता supervisor नियंत्रण ठेवतो, हा प्रश्न अजूनही महत्त्वाचा आहे, विशेषतः तुम्ही Docker Compose stack reboot नंतर पुन्हा सुरू करता तेव्हा.
Debian चा निर्णय सर्वाधिक चर्चेत राहिला. Technical Committee ने February 2014 मध्ये मतदान केले. मतदान समान झाले आणि chair Bdale Garbee यांनी systemd च्या बाजूने निर्णायक मत दिले. त्यानंतर काही दिवसांनी Ubuntu ने Upstart सुरू ठेवण्याऐवजी Debian चे अनुसरण करणार असल्याचे जाहीर केले. Debian developers च्या एका गटाने November 2014 मध्ये distribution चे Devuan म्हणून fork केले आणि May 2017 मध्ये Devuan 1.0 release केले.
आक्षेप योग्य पद्धतीने मांडलेले
व्याप्ती. आता एका प्रकल्पामध्ये PID 1, logging daemon, login session management, device manager, network configuration daemon, DNS (domain name system) resolver, NTP (network time protocol) client, container runner आणि boot loader यांचा समावेश आहे. ही स्वतंत्र binaries आहेत आणि त्या install करणे आवश्यक नाही, हा नेहमीचा बचाव योग्य आहे; परंतु त्यामुळे आक्षेप दूर होत नाही. Desktop ला logind आवश्यक झाल्यावर आणि logind ला systemd च्या tree मधून वेगळे release केल्यावर निवड स्वेच्छेची राहत नाही. युक्तिवादातील coupling याचाच अर्थ होता आणि प्रत्यक्षात तसेच झाले.
Binary journal. journald plain text ऐवजी indexed binary format मध्ये लिहिते. Text log मध्ये नसलेल्या सुविधा येथे मिळतात: प्रति-unit आणि प्रति-priority filtering, structured fields, तसेच sending program बनावट तयार करू शकत नाही अशी metadata, कारण unit आणि cgroup journald स्वतः नोंदवते. journalctl -u nginx -p err --since "-1h" grep ऐवजी date regular expression वापरते. याची किंमतही वास्तविक आहे. ज्या मशीनला boot करता येत नाही, त्या मशीनवरील log rescue shell मधून less वापरून वाचता येत नाही. त्याऐवजी mounted disk कडे journalctl निर्देशित करा:
sudo journalctl --directory /mnt/var/log/journal --boot -1 --priority errयेथे आणखी एक समस्या आहे, जी लोकांच्या लक्षात सहसा एकदा अडचण आल्यानंतर येते. /var/log/journal अस्तित्वात नसल्यास journald logs /run/log/journal मध्ये ठेवते; हे memory आहे. ज्या मशीनवर ते अस्तित्वात नाही, तेथे reboot नंतर journalctl -b -1 दाखवण्यासाठी काहीही नसते. आणि तुम्हाला log ची सर्वाधिक गरज नेमकी त्याच वेळी असते. ते तपासा आणि दुरुस्त करा:
journalctl --disk-usage
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journaldjournalctl --disk-usage ने आता /var/log/journal अंतर्गत archived journals दाखवले पाहिजेत. Plain text देखील हवा असल्यास /etc/systemd/journald.conf मध्ये ForwardToSyslog=yes सेट करा आणि rsyslog install ठेवलेले असू द्या.
Boot ची debugging क्षमता. एखादे unit अडकल्यावर console वर एकच ओळ दिसते आणि त्यापुढे काहीही दिसत नाही:
[ *** ] A start job is running for Wait for Network to be Configured (1min 32s / no limit)पुढील तपासणीसाठी साधने उपलब्ध आहेत: अडकल्यावेळी systemctl list-jobs, त्यानंतर systemd-analyze blame आणि systemd-analyze critical-chain, तसेच kernel command line वर systemd.log_level=debug. या तक्रारीची योग्य मांडणी अशी आहे की sh माहीत असलेल्या कोणालाही init script सुरुवातीपासून शेवटपर्यंत वाचता येत होती; परंतु अडकलेल्या unit साठी कोणत्या डझनभर commands पैकी कोणता command वापरायचा हे माहीत असणे आवश्यक असते. ही वास्तविक किंमत आहे. प्रत्येक administrator साठी ती एकदाच चुकवावी लागते; परंतु अनेक administrators ना ती एकाच वेळी चुकवावी लागली.
सर्वांसाठी बदलणारा default. 2016 मधील systemd 230 ने logind चा default बदलला आणि logout वेळी उरलेल्या user processes ना terminate केले. Detached tmux आणि screen sessions सुरू करणारे session संपल्यावर बंद झाले. Distributions नी KillUserProcesses=no हे /etc/systemd/logind.conf मध्ये release केले आणि समर्थित उपाय loginctl enable-linger <user> आहे. एका प्रकल्पातील एका default मुळे लाखो लोक ज्या सवयीवर अवलंबून होते ती बदलली. "userland चा खूप मोठा भाग एकाच ठिकाणी असणे" याचा व्यवहारातील अर्थ हाच आहे.
Default dependency ही security surface असते. March 2024 मध्ये xz-utils मधील backdoor ने Debian आणि Ubuntu वरील sshd ला लक्ष्य केले. Upstream OpenSSH ला libsystemd शी link केलेले नाही. sshd ला systemd कडे readiness कळवता यावी म्हणून त्या distributions नी त्यात बदल करून libsystemd जोडले; आणि libsystemd मुळे liblzma जोडले गेले, जिथे backdoor होता. Readiness protocol स्वतः $NOTIFY_SOCKET मध्ये नमूद केलेल्या socket कडे पाठवला जाणारा एकच datagram आहे. त्यामुळे त्यासाठी library कधीही आवश्यक नव्हती. systemd ने याला प्रतिसाद म्हणून compression libraries dlopen सह load केल्या, त्यामुळे त्या आता default ने linked नसतात. याच प्रकारातील आणखी एक bug हेच स्वरूप दाखवतो: 2017 मध्ये digit ने सुरू होणारे User= value invalid मानले गेले आणि unit fail होण्याऐवजी root म्हणून चालले. त्यामुळे typo चे रूपांतर privilege escalation मध्ये झाले. नंतरच्या versions मध्ये unit सुरू करण्यास नकार दिला जातो.
तुमच्या systemctl prompt मधील इतिहास
वर दिलेली प्रत्येक समस्या आता तुम्ही वाचू शकता अशा फाइलमधील एका directive मध्ये रूपांतरित झाली आहे.
- Serial boot चे रूपांतर
After=आणिWants=मध्ये झाले, तरsystemd-analyze critical-chainमुळे तुमच्या boot ला प्रत्यक्षात कशामुळे विलंब झाला ते दिसते. - Readiness चे रूपांतर
Type=notifyमध्ये झाले. सेवा विनंत्या हाताळू शकते तेव्हा तीREADY=1हे$NOTIFY_SOCKETमध्ये लिहिते. जुन्या daemon साठीType=forkingआणिPIDFile=अजूनही वापरता येतात. PID file कधीच तयार झाली नाही तरstart operation timed out. Terminating.सह अपयशी होणारा हाच प्रकार आहे. - Supervision ची जबाबदारी cgroup कडे गेली. त्यामुळे wrapper script ऐवजी
Restart=on-failureआणिRestartSec=वापरता येतात. Crash loop अनंत काळ चालू राहू नये यासाठीStartLimitBurst=वापरता येते. - inetd चे रूपांतर
.socketunit मध्ये झाले. हा unit.serviceunit च्या शेजारी राहतो. ulimitया init script मधील line चे रूपांतरMemoryMax=,CPUQuota=आणिTasksMax=मध्ये झाले.- Init script मधील
su - appuser -cline चे रूपांतरUser=,NoNewPrivileges=yesआणिProtectSystem=strictमध्ये झाले. त्यामुळे unprivileged user म्हणून सेवा चालवणे हे unit चे default स्वरूप आहे; त्यासाठी अतिरिक्त काम करावे लागत नाही.
[Unit]
Description=Example API
Wants=network-online.target
After=network-online.target postgresql.service
Requires=postgresql.service
[Service]
Type=notify
ExecStart=/usr/local/bin/exampled
Restart=on-failure
RestartSec=2
MemoryMax=512M
CPUQuota=50%
TasksMax=128
User=exampled
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
StateDirectory=exampled
[Install]
WantedBy=multi-user.targetत्या फाइलमधील एक line अशी आहे जिथे प्रत्येकजण एकदा तरी चूक करतो. Requires=postgresql.service ही requirement आहे, ordering नाही. याचा अर्थ Postgres बंद पडल्यास तुमचा unit fail होईल; Postgres आधी सुरू करा, असा त्याचा अर्थ नाही. After=postgresql.service नसल्यास दोन्ही एकाच वेळी सुरू होतात आणि तुमची सेवा अशा port शी connect करण्याचा प्रयत्न करते जिथे अद्याप काहीही listening करत नसते. हे दोन्ही मुद्दाम स्वतंत्र ठेवले आहेत, कारण कधी कधी तुम्हाला त्यांपैकी फक्त एकाची गरज असते. ProtectSystem=strict या सेवेसाठी file system read-only mount करते. म्हणून StateDirectory= आहे: ते /var/lib अंतर्गत सेवेसाठी एक writable path देते.
2026 मध्ये चालू असलेल्या server वर 2005 पाहण्याचे सर्वात स्पष्ट उदाहरण Ubuntu 24.04 वरील SSH आहे. August 2026 पर्यंत त्यासोबत systemd 255 येते. ssh.service हे default ने socket activated असते: ssh.socket listening socket ठेवते आणि connection आल्यावर sshd सुरू करते. त्यामुळे /etc/ssh/sshd_config मधील Port 2222 चा काही परिणाम होत नाही, कारण port उघडणारी process sshd नसते. हा बदल socket unit मध्ये करावा लागतो.
sudo systemctl edit ssh.socket[Socket]
ListenStream=
ListenStream=2222रिकामे ListenStream= packaged unit मधून inherited value काढून टाकते. ते वगळल्यास दोन्ही ports मिळतात, कारण systemd list बदलून लिहिण्याऐवजी त्यात value जोडते. त्यानंतर apply करून तपासा. संपूर्ण प्रक्रियेदरम्यान दुसरे SSH session उघडे ठेवा:
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
sudo ss -lntp | grep 2222ss मध्ये port 2222 वर एकच socket दिसला पाहिजे. त्याचा मालक systemd असला पाहिजे, sshd नाही. तुमच्या VPS वर वीस वर्षांनंतर दिसणारी ही launchd ची रचना आहे. जुने behaviour हवे असल्यास sudo systemctl disable --now ssh.socket नंतर sudo systemctl enable --now ssh.service चालवा. यामुळे दीर्घकाळ चालणारा sshd सुरू होईल आणि तो पुन्हा स्वतःच्या config मधून Port वाचेल.
तुम्ही यांपैकी कोणते तपशील पाहाल हे तुम्ही चालवत असलेल्या release वर अवलंबून असते. त्यामुळे upgrade चे नियोजन करण्यापूर्वी LTS आणि interim Ubuntu release मधील फरक जाणून घेणे उपयुक्त ठरते. एकापेक्षा अधिक machine वर unit file सर्वत्र समान असणे हेच एकाच ठिकाणाहून अनेक server व्यवस्थापित करणे आता configuration problem का आहे, shell scripting problem का नाही, याचे कारण आहे. तसेच स्वतःचे unit लिहिताना service आणि timer ची जोडी 2009 मध्ये init script आणि cron line यांच्यात विभागलेले काम करते.
FAQ
Linux distributions ने SysV init ऐवजी systemd का वापरायला सुरुवात केली?
यामागे दोन अभियांत्रिकी कारणे आणि एक देखभालीचे कारण होते. SysV init सेवांचा क्रम filename नुसार लावत असे. हा क्रम dependency ऐवजी स्थानावर आधारित होता. तसेच parent कडून fork होऊन वेगळी झालेल्या daemon चा मागोवा तो गमावत असे. त्यामुळे कालबाह्य PID files मुळे चुकीची process बंद होऊ शकत असे. systemd ने socket activation आणि dependency directives वापरून ordering ची समस्या सोडवली. त्याने control groups वापरून process tracking ची समस्या सोडवली. देखभालीच्या कारणामुळे ही प्रक्रिया वेगाने झाली. प्रत्येक distribution वर एकच unit file चालते. त्यामुळे upstream projects ने .service file वितरित केली आणि distribution maintainers ने प्रत्येक package साठी स्वतंत्र shell script लिहिणे थांबवले. Fedora 15 ने May 2011 मध्ये systemd स्वीकारले. Ubuntu 15.04 हे April 2015 मध्ये systemd स्वीकारणारे शेवटचे मोठे distribution होते.
systemd हा एकच मोठा binary आहे का?
नाही. Source tree मधून अनेक स्वतंत्र programs तयार होतात. PID 1 हे /usr/lib/systemd/systemd आहे. journald, logind आणि udevd या स्वतंत्र binaries असलेल्या वेगळ्या processes आहेत. आपल्या system वर त्या पाहण्यासाठी ls /usr/lib/systemd/ चालवा. Binary च्या आकारापेक्षा release coupling विषयीची टीका अजूनही कायम आहे. हे programs एकत्र release केले जातात आणि private interfaces सामायिक करतात. त्यामुळे distributions त्यांना सहसा एक संच म्हणून स्वीकारतात. GNOME सारख्या software ला विशेषतः logind अपेक्षित राहू लागले.
मी अजूनही systemd शिवाय Linux चालवू शकतो का?
होय. Devuan मध्ये sysvinit वितरित केले जाते. Gentoo मध्ये OpenRC default आहे. Void मध्ये runit वापरले जाते. Alpine मध्ये OpenRC सोबत busybox init वापरले जाते. Slackware मध्ये BSD style scripts कायम आहेत. याची किंमत compatibility साठी करावे लागणारे अतिरिक्त काम आहे. logind अपेक्षित असलेल्या desktop software साठी elogind आवश्यक असते. हे systemd चे logind standalone package म्हणून maintain केलेले रूप आहे. तसेच आता वाढत्या प्रमाणात server software फक्त .service file वितरित करते. त्यामुळे startup script तुम्हालाच लिहावी आणि maintain करावी लागते.
journal plain text file ऐवजी binary का आहे?
कारण journald structured fields index सह साठवते. त्यामुळे per-unit filtering, priority filtering आणि sending program बनावट करू शकत नाही असा metadata उपलब्ध होतो. Log line वर विश्वास ठेवण्याऐवजी journald unit, cgroup आणि real UID स्वतः नोंदवते. याची किंमत अशी आहे की ते वाचण्यासाठी, rescue system मधूनही, तुम्हाला journalctl आवश्यक असते. अशा वेळी mounted disk कडे निर्देश करण्यासाठी journalctl --directory /mnt/var/log/journal वापरा. Text स्वरूपातही logs हवे असल्यास /etc/systemd/journald.conf मध्ये ForwardToSyslog=yes सेट करा.
माझी /etc/init.d script संपादित करण्याची जागा कशाने घेतली?
Drop-in files ने. /usr/lib/systemd/system/ मधील unit संपादित करू नका, कारण package upgrade ती overwrite करते. sudo systemctl edit nginx.service चालवा. systemd /etc/systemd/system/nginx.service.d/override.conf तयार करते आणि तो packaged unit वर लागू केला जातो. एकत्रित परिणाम systemctl cat nginx.service दाखवते. Machine वरील प्रत्येक override ची यादी systemd-delta देते. हाताने केलेल्या कोणत्याही edit नंतर sudo systemctl daemon-reload चालवा. अन्यथा पुढील command Warning: The unit file, source configuration file or drop-ins of nginx.service changed on disk. दाखवते.