SSD Nodes Learn 🎉 VPS $5.50/माह से
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-12

systemd का इतिहास और इसकी सफलता के मुख्य कारण

SysV init की सीमाओं से लेकर systemd के प्रभुत्व तक का सफर जानें। यह लेख बताता है कि कैसे control groups और socket activation ने Linux जगत को चार वर्षों में पूरी तरह बदल दिया।

systemd क्यों सफल हुआ

systemd का इतिहास उन दो चीजों से शुरू होता है जिन्हें SysV init नहीं कर सकता था। SysV init (System V init, वह startup system जिसे Linux ने AT&T Unix से विरासत में प्राप्त किया था) के पास यह बताने का कोई तरीका नहीं था कि कोई service किस पर निर्भर करती है, और यह जानने का भी कोई तरीका नहीं था कि चलने के बाद कौन सी processes किसी service का हिस्सा हैं। systemd ने इन दोनों समस्याओं का समाधान उन kernel features के साथ दिया जो shell script की पहुँच से बाहर थे: processes को ट्रैक करने के लिए control groups, और services के क्रम को निर्धारित करने के लिए पहले से खुले (pre-opened) listening sockets। बाकी कहानी यह है कि कैसे वे दो समाधान बाकी userland में फैल गए, जहाँ से आपत्तियाँ शुरू हुईं, और उनमें से कई आपत्तियाँ सही थीं।

SysV init वास्तव में क्या करता था

एक SysV सिस्टम पर, PID 1 (process ID 1, वह पहला process जिसे kernel शुरू करता है) /etc/inittab को पढ़ता था, एक runlevel चुनता था, और उस runlevel के लिए scripts चलाता था। ये scripts /etc/init.d/ में स्थित होती थीं। /etc/rc3.d/ में मौजूद symbolic links यह तय करते थे कि कौन सी script कब और किस क्रम में चलेगी, इसलिए /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
    ;;
esac

S20nginx में मौजूद 20 एक स्थान है, न कि कोई dependency। यह बताता है कि यह script S19 के बाद और S21 से पहले चलती है। यह यह नहीं बताता कि ऐसा क्यों है, इसलिए कोई भी सिस्टम इसकी जाँच नहीं कर सकता, और कोई भी सुरक्षित रूप से दो असंबंधित scripts को एक साथ तब तक नहीं चला सकता जब तक कि कोई इंसान यह तय न कर ले कि ऐसा करना सुरक्षित है।

rc प्रोग्राम हर script को बारी-बारी से चलाता था और उसके समाप्त होने का इंतज़ार करता था। एक script जो network address के लिए तीस सेकंड तक रुकी रहती थी, वह पूरे boot process को तीस सेकंड के लिए रोक देती थी, उन सेवाओं के लिए भी जिन्हें network से कोई लेना-देना नहीं था।

उस script के शीर्ष पर मौजूद LSB (Linux Standard Base) header इसे अंदर से ठीक करने का एक प्रयास था। 2011 में Debian 6.0 ने insserv को default बना दिया: यह हर script से Required-Start को पढ़ता था, एक graph बनाता था, और symlinks को फिर से number देता था। इसके बाद Debian startpar के साथ स्वतंत्र scripts को एक साथ चला सकता था। इससे मदद तो मिली, लेकिन यह गहरी समस्या तक नहीं पहुँच पाया। dependency अभी भी script के समाप्त होने पर ही टिकी थी। S20nginx के 0 return करने का मतलब केवल यह है कि एक shell function ने success return किया है। इसका मतलब यह नहीं है कि nginx connections स्वीकार कर रहा है।

पाँच चीजें जिन्हें कोई init script ठीक नहीं कर सकी

  • Parallel startup: फ़ाइल नाम के आधार पर क्रम निर्धारित करना मशीन की हर service पर एक पूर्ण क्रम (total order) थोपता है, इसलिए बूट प्रक्रिया उसके सभी हिस्सों के योग जितनी धीमी हो जाती है।
  • Readiness: एक start script तब exit हो जाती है जब वह daemon को fork कर देती है, न कि तब जब daemon request serve करने के लिए तैयार हो जाता है, इसलिए अगली script अक्सर बहुत जल्दी शुरू हो जाती है।
  • Supervision: एक daemon दो बार fork होता है और उसका parent exit हो जाता है, जो उसे terminal से अलग कर देता है और उसे PID 1 का child बना देता है। init एक child को exit होते हुए देखता है और उसके पास उस process से कोई विश्वसनीय लिंक नहीं होता जो जीवित बची है।
  • On-demand start: inetd (internet super-server) connection आने पर daemon को launch कर सकता था, लेकिन यह अपनी अलग configuration फ़ाइल वाला एक अलग system था, और यह बूट के समय बाकी सब चीजों के क्रम के बारे में कुछ नहीं करता था।
  • Resource control: init script में ऐसी कोई चीज नहीं थी जो service की memory या CPU share को सीमित कर सके। ulimit केवल एक process पर लागू होता था और nice केवल scheduler को प्रभावित करता था, इसलिए service का कोई अनियंत्रित child process box पर मौजूद किसी भी अन्य process जैसा ही दिखता था।

