From Fedora Project Wiki

Project Information

Organization: Fedora Project

Fedora SIG: Fedora DotNet SIG

Student: Amitosh Swain Mahapatra

Possible mentor: Radka (rhea) Janek

Contact Information

PGP Key 89A3A2B0
Time zone UTC +5:30
Freenode IRC nick amitosh
Github Agathver
Twitter OriginalASM



This project aims to create a .NET core wrapper library for systemd, a service manager and process hypervisor in modern Linux systems. Using this library, actions such as monitoring and controlling the state of services, controlling power, devices and other system aspects of the underlying system can be performed from a language running on .NET, such as C#.


systemd is a suite of basic building blocks for a Linux system. It provides a system and service manager and starts the rest of the system. It also includes a logging system, utilities to control basic system configuration like the hostname, date, locale etc. systemd provides a way for programmatic access to systemd actions through the DBus API. This library would use DBus to interact with systemd daemon and offer monitoring and control over services running on the system.


  • A Job is a task that has been queued to the systemd job queue. It can be any request to systemd such as a request to start a service or a request to restart the system. Every systemd command to perform an action, creates a job which is identified by its ID, and is queued to the systemd job queue. systemd then processes the job sequentially. A job can also be cancelled before it is executed. This results in the removal of the job from the systemd job queue.
  • A Unit is an individual systemd service. It can represent a device, a daemon service, or a repeating action i.e., timer. It is mapped to a systemd unit file, which serves as its identifier.
  • A User is an entity, under which context a process can run. The user of a process determines the actions it can perform.
  • A Session is a group of processes which run under the control of a single user. It usually refers to a shell session. Each interactive login by the user creates a session.
  • A Seat refers to a set of hardware peripherals using which a user can start an independent interactive Session.

systemd is broken down into various services which are started by systemd itself. These services along with systemd, provide the basic services required by Linux system.

systemd components
Service Role
manager The principal component of systemd, which manages services and basic system configuration.
journald Provides an event logging system.
logind Manages user login sessions, and provides a convenient way to logout, shutdown, restart etc.
networkd Controls network related settings
timedated Manages time-date related settings

Project Goals

Create a .NET wrapper for systemd, that will be able to:

  1. Fetch a list of services available on the host.
  2. Fetch a service by its unit ID.
  3. Control the state of a service - enable, disable, start, stop, restart, reload and kill.
  4. Control the power state of the system - restart, shutdown, suspend and halt.
  5. Create events to listen for various systemd signals.

Optional Goals (if time permits)

  1. Logging interface to log using systemd-journald


1st evaluation

  1. Implementation of the following interfaces in C#, and the binding using DBus APIs.
    1. org.freedesktop.systemd1.Manager
    2. org.freedesktop.systemd1.Unit
    3. org.freedesktop.systemd1.Job
  2. Library will be able to query a service’s status, start, stop and restart services. It will also list all currently running services.

2nd evaluation

  1. Implementation of systemd signals.
  2. Implementation of the following interfaces in C#, and the binding using DBus APIs.
    • org.freedesktop.login1.Manager
    • org.freedesktop.login1.User
    • org.freedesktop.login1.Session
    • org.freedesktop.login1.Seat
  3. Library will be able to shutdown and reboot the host, schedule reboots, display and logout users and their sessions.

3rd evaluation

A systemd wrapper library, published as a nuget package.


We will be implementing the interface to systemd service manager and the systemd-logind manager. We are going to use the DBus API of systemd to make inter-process calls to systemd daemon. For DBus in C#, We will be using Tom Deseyn’s Tmds.DBus library.

Advantages of DBus

  • No dependency on presence of specific system libraries.
  • 100% purely portable and managed code.

Advantages of Tmds.DBus over other libraries

  • The library is entirely based on C# async/await pattern, for which it is easier to implement an async/await based API for systemd. It will be especially attractive to users implementing with ASP.NET async controller actions.
  • As a side effect of being based on async/await, developing using async/await will result in cleaner and easier implementation.

Alternatives considered

P/Invoke wrapper on


  1. Platform dependent, needs testing in all supported architectures.
  2. Running code using such a library might need multi-arch support, if not compiled carefully.

NDesk.DBus/Mono.DBus library for systemd.

This is another library that enables to make us DBus calls from .NET and Mono.

  1. Disadvantages of NDesk.DBus
  2. Has not tested been against .NET core.
  3. Does not appear to be maintained currently.

The library

The library will contain a set of interfaces that specifies the general API for interacting with systemd from .NET. Any implementations are required to provide the same set of methods. This set of interfaces will make the primary part that a consumer using the library will use.


