Пример #1
0
gboolean
systemd_unit_exec(svc_action_t * op)
{
    CRM_ASSERT(op);
    CRM_ASSERT(systemd_init());
    op->rc = PCMK_OCF_UNKNOWN_ERROR;
    crm_debug("Performing %ssynchronous %s op on systemd unit %s named '%s'",
              op->synchronous ? "" : "a", op->action, op->agent, op->rsc);

    if (safe_str_eq(op->action, "meta-data")) {
        /* TODO: See if we can teach the lrmd not to make these calls synchronously */
        op->stdout_data = systemd_unit_metadata(op->agent);
        op->rc = PCMK_OCF_OK;

        if (op->synchronous == FALSE) {
            operation_finalize(op);
        }
        return TRUE;
    }

    systemd_unit_by_name(op->agent, op);
    if (op->synchronous == FALSE) {
        return TRUE;
    }

    return op->rc == PCMK_OCF_OK;
}
Пример #2
0
gboolean
systemd_unit_exists(const char *name)
{
    /* Note: Makes a blocking dbus calls
     * Used by resources_find_service_class() when resource class=service
     */
    if(systemd_unit_by_name(name, NULL)) {
        return TRUE;
    }
    return FALSE;
}
Пример #3
0
gboolean
systemd_unit_exists(const char *name)
{
    char *unit = NULL;

    /* Note: Makes a blocking dbus calls
     * Used by resources_find_service_class() when resource class=service
     */
    unit = systemd_unit_by_name(name, NULL);
    if(unit) {
        free(unit);
        return TRUE;
    }
    return FALSE;
}
Пример #4
0
static char *
systemd_unit_metadata(const char *name, int timeout)
{
    char *meta = NULL;
    char *desc = NULL;
    char *path = systemd_unit_by_name(name, NULL);

    if (path) {
        /* TODO: Worth a making blocking call for? Probably not. Possibly if cached. */
        desc = pcmk_dbus_get_property(systemd_proxy, BUS_NAME, path, BUS_NAME ".Unit", "Description", NULL, NULL, NULL, timeout);
    } else {
        desc = crm_strdup_printf("Systemd unit file for %s", name);
    }

    meta = crm_strdup_printf("<?xml version=\"1.0\"?>\n"
                           "<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n"
                           "<resource-agent name=\"%s\" version=\"0.1\">\n"
                           "  <version>1.0</version>\n"
                           "  <longdesc lang=\"en\">\n"
                           "    %s\n"
                           "  </longdesc>\n"
                           "  <shortdesc lang=\"en\">systemd unit file for %s</shortdesc>\n"
                           "  <parameters>\n"
                           "  </parameters>\n"
                           "  <actions>\n"
                           "    <action name=\"start\"   timeout=\"15\" />\n"
                           "    <action name=\"stop\"    timeout=\"15\" />\n"
                           "    <action name=\"status\"  timeout=\"15\" />\n"
                           "    <action name=\"restart\"  timeout=\"15\" />\n"
                           "    <action name=\"monitor\" timeout=\"15\" interval=\"15\" start-delay=\"15\" />\n"
                           "    <action name=\"meta-data\"  timeout=\"5\" />\n"
                           "  </actions>\n"
                           "  <special tag=\"systemd\">\n"
                           "  </special>\n" "</resource-agent>\n", name, desc, name);
    free(desc);
    free(path);
    return meta;
}
Пример #5
0
static char *
systemd_unit_metadata(const char *name)
{
    char *path = NULL;
    char *meta = NULL;
    char *desc = NULL;
    GError *error = NULL;

    CRM_ASSERT(systemd_init());
    if (systemd_unit_by_name(systemd_proxy, name, &path, NULL, &error)) {
        desc = systemd_unit_property(path, BUS_NAME ".Unit", "Description");
    } else {
        desc = g_strdup_printf("systemd unit file for %s", name);
    }

    meta = g_strdup_printf("<?xml version=\"1.0\"?>\n"
                           "<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n"
                           "<resource-agent name=\"%s\" version=\"0.1\">\n"
                           "  <version>1.0</version>\n"
                           "  <longdesc lang=\"en\">\n"
                           "    %s\n"
                           "  </longdesc>\n"
                           "  <shortdesc lang=\"en\">systemd unit file for %s</shortdesc>\n"
                           "  <parameters>\n"
                           "  </parameters>\n"
                           "  <actions>\n"
                           "    <action name=\"start\"   timeout=\"15\" />\n"
                           "    <action name=\"stop\"    timeout=\"15\" />\n"
                           "    <action name=\"status\"  timeout=\"15\" />\n"
                           "    <action name=\"restart\"  timeout=\"15\" />\n"
                           "    <action name=\"monitor\" timeout=\"15\" interval=\"15\" start-delay=\"15\" />\n"
                           "    <action name=\"meta-data\"  timeout=\"5\" />\n"
                           "  </actions>\n"
                           "  <special tag=\"systemd\">\n"
                           "  </special>\n" "</resource-agent>\n", name, desc, name);
    free(desc);
    return meta;
}
Пример #6
0
gboolean
systemd_unit_exists(const char *name)
{
    char *path = NULL;
    GError *error = NULL;
    gboolean pass = FALSE;

    if (systemd_init() == FALSE) {
        return FALSE;
    }

    pass = systemd_unit_by_name(systemd_proxy, name, &path, NULL, &error);

    if (error || pass == FALSE) {
        crm_err("Call to ListUnits failed: %s", error ? error->message : "unknown");
        g_error_free(error);
        pass = FALSE;

    } else {
        crm_trace("Got %s", path);
    }
    /* free(path) */
    return pass;
}
Пример #7
0
gboolean
systemd_unit_exec(svc_action_t * op, gboolean synchronous)
{
    char *unit = NULL;
    GError *error = NULL;
    gboolean pass = FALSE;
    GVariant *_ret = NULL;
    const char *action = op->action;
    char *name = systemd_service_name(op->agent);

    op->rc = PCMK_EXECRA_UNKNOWN_ERROR;
    CRM_ASSERT(systemd_init());

    crm_debug("Performing %ssynchronous %s op on systemd unit %s named '%s'",
              synchronous ? "" : "a", op->action, op->agent, op->rsc);

    if (safe_str_eq(op->action, "meta-data")) {
        op->stdout_data = systemd_unit_metadata(op->agent);
        op->rc = PCMK_EXECRA_OK;
        goto cleanup;
    }

    pass = systemd_unit_by_name(systemd_proxy, op->agent, &unit, NULL, &error);
    if (error || pass == FALSE) {
        crm_debug("Could not obtain unit named '%s': %s", op->agent,
                  error ? error->message : "unknown");
        if (error && strstr(error->message, "systemd1.NoSuchUnit")) {
            op->rc = PCMK_EXECRA_NOT_INSTALLED;
        }
        g_error_free(error);
        goto cleanup;
    }

    if (safe_str_eq(op->action, "monitor") || safe_str_eq(action, "status")) {
        char *state = systemd_unit_property(unit, BUS_NAME ".Unit", "ActiveState");

        if (g_strcmp0(state, "active") == 0) {
            op->rc = PCMK_EXECRA_OK;
        } else {
            op->rc = PCMK_EXECRA_NOT_RUNNING;
        }

        free(state);
        goto cleanup;

    } else if (g_strcmp0(action, "start") == 0) {
        action = "StartUnit";
    } else if (g_strcmp0(action, "stop") == 0) {
        action = "StopUnit";
    } else if (g_strcmp0(action, "restart") == 0) {
        action = "RestartUnit";
    } else {
        op->rc = PCMK_EXECRA_UNIMPLEMENT_FEATURE;
        goto cleanup;
    }

    crm_debug("Calling %s for %s: %s", action, op->rsc, unit);
    if (synchronous == FALSE) {
        g_dbus_proxy_call(systemd_proxy, action, g_variant_new("(ss)", name, "replace"),
                          G_DBUS_CALL_FLAGS_NONE, op->timeout, NULL, systemd_unit_exec_done, op);
        free(unit);
        free(name);
        return TRUE;
    }

    _ret = g_dbus_proxy_call_sync(systemd_proxy, action, g_variant_new("(ss)", name, "replace"),
                                  G_DBUS_CALL_FLAGS_NONE, op->timeout, NULL, &error);

    if (error) {
        /* ignore "already started" or "not running" errors */
        if (safe_str_eq(op->action, "stop")
            && strstr(error->message, "systemd1.InvalidName")) {
            crm_trace("Masking Stop failure for %s: unknown services are stopped", op->rsc);
            op->rc = PCMK_EXECRA_OK;
        } else {
            crm_err("Could not issue %s for %s: %s (%s)", action, op->rsc, error->message, unit);
        }
        g_error_free(error);

    } else if(g_variant_is_of_type (_ret, G_VARIANT_TYPE("(o)"))) {
        char *path = NULL;

        g_variant_get(_ret, "(o)", &path);
        crm_info("Call to %s passed: type '%s' %s", op->action, g_variant_get_type_string(_ret),
                 path);
        op->rc = PCMK_EXECRA_OK;

    } else {
        crm_err("Call to %s passed but return type was '%s' not '(o)'", op->action, g_variant_get_type_string(_ret));
        op->rc = PCMK_EXECRA_OK;
    }

  cleanup:
    free(unit);
    free(name);

    if (_ret) {
        g_variant_unref(_ret);
    }
    if (synchronous == FALSE) {
        operation_finalize(op);
        return TRUE;
    }
    return op->rc == PCMK_EXECRA_OK;
}