systemd చరిత్ర: అది ఎందుకు గెలిచింది?
SysV init చేయలేనివి, Upstart మరియు launchd ముందుగా ప్రయత్నించినవి, నాలుగేళ్లలో అన్ని distributions systemd వైపు ఎందుకు మారాయి, సరైన అభ్యంతరాలు ఏవో తెలుసుకోండి.
systemd ఎందుకు విజయం సాధించింది
systemd చరిత్రను SysV init చేయలేని రెండు విషయాలతో ప్రారంభించవచ్చు. SysV init (System V init; AT&T Unix నుంచి Linux స్వీకరించిన startup system) కు ఒక service దేనిపై ఆధారపడుతుందో వివరించే మార్గం లేదు. అది ప్రారంభమైన తర్వాత ఆ service కు చెందిన processes ఏవో తెలుసుకునే మార్గం కూడా లేదు. Shell script చేరుకోలేని kernel features ద్వారా systemd ఈ రెండు సమస్యలకు పరిష్కారం ఇచ్చింది: processes ను track చేయడానికి control groups, అలాగే సేవల క్రమాన్ని నిర్వహించడానికి ముందుగానే open చేసిన 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 ను వరుసగా అమలు చేసి, అది exit అయ్యే వరకు వేచి ఉండేది. Network address కోసం ముప్పై seconds వేచి ఉండి ఒక script block అయితే, network ను ఎప్పుడూ ఉపయోగించని services తో సహా మొత్తం boot ముప్పై seconds పాటు ఆగిపోయేది.
ఆ script ప్రారంభంలో ఉన్న LSB (Linux Standard Base) header దీనిని అంతర్గతంగా పరిష్కరించే ప్రయత్నం. 2011లో Debian 6.0 insserv ను default గా చేసింది. అది ప్రతి script నుంచి Required-Start ను చదివి, ఒక graph ను నిర్మించి, symlinks కు మళ్లీ సంఖ్యలు కేటాయించేది. ఆ తర్వాత Debian startpar తో independent scripts ను ఒకేసారి అమలు చేయగలిగింది. ఇది కొంత సహాయపడింది, కానీ అసలు లోతైన సమస్యను పరిష్కరించలేదు. Dependency ఇప్పటికీ ఒక script exit అవడంపైనే ఆధారపడి ఉంది. S20nginx 0 ను తిరిగి ఇవ్వడం అంటే shell function తిరిగి వచ్చింది అని మాత్రమే. nginx connections ను స్వీకరిస్తోందని దాని అర్థం కాదు.
init script ఏదీ పరిష్కరించలేని ఐదు విషయాలు
- సమాంతర ప్రారంభం. ఫైల్ పేర్ల ఆధారంగా చేసే క్రమం యంత్రంలోని ప్రతి సేవపై సంపూర్ణ క్రమాన్ని విధిస్తుంది. అందువల్ల boot సమయం అన్ని సేవల ప్రారంభ సమయాల మొత్తానికి సమానంగా ఉంటుంది.
- సిద్ధంగా ఉండటం. Start script daemon ను fork చేసిన వెంటనే ముగుస్తుంది. Daemon అభ్యర్థనను అందించగలదా అనే దాని కోసం అది వేచి ఉండదు. అందువల్ల తరువాతి script తరచుగా చాలా ముందుగానే ప్రారంభమవుతుంది.
- పర్యవేక్షణ. Daemon రెండుసార్లు fork అయి, దాని parent ముగుస్తుంది. దీంతో అది terminal నుండి వేరవుతుంది మరియు PID 1 కు reparent అవుతుంది. Child ముగిసిందని init చూస్తుంది. కానీ కొనసాగి నడుస్తున్న process తో నమ్మదగిన సంబంధం దానికి ఉండదు.
- అవసరమైనప్పుడు ప్రారంభం. inetd (internet super-server) కు connection వచ్చినప్పుడు daemon ను ప్రారంభించగల సామర్థ్యం ఉండేది. కానీ అది స్వంత configuration file కలిగిన ప్రత్యేక వ్యవస్థ. Boot సమయంలో మిగిలిన సేవల ప్రారంభ క్రమంపై అది ఎలాంటి నియంత్రణ చూపేది కాదు.
- వనరుల నియంత్రణ. ఒక సేవ వినియోగించగల memory పరిమాణాన్ని లేదా CPUలో దాని వాటాను init script పరిమితం చేయలేకపోయేది.
ulimitఒక process కు మాత్రమే వర్తించేది.nicescheduler ను మాత్రమే ప్రభావితం చేసేది. అందువల్ల సేవకు చెందిన అదుపు తప్పిన child, ఆ యంత్రంలోని ఇతర process లాగానే కనిపించేది.
రోజువారీ నిర్వహణలో ఎక్కువ సమస్య కలిగించినది supervision లోని లోటు. దీనికి పరిష్కారంగా PID file ఉపయోగించబడేది. Daemon తన process ID ని /run/nginx.pid లో రాసేది. Stop function ఆ file ను చదివేది. Daemon ను బలవంతంగా terminate చేస్తే file అలాగే మిగిలేది. తరువాత kernel అదే సంఖ్యను వేరే process కు కేటాయించేది. అప్పుడు start-stop-daemon --stop --pidfile ఆ సంఖ్యను ప్రస్తుతం కలిగి ఉన్న process కు signal పంపేది. పాత PID file వల్ల init script తప్పు process ను terminate చేస్తుంది.
socket సమస్యను ముందుగా launchd పరిష్కరించింది
Apple, Dave Zarzycki రచించిన launchd ను 2005లో Mac OS X 10.4లో విడుదల చేసింది. ఒకే process, init, rc, xinetd, crond మరియు watchdogd స్థానాలను భర్తీ చేసింది.
అనుసరించదగిన ఆలోచన socket activation. launchd ముందుగా ప్రతి listening socket ను సృష్టించి, తరువాత daemons ను ప్రారంభిస్తుంది. ఇంకా ప్రారంభం కాని daemon కు client కనెక్ట్ అయినప్పుడు connection refused రాదు. ఎందుకంటే daemon accept() ను call చేసే వరకు kernel ఆ connection ను సంబంధిత socket యొక్క backlog queueలో ఉంచుతుంది. రెండు daemons మధ్య క్రమాన్ని ఇకపై ఒక వ్యక్తి నిర్వచించాల్సిన అవసరం ఉండదు. ఆ socket దాన్ని నిర్వహిస్తుంది.
launchd, Mach IPC (inter-process communication)పై నిర్మించబడింది. ఇది Apple యొక్క XNU kernelకు చెందినది. దీనికి Linuxలో సమానమైన implementation లేదు. ఆ codeను port చేయడం ఎప్పుడూ వాస్తవికం కాదు. అయినప్పటికీ ఆ ఆలోచన వ్యాపించింది.
Upstartలో పని యూనిట్లుగా events
Scott James Remnant రూపొందించిన Canonical యొక్క Upstart, October 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ను ఉత్పత్తి చేసేలా చేయాల్సి వచ్చేది.
రెండవది tracking. Forking daemonను అనుసరించడానికి Upstart fork() callsను ptraceతో లెక్కించేది. దీన్ని expect fork లేదా expect daemonగా configure చేసేవారు. Forkల సంఖ్యను తప్పుగా అంచనా వేస్తే, ఇప్పటికే exit అయిన processను Upstart supervise చేస్తుంది లేదా ఇప్పటికే జరిగిన fork కోసం వేచి ఉంటుంది. Error లేకుండా initctl start hang అవడం దీని లక్షణం. దీనికి కారణాన్ని job file ద్వారా వివరించే మార్గం ఉండదు.
అదనంగా, Upstartకు contributors, Canonical యొక్క contributor agreementపై సంతకం చేయాలి. అది engineering లోపం కాదు. అయితే దాని వల్ల దానిపై పనిచేసిన వ్యక్తుల పరిధి ప్రభావితమైంది.
PID 1 గురించి పునరాలోచన, April 2010
30 April 2010న Lennart Poettering "Rethinking PID 1" అనే post ను ప్రచురించారు. Kay Sievers ఆయనతో కలిసి ఈ project పై పనిచేశారు. ఆ వాదనలో నాలుగు భాగాలు ఉన్నాయి.
- తక్కువగా ప్రారంభించండి. ఏదైనా సేవను నిజంగా కోరే వరకు అనేక services వేచి ఉండవచ్చు.
- socket ద్వారా క్రమం స్పష్టమయ్యే చోట ప్రత్యేకంగా క్రమాన్ని ప్రకటించవద్దు. అన్ని sockets ను ఒకే pass లో open చేసి, తరువాత అన్నింటినీ ఒకేసారి ప్రారంభించండి.
- PID files కు బదులుగా control groups తో processes ను track చేయండి.
- ఒక service ను declarative file లో వివరించండి. అప్పుడు ఒకే description ప్రతి distribution లో పనిచేస్తుంది.
ఆ సంవత్సరం మొదటి release వచ్చింది. Fedora 14, November 2010లో systemd ను ఒక option గా విడుదల చేసింది. Fedora 15, May 2011లో దాన్ని default గా చేసింది.
పర్యవేక్షణను cgroups ఎలా విశ్వసనీయంగా మార్చాయి
cgroup (control group) అనేది processes ను సమూహాలుగా నిర్వహించే kernel feature. ఇది 2008లో Linux 2.6.24లో చేర్చబడింది. systemd ప్రతి service ను దాని స్వంత cgroupలో ఉంచుతుంది. ఒక child, దాని parent యొక్క cgroupను వారసత్వంగా పొందుతుంది. unprivileged process తాను ఉన్న cgroup నుంచి బయటకు తనను తాను తరలించుకోలేరు. అందువల్ల double forking ఏదీ దాచదు. PID 1 ప్రతి unitకు చెందిన processes యొక్క ఖచ్చితమైన సమూహాన్ని ఎల్లప్పుడూ నిర్వహిస్తుంది. ఒక serviceను ఆపడం అంటే దాని cgroupలోని ప్రతిదానినీ 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 సమస్యకు పూర్తి సమాధానం ఇదే. ఆ file stale అయ్యే అవకాశం లేదు, ఎందుకంటే ఈ జాబితా kernel state ఆధారంగా ఉంటుంది.
అదే tree limits ను కూడా నిర్వహిస్తుంది. ఎందుకంటే cgroupsను process tracking కోసం ఉపయోగించకముందే accounting కోసం రూపొందించారు. MemoryMax=, CPUQuota= మరియు TasksMax= ఒక్కొక్కటి ఒక్క line మాత్రమే. ఒక serviceకు hard memory మరియు CPU cap అమర్చడం ఒక serviceపై hard memory మరియు CPU cap అమర్చడం ప్రస్తుతం drop-in file ద్వారా చేయవచ్చు. 2009లో అదే పని ఎవరూ రాయని shell scriptకు patchగా ఉండేది.
2011 మరియు 2015 మధ్య ప్రతి distribution ఎందుకు మారింది
- 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.
కారణాలు ఎక్కువగా సాధారణమైనవే. అందుకే ఈ మార్పు వేగంగా జరిగింది.
- ఒక unit file ప్రతి distribution లో పనిచేస్తుంది. అందువల్ల upstream projects ఒక
.servicefile ను విడుదల చేయడం ప్రారంభించాయి. Distributions ప్రతి package మరియు ప్రతి release కోసం ప్రత్యేక shell script ను నిర్వహించడం ఆపేశాయి. - 2012 ప్రాంతంలో ConsoleKit నిర్వహణ ఆగిపోయిన తరువాత desktop session tracking ను
systemd-logindకు మార్చారు. GNOME కు logind అవసరమైంది. అందువల్ల systemd లేని distribution ప్రత్యామ్నాయం కనుగొనాల్సి వచ్చింది. ఆ ప్రత్యామ్నాయంelogind. ఇది systemd లోని logind ను విడిగా తీసి నిర్వహించే రూపం. - Device manager అయిన udev ను April 2012 లో systemd source tree లో విలీనం చేశారు. udev ను విడుదల చేస్తున్న distributions ఇప్పుడు systemd repository ను కూడా track చేయాల్సి వచ్చింది. దీనికి ప్రతిస్పందనగా Gentoo
eudevను fork చేసింది. - Containers కారణంగా process tracking మరియు ప్రతి service కు limits మరింత ముఖ్యమయ్యాయి. ఇవి రెండూ cgroup features. ఒక container process కు ఏ supervisor బాధ్యత వహించాలి అనే ప్రశ్న, reboot తర్వాత Docker Compose stack ను మళ్లీ ప్రారంభించేటప్పుడు ఇప్పటికీ ఎదురవుతుంది.
Debian తీసుకున్న నిర్ణయమే ఎక్కువ చర్చకు దారితీసింది. Technical Committee February 2014 లో ఓటు వేసింది. ఓట్లు సమంగా వచ్చాయి. Chair అయిన Bdale Garbee systemd కు అనుకూలంగా నిర్ణయాత్మక ఓటు వేశారు. కొన్ని రోజుల తరువాత Ubuntu, Upstart తో కొనసాగకుండా Debian ను అనుసరిస్తామని ప్రకటించింది. Debian developers లో ఒక వర్గం November 2014 లో distribution ను Devuan గా fork చేసింది. Devuan 1.0 ను May 2017 లో విడుదల చేసింది.
అభ్యంతరాలను న్యాయంగా పరిశీలించడం
పరిధి. ఇప్పుడు ఒకే project 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 నుంచి విడిగా విడుదలైనప్పటికీ, ఎంపిక ఇక స్వేచ్ఛగా ఉండదు. వాదనలో coupling అంటే ఇదే. అది వాస్తవంగా జరిగింది.
Binary journal. journald plain text బదులుగా indexed binary format లో రాస్తుంది. Plain text ఎప్పుడూ ఇవ్వలేని కొన్ని ప్రయోజనాలు మీకు లభిస్తాయి: ప్రతి unit మరియు priority ఆధారంగా filtering, structured fields, అలాగే sending program forge చేయలేని metadata. ఎందుకంటే unit మరియు cgroup ను journald స్వయంగా నమోదు చేస్తుంది. journalctl -u nginx -p err --since "-1h" grep కు బదులుగా date regular expression ను ఉపయోగిస్తుంది. దీని వ్యయం కూడా వాస్తవమే. Boot కాకుండా ఉన్న machine లో rescue shell నుంచి less ఉపయోగించి log చదవలేరు. దానికి బదులుగా mounted disk ను journalctl కు సూచించాలి:
sudo journalctl --directory /mnt/var/log/journal --boot -1 --priority errఇక్కడ మరో సమస్య ఉంది. ఇది చాలామందిని కనీసం ఒకసారి ఇబ్బంది పెడుతుంది. /run/log/journal లో journald logs ఉంచుతుంది. అది memory. /var/log/journal ఉన్నప్పుడు మాత్రమే అవి అక్కడ కాకుండా నిల్వ చేయబడతాయి. ఆ machine లో అది లేకపోతే 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-journaldఇప్పుడు journalctl --disk-usage, /var/log/journal కింద archived journals ఉన్నాయని చూపాలి. Plain text కూడా కావాలంటే /etc/systemd/journald.conf లో ForwardToSyslog=yes సెట్ చేసి rsyslog ను install చేసి ఉంచండి.
Boot ను debug చేయగల సామర్థ్యం. ఒక unit hang అయినప్పుడు console పై ఒక line మాత్రమే కనిపిస్తుంది. అంతకు మించి ఏమీ కనిపించదు:
[ *** ] A start job is running for Wait for Network to be Configured (1min 32s / no limit)మరింత పరిశీలించడానికి tools ఉన్నాయి: అది stuck గా ఉన్నప్పుడు systemctl list-jobs, తరువాత systemd-analyze blame మరియు systemd-analyze critical-chain, అలాగే kernel command line లో systemd.log_level=debug. ఈ అభ్యంతరాన్ని న్యాయంగా చెప్పాలంటే, sh తెలిసిన ఎవరైనా init script ను మొదటి నుంచి చివరి వరకు చదవగలిగేవారు. కానీ stuck అయిన unit కోసం dozen commands లో ఏది ఉపయోగించాలో తెలుసుకోవాలి. ఇది నిజమైన వ్యయం. ప్రతి administrator కు ఒకసారి ఈ వ్యయం వస్తుంది. అదే సమయంలో అనేక మంది administrators దీనిని చెల్లించాల్సి వచ్చింది.
అందరికీ మారే default. 2016లో systemd 230, logout సమయంలో మిగిలిపోయిన user processes ను terminate చేసేలా logind default ను మార్చింది. Detached tmux మరియు screen sessions ను ప్రారంభించిన session ముగిసినప్పుడు అవి కూడా ముగిశాయి. Distributions KillUserProcesses=no ను /etc/systemd/logind.conf లో విడుదల చేశాయి. దీనికి supported సమాధానం loginctl enable-linger <user>. ఒక project లోని ఒక default, millions of people ఆధారపడిన అలవాటును మార్చింది. “Userland లో ఎక్కువ భాగాన్ని ఒకే చోట ఉంచడం” అంటే ఆచరణలో ఇదే.
Default dependency ఒక security surface. March 2024లో xz-utils లోని backdoor Debian మరియు Ubuntu లోని sshd ను లక్ష్యంగా చేసుకుంది. Upstream OpenSSH, libsystemd తో link అవదు. sshd systemd కు readiness ను తెలియజేయగలిగేలా ఆ distributions దానిలో patch చేశాయి. దాంతో libsystemd, backdoor ఉన్న liblzma ను dependency గా తీసుకుంది. Readiness protocol స్వయంగా $NOTIFY_SOCKET లో పేర్కొన్న socket కు పంపే ఒకే datagram. కాబట్టి దానికి library ఎప్పుడూ అవసరం లేదు. అందువల్ల compression libraries ను dlopen తో load చేయాలని systemd మార్చింది. ఇప్పుడు అవి default గా link చేయబడవు. సంబంధిత bugs లో ఇదే విధమైన సమస్య కనిపిస్తుంది: 2017లో digit తో ప్రారంభమైన User= value ను invalid గా పరిగణించడంతో unit విఫలమవ్వకుండా root గా నడిచింది. దాంతో ఒక typo privilege escalation గా మారింది. తరువాతి versions ఆ unit ను ప్రారంభించడానికి నిరాకరిస్తాయి.
మీ systemctl promptలో స్వయంగా చరిత్ర
పైన పేర్కొన్న ప్రతి సమస్య ఇప్పుడు మీరు చదవగలిగే ఒక ఫైల్లోని ఒక directiveగా మారింది.
- Serial boot
After=మరియుWants=గా మారింది. మీ bootను వాస్తవంగా ఏది ఆపిందోsystemd-analyze critical-chainచూపిస్తుంది. - Readiness
Type=notifyగా మారింది. సేవ అందించగలిగినప్పుడు అదిREADY=1ను$NOTIFY_SOCKETలో రాస్తుంది. పాత daemons కోసంType=forkingతో కూడినPIDFile=ఇంకా ఉంది. PID file ఎప్పుడూ కనిపించకపోతేstart operation timed out. Terminating.తో విఫలమయ్యే type ఇదే. - Supervision ఇప్పుడు cgroup ద్వారా జరుగుతుంది. అందువల్ల
RestartSec=తో కూడినRestart=on-failurewrapper script స్థానాన్ని తీసుకుంటుంది.StartLimitBurst=crash loop ఎప్పటికీ నడవకుండా ఆపుతుంది. - inetd స్థానంలో
.serviceunit పక్కనే ఉండే.socketunit వచ్చింది. ulimitస్థానంలోMemoryMax=,CPUQuota=మరియుTasksMax=వచ్చాయి.- init scriptలోని
su - appuser -cline స్థానంలోUser=,NoNewPrivileges=yesమరియుProtectSystem=strictవచ్చాయి. అందువల్ల తక్కువ ప్రత్యేక హక్కులు ఉన్న 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 కూడా విఫలమవుతుందని అది చెబుతుంది. Postgresను ముందుగా start చేయాలని అది చెప్పదు. After=postgresql.service లేకపోతే రెండూ ఒకేసారి start అవుతాయి. అప్పుడు మీ సేవ ఇంకా ఏ process వినని portకు connect చేయడానికి ప్రయత్నిస్తుంది. ఈ రెండింటిని ఉద్దేశపూర్వకంగా వేరు చేశారు. ఎందుకంటే కొన్నిసార్లు ఒకటి కావాలి, మరొకటి అవసరం ఉండదు. ఈ సేవ కోసం 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 start అవుతుంది. అందువల్ల /etc/ssh/sshd_config లోని Port 2222 కు ఎలాంటి ప్రభావం ఉండదు. Portను తెరిచిన process sshd కాదు. ఈ మార్పు socket unitలో చేయాలి.
sudo systemctl edit ssh.socket[Socket]
ListenStream=
ListenStream=2222ఖాళీ ListenStream= packaged unit నుంచి వారసత్వంగా వచ్చిన విలువను తొలగిస్తుంది. దాన్ని వదిలేస్తే రెండు ports లభిస్తాయి. ఎందుకంటే systemd listకు విలువను జోడిస్తుంది; ఉన్న విలువను భర్తీ చేయదు. తరువాత apply చేసి తనిఖీ చేయండి. మొత్తం సమయంలో రెండో SSH sessionను తెరిచి ఉంచండి:
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
sudo ss -lntp | grep 2222ss port 2222పై ఒకే socketను చూపాలి. దాని owner systemd అయి ఉండాలి; sshd కాదు. ఇరవై సంవత్సరాల తరువాత మీ VPSలో కనిపించే launchd design ఇదే. పాత ప్రవర్తన కావాలంటే 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 సమస్యగా మారుతుంది; shell scripting సమస్యగా కాదు. మీరు స్వయంగా units రాసేటప్పుడు, 2009లో init script మరియు cron line మధ్య విభజించాల్సిన పనిని service మరియు timer జత నిర్వహిస్తుంది.
FAQ
Linux distributions SysV init ను systemd తో ఎందుకు భర్తీ చేశాయి?
దీనికి రెండు engineering కారణాలు మరియు ఒక maintenance కారణం ఉన్నాయి. SysV init సేవలను filename ఆధారంగా క్రమబద్ధం చేసేది. అది dependency కాకుండా ఒక స్థానం మాత్రమే. Parent నుంచి fork అయి విడిపోయిన daemon గురించి కూడా అది track చేయలేకపోయేది. అందుకే stale PID files తప్పు process ను terminate చేయగలిగేవి. systemd socket activation మరియు dependency directives ద్వారా ordering సమస్యను పరిష్కరించింది. Control groups ద్వారా process tracking సమస్యను పరిష్కరించింది. Maintenance కారణం మార్పు వేగాన్ని నిర్ణయించింది: ప్రతి distribution లో ఒకే unit file పనిచేస్తుంది. అందువల్ల upstream projects ఒక .service file ను విడుదల చేశాయి. Distribution maintainers ప్రతి package కోసం ప్రత్యేక shell script రాయడం ఆపేశారు. Fedora 15 May 2011లో మారింది. Ubuntu 15.04 April 2015లో మారిన చివరి పెద్ద distribution.
systemd ఒకే పెద్ద binaryనా?
కాదు. Source tree అనేక ప్రత్యేక programs ను build చేస్తుంది. PID 1 అనేది /usr/lib/systemd/systemd. journald, logind మరియు udevd తమ స్వంత binaries కలిగిన వేర్వేరు processes. మీ systemలో వాటిని చూడటానికి ls /usr/lib/systemd/ ను run చేయండి. మిగిలి ఉన్న విమర్శ binary size గురించి కాదు; release coupling గురించి. ఈ programs ఒకేసారి విడుదలవుతాయి మరియు private interfaces ను పంచుకుంటాయి. అందువల్ల distributions సాధారణంగా వాటిని ఒక setగా స్వీకరిస్తాయి. GNOME వంటి software ప్రత్యేకంగా logind పై ఆధారపడటం ప్రారంభించింది.
systemd లేకుండా Linux ను ఇంకా run చేయవచ్చా?
అవును. Devuan sysvinit ను ship చేస్తుంది. Gentoo కి OpenRC default. Void runit ను ఉపయోగిస్తుంది. Alpine OpenRCతో busybox init ను ఉపయోగిస్తుంది. Slackware BSD style scripts ను కొనసాగిస్తుంది. దీని ఖర్చు compatibility work. logind ను ఆశించే desktop software కు elogind అవసరం. ఇది standalone packageగా maintain చేయబడే systemd యొక్క logind. ప్రస్తుతం పెరుగుతున్న server softwareలో కేవలం .service file మాత్రమే ship అవుతోంది. అందువల్ల startup script ను మీరే రాసి maintain చేయాలి.
journal plain text file బదులుగా binaryగా ఎందుకు ఉంది?
journald indexed structured fields ను store చేస్తుంది. దీనివల్ల per-unit filtering, priority filtering మరియు sending program forge చేయలేని metadata లభిస్తాయి. Log line ను నమ్మకుండా journald స్వయంగా unit, cgroup మరియు real UID ను record చేస్తుంది. దీని ప్రతికూలత ఏమిటంటే చదవడానికి journalctl అవసరం. Rescue system నుంచి చదివేటప్పుడు కూడా ఇదే అవసరం. అక్కడ mounted disk ను journalctl --directory /mnt/var/log/journal తో చూపించాలి. Text format కూడా కావాలంటే /etc/systemd/journald.conf లో ForwardToSyslog=yes ను set చేయండి.
నా /etc/init.d script ను edit చేయడానికి బదులుగా ఏమి ఉపయోగించాలి?
Drop-in files ను ఉపయోగించాలి. /usr/lib/systemd/system/ లోని unit ను edit చేయకండి. Package upgrade దాన్ని overwrite చేస్తుంది. sudo systemctl edit nginx.service ను run చేయండి. అప్పుడు systemd /etc/systemd/system/nginx.service.d/override.conf ను సృష్టిస్తుంది. ఇది packaged unit పై merge అవుతుంది. Merge అయిన result ను systemctl cat nginx.service చూపిస్తుంది. Machineలోని అన్ని overrides ను systemd-delta list చేస్తుంది. చేతితో చేసిన ఏ edit తరువాత అయినా sudo systemctl daemon-reload ను run చేయండి. లేకపోతే తదుపరి command Warning: The unit file, source configuration file or drop-ins of nginx.service changed on disk. ను print చేస్తుంది.