All interfaces will contain both, the synchronous and asynchronous versions of all the supported systemd operations. As per the .NET conventions, all the async counterparts will be suffixed with Async.

API Overview for systemd Wrapper Library

Namespace Systemd

Class Description
Systemd Main entrypoint to the library, returns default implementations of ISystemdManager and ISystemdLogind manager.


This class will serve as the main entrypoint to the library. It will return implementations of ISystemdManager and ISystemdLogind manager.

Method Description
GetManager Returns an interface to systemd manager.
GetLoginManager Returns an interface to systemd-logind manager.

Namespace Systemd.Manager

Interface Description
ISystemdManager Represents the systemd Manager
ISystemdUnit Represents a systemd unit
ISystemdJob Represents a systemd job


ISystemdManager interface exposes the functionality of systemd service manager.

Method Description
ListUnits Return a list of service units currently loaded by systemd
GetUnit Returns a service unit, specified by its unit ID.
EnableUnitFiles Enables a list of systemd unit files
DisableUnitFiles Disables a list of unit files
SetEnvironment Sets a systemd environment variable which is passed on to all services started by systemd
UnsetEnvironment Unsets a previously defined systemd environment variable.
Reload Reloads all unit files
ListUnitFiles Lists all unit files found in disk.

These methods, when invoked with appropriate parameters, will return a object of a class which implements ISystemdUnit interface.


The ISystemdUnit interface is a representation of an individual systemd unit file. Using an instance of an implementation that implements this interface, the consumer will be able to start, stop, query status, restart and kill the underlying service. The ISystemdUnit interface will be modelled after The interface will contain the following methods:

Method Description
Start Attempts to start the unit.
Stop Attempts to stop the unit.
Restart Attempts to restart the unit. The unit is started if it is not running.
Kill Kills the unit.
Reload Attempts to reload the unit. The unit is started if it is not running.
ReloadOrRestart Attempts to reload the service, if the service provides such an action, else restarts the service.
ReloadOrRestartIfRunning Attempts to reload the service, if the service provides such an action, else creates a request to restart the service only if the unit is already running. Calls systemd dbus method ReloadOrTryRestart.
RestartIfRunning Creates a request to restart the service, only if it is running. Calls systemd dbus method TryRestart.

Every method will return an instance of an implementation of ISystemdJob. It represents a systemd job with the job queue, which can be used later to check the status or cancel the job.


The ISystemdJob represents a systemd job in the job queue. It will have the following methods and properties:

Method Description
Cancel Cancels the job. Can only be called before the job has been executed by systemd.

This pattern will leave the scope for extending or replacing the default implementation of the ISystemdManager, such as connecting to a remote host using SSH and proxying calls between the local and remote systems.

Namespace Systemd.Logind

Interface Description
ISystemdLogindManager Represents the systemd-logind manager.
IUser Represents a system user in the host.
ISession Represents a session started by an user.
ISeat Represents a seat in a multi seat system.


ISystemdLogindManager interface exposes the functionality of systemd service manager.

Method Description
GetSession Get a session by its session ID or PID,
GetUser Get an user by its ID or PID,
GetSeat Get a Seat by its ID or PID,
AttachDevice Attaches a device by its /dev node to a seat
RemoveDevice Removes a device attached to a seat.
FlushDevices Removes all device attachments made by AttachDevice and restores the default attachment of all devices.
PowerOff Powers off the host.
Reboot Reboots the host.
Suspend Suspends the host.
Hibernate Hibernates the host.
HybridSleep Puts the host to hybrid sleep.
CanPowerOff Returns if the host supports power off state (S5) and the calling user has the privileges to perform a shutdown.
CanReboot Returns if the host supports reboot and the calling user has the privileges to perform a reboot.
CanSuspend Returns if the host supports suspend to RAM and the calling user has the privileges to perform a suspend to RAM (sleep mode).
CanHibernate Returns if the host supports suspend to disk and the calling user has the privileges to perform a suspend to disk.
CanHybridSleep Returns if the host supports hybrid sleep (suspend to RAM and subsequent suspend to disk, if not awaken for an extended period of time) and the calling user has the privileges to perform a shutdown.
ScheduleShutdown Schedules a shutdown
CancelScheduledShutdown Cancels a previously scheduled shutdown


The IUser interface represents a User on the host.

Method Description
Kill Forcibly kills all processes started by the user and logs out.
Terminate Terminates the user and sessions started by the user.


The ISession interface represents a shell session started by a user.

