SystemD Sistem Yükleyicisi ve Yöneticisi

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.

SystemD tarafından bilinen tüm birim türlerinin adlarını listelemek için aşağıdaki komutu çalıştırabilirsiniz:

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:

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:

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:

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:

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:

Ağ ve çoklu kullanıcı desteği ile grafik masaüstü kipine geçmek için graphical hedefi kullanılır:

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;

Ön tanımlı açılış çalışma seviyesini multi-user olarak değiştirmek için:

Raspberry Pi’ın grafik kullanıcı arabirimi ile açılmasını sağlamak graphical hedefi kullanılır:

Raspberry Pi’ın kurtarma kipinde açılması için rescue hedefi kullanılır:

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:

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.

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:

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:

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:

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.

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:

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:

Ç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:

Servisin SystemD içinde tanımlanmış olan özelliklerini görüntülemek için show seçeneğini aşağıdaki gibi kullanabilirsiniz:

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:

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:

Bir servisin çalışıp çalışmadığı hakkında durum bilgisi almak için ise status seçeneği kullanılır:

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:

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.

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:

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:

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:

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:

Ö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:

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:

Daha sonra nano editörünü aşağıdaki gibi kullanarak birim dosyasını oluşturalım:

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:

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:

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.

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:

Ardından aşağıdaki komutla servis dosyasının konumunu bulun:

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:

Yazar: Özgür Koca

Yazar - Tankado.com

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.