Supervision की कमी वह समस्या है जिसने दैनिक आधार पर सबसे अधिक नुकसान पहुँचाया। PID फ़ाइल इसका workaround थी: daemon अपना process ID /run/nginx.pid में लिखता था, और stop function उस फ़ाइल को वापस पढ़ता था। यदि daemon को hard kill किया जाता था, तो वह फ़ाइल वहीं रह जाती थी। kernel फिर उस नंबर को किसी और चीज के लिए reuse कर लेता था, और start-stop-daemon --stop --pidfile उस signal को उसे भेज देता था जो अब उसका मालिक था। एक पुरानी (stale) PID फ़ाइल ही वह कारण है जिससे init script गलत process को kill कर देती है।

launchd ने सबसे पहले socket समस्या का समाधान किया

Apple ने 2005 में Mac OS X 10.4 में launchd को ship किया, जिसे Dave Zarzycki ने लिखा था। एक ही process ने init, rc, xinetd, crond और watchdogd का स्थान ले लिया।

कॉपी करने योग्य विचार socket activation था। launchd सबसे पहले हर listening socket को बनाता है, और फिर daemons को start करता है। जो client ऐसे daemon से connect करता है जो अभी तक start नहीं हुआ है, उसे connection refused error नहीं मिलता है। ऐसा इसलिए है क्योंकि kernel connection को उस socket की backlog queue में तब तक hold रखता है जब तक daemon accept() को call नहीं करता। दो daemons के बीच ordering तय करना अब मानवीय हस्तक्षेप का विषय नहीं रहा। socket इसे खुद संभाल लेता है।

launchd को Mach IPC (inter-process communication) पर बनाया गया था, जो Apple के XNU kernel का हिस्सा है और Linux में इसका कोई समकक्ष नहीं है। इस code को port करना कभी भी व्यावहारिक नहीं था। फिर भी, यह विचार आगे बढ़ गया।

Upstart ने events को काम की इकाई बनाया

Canonical का Upstart, जिसे Scott James Remnant ने लिखा था, Ubuntu 6.10 में अक्टूबर 2006 में release किया गया था। Fedora 9 से Fedora 14 तक इसका उपयोग हुआ, जैसा कि RHEL 6 और Chrome OS में भी हुआ। इसने runlevel की जगह event का उपयोग किया, और एक job यह निर्धारित करती थी कि किन events पर उसे start और stop होना चाहिए।

# /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/exampled

जैसे-जैसे jobs की संख्या बढ़ी, दो समस्याएँ सामने आईं। पहली समस्या direction की थी। एक job कहती है "जब यह हो तो मुझे start करो", इसलिए किस पर क्या निर्भर है, इसकी जानकारी गलत file में रहती है: एक service को पता होता है कि उसे क्या चाहिए, लेकिन उसे यह पता नहीं हो सकता कि भविष्य में किसे उसकी आवश्यकता होगी। एक नई service जोड़ने का मतलब अक्सर किसी मौजूदा job को edit करना होता था ताकि वह एक नया event emit करे।

दूसरी समस्या tracking की थी। Upstart एक forking daemon को fork() calls को ptrace के साथ count करके track करता था, जिसे आप expect fork या expect daemon के रूप में configure करते थे। यदि forks की संख्या का अनुमान गलत हो जाए, तो Upstart ऐसी process को supervise करता था जो पहले ही exit हो चुकी होती थी, या फिर ऐसे fork का इंतज़ार करता था जो पहले ही हो चुका होता था। इसका लक्षण initctl start का बिना किसी error के hang हो जाना था, जिसे समझाने का कोई तरीका job file में नहीं था।