Method Description
Lock Locks the session. Shows a lock screen for graphical sessions.
Unlock Unlocks the session
Kill Kills the session


The ISeat interface represents a physical seat on a multi-seat capable system.

Method Description
ActivateSession Activates a session identified by session ID on the seat
Terminate Terminates the session


systemd signals provide an way to notify listeners about various system events. Signals will be implemented as standard .NET events on ISystemdManager and ISystemdLogindManager.

+ Signals of systemd manager
Signal Description
UnitAdded Raised when a new unit is added. Maps to underlying systemd signal UnitNew.
UnitRemoved Raised when a unit is removed.
UnitFilesChanged Raised when a unit file is modified in any manner.
JobAdded Raised when a new job is queued in systemd job queue. Maps to underlying systemd signal JobNew.
JobRemoved Raised when a job is removed from the systemd job queue.
StartupFinished Raised after system startup sequence is completed.
Reloading Raised when systemd is reloading untis.
Signals of systemd-logind
Signal Description
SessionCreated Raised when a new session is created. Maps to underlying systemd signal SessionNew.
SessionRemoved Raised when a session is removed.
UserAdded Raised when a new user logs into the system. Maps to underlying systemd signal UserNew.
UserRemoved Raised when a user logs out of the host, and exiting all sessions.
SeatAdded Raised when a new seat is attached to the host. Maps to underlying systemd signal SeatNew.
SeatRemoved Raised when a seat is removed from the host.
ShuttingDown Raised before starting the shutdown process, consumers can perform pre-exit tasks after receiving this signal. Maps to underlying systemd signal PrepareForShutdown
PrepareForSleep Raised before transitioning into a sleep or hybrid sleep state. Consumers can pause any interactive operations on receiving this signal.

Implementation using DBus

The default implementation included with this library will be an implementation of ISystemdManager which will use DBus as its medium to connect to the local host’s DBus running on the system bus and the session bus.

The systemd service manager is available at org.freedesktop.systemd1.Manager DBus interface in the system bus and session bus. The systemd interface on system bus is used to control system wide services, and the interface on session bus is used to control user services.

The systemd-logind is available at org.freedesktop.login1.Manager DBus interface in the system bus.

The default implementation will be set of classes under the implementation namespace. The classes will proxy all method calls to a DBus interfaces using Tmds.DBus.

The general pattern for all classes in the implementation will be: Constructor that accepts the underlying DBus interface for the class. Methods that when invoked will call methods on the DBus interface.


The main entry point to the library will be a singleton Systemd class. This singleton class will return an instance of another singleton classes that implement the methods of the ISystemdManager or the ISystemdLogindManager interface.


systemd-logind functionality such as shutdown and restart cannot be tested in CI

Shutdown and restart will stop a system and start it again. Tests cannot be made in virtual machine based CI systems.

Solution: Using docker containers running systemd

A docker container can contain logind tests for reboot, and shutdown, which will be started on receiving a signal from the test runner host. The host will then check for desired outcome of the test by using the API of docker daemon.

Multi-seat management, session locking and unlocking cannot be tested in CI

Multi-seat and session locking is only relevant when the system has at least 2 display units, CI environments and docker containers are headless.

Current workaround: Test locally (inconvenient)

I will be testing the code on my desktop, connected to two monitors, two keyboards and two mice, to make a multi-seat system.

Possible Solutions:

Here are some alternatives to consider in the long run:

Test using nested virtual machines

We can setup QEMU-KVM virtual machines, inside the CI environment, with two display units and test within it. However, this will be inconvenient as it requires moving huge files (8-9 GB) around (as CI services do not cache files), and due to memory constraints inside a CI environment.

Testing on a cloud virtual machine The same KVM virtual machines can be made to run inside a cloud hosted virtual machine of required size. This is more practical, but requires a lot of work.


Phase I - Learning, ideation and preparation

  • May 5 - second week of May:
    • Learn more about systemd and its dbus interface.
    • Discuss with the community to decide on the exact particulars of the implementation, library pattern, code styles, possible pitfalls etc.
    • Learn about publishing packages to NuGet.
  • Third week May - 1st of June (during community bonding period):
    • Setting up IDEs, Git repositories etc.
    • Setting up a local testing environment.
    • Creating classes and interfaces for systemd for use with the DBus API.

