You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求基于glib gio与systemd服务交互的示例代码

使用GLib GIO与systemd服务交互的示例代码

systemd通过DBus提供服务管理接口,GLib的GIO模块可通过GDBusProxy直接与这些接口交互。以下是实现启动、停止、查询服务状态的完整示例:

示例代码

#include <glib-2.0/gio/gio.h>
#include <stdio.h>

#define SYSTEMD_BUS_NAME "org.freedesktop.systemd1"
#define SYSTEMD_OBJECT_PATH "/org/freedesktop/systemd1"
#define SYSTEMD_MANAGER_INTERFACE "org.freedesktop.systemd1.Manager"
#define SYSTEMD_SERVICE_INTERFACE "org.freedesktop.systemd1.Service"

// 查询指定服务的状态
gboolean get_service_status(const gchar *service_name, GError **error) {
    GDBusProxy *manager_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
                                                              G_DBUS_PROXY_FLAGS_NONE,
                                                              NULL,
                                                              SYSTEMD_BUS_NAME,
                                                              SYSTEMD_OBJECT_PATH,
                                                              SYSTEMD_MANAGER_INTERFACE,
                                                              NULL,
                                                              error);
    if (!manager_proxy) return FALSE;

    // 获取服务的DBus对象路径
    GVariant *result = g_dbus_proxy_call_sync(manager_proxy,
                                              "GetUnit",
                                              g_variant_new("(s)", service_name),
                                              G_DBUS_CALL_FLAGS_NONE,
                                              -1,
                                              NULL,
                                              error);
    if (!result) {
        g_object_unref(manager_proxy);
        return FALSE;
    }

    gchar *unit_path;
    g_variant_get(result, "(o)", &unit_path);
    g_variant_unref(result);

    // 创建服务对象的代理
    GDBusProxy *service_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
                                                              G_DBUS_PROXY_FLAGS_NONE,
                                                              NULL,
                                                              SYSTEMD_BUS_NAME,
                                                              unit_path,
                                                              SYSTEMD_SERVICE_INTERFACE,
                                                              NULL,
                                                              error);
    g_free(unit_path);
    if (!service_proxy) {
        g_object_unref(manager_proxy);
        return FALSE;
    }

    // 获取服务的ActiveState属性
    GVariant *state = g_dbus_proxy_get_cached_property(service_proxy, "ActiveState");
    if (state) {
        const gchar *state_str = g_variant_get_string(state, NULL);
        g_print("服务 %s 状态: %s\n", service_name, state_str);
        g_variant_unref(state);
    }

    g_object_unref(service_proxy);
    g_object_unref(manager_proxy);
    return TRUE;
}

// 启动指定服务
gboolean start_service(const gchar *service_name, GError **error) {
    GDBusProxy *manager_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
                                                              G_DBUS_PROXY_FLAGS_NONE,
                                                              NULL,
                                                              SYSTEMD_BUS_NAME,
                                                              SYSTEMD_OBJECT_PATH,
                                                              SYSTEMD_MANAGER_INTERFACE,
                                                              NULL,
                                                              error);
    if (!manager_proxy) return FALSE;

    GVariant *result = g_dbus_proxy_call_sync(manager_proxy,
                                              "StartUnit",
                                              g_variant_new("(ss)", service_name, "replace"),
                                              G_DBUS_CALL_FLAGS_NONE,
                                              -1,
                                              NULL,
                                              error);
    if (result) {
        g_variant_unref(result);
        g_print("服务 %s 启动请求已发送\n", service_name);
    }

    g_object_unref(manager_proxy);
    return result != NULL;
}

// 停止指定服务
gboolean stop_service(const gchar *service_name, GError **error) {
    GDBusProxy *manager_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
                                                              G_DBUS_PROXY_FLAGS_NONE,
                                                              NULL,
                                                              SYSTEMD_BUS_NAME,
                                                              SYSTEMD_OBJECT_PATH,
                                                              SYSTEMD_MANAGER_INTERFACE,
                                                              NULL,
                                                              error);
    if (!manager_proxy) return FALSE;

    GVariant *result = g_dbus_proxy_call_sync(manager_proxy,
                                              "StopUnit",
                                              g_variant_new("(ss)", service_name, "replace"),
                                              G_DBUS_CALL_FLAGS_NONE,
                                              -1,
                                              NULL,
                                              error);
    if (result) {
        g_variant_unref(result);
        g_print("服务 %s 停止请求已发送\n", service_name);
    }

    g_object_unref(manager_proxy);
    return result != NULL;
}

int main(int argc, char *argv[]) {
    g_type_init();
    GError *error = NULL;

    if (argc < 3) {
        g_print("用法: %s <start/stop/status> <服务名(如nginx.service)>\n", argv[0]);
        return 1;
    }

    const gchar *action = argv[1];
    const gchar *service = argv[2];

    if (g_str_equal(action, "start")) {
        if (!start_service(service, &error)) goto error_handler;
    } else if (g_str_equal(action, "stop")) {
        if (!stop_service(service, &error)) goto error_handler;
    } else if (g_str_equal(action, "status")) {
        if (!get_service_status(service, &error)) goto error_handler;
    } else {
        g_print("无效操作: %s,支持的操作:start/stop/status\n", action);
        return 1;
    }

    return 0;

error_handler:
    g_print("错误: %s\n", error->message);
    g_error_free(error);
    return 1;
}

编译与运行

编译时需链接GLib和GIO库,使用以下命令:

gcc -o systemd-gio systemd-gio.c `pkg-config --cflags --libs glib-2.0 gio-2.0`

运行需要root权限(管理systemd服务需特权):

sudo ./systemd-gio status nginx.service
sudo ./systemd-gio start nginx.service

关键说明

  • 通过系统DBus与systemd交互,使用G_BUS_TYPE_SYSTEM而非会话DBus
  • systemd核心管理接口为org.freedesktop.systemd1.Manager,提供StartUnit、StopUnit、GetUnit等方法
  • 服务的具体属性(如运行状态)通过服务对象的org.freedesktop.systemd1.Service接口获取
  • 示例使用同步DBus调用,适合简单场景;如需异步处理,可替换为g_dbus_proxy_call()

内容的提问来源于stack exchange,提问作者CTCoding

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 21:46:05