Upstart के लिए contributors को Canonical के contributor agreement पर हस्ताक्षर करना भी आवश्यक था। यह कोई engineering दोष नहीं था, लेकिन इसने यह तय किया कि इस पर कौन काम करेगा।

PID 1 पर पुनर्विचार, अप्रैल 2010

30 अप्रैल 2010 को Lennart Poettering ने "Rethinking PID 1" नामक एक पोस्ट प्रकाशित की। Kay Sievers ने इस प्रोजेक्ट पर उनके साथ काम किया। इस तर्क के चार भाग थे।

  • कम सेवाओं के साथ शुरुआत करें। कई सेवाएं तब तक प्रतीक्षा कर सकती हैं जब तक कि वास्तव में उनकी आवश्यकता न हो।
  • जहां socket से क्रम का पता चल सके, वहां क्रम घोषित करना बंद करें। सभी sockets को एक बार में खोलें, फिर सब कुछ एक साथ शुरू करें।
  • PID files के बजाय control groups के साथ processes को ट्रैक करें।
  • एक सेवा का विवरण declarative file में दें, ताकि एक ही विवरण हर distribution पर काम करे।

उसी वर्ष इसका पहला release आया। Fedora 14 ने नवंबर 2010 में systemd को एक विकल्प के रूप में पेश किया, और Fedora 15 ने मई 2011 में इसे default बना दिया।

cgroups ने supervision को विश्वसनीय क्यों बनाया

cgroup (control group) प्रक्रियाओं को समूहबद्ध करने के लिए एक kernel feature है, जिसे 2008 में Linux 2.6.24 में शामिल किया गया था। systemd प्रत्येक service को उसके अपने cgroup में रखता है। एक child प्रक्रिया अपने parent के cgroup को inherit करती है, और एक unprivileged प्रक्रिया खुद को उससे बाहर नहीं ले जा सकती। इसलिए double forking कुछ भी नहीं छिपाती है: PID 1 के पास हर समय उन प्रक्रियाओं का सटीक सेट होता है जो एक unit से संबंधित हैं। एक service को रोकने का अर्थ है उसके cgroup में मौजूद हर चीज को kill करना, जो कि default KillMode=control-group का कार्य है।

systemctl status उस समूह को print करता है:

● 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"

वह block stale PID file की समस्या का पूरा समाधान है। यहाँ कोई ऐसी file नहीं है जो stale हो सके, क्योंकि यह सूची kernel state है।

वही tree limits भी लागू करती है, क्योंकि cgroups को tracking के लिए उपयोग किए जाने से पहले accounting के लिए बनाया गया था। MemoryMax=, CPUQuota= और TasksMax= प्रत्येक एक line के हैं। किसी service पर hard memory और CPU cap लगाना आज एक drop-in file का काम है, जबकि 2009 में यह एक shell script के लिए ऐसा patch था जिसे किसी ने नहीं लिखा था।

हर डिस्ट्रीब्यूशन ने 2011 और 2015 के बीच स्विच क्यों किया

  • Fedora 15, मई 2011।
  • openSUSE 12.1, नवंबर 2011।
  • Mageia 2, मई 2012।
  • Arch Linux, अक्टूबर 2012 से नए इंस्टॉलेशन के लिए डिफ़ॉल्ट।
  • RHEL 7, जून 2014।
  • SLES 12, अक्टूबर 2014।
  • Debian 8, अप्रैल 2015।
  • Ubuntu 15.04, अप्रैल 2015।

इसके कारण अधिकतर सामान्य थे, यही वजह है कि यह बदलाव तेजी से हुआ।

  • एक unit file हर डिस्ट्रीब्यूशन पर काम करती है, इसलिए अपस्ट्रीम प्रोजेक्ट्स ने .service फाइल देना शुरू कर दिया और डिस्ट्रीब्यूशन्स ने प्रति पैकेज प्रति रिलीज़ शेल स्क्रिप्ट बनाए रखना बंद कर दिया।
  • 2012 के आसपास ConsoleKit का रखरखाव बंद होने के बाद डेस्कटॉप सेशन ट्रैकिंग systemd-logind पर चली गई। GNOME को logind की आवश्यकता थी, इसलिए बिना systemd वाले डिस्ट्रीब्यूशन को एक विकल्प खोजना पड़ा। वह विकल्प, elogind, systemd का logind है जिसे अलग से निकाला और बनाए रखा गया है।
  • udev, जो कि डिवाइस मैनेजर है, को अप्रैल 2012 में systemd सोर्स ट्री में मर्ज कर दिया गया। udev का उपयोग करने वाले डिस्ट्रीब्यूशन अब systemd के रिपॉजिटरी को ट्रैक कर रहे थे। इसके जवाब में Gentoo ने eudev को फोर्क कर लिया।
  • कंटेनर्स ने विश्वसनीय प्रोसेस ट्रैकिंग और प्रति-सर्विस लिमिट्स को अधिक महत्वपूर्ण बना दिया, क्योंकि ये दोनों cgroup फीचर्स हैं। यह सवाल कि कौन सा सुपरवाइज़र कंटेनर प्रोसेस का मालिक है, तब भी बना रहता है जब आप reboot के बाद Docker Compose स्टैक को वापस लाते हैं