Phase 2 - Coding for the systemd manager:

  • Week 1 (1st June - 6th June):
    • Connecting to a running systemd instance.
    • Handling and generating proper exceptions.
  • Week 2 (7th June - 13th June):
    • Listing active services and their status.
    • Finding an installed service by its id.
  • Week 3 (14th June - 21nd June):
    • Enabling and disabling unit files.
    • Start, Stop, Kill, Restart and Reload units.
  • Week 4 (21nd - 26th June):
    • Fix bugs and write additional tests.
    • Prepare for 1st term evaluation.
  • Week 5 (29th June - 6th July):
    • Begin implementing the systemd-logind wrapper.
    • Library will now be able to shutdown, restart and halt the host.
  • Week 6 (7th July - 13th July):
    • Fetching users, sessions and seat from logind.
    • Operations on users, sessions and seats - Kill, Terminate
  • Week 7 (14th July - 20th July):
    • Test seat operations on a real multi-seat setup.
  • Week 8 (21st July - 26th July):
    • Write more tests
    • Prepare for 2nd term evaluation

Phase III - Testing, Optimization and Documentation

  • Week 9 (29th July - 5th August):
    • Resolve discovered issues.
    • Incorporate suggestions by the community.
    • Check test code coverage of the library
    • Test on real hosts
  • Week 10 (6th August - 12th August):
    • Write more tests if required.
    • Review inline documentation and fix them
    • Prepare HTML documentation
    • Document testing processes.
  • Week 11 (12th August - 18th August):
    • Buffer time for unforeseen circumstances.
  • Week 12 (19th August - 25th August):
    • Publish package to nuget, after approval.
    • Prepare for final evaluation.

About Me

Educational background

I am currently a second year B.Tech student in computer science and engineering at College of Engineering and Technology, Bhubaneswar, India. How computers and software worked have fascinated me since my middle school days. My first exposure to programming was with C in 6th grade. Since then, I have been constantly exploring new areas in programming. I chose to study computer science, in order to satisfy my curiosity for learning new things in the field of computer science and IT, and also due to fact that I perform academically well in computer science courses, due to my interest in the subject.

Why did I choose Fedora ?

My first exposure to Linux world was thorough Fedora. It was back in my 9th grade when I first installed Fedora 16 (Verne). So I was always interested to contribute back to the project if I got any chance. Fedora project is also a very good project with a large user base, so any effort in contributing the project will help a large community.

Besides, the project idea of building a .NET core wrapper to systemd was appealing as I’m familiar with systemd and its working, as well as I have good coding experience in .NET in general.

Why did I choose this project ?

.NET core is a budding open source platform, based on the foundation of the well tested .NET framework. It is cross-platform and has the potential to become a great server side framework, in near future.

However, one of the of hurdles for developing solutions in .NET in Linux has been the lack of decent libraries for system integration. This project is a step towards bridging those gaps and bringing a deeper system integration to .NET core applications. Experience I have been writing code in .NET over last four years. I am confident enough about my language skills. I have completed a number of freelance projects using .NET. I also have a good experience in object oriented programming concepts and software testing.

Being a long time Fedora user and a programmer with curiosity, I am familiar with the internal workings of a Linux system and system APIs. I have worked with DBus (though mostly in Python and Go) as part of two hobby projects.

Last summer, I had interned at an educational startup (and subsequently worked part time of 8 months) where I have worked with PHP and .NET (on Windows) and managing CentOS and Ubuntu servers. I had written some simple systemd service unit files, and python code that used python bindings for systemd APIs.

Contributions to open source

  • Active contributor to a project called bcrypt. It is a very widely used NodeJS module that provides bcrypt hashing capabilities, which is commonly used to store passwords in hashed form.
  • Member of the technical society of our college where we promote the use of FOSS technology among the students. I also help out students who decide to start using Fedora, Ubuntu or any other Linux system.
  • Answering questions on StackOverflow, CodeProject and AskFedora about FOSS technologies as well as general programming and help questions.

Previous Google Summer of Code Experience

This is my first application to Google Summer of Code programme.

Commitments and engagements during GSoC

I have discussed my proposal with my mentor and have agreed upon the timeline and implementation. If selected, I’ll give my full dedication to the project. I have no prior commitments during the month of June to August and will be able to provide 30 hours a week to the project.

Periods of unavailability or other constraints:

  • May 2 to May 20: I have my end semester exams from during this period. Since this period lies during the community bonding period, I expect it to have very little effect on the implementation of the project. I have one paper per week, so I will be able to devote my free time to research about systemd dbus APIs, to discuss the implementation with the community, and to learn about publishing to NuGet.
  • August 3rd week onwards: My classes are expected to begin from 3rd week of August. During that period, I would be able to give 20-25 hours per week.