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; }
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; }
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; }
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; }
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; }
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; }
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; }