Debian का निर्णय सबसे चर्चित था। तकनीकी समिति ने फरवरी 2014 में मतदान किया, वोट बराबर रहे, और अध्यक्ष Bdale Garbee ने systemd के पक्ष में निर्णायक वोट दिया। Ubuntu ने कुछ दिनों बाद घोषणा की कि वह Upstart के साथ जारी रहने के बजाय Debian का अनुसरण करेगा। Debian डेवलपर्स के एक समूह ने नवंबर 2014 में डिस्ट्रीब्यूशन को Devuan के रूप में फोर्क किया और मई 2017 में Devuan 1.0 जारी किया।

आपत्तियां, निष्पक्ष रूप से प्रस्तुत

दायरा (Scope)। एक प्रोजेक्ट अब PID 1, लॉगिंग डेमन, लॉगिन सेशन मैनेजमेंट, डिवाइस मैनेजर, नेटवर्क कॉन्फ़िगरेशन डेमन, DNS (डोमेन नेम सिस्टम) रिज़ॉल्वर, NTP (नेटवर्क टाइम प्रोटोकॉल) क्लाइंट, कंटेनर रनर और बूट लोडर प्रदान करता है। सामान्य बचाव यह है कि ये अलग-अलग बाइनरी हैं जिन्हें इंस्टॉल करना अनिवार्य नहीं है; यह सच है, लेकिन यह आपत्ति का समाधान नहीं है। एक बार जब डेस्कटॉप को logind की आवश्यकता होती है, और logind को systemd के ट्री से अलग नहीं किया जा सकता, तो विकल्प स्वतंत्र नहीं रह जाता। तर्क में 'कपलिंग' (coupling) का यही अर्थ था, और ऐसा ही हुआ।

बाइनरी जर्नल। journald सादे टेक्स्ट के बजाय एक इंडेक्स किया हुआ बाइनरी फॉर्मेट लिखता है। आपको वे सुविधाएं मिलती हैं जो टेक्स्ट कभी नहीं दे सकता था: प्रति-यूनिट और प्रति-प्राथमिकता फ़िल्टरिंग, स्ट्रक्चर्ड फ़ील्ड्स, और ऐसा मेटाडेटा जिसे भेजने वाला प्रोग्राम बदल नहीं सकता, क्योंकि journald स्वयं यूनिट और cgroup को रिकॉर्ड करता है। journalctl -u nginx -p err --since "-1h" तारीख के रेगुलर एक्सप्रेशन के साथ grep की जगह ले लेता है। इसकी कीमत भी चुकानी पड़ती है। जिस मशीन में बूटिंग की समस्या हो, वहां आप रेस्क्यू शेल से less के साथ लॉग नहीं पढ़ सकते। इसके बजाय, आप journalctl को माउंट की गई डिस्क की ओर निर्देशित करते हैं:

sudo journalctl --directory /mnt/var/log/journal --boot -1 --priority err

यहाँ एक दूसरा जाल है जिसमें लोग एक बार फंसते हैं। journald लॉग्स को /run/log/journal में रखता है, जो कि मेमोरी है, जब तक कि /var/log/journal मौजूद न हो। जिस मशीन पर यह मौजूद नहीं है, वहां रीबूट के बाद journalctl -b -1 के पास दिखाने के लिए कुछ नहीं होता, और यही वह क्षण है जब आपको इसकी सबसे अधिक आवश्यकता होती है। इसे जांचें और ठीक करें:

journalctl --disk-usage
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

