File pacemaker-libcrmcommon-functions-agent-specifications.patch of Package pacemaker.14737
commit d16acf031b3502dfccb8ae3bac5c0203f9f0c0d1
Author: Ken Gaillot <kgaillot@redhat.com>
Date: Fri Oct 6 16:23:05 2017 -0500
Feature: libcrmcommon: add functions for using agent specifications
Index: pacemaker/include/crm/common/util.h
===================================================================
--- pacemaker.orig/include/crm/common/util.h
+++ pacemaker/include/crm/common/util.h
@@ -140,4 +140,8 @@ void crm_gnutls_global_init(void);
int crm_exit(int rc);
bool pcmk_acl_required(const char *user);
+bool crm_provider_required(const char *standard);
+int crm_parse_agent_spec(const char *spec, char **standard, char **provider,
+ char **type);
+
#endif
Index: pacemaker/lib/common/utils.c
===================================================================
--- pacemaker.orig/lib/common/utils.c
+++ pacemaker/lib/common/utils.c
@@ -2435,3 +2435,81 @@ crm_gnutls_global_init(void)
}
#endif
+/*!
+ * \brief Check whether a resource standard requires a provider to be specified
+ *
+ * \param[in] standard Standard name
+ *
+ * \return TRUE if standard requires a provider, FALSE otherwise
+ */
+bool
+crm_provider_required(const char *standard)
+{
+ CRM_CHECK(standard != NULL, return FALSE);
+
+ /* @TODO
+ * - this should probably be case-sensitive, but isn't,
+ * for backward compatibility
+ * - it might be nice to keep standards' capabilities (supports provider,
+ * master/slave, etc.) as structured data somewhere
+ */
+ if (!strcasecmp(standard, "ocf")) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*!
+ * \brief Parse a "standard[:provider]:type" agent specification
+ *
+ * \param[in] spec Agent specification
+ * \param[out] standard Newly allocated memory containing agent standard (or NULL)
+ * \param[out] provider Newly allocated memory containing agent provider (or NULL)
+ * \param[put] type Newly allocated memory containing agent type (or NULL)
+ *
+ * \return pcmk_ok if the string could be parsed, -EINVAL otherwise
+ *
+ * \note It is acceptable for the type to contain a ':' if the standard supports
+ * that. For example, systemd supports the form "systemd:UNIT@A:B".
+ * \note It is the caller's responsibility to free the returned values.
+ */
+int
+crm_parse_agent_spec(const char *spec, char **standard, char **provider,
+ char **type)
+{
+ char *colon;
+
+ CRM_CHECK(spec && standard && provider && type, return -EINVAL);
+ *standard = NULL;
+ *provider = NULL;
+ *type = NULL;
+
+ colon = strchr(spec, ':');
+ if ((colon == NULL) || (colon == spec)) {
+ return -EINVAL;
+ }
+
+ *standard = calloc(colon - spec + 1, sizeof(char));
+ strncpy(*standard, spec, colon - spec);
+ spec = colon + 1;
+
+ if (crm_provider_required(*standard)) {
+ colon = strchr(spec, ':');
+ if ((colon == NULL) || (colon == spec)) {
+ free(*standard);
+ return -EINVAL;
+ }
+ *provider = calloc(colon - spec + 1, sizeof(char));
+ strncpy(*provider, spec, colon - spec);
+ spec = colon + 1;
+ }
+
+ if (*spec == '\0') {
+ free(*standard);
+ free(*provider);
+ return -EINVAL;
+ }
+
+ *type = strdup(spec);
+ return pcmk_ok;
+}