SystemD (System Daemon) Linux’un açılışı sırasında devreye girerek açılış servislerini başlatan, Linux’un çalışması sırasında da tüm yönetimsel işlevleri yerine getiren bir programlar topluluğu ve aynı zamanda bir sistem yönetim altyapısının adıdır. Systemd, öncelikle sistemin açılışı sırasında gerekli servislerin başlatılmasından ve yönetilmesinden sorumludur. Servislerin dışında kullanıcı oturumlarının, donanım aygıtlarının ve günlük (log) sisteminin yönetimi, sistem yapılandırmasının uygulanması ve izlenmesine kadar tüm yönetimsel süreçlerin içerisinde aktif olarak yer alır. Kullanıcılar ise systemctl, journalctl, notify, analyze, cgls, cgtop, loginctl ve nspawn gibi araçlar ile SystemD ile etkileşime geçerek sistemi yönetebilir. Bu bölümde SystemD’nin en önemli bileşenlerinden biri olan service unit’leri (servisler) hakkında temel bilgiler verilecektir.
Kısaca SystemD’nin öncesinden bahsetmek gerekirse; daha önceleri Linux işletim sisteminin açılmasını ve servislerinin yüklenmesi görevini yerine getiren init (SystemV işletim sisteminden kalma) adında bir sistem kullanılmakta idi. Açılış betikleri (script) aracılığı ile sistemin açılmasını ve servislerin idaresini sağlayan init adındaki sistem yerini hızlı bir şekilde SystemD’ye bırakmaktadır. SystemD günümüzde birçok Linux dağıtımı tarafından varsayılan olarak kullanılmaktadır. Raspberry Pi’ın resmi dağıtımı olan Raspberry Pi OS da SystemD’yi sistem ve servis yöneticisi olarak kullanır. SystemD eski init mekanizması ile de uyumlu çalışmaktadır.
SystemD, init mekanizmasına göre servisleri açılışta paralel çalıştırabilme, çalışma seviyeleri ve servis gereksinimleri ile bunların çok detaylı olarak yapılandırılabilmesine imkân tanıma gibi birçok avantaja sahiptir. SystemD aynı zamanda sahip olduğu birim yapı taşı (unit) yapısı ile birçok sistem bileşeninin organizasyonel ve hiyerarşik olarak tanımlanabilmesini ve ilişkilendirilebilmesini sağlayan standart bir arayüz sunar. Bu standart, pratikte, birçok Linux dağıtımının aynı yönetimsel şemaya sahip olması gibi bir avantaj yaratır. Bu avantaj, özellikle Linux kullanıcılarının farklı dağıtımlara alışma sürelerinin kısalmasını ve ortak bir yönetimsel süreç geliştirilmesi amacına hizmet eder.
SystemD Hakkında Bazı Eleştiriler
SystemD, avantajları yanında birçok kritik görevi üzerinde toplayan merkezi bir konum elde ettiğinden, eleştirilere de maruz kalır. Linux felsefesinde; birçok görevi yerine getiren tek bir programdan ziyade, her birinin kendi görevi olan daha küçük programlardan oluşan bir yapı benimsenmiştir. SystemD’nin durumunda ise, oluşacak bir güvenlik açığı tüm sistemi derinden sarsabilecek potansiyeldedir. Diğer bir eleştiri de kolektif güçle inşa edilen ve aynı görevi yerine getiren alışılagelmiş araçların yerini SystemD ve onun nispeten sınırlı geliştirici kitlesinin almasıdır.
Unit’ler (birimler) yönetimsel işlevleri yerine getiren ve SystemD’yi oluşturan en küçük yapı taşlarıdır ve her birinin kendi yapılandırma dosyası vardır. SystemD’nin birimlerini tanımlayan yapılandırma dosyalarını /lib/systemd/system dizininde görebilirsiniz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
pi@raspberry:~ $ ls /lib/systemd/system alsa-restore.service rc.local.service alsa-state.service rc-local.service.d alsa-utils.service rc.service apply_noobs_os_config.service rcS.service apt-daily.service reboot.service apt-daily.timer reboot.target apt-daily-upgrade.service reboot.target.wants apt-daily-upgrade.timer regenerate_ssh_host_keys.service |
SystemD tarafından bilinen tüm birim türlerinin adlarını listelemek için aşağıdaki komutu çalıştırabilirsiniz:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
pi@raspberry:~ $ systemctl -t help Available unit types: service socket busname target device mount automount swap timer path slice scope |
SystemD Çalışma Seviyeleri (Run levels)
Çalışma seviyeleri, diğer adı ile run levels, Linux’un çalışma kipini ya da çalışma seviyesini ifade eden çok eski bir terminolojidir ve günümüzde de yaygınlığını korumaktadır. Çalışma seviyeleri Linux bilgisayarının, dolayısıyla Raspberry Pi’ın açılışından itibaren içinde bulunacağı çalışma kiplerini ifade etmek için kullanılır. Raspbian, sistem yükleyicisi olarak init adlı programın yerine SystemD’yi kullanmaya başladığından beri, çalışma seviyeleri sadece simgesel olarak varlığını korumaktadır. 2016’da gelen güncelleme ile yerini SystemD’ye ve onun target adlı birimlerine (unit) bırakmıştır. Bu simgesel varlık, SystemD Linux çekirdeği ile tam olarak entegre olduğunda tamamen ortadan kalkacaktır.
Linux işletim sistemlerinin hemen hepsinde var olan çalışma seviyeleri temel olarak 7 tanedir. Bunlar:
- Halt: Bu çalışma seviyesi özel bir işleve sahiptir ve sistemin kapalı olması durumunu ifade eder. Çalışmakta olan bir sistem kapatılmak istenirse 0. çalışma seviyesine geçiş yapmak sistemin kapatılmasını sağlar. SystemD modelinde poweroff.target ile tanımlanmıştır.
- Tek kullanıcı: Tek kullanıcı kipini ifade eder. Bu kipte tek kullanıcı oturum açabilir ve ağ bağlantısı imkânları yer almaz. Temel olarak güvenli kip ya da kurtarma amaçlı müdahalelerin yapılabileceği sadece dosya sistemine erişimi sağlayan bir kiptir. SystemD modelinde rescue.target ile tanımlanmıştır.
- Çok kullanıcı: Birinci çalışma seviyesine benzerdir. Fark olarak birden fazla kullanıcının oturum açması desteklenir. SystemD modelinde multi-user.target ile tanımlanmıştır.
- Ağ desteği ile çok kullanıcı: Birçok kullanıcı ağ desteğine sahip sistemi kullanabilir. SystemD modelinde multi-user.target ile tanımlanmıştır.
- Tanımsız: Bu çalışma seviyesi için bir görev tanımlanmamış, kullanıcı tanımı için ayrılmıştır. Kullanıcı dilerse bu çalışma seviyesi için bir yapılandırma tanımlayabilir. SystemD modelinde multi-user.target ile tanımlanmıştır.
- X11: Üçüncü çalışma seviyesinin sunduğu imkânlara ek olarak bu çalışma seviyesinde grafiksel kullanıcı arabirimi de yer alır. SystemD modelinde graphical.target ile tanımlanmıştır.
- Yeniden başlatma: Bu çalışma seviyesine geçildiğinde sistemin yeniden başlama prosedürü çalıştırılır. Servisler, kullanıcı oturumları ve programları kapatılır ve donanımsal RESET işlevlerinden biri tetiklenir. Yani, kısaca bilgisayar yeniden başlar. SystemD modelinde reboot.targetile tanımlanmıştır.
Raspberry Pi’ın çalışma seviyesini değiştirmek için init komutu kullanılabilir, lakin bu çalışma kipini değiştirmek için kullanılan eski bir yöntemdir. Örneğin aşağıdaki komut ile Raspberry Pi’ın 0. çalışma seviyesine gitmesini sağlayarak tamamen kapatılmasını sağlayabilirsiniz:
1 |
pi@raspberry:~ $ sudo init 0 |
SystemD modelinde alışılagelmiş çalışma seviyeleri yerine kullanılan target (hedef) birimleri, sayılar ile (0-7) ifade edilen çalışma kipleri yerine daha açık, anlaşılır ve kolayca özelleştirilebilir çalışma kipleri sunar.
SystemD bütünlüğü içinde arka plan servislerine göz atmak gerekirse; Tüm SystemD bileşenleri gibi sistemde yüklü servisler de kendini bir target’ın altında tanımlayarak hiyerarşik bir bağ oluşturur. Dolayısıyla birim yapılandırma dosyaları aracılığı ile hangi kiplerde ya da olaylarda çalışacakları SystemD tarafından bilinmiş olur. Aşağıda runlevel ve target birimi açısından bulunulan çalışma kipini görüntülemek üzere kullanılan komutlar verilmiştir:
1 2 3 4 5 6 7 |
pi@raspberry:~ $ runlevel N 5 pi@raspberry:~ $ systemctl get-default graphical.target |
Yukarıdaki ekran çıktısında yer alan graphical.target’ın sunduğu çalışma kipini tanımlayan unit’in yapılandırma dosyasının içeriğine bakmak isterseniz, şu komutu verebilirsiniz:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
pi@raspberry:~ $ cat /lib/systemd/system/graphical.target # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. [Unit] Description=Graphical Interface Documentation=man:systemd.special(7) Requires=multi-user.target Wants=display-manager.service Conflicts=rescue.service rescue.target After=multi-user.target rescue.service rescue.target display-manager.service AllowIsolate=yes |
Yukarıdaki birim yapılandırma dosyasında (graphical.target) şu bilgiler yer almaktadır: birim multi-user.target birimine ihtiyaç duyar (requires), display-manager.service birimi ise require’a göre daha düşük bir ihtiyaç tanımı sağlar (wants). Bunun anlamı bu birim (display-manager.service) olmadan da grafik moda çalışılabilir. Grafik masa üstü ortamı ağ tabanlı (socket) bir uygulama olduğundan yerel bilgisayardan grafik kipi kullanmadan uzak masaüstü olarak bağlanılabilir. conflicts yapılandırması, rescue (kurtarma kipi) kipinde grafik kipin çalıştırılmayacağını söyler, yani bu ikisi için bir çakışma tanımlar. After ile listelenen birimler, graphical.target biriminden önce başlatılabilecek birimleri tanımlar. After altında tanımlanan birimler herhangi bir bağımlılık tanımlamaz. AllowIsolate yapılandırması bu birimin systemctl isolate komutu ile kullanılabileceğini söyler. Böylece geçiş yapılacak target kipinin bağımlılığında yer almayan tüm servisler ve işlemler sonlandırılır.
Raspberry Pi’ın mevcut target birimlerini görmek için ise aşağıdaki listelemeyi çalıştırabilirsiniz:
1 |
pi@raspberry:~ $ ls -la /lib/systemd/system/*.target |
Raspberry Pi’ın çalışma seviyesini değiştirmek
SystemD kullanarak Raspberry Pi’ın çalışma seviyesini değiştirebilirsiniz. Örneğin Raspberry Pi konsol kipinde çalışırken grafik masaüstü kipine geçiş yapabilirsiniz veya tam tersi. Daha önce de bahsedildiği gibi çalışma seviyeleri target birimi ile tanımlanmıştır.
Ağ desteği ile çok kullanıcılı konsol kipine geçiş yapmak için multi-user target’ı aşağıdaki gibi kullanılabilir:
1 |
pi@raspberry:~ $ sudo systemctl isolate multi-user.target |
Ağ ve çoklu kullanıcı desteği ile grafik masaüstü kipine geçmek için graphical hedefi kullanılır:
1 2 3 4 5 6 7 8 9 |
pi@raspberry:~ $ sudo systemctl isolate graphical.target Raspberry Pi’ı yeniden başlatmak için: pi@raspberry:~ $ sudo systemctl isolate reboot.target Raspberry Pi’ı tamamen kapatmak için: pi@raspberry:~ $ sudo systemctl isolate halt.target |
halt.target ve reboot.target hedeflerinin yerine reboot, poweroff ve halt takma adları (alias) da kullanılabilir.
Raspberry Pi’ın açılış kipini değiştirmek
Bir önceki konuda SystemD kullanılarak, Raspberry Pi’ın çalıştığı sırada çalışma seviyesinin nasıl değiştirileceği örneklenmişti. Bu çalışma seviyesi, Raspberry Pi yeniden başladığında ön tanımlı seviyeye geri döner. Raspberry Pi’ın açılışının belli bir target yani çalışma seviyesi ile gerçekleştirmek ve bunu kalıcı hale getirmek için set-target seçeneğinden faydalanılır.
Mevcut varsayılan çalışma seviyesini görmek için;
1 2 3 |
pi@raspberry:~ $ sudo systemctl get-default multi-user.target |
Ön tanımlı açılış çalışma seviyesini multi-user olarak değiştirmek için:
1 |
pi@raspberry:~ $ sudo systemctl set-default multi-user.target |
Raspberry Pi’ın grafik kullanıcı arabirimi ile açılmasını sağlamak graphical hedefi kullanılır:
1 |
pi@raspberry:~ $ sudo systemctl set-default graphical.target |
Raspberry Pi’ın kurtarma kipinde açılması için rescue hedefi kullanılır:
1 |
pi@raspberry:~ $ sudo systemctl set-default rescue.target |
Kurtarma kipinde Raspberry Pi mümkün olan düşük yapılandırma ayarları ile başlatıldığından açılışta birçok program ve servis yüklenmez. SSH servisi de bunlardan biridir. Bu nedenle Raspberry Pi’a uzaktan (ağ bağlantısı üzerinden) bağlanmak mümkün değildir. Bu durumda bir klavye ve monitör kullanarak Raspberry Pi’da fiziksel olarak oturum açmak gerekir. Raspberry Pi kurtarma kipinde başladığında, monitörde aşağıdaki gibi bir karşılama ekranı görüntülenir:
1 2 3 4 5 6 7 |
You are in rescue mode. After logging in, type “journalctl –xb” to view system logs, “systemctl reboot” to reboot, “systemctl default” or ^D to Boot into default mode. Give root password for maintenance (or pres Control-D to continue): |
Karşılama ekranında oturum için yönetici parolası, yani pi kullanıcısının parolasının girilmesi için beklenir. Parola girildikten sonra # işareti ile bekleyen bir komut kabuğu açılır ve komut bekler. journalctl –xb komutu ile sistem günlüklerinin listelenmesi sağlanabilir. Bu günlükler olası donanımsal ve yazılımsal açılış sorunlarını görmek açısından faydalıdır.
systemctl reboot komutunu verdiğinizde ise Raspberry Pi yeniden başlar ve tekrar kurtarma kipinde açılır. Raspberry Pi’ın varsayılan kipte açılması için ise systemctl default komutunu aşağıdaki gibi vermeli ve yeniden başlatmalısınız.
1 2 3 |
pi@raspberry:~# systemctl set-default graphical.target pi@raspberry:~# systemctl reboot |
rescue kipinin dışında birde emergency (ilk yardım) kipi vardır. rescue’dan tek farkı SystemD’nin kurulu olduğu disk bölümü haricindeki bölümlerin bağlanmamasıdır.
Servisleri listelemek
SystemD’nin temel görevlerinden biri de arka planda çalışan servisleri yönetmek ve senkronize etmektir. SystemD modelinde servisler, service birimi (unit) altında toplanmıştır. Sistemde hangi servisleri etkin veya pasif olduğunu görmek için aşağıdaki komutu çalıştırabilirsiniz:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
pi@raspberry:~ $ systemctl list-unit-files --type service UNIT FILE STATE dhcpcd.service enabled dhcpcd5.service enabled Bluetooth.service enabled apt-daily-upgrade.service static apt-daily.service static alsa-utils.service masked checkfs.service masked cron.service enabled cryptdisks.service masked |
Yukarıdaki ekran çıktısında tipi (type) servis olan birim (unit) dosyaları listelenmiştir. Durum sütununda (STATE) enabled yazan servisler açılışta aktif olan servislerdir. Masked yazan servisler ise tamamen devre dışı bırakılmıştır ve ne elle ne de otomatik olarak başlatılmazlar. Öncelikle masked durumundan çıkartılmaları gerekir. Bu durum ile ilgili detaylı bilgi ilerleyen kısımlarda yer almaktadır. Static ifadesi, servisin SystemD tarafından bir bağımlılığı sağlamak üzere etkinleştirildiğini söyler.
İçinde servislerin de yer aldığı SystemD birimlerini hiyerarşik bir yapıda görüntülemek isterseniz systemctl aracını aşağıdaki gibi status seçeneği ile çalıştırabilirsiniz:
1 |
pi@raspberry:~ $ systemctl status |
Sistemin status çıktısı, aktif olarak yerine getirilen işler (Jobs) ve başarısız olan SystemD birimleri hakkında da bilgi verir.
Sistemde kurulu ve aktif olan servisleri ise systemctl aracı ile aşağıdaki gibi listeletebilirsiniz:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
pi@raspberry:~ $ systemctl list-units --type service UNIT LOAD ACTIVE SUB DESCRIPTION alsa-restore.service loaded active exited Save/Restore Sound Card State cron.service loaded active running Background processing daemon dhcpcd.service loaded active running dhcpcd on all interfaces keyboard-setup.service loaded active exited Set the console keyboard layout ssh.service loaded active running OpenBSD Secure Shell server rsyslog.service loaded active running System Logging Service |
Yukarıdaki örnek ekran çıktısında sadece yüklü ve aktif servisler listelenmektedir. Yüklü/aktif olmayan servisler ile birlikte tüm servislerin listelenmesi için –all seçeneğinden faydalanabilirsiniz. Ekran çıktısında her bir servisin kısa açıklaması DESCRIPTION adlı sütunda yer almaktadır. LOAD, ACTIVE ve SUB sütunlarındaki bilgiler ise şu anlamlara gelir:
LOAD: İlgili servisin yapılandırma bilgisinin SystemD tarafından okunup hafızaya yüklendiği loaded (yüklendi) açıklaması ile gösterilir.
ACTIVE: Servisin etkin olduğundan çok başarılı bir şekilde başlatıldığını anlatan bir açıklama sunar.
SUB: Servisin anlık durumu hakkında daha detaylı bir bilgi sunar. Running (çalışıyor) ifadesi listelemenin yapıldığı sırada servisin çalıştığını, exited (çıkıldı) ifadesi ise servisin iş yapan alt parçasının o anda işini tamamlandığını söyler.
Servisler dışında sistemde aktif olan tüm SystemD bileşenlerini (units) aşağıdaki gibi listeletebilirsiniz.
1 |
pi@raspberry:~ $ systemctl list-units --all |
Listelenen servislerin çalışma durumlarına göre filtre uygulamak için state seçeneği kullanılır. State seçeneğine verilebilecek değerler: active, inactive, not-found, dead, exited, plugged ve failed’dır. Aşağıdaki komut ile çalışması sırasında başarısız olmuş birimleri listeletebilirsiniz:
1 |
pi@raspberry:~ $ systemctl list-units --all --state=failed |
Servislerin bağımlılıklarını listelemek
SystemD, bir servisin başlayabilmesi için gerekli bağımlılık bilgilerini de tutar. Bir servisin ihtiyaç duyduğu alt SystemD bileşenleri list-dependencies seçeneği ile görülebilir. Bu hiyerarşik bir listedir ve öncelik sırasına göre dizilmiştir. Bu listede gösterilen bağımlılıklar ilgili servisin yapılandırma dosyasında ihtiyaç olarak tanımlanmış olan wanted (az öncelikli bağımlılık) ve required (mutlaka gereken bağımlılıklar) türündeki bağımlılıkları içerir. Aşağıdaki örneği inceleyelim:
1 |
pi@raspberry:~ $ systemctl list-dependencies networking.service |
Çoğu durumda listelenen bağımlılıkların da alt bağımlılıkları vardır. Öz yinelemeli bir bağımlılık listesi almak için –all seçeneğinden faydalanılabilir:
1 |
pi@raspberry:~ $ systemctl list-dependencies networking.service –-all |
Servisin SystemD içinde tanımlanmış olan özelliklerini görüntülemek için show seçeneğini aşağıdaki gibi kullanabilirsiniz:
1 |
pi@raspberry:~ $ systemctl show sshd.service |
Servisleri başlatmak ve durdurmak
SystemD aracılığı ile servisleri başlatmak için start ve stop seçenekleri kullanılır. Aşağıda cron servisinin durdurulması ve başlatılmasına birer örnek yer alıyor:
1 2 3 |
pi@raspberry:~ $ sudo systemctl stop cron.service pi@raspberry:~ $ sudo systemctl start cron.service |
cron servisini durdurmak için service birim adını kullanmadık. systemctl aracılığı ile servisler ile ilgili işlem yaparken service birim adını kullanmak zorunlu değildir. Açıklayıcı ve anlaşılır olması açısından kullanılmasında fayda vardır. Bir servisin yapılandırma dosyasında değişiklik yaptığınızda ya da servis çalışma kararlılığını yitirdiğinde yeniden başlatmanız gerekebilir. Bunun için stop ve start şeklinde iki ayrı komut vermenize gerek yoktur. restart seçeneğini bir servisi yeniden başlatmak için (durdurup tekrar başlatmak) kullanabilirsiniz:
1 |
pi@raspberry:~ $ sudo systemctl restart ssh |
Bir servisin çalışıp çalışmadığı hakkında durum bilgisi almak için ise status seçeneği kullanılır:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
pi@raspberry:~ $ sudo systemctl status cron ● cron.service - Regular background program processing daemon Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2018-01-08 14:41:00 UTC; 1s ago Docs: man:cron(8) Main PID: 16343 (cron) CGroup: /system.slice/cron.service └─16343 /usr/sbin/cron –f |
Status çıktısı servis hakkında birçok faydalı bilgi verir. Status çıktısındaki Loaded ve Active sütunlarından servisin çalışıp çalışmadığı izlenebilir. Ayrıca cron servisinin birim yapılandırma dosyasının konumunun /lib/systemd/system/cron.service olduğu, enabled yapılandırması ile açılışta otomatik olarak başlayacağı, servisin 2018-01-08 14:41:00 UTC tarihinde başladığı gibi bilgiler listelenir. Docs satırında servisin kullanım kılavuzunun adresi yer alır (“man:cron(8)”). Bu kılavuza erişmek için man komutu aşağıdaki kullanılabilir:
1 |
pi@raspberry:~ $ man cron 8 |
Status çıktısındaki bir başka bilgi de; cron servisinin, SystemD tarafından system.slice kontrol grubu (CGroup) altında yer alacak şekilde, /usr/sbin/cron çalıştırılabilir dosyasına –f seçeneği verilerek çalıştırılmış olduğu ve çalıştırılan prosese çekirdek tarafından 16343 PID (işlem numarası) numarası verildiğidir.
Servisler için kullanılabilecek bir başka seçenek de reload’dır. Bu seçenek servisi durdurmadan servis ile ilgili yapılan yeni yapılandırmanın geçerli olmasını sağlar. Örneğin /etc/ssh/sshd_config dosyasında yapacağınız bir değişikliğin ssh servisi tarafından uygulanmasını istiyorsanız reload seçeneğini kullanabilirsiniz. Böylece ssh servisini yeniden başlatmaya gerek kalmaz. Tabii ki bu seçenek sadece reload işlemini destekleyen servisler için geçerlidir.
1 |
pi@raspberry:~ $ sudo systemctl reload ssh |
Bir servisin çalışması sırasında ürettiği mesajları görmek için journalctl aracından faydalanılabilir. journalctl, -u seçeneği ile belirtilen birimin ürettiği günlük kayıtlarını listeler. Özellikle bir servis ya da işlev istenildiği gibi çalışmıyorsa, hatayı bulmak için ilk bakılması gereken yer journal kayıtlarıdır:
1 |
pi@raspberry:~ $ sudo journalctl -u cron |
Servislerin açılışta (boot) otomatik başlatılmasını sağlamak
Raspberry Pi’ın açılışında bir servisi etkinleştirmek ve devre dışı bırakmak için enable ve disable seçenekleri kullanılır. Örneğin açılışta Bluetooth servisini devre dışı bırakmak için systemctl komutunu aşağıdaki şekilde kullanabilirsiniz:
1 |
pi@raspberry:~ $ sudo systemctl disable Bluetooth |
disable seçeneği Bluetooth servisinin birim dosyasına ait sembolik bağlantıyı (kısayol) /etc/systemd/system/ dizininden silerek bu işlemi gerçekleştirir. Servis etkinleştirildiğinde ise bu sembolik bağlantı yeniden oluşturulur:
1 2 3 4 5 6 7 |
pi@raspberry:~ $ sudo systemctl enable Bluetooth Synchronizing state of Bluetooth.service with SysV service script with /lib/systemd/systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install enable Bluetooth Created symlink /etc/systemd/system/dbus-org.bluez.service → /lib/systemd/system/Bluetooth.service. |
Servisleri maskelemek
SystemD içinde bir servisi başlatılamaz olarak ayarlamanın yolu masked olarak işaretlemektir. Bir servis masked olarak işaretlendiğinde hiçbir şekilde (elle veya otomatik) başlatılmaz. Hiçbir şekilde başlatılmasını istemediğiniz servisleri masked olarak ayarlayabilirsiniz. Örneği inceleyelim:
1 |
pi@raspberry:~ $ sudo systemctl mask Bluetooth |
Örnekte Bluetooth servisi maskelenmiştir ve hiçbir şekilde başlatılamaz duruma gelmiştir. Başlatılmaya ya da enable yapılmaya çalışıldığında aşağıdaki gibi bir uyarı görüntülenir:
1 2 3 4 5 6 7 |
pi@raspberry:~ $ sudo systemctl start Bluetooth Failed to start Bluetooth.service: Unit Bluetooth.service is masked. Servisin maskesini kaldırmak için ise unmask seçeneği kullanılır: pi@raspberry:~ $ sudo systemctl unmask Bluetooth |
Yeni bir SystemD servisi oluşturmak
/lib/systemd/system/ dizini altında birim dosyası oluşturularak bir servis tanımlanabilir. Öncelikle arka planda sürekli olarak çalışmasını istediğimiz bir programa ihtiyacımız olacak. Bunun için varsayılan ses çıkışından 1 dk. aralıklarla bir metin seslendiren basit bir Python betiği kullanacağız. Betik espeak aracını kullanarak varsayılan hoparlörden bir metni seslendirmektedir. Betiği home dizini içinde oluşturmak için aşağıdaki komutları kullanabilirsiniz:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
pi@raspberry:~ $ nano realworld.py #! /usr/bin/env python from subprocess import call import time while (0<1): call(['espeak "Welcome to the real World Neo." 2>/dev/null'], shell=True) time.sleep(60) |
Daha sonra nano editörünü aşağıdaki gibi kullanarak birim dosyasını oluşturalım:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
pi@raspberry:~ $ sudo nano /lib/systemd/system/realworld.service [Unit] Description=Ornek systemd servisi After=multi-user.target [Service] Type=idle ExecStart=/usr/bin/python /home/pi/realworld.py [Install] WantedBy=multi-user.target |
Birim dosyasını yukarıdaki gibi oluşturduktan sonra SystemD’a birim dosyalarını yeniden yüklemesini ve realworld.service isimli servisimizi açılışta çalıştırmak üzere etkinleştirmesini söyleyelim:
1 2 3 |
pi@raspberry:~ $ sudo systemctl daemon-reload pi@raspberry:~ $ sudo systemctl enable realworld.service |
Servis enable komutu ile etkinleştirildiğinde /etc/systemd/system/multi-user.target.wants/ dizini altında realworld.service isimli bir sembolik link oluşturulur.
Servisimiz Raspberry Pi yeniden başladığında aktif olacak ve birer dakika aralıklarla metni seslendirecektir. Dilerseniz yeni oluşturduğumuz servisi aşağıdaki gibi başlatıp durdurabilirsiniz:
1 2 3 |
pi@raspberry:~ $ sudo systemctl start realworld pi@raspberry:~ $ sudo systemctl stop realworld |
Birim dosyasında kullanılan tanımlamalara değinmek gerekirse Description seçeneği servise bir açıklama tanımlamıştır. After seçeneği servisimizin multi-user çalışma kipine geçildikten sonra etkin olmasını, Idle da tüm multi-user servisleri başladıktan sonra çalışmasını söylenmiştir. Execstart ile de çalıştırılacak olan betik ya da programın yolu tanımlanmıştır. WantedBy seçeneği ile de servisin multi-user kipi servisi olduğu tanımlanmıştır.
SystemD servisini tamamen silmek
Bu konuda bir SystemD servisini sistemden tamamen nasıl kaldıracağımızı öğreneceğiz. Tabi bir servisi sistemden tamamen kaldırmadan önce ne yaptığınızı iyi biliyor olmalısınız. Servis bir başka servisin bir bağımlıllığı olabilir veya sistemde kritik bir görevi yerine getiriyor olabilir. Daha önce anlatıldığı gibi genel olarak bir servis maskelenirse SystemD tarafından görünmez olur ve yok sayılır; fakat bazı özel işlevler yine de servisi etkinleştirip başlatabilir. Bir servisin binary çalıştırılabilir dosyaları sistemden kaldırılmış olabilir, binary dosya veya yapılandırması işini düzgün yapamayacak şekilde bozulmuş olabilir. Tüm bunlara rağmen servis dosyası hala tedavülde olabilir. Bu gibi servisler sürekli hata durumuna düşerler ve aşağıdaki komutla teşhis edebilirler.
1 2 3 |
pi@raspberry:~ $ sudo systemctl --failed openvpn-server@intranert.service loaded failed failed OpenVPN service for intranert |
Yukarıdaki ekran çıktısında openvpn-server htalı bir durumdadır. Bu servisi sistemden tamamen kaldırmak için önce servisi maskeleyin ve devre dışı bırakın:
1 2 3 |
pi@raspberry:~$ sudo systemctl disable openvpn-server pi@raspberry:~$ sudo systemctl mask openvpn-server |
Ardından aşağıdaki komutla servis dosyasının konumunu bulun:
1 2 3 |
pi@raspberry:~$ find /etc/systemd/system -name openvpn* /etc/systemd/system/multi-user.target.wants/openvpn.service |
Dosyanı konumunu bulduktan sonra servis dosyasının başlattığı binary dosyaları öğrenebilirsiniz. Bu servis dosyasının içeriği servise ait çalıştırılabilir binary hakkında çok şey söyler. cat ile içeriğine bakarak çalıştırılabilir dosyaların yerini öğrenip silmeyi tercih edebilirsiniz.
Ardından servis dosyasını silin ve SystemD’ın failed listesini sıfırlayın ve servis dosyalarını yeniden yükleyin:
1 2 3 4 5 |
pi@raspberry:~$ sudo rm -rf /etc/systemd/system/multi-user.target.wants/openvpn.service pi@raspberry:~$ sudo systemctl reset-failed pi@raspberry:~$ sudo systemctl daemon-reload |