journalctl --disk-usage को अब /var/log/journal के अंतर्गत आर्काइव किए गए जर्नल दिखाने चाहिए। यदि आप सादा टेक्स्ट भी चाहते हैं, तो /etc/systemd/journald.conf में ForwardToSyslog=yes सेट करें और rsyslog को इंस्टॉल रखें।

बूट की डिबग क्षमता। जब कोई यूनिट हैंग हो जाती है, तो कंसोल केवल एक लाइन दिखाता है और कुछ नहीं:

[  *** ] 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, और कर्नल कमांड लाइन पर systemd.log_level=debug। शिकायत का निष्पक्ष संस्करण यह है कि एक init स्क्रिप्ट को कोई भी व्यक्ति जो sh जानता है, ऊपर से नीचे तक पढ़ सकता था, जबकि एक अटकी हुई यूनिट के लिए यह जानना आवश्यक है कि दर्जन भर कमांड्स में से किसका उपयोग करना है। यह एक वास्तविक लागत है। इसे प्रत्येक एडमिनिस्ट्रेटर को एक बार चुकाना पड़ता है, और बहुत सारे एडमिनिस्ट्रेटर ने इसे एक ही समय में चुकाया था।

एक डिफ़ॉल्ट जो सभी के लिए बदलता है। 2016 में systemd 230 ने logind के डिफ़ॉल्ट को बदल दिया ताकि लॉगआउट पर बचे हुए यूज़र प्रोसेस समाप्त हो जाएं। अलग किए गए tmux और screen सेशन तब समाप्त हो जाते थे जब उन्हें शुरू करने वाला सेशन समाप्त होता था। डिस्ट्रिब्यूशंस ने /etc/systemd/logind.conf में KillUserProcesses=no शिप किया, और समर्थित उत्तर loginctl enable-linger <user> है। एक प्रोजेक्ट में एक डिफ़ॉल्ट ने उन आदतों को बदल दिया जिन पर लाखों लोग निर्भर थे, जिसका व्यावहारिक अर्थ है "यूज़रलैंड का एक ही जगह बहुत अधिक होना"।

एक डिफ़ॉल्ट निर्भरता एक सुरक्षा सतह है। मार्च 2024 में xz-utils में मौजूद बैकडोर ने Debian और Ubuntu पर sshd को लक्षित किया। अपस्ट्रीम OpenSSH, libsystemd से लिंक नहीं होता है। उन डिस्ट्रिब्यूशंस ने इसे पैच किया ताकि sshd, systemd को तत्परता (readiness) की रिपोर्ट दे सके, और libsystemd ने liblzma को खींच लिया, जहाँ बैकडोर मौजूद था। तत्परता प्रोटोकॉल स्वयं $NOTIFY_SOCKET में नामित सॉकेट पर भेजा गया एक सिंगल डेटाग्राम है, इसलिए इसके लिए किसी लाइब्रेरी की कभी आवश्यकता नहीं थी। systemd की प्रतिक्रिया dlopen के साथ कंप्रेशन लाइब्रेरी को लोड करने की थी, ताकि वे अब डिफ़ॉल्ट रूप से लिंक न हों। बग का एक संबंधित वर्ग समान रूप से दिखाई देता है: 2017 में एक User= मान जो अंक से शुरू होता था, उसे अमान्य माना गया और यूनिट विफल होने के बजाय root के रूप में चल गई, जिससे एक टाइपो प्रिविलेज एस्केलेशन बन गया। बाद के वर्ज़न यूनिट को शुरू करने से मना कर देते हैं।

अपने systemctl प्रॉम्प्ट पर इतिहास

ऊपर बताई गई हर समस्या अब एक ऐसी निर्देशिका (directive) है जिसे आप एक फाइल में पढ़ सकते हैं।

  • Serial boot अब After= और Wants= बन गया है, और systemd-analyze critical-chain यह दिखाता है कि वास्तव में आपके बूट को किस चीज ने रोक रखा था।
  • Readiness अब Type=notify बन गया है, जहाँ service सेवा देने के लिए तैयार होने पर READY=1 को $NOTIFY_SOCKET में लिखती है। पुराने daemons के लिए Type=forking के साथ PIDFile= अभी भी मौजूद है, और यह वह प्रकार है जो start operation timed out. Terminating. के साथ विफल हो जाता है जब PID फाइल कभी दिखाई नहीं देती।
  • Supervision अब cgroup बन गया है, इसलिए Restart=on-failure के साथ RestartSec= एक wrapper script की जगह ले लेता है, और StartLimitBurst= एक क्रैश लूप को हमेशा चलने से रोकता है।
  • inetd अब .service unit के बगल में स्थित एक .socket unit बन गया है।
  • ulimit अब MemoryMax=, CPUQuota= और TasksMax= बन गया है।
  • Init script में su - appuser -c लाइन अब User=, NoNewPrivileges=yes और ProtectSystem=strict बन गई है, इसलिए unprivileged user के रूप में service चलाना अब अतिरिक्त काम के बजाय unit का डिफ़ॉल्ट स्वरूप है।
[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

उस फाइल में एक लाइन ऐसी है जिसे हर कोई एक बार गलत करता है। Requires=postgresql.service एक आवश्यकता है, न कि कोई क्रम (ordering): यह कहता है कि यदि Postgres विफल होता है तो आपकी unit विफल हो जाएगी, और यह यह नहीं कहता कि पहले Postgres को शुरू करें। After=postgresql.service के बिना दोनों एक ही समय पर शुरू होते हैं, और आपकी service एक ऐसे पोर्ट से जुड़ने की कोशिश करती है जिस पर अभी कुछ भी listening नहीं है। ये दोनों जानबूझकर अलग रखे गए हैं, क्योंकि कभी-कभी आपको एक की आवश्यकता होती है और दूसरे की नहीं। ProtectSystem=strict इस service के लिए फाइल सिस्टम को read-only के रूप में माउंट करता है, और इसीलिए StateDirectory= वहां मौजूद है: यह service को /var/lib के अंतर्गत एक writable पाथ देता है।

2026 के सर्वर पर 2005 को देखने की सबसे स्पष्ट जगह Ubuntu 24.04 पर SSH है, जो अगस्त 2026 तक systemd 255 के साथ आता है। ssh.service डिफ़ॉल्ट रूप से socket activated है: ssh.socket listening socket को होल्ड करता है, और कनेक्शन आने पर sshd शुरू होता है। इसलिए /etc/ssh/sshd_config में Port 2222 का कोई प्रभाव नहीं पड़ता, क्योंकि sshd वह प्रक्रिया नहीं है जिसने पोर्ट खोला है। यह बदलाव socket unit में किया जाना चाहिए।

sudo systemctl edit ssh.socket
[Socket]
ListenStream=
ListenStream=2222

खाली ListenStream= packaged unit से विरासत में मिली वैल्यू को क्लियर कर देता है। इसे हटा दें तो आपको दोनों पोर्ट मिल जाएंगे, क्योंकि systemd रिप्लेस करने के बजाय लिस्ट में जोड़ता है। फिर लागू करें और जांचें, इस दौरान दूसरा SSH सेशन खुला रखें:

sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
sudo ss -lntp | grep 2222

ss को पोर्ट 2222 पर एक socket दिखाना चाहिए जो systemd के स्वामित्व में हो, न कि sshd के। यह बीस साल बाद आपके VPS पर launchd डिज़ाइन है। यदि आप पुराने व्यवहार को पसंद करते हैं, तो sudo systemctl disable --now ssh.socket के बाद sudo systemctl enable --now ssh.service आपको एक लंबे समय तक चलने वाला sshd देता है जो फिर से अपनी कॉन्फ़िगरेशन से Port पढ़ता है।

आप इनमें से किन विवरणों का सामना करते हैं, यह आपके द्वारा चलाए जा रहे रिलीज़ पर निर्भर करता है, इसलिए अपग्रेड की योजना बनाने से पहले LTS और interim Ubuntu रिलीज़ के बीच का अंतर जानना उचित है। एक से अधिक मशीनों पर, यह तथ्य कि एक unit फाइल हर जगह समान है, यही कारण है कि एक जगह से कई सर्वर मैनेज करना अब शेल स्क्रिप्टिंग की समस्या के बजाय एक कॉन्फ़िगरेशन समस्या है। और जब आप अपनी खुद की units लिखते हैं, तो service और timer की जोड़ी वह काम करती है जिसे आप 2009 में एक init script और एक cron लाइन के बीच विभाजित करते थे।

FAQ

Linux distributions ने SysV init को systemd से क्यों बदला?

दो इंजीनियरिंग कारणों और एक मेंटेनेंस कारण से। SysV init सेवाओं को फाइलनाम के आधार पर क्रमबद्ध करता था, जो कि एक dependency के बजाय केवल एक स्थान (position) था। यह उन daemons को ट्रैक नहीं कर पाता था जो अपने parent से fork हो जाते थे, जिस कारण stale PID files के चलते गलत process kill हो सकती थी। systemd ने socket activation और dependency directives के जरिए क्रमबद्धता की समस्या को हल किया, और control groups के जरिए ट्रैकिंग की समस्या को। मेंटेनेंस का कारण गति से संबंधित था: एक unit file हर distribution पर काम करती है, इसलिए upstream projects ने एक .service फाइल जारी करना शुरू किया और distribution maintainers ने हर पैकेज के लिए अलग shell script लिखना बंद कर दिया। Fedora 15 ने मई 2011 में इसे अपनाया और Ubuntu 15.04 अप्रैल 2015 में इसे अपनाने वाला अंतिम बड़ा distribution था।

क्या systemd एक विशाल binary है?

नहीं। इसका source tree कई अलग-अलग प्रोग्राम बनाता है। PID 1 का नाम /usr/lib/systemd/systemd है, जबकि journald, logind और udevd अलग-अलग processes हैं जिनकी अपनी binaries होती हैं; इन्हें अपने सिस्टम पर देखने के लिए ls /usr/lib/systemd/ चलाएं। जो आलोचना आज भी कायम है, वह binary के आकार के बजाय release coupling के बारे में है: ये प्रोग्राम एक साथ release किए जाते हैं और private interfaces साझा करते हैं, इसलिए distributions इन्हें एक सेट के रूप में लेते हैं, और GNOME जैसे सॉफ्टवेयर विशेष रूप से logind की अपेक्षा करने लगे हैं।

क्या मैं अभी भी बिना systemd के Linux चला सकता हूँ?

हाँ। Devuan में sysvinit मिलता है, Gentoo डिफ़ॉल्ट रूप से OpenRC का उपयोग करता है, Void में runit का उपयोग होता है, Alpine में OpenRC के साथ busybox init का उपयोग होता है, और Slackware BSD-style scripts का उपयोग जारी रखता है। इसकी कीमत compatibility के काम के रूप में चुकानी पड़ती है। जो desktop software logind की अपेक्षा करते हैं, उन्हें elogind की आवश्यकता होती है, जो कि systemd का logind है जिसे एक standalone पैकेज के रूप में मेंटेन किया जाता है। साथ ही, अब अधिक से अधिक server software केवल एक .service फाइल प्रदान करते हैं, इसलिए आपको startup script खुद लिखनी और मेंटेन करनी पड़ती है।

journal plain text फाइल के बजाय binary क्यों है?

क्योंकि journald इंडेक्स के साथ structured fields को स्टोर करता है। यह प्रति-unit (per-unit) फिल्टरिंग, प्राथमिकता (priority) फिल्टरिंग और ऐसे metadata की सुविधा देता है जिसे भेजने वाला प्रोग्राम बदल नहीं सकता: journald लॉग लाइन पर भरोसा करने के बजाय unit, cgroup और वास्तविक UID को स्वयं रिकॉर्ड करता है। इसकी कीमत यह है कि इसे पढ़ने के लिए आपको journalctl की आवश्यकता होती है, यहाँ तक कि rescue system से भी, जहाँ आप journalctl --directory /mnt/var/log/journal के साथ mounted disk को पॉइंट करते हैं। यदि आप टेक्स्ट भी चाहते हैं, तो /etc/systemd/journald.conf में ForwardToSyslog=yes सेट करें।

मेरी /etc/init.d स्क्रिप्ट को एडिट करने की जगह क्या आया है?

Drop-in files। /usr/lib/systemd/system/ में मौजूद unit को एडिट न करें, क्योंकि पैकेज अपग्रेड के दौरान यह ओवरराइट हो जाएगी। sudo systemctl edit nginx.service चलाएं और systemd /etc/systemd/system/nginx.service.d/override.conf बनाएगा, जिसे packaged unit के ऊपर मर्ज कर दिया जाता है। systemctl cat nginx.service मर्ज किए गए परिणाम को दिखाता है, और systemd-delta मशीन पर मौजूद हर override को लिस्ट करता है। हाथ से किए गए किसी भी बदलाव के बाद, sudo systemctl daemon-reload चलाएं, अन्यथा अगला कमांड Warning: The unit file, source configuration file or drop-ins of nginx.service changed on disk. प्रिंट करेगा।

#systemd#linux#init#sysvinit#history