diff --git a/maint/mocked/Makefile b/maint/mocked/Makefile deleted file mode 100644 index 1b729c9d52..0000000000 --- a/maint/mocked/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -# -# Copyright 2019 the Pacemaker project contributors -# -# The version control history for this file may have further details. -# -# Copying and distribution of this file, with or without modification, -# are permitted in any medium without royalty provided the copyright -# notice and this notice are preserved. This file is offered as-is, -# without any warranty. -# - -#BASED_LDFLAGS = $$(pkgconf -libs glib-2.0) \ -# $$(pkgconf -libs libxml-2.0) \ -# $$(pkgconf -libs libqb) \ -# $$(pkgconf -libs pacemaker) -BASED_LDFLAGS = $$(pkgconf -libs glib-2.0) \ - $$(pkgconf -libs libxml-2.0) \ - $$(pkgconf -libs libqb) \ - -Wl,-rpath=$(CURDIR)/../../lib/common/.libs \ - -L../../lib/common/.libs -lcrmcommon \ - -L../../lib/pacemaker/.libs -lpacemaker - -BASED_CPPFLAGS = $$(pkgconf -cflags glib-2.0) \ - $$(pkgconf -cflags libxml-2.0) \ - $$(pkgconf -cflags libqb) \ - -I ../.. -I ../../include -g - -PROGRAMS = based - -BASED_OBJECTS = based.o - -# include or not the modules as you wish -BASED_OBJECTS += based-notifyfenced.o - -all: ${PROGRAMS} - -based: $(BASED_OBJECTS) - $(CC) $(BASED_LDFLAGS) $^ -o $@ - -$(BASED_OBJECTS): %.o: %.c - $(CC) $(BASED_CPPFLAGS) $(BASED_LDFLAGS) -c $< -o $@ - -clean: - rm ${PROGRAMS} $(BASED_OBJECTS) diff --git a/maint/mocked/based-notifyfenced.c b/maint/mocked/based-notifyfenced.c deleted file mode 100644 index 1f5b714708..0000000000 --- a/maint/mocked/based-notifyfenced.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright 2019-2020 the Pacemaker project contributors - * - * The version control history for this file may have further details. - * - * Licensed under the GNU General Public License version 2 or later (GPLv2+). - */ - -/* - * Intended demo use case: - * - * - as root, start corosync - * - start "./based -N"; hint: - * su -s /bin/sh -c './based -N' hacluster - * - start pacemaker-fenced; hint: - * su -c 'env PCMK_logpriority=crit ../../daemons/fenced/pacemaker-fenced' - * - wait a bit (5 < seconds < 20) - * - as haclient group (or root), run "stonith admin --list-registered" - * - observe whether such invocation is blocked or not - */ - - -#include /* printf, perror */ - -#include "crm/cib.h" /* cib_zero_copy */ -#include "crm/cib/internal.h" /* CIB_OP_CREATE */ -#include "crm/msg_xml.h" /* F_SUBTYPE */ -#include "daemons/based/pacemaker-based.h" /* cib_notify_diff */ - -#include "based.h" - - -#define OPTCHAR 'N' -static size_t module_handle; - - -struct cib_notification_s { - xmlNode *msg; - struct iovec *iov; - int32_t iov_size; -}; - -/* see based/based_notify.c:cib_notify_send_one */ -static bool -mock_based_cib_notify_send_one(pcmk__client_t *client, xmlNode *xml) -{ - const char *type = NULL; - bool do_send = false; - struct iovec *iov; - ssize_t bytes; - struct cib_notification_s update = { - .msg = xml, - }; - - CRM_CHECK(client != NULL, return true); - pcmk__ipc_prepare_iov(0, xml, 0, &iov, &bytes); - update.iov = iov; - update.iov_size = bytes; - if (client->ipcs == NULL && client->remote == NULL) { - crm_warn("Skipping client with NULL channel"); - return FALSE; - } - - type = crm_element_value(update.msg, F_SUBTYPE); - CRM_LOG_ASSERT(type != NULL); - if (pcmk_is_set(client->options, cib_notify_diff) - && pcmk__str_eq(type, T_CIB_DIFF_NOTIFY, pcmk__str_casei)) { - - if (pcmk__ipc_send_iov(client, update.iov, - crm_ipc_server_event) != pcmk_rc_ok) { - crm_warn("Notification of client %s/%s failed", client->name, client->id); - } - - } - pcmk_free_ipc_event(iov); - - return FALSE; -} - -/* see based/based_notify.c:do_cib_notify + cib_notify_send */ -void -do_cib_notify(pcmk__client_t *cib_client, int options, const char *op, - xmlNode *update, int result, xmlNode *result_data, - const char *msg_type) -{ - xmlNode *update_msg = NULL; - const char *id = NULL; - - update_msg = create_xml_node(NULL, "notify"); - - - crm_xml_add(update_msg, F_TYPE, T_CIB_NOTIFY); - crm_xml_add(update_msg, F_SUBTYPE, msg_type); - crm_xml_add(update_msg, F_CIB_OPERATION, op); - crm_xml_add_int(update_msg, F_CIB_RC, result); - - if (result_data != NULL) { - id = crm_element_value(result_data, XML_ATTR_ID); - if (id != NULL) - crm_xml_add(update_msg, F_CIB_OBJID, id); - } - - if (update != NULL) { - crm_trace("Setting type to update->name: %s", crm_element_name(update)); - crm_xml_add(update_msg, F_CIB_OBJTYPE, crm_element_name(update)); - - } else if (result_data != NULL) { - crm_trace("Setting type to new_obj->name: %s", crm_element_name(result_data)); - crm_xml_add(update_msg, F_CIB_OBJTYPE, crm_element_name(result_data)); - - } else { - crm_trace("Not Setting type"); - } - -#if 0 - attach_cib_generation(update_msg, "cib_generation", the_cib); -#endif - - if (update != NULL) { - add_message_xml(update_msg, F_CIB_UPDATE, update); - } - if (result_data != NULL) { - add_message_xml(update_msg, F_CIB_UPDATE_RESULT, result_data); - } - - mock_based_cib_notify_send_one(cib_client, update_msg); - free_xml(update_msg); -} - -static gboolean -mock_based_notifyfencedmer_callback_worker(gpointer data) -{ - pcmk__client_t *cib_client = (pcmk__client_t *) data; - - xmlNode *result_data; - xmlNode *input, *update; - int options; - char update_str[4096]; - - cib__set_call_options(options, crm_system_name, cib_zero_copy); - - - input = create_xml_node(NULL, "cib"); - - /* spam it */ -#if 0 - for (size_t i = 0; i < SIZE_MAX - 1; i++) { -#else - for (size_t i = 0; i < 10000; i++) { -#endif - /* NOTE: we need to trigger fenced attention, add new fence device */ - snprintf(update_str, sizeof(update_str), -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n", i, i+1); - update = xmlReadMemory(update_str, sizeof(update_str), - "file:///tmp/update", NULL, 0)->children; - do_cib_notify(cib_client, options, CIB_OP_CREATE, input, pcmk_ok, - update, T_CIB_DIFF_NOTIFY); - free_xml(update); - }; - - free_xml(input); -} - -static void -mock_based_notifyfenced_cib_notify_hook(pcmk__client_t *cib_client) -{ - - /* MOCK: client asked for upcoming diff's, let's - spam it a bit after a while... */ - crm_info("Going to spam %s (%s) in 5 seconds...", - cib_client->name, cib_client->id); - mainloop_timer_start(mainloop_timer_add("spammer", 5000, FALSE, - mock_based_notifyfencedmer_callback_worker, - cib_client)); -} - -/* * */ - -static int -mock_based_notifyfenced_argparse_hook(struct mock_based_context_s *ctxt, - bool usage, int argc_to_go, - const char *argv_to_go[]) -{ - const char *opt = *argv_to_go; -restart: - switch(*opt) { - case '-': - if (opt == *argv_to_go) { - opt++; - goto restart; - } - break; - case OPTCHAR: - if (usage) { - printf("spam the \"cib diff\" notification client" - " (targeting pacemaker-fenced in particular)\n"); - - } else { -#if 0 - ctxt->modules[module_handle]->priv = - malloc(sizeof(mock_based_notifyfenced_priv_t)); - if (ctxt->modules[module_handle]->priv == NULL) { - perror("malloc"); - return -1; - } -#endif - } - return 1; - } - return 0; -} - -#if 0 -static void -mock_based_notifyfenced_destroy_hook(module_t *mod) { - free(mod->priv); -} -#endif - -__attribute__((__constructor__)) -void -mock_based_notifyfenced_init(void) { - module_handle = mock_based_register_module((module_t){ - .shortopt = OPTCHAR, - .hooks = { - .argparse = mock_based_notifyfenced_argparse_hook, - //.destroy = mock_based_notifyfenced_destroy_hook, - /* specialized hooks */ - .cib_notify = mock_based_notifyfenced_cib_notify_hook, - } - }); -} diff --git a/maint/mocked/based.c b/maint/mocked/based.c deleted file mode 100644 index 63f61a63ac..0000000000 --- a/maint/mocked/based.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019-2020 the Pacemaker project contributors - * - * The version control history for this file may have further details. - * - * Licensed under the GNU General Public License version 2 or later (GPLv2+). - */ - -/* - * Clean room attempt (admittedly with lot of code borrowed or inspired from - * the full-blown daemon), minimalistic implementation of based daemon, with - * only important aspects being implemented at the moment. - * - * Hopefully easy to adapt for variety of purposes. - * - * NOTE: currently, only cib_rw API end-point is opened, future refinements - * as new modules are added should conditionalize per what the module - * indicates in the context (which is intentionally very loose data glue - * between the skeleton and modules themselves (like CGI variables so - * to say, but more structurally predestined so as to avoid complexities - * of hash table lookups etc.) - */ - -#include -#if 0 -#include "crm/common/ipc_internal.h" /* pcmk__client_t */ -#include "crm/common/xml.h" /* crm_xml_add */ -#endif -#include "crm/msg_xml.h" /* F_SUBTYPE */ -#include "daemons/based/pacemaker-based.h" /* cib_notify_diff */ - -#include /* qb_ipcs_connection_t */ - -#include "based.h" - - -/* direct global access violated in one case only - - mock_based_ipc_accept adds a reference to it to crm_cient_t->userdata */ -mock_based_context_t mock_based_context; - - -/* see based/based_callbacks.c:cib_ipc_accept */ -static int32_t -mock_based_ipc_accept(qb_ipcs_connection_t *c, uid_t uid, gid_t gid) -{ - int32_t ret = 0; - pcmk__client_t *cib_client; - - crm_trace("Connection %p", c); - cib_client = pcmk__new_client(c, uid, gid); - if (cib_client == NULL) { - ret = -EIO; - } - - cib_client->userdata = &mock_based_context; - - return ret; -} - -/* see based/based_callbacks.c:cib_ipc_closed */ -static int32_t -mock_based_ipc_closed(qb_ipcs_connection_t *c) -{ - pcmk__client_t *client = pcmk__find_client(c); - - if (client != NULL) { - crm_trace("Connection %p", c); - pcmk__free_client(client); - } - - return 0; -} - -/* see based/based_callbacks.c:cib_ipc_destroy */ -static void -mock_based_ipc_destroy(qb_ipcs_connection_t *c) -{ - crm_trace("Connection %p", c); - mock_based_ipc_closed(c); -} - -/* see based/based_callbacks.c:cib_process_command (and more) */ -static void -mock_based_handle_query(pcmk__client_t *cib_client, uint32_t flags, - const xmlNode *op_request) -{ - xmlNode *reply, *cib; - const char cib_str[] = -#if 0 -""; -#else -""\ -" "\ -" "\ -" "\ -" "\ -" "\ -" "\ -" "\ -""; -#endif - cib = xmlReadMemory(cib_str, sizeof(cib_str), "file:///tmp/foo", NULL, 0)->children; - - reply = create_xml_node(NULL, "cib-reply"); - crm_xml_add(reply, F_TYPE, T_CIB); - crm_xml_add(reply, F_CIB_OPERATION, - crm_element_value(op_request, F_CIB_OPERATION)); - crm_xml_add(reply, F_CIB_CALLID, - crm_element_value(op_request, F_CIB_CALLID)); - crm_xml_add(reply, F_CIB_CLIENTID, - crm_element_value(op_request, F_CIB_CLIENTID)); - crm_xml_add_int(reply, F_CIB_CALLOPTS, flags); - crm_xml_add_int(reply, F_CIB_RC, pcmk_ok); - - if (cib != NULL) { - crm_trace("Attaching reply output"); - add_message_xml(reply, F_CIB_CALLDATA, cib); - } - - pcmk__ipc_send_xml(cib_client, cib_client->request_id, reply, - ((flags & cib_sync_call)? crm_ipc_flags_none - : crm_ipc_server_event)); - - free_xml(reply); - free_xml(cib); -} - -/* see based/based_callbacks.c:cib_common_callback_worker */ -static void -mock_based_common_callback_worker(uint32_t id, uint32_t flags, - xmlNode *op_request, - pcmk__client_t *cib_client) -{ - const char *op = crm_element_value(op_request, F_CIB_OPERATION); - mock_based_context_t *ctxt; - - if (!strcmp(op, CRM_OP_REGISTER)) { - if (flags & crm_ipc_client_response) { - xmlNode *ack = create_xml_node(NULL, __func__); - crm_xml_add(ack, F_CIB_OPERATION, CRM_OP_REGISTER); - crm_xml_add(ack, F_CIB_CLIENTID, cib_client->id); - pcmk__ipc_send_xml(cib_client, id, ack, flags); - cib_client->request_id = 0; - free_xml(ack); - } - - } else if (!strcmp(op, T_CIB_NOTIFY)) { - int on_off = 0; - const char *type = crm_element_value(op_request, F_CIB_NOTIFY_TYPE); - crm_element_value_int(op_request, F_CIB_NOTIFY_ACTIVATE, &on_off); - - crm_debug("Setting %s callbacks for %s (%s): %s", - type, cib_client->name, cib_client->id, on_off ? "on" : "off"); - - if (!strcmp(type, T_CIB_DIFF_NOTIFY) && on_off) { - pcmk__set_client_flags(cib_client, cib_notify_diff); - } - - ctxt = (mock_based_context_t *) cib_client->userdata; - for (size_t c = ctxt->modules_cnt; c > 0; c--) { - if (ctxt->modules[c - 1]->hooks.cib_notify != NULL) { - ctxt->modules[c - 1]->hooks.cib_notify(cib_client); - } - } - - if (flags & crm_ipc_client_response) { - pcmk__ipc_send_ack(cib_client, id, flags, "ack", CRM_EX_OK); - } - - } else if (!strcmp(op, CIB_OP_QUERY)) { - mock_based_handle_query(cib_client, flags, op_request); - - } else { - crm_notice("Discarded request %s", op); - } -} - -/* see based/based_callbacks.c:cib_ipc_dispatch_rw */ -static int32_t -mock_based_dispatch_command(qb_ipcs_connection_t *c, void *data, size_t size) -{ - uint32_t id = 0, flags = 0; - int call_options = 0; - pcmk__client_t *cib_client = pcmk__find_client(c); - xmlNode *op_request = pcmk__client_data2xml(cib_client, data, &id, &flags); - - crm_notice("Got connection %p", c); - assert(op_request != NULL); - - if (cib_client == NULL || op_request == NULL) { - if (op_request == NULL) { - crm_trace("Invalid message from %p", c); - pcmk__ipc_send_ack(cib_client, id, flags, "nack", CRM_EX_PROTOCOL); - } - return 0; - } - - crm_element_value_int(op_request, F_CIB_CALLOPTS, &call_options); - if (call_options & cib_sync_call) { - assert(flags & crm_ipc_client_response); - cib_client->request_id = id; /* reply only to last in-flight request */ - } - - assert(cib_client->name == NULL); - crm_element_value_int(op_request, F_CIB_CALLOPTS, &call_options); - crm_xml_add(op_request, F_CIB_CLIENTID, cib_client->id); - crm_xml_add(op_request, F_CIB_CLIENTNAME, cib_client->name); - - mock_based_common_callback_worker(id, flags, op_request, cib_client); - free_xml(op_request); - - return 0; -} - -/* * */ - -size_t mock_based_register_module(module_t mod) { - module_t *module; - size_t ret = mock_based_context.modules_cnt++; - - mock_based_context.modules = realloc(mock_based_context.modules, - sizeof(*mock_based_context.modules) - * mock_based_context.modules_cnt); - if (mock_based_context.modules == NULL - || (module = malloc(sizeof(module_t))) == NULL) { - abort(); - } - - memcpy(module, &mod, sizeof(mod)); - mock_based_context.modules[mock_based_context.modules_cnt - 1] = module; - - return ret; -} - -static int -mock_based_options(mock_based_context_t *ctxt, - bool usage, int argc, const char *argv[]) -{ - const char **args2argv; - char *s; - int ret = 0; - - if (argc <= 1) { - const char *help_argv[] = {argv[0], "-h"}; - return mock_based_options(ctxt, false, 2, (const char **) &help_argv); - } - - for (size_t i = 1; i < argc; i++) { - if (argv[i][0] == '-' && argv[i][1] != '-' && argv[i][1] != '\0') { - if (usage) { - printf("\t-%c\t", argv[i][1]); - } - switch(argv[i][1]) { - case 'h': - if (usage) { - printf("show this help message\n"); - ret = 1; - - } else { - if ((args2argv - = malloc((ctxt->modules_cnt + 2) * sizeof(*args2argv))) == NULL - || (s - = malloc((ctxt->modules_cnt * 2 + 2) * sizeof(*s))) == NULL) { - return -1; - } - s[0] = 'h'; - args2argv[ctxt->modules_cnt + 1] = (char[]){'-', 'h', '\0'}; - for (size_t c = ctxt->modules_cnt; c > 0; c--) { - args2argv[c] = (char[]){'-', ctxt->modules[c - 1]->shortopt, '\0'}; - s[(ctxt->modules_cnt - i) + 1] = '|'; - s[(ctxt->modules_cnt - i) + 2] = ctxt->modules[c - 1]->shortopt; - } - s[ctxt->modules_cnt * 2 + 1] = '\0'; - printf("Usage: %s [-{%s}]\n", argv[0], s); - (void) mock_based_options(ctxt, true, 2 + ctxt->modules_cnt, args2argv); - free(args2argv); - free(s); - } - return ret; - default: - for (size_t c = ctxt->modules_cnt; c > 0; c--) { - if (ctxt->modules[c - 1]->shortopt == argv[i][1]) { - ret = ctxt->modules[c - 1]->hooks.argparse(ctxt, usage, argc - i, &argv[i]); - if (ret < 0) { - break; - } else if (ret > 1) { - i += (ret - 1); - } - } - } - if (ret == 0) { - printf("uknown option \"%s\"\n", argv[i]); - } - break; - } - } - } - return ret; -} - -int main(int argc, char *argv[]) -{ - mock_based_context_t *ctxt = &mock_based_context; - - if (mock_based_options(ctxt, false, argc, (const char **) argv) > 0) { - struct qb_ipcs_service_handlers cib_ipc_callbacks = { - .connection_accept = mock_based_ipc_accept, - .connection_created = NULL, - .msg_process = mock_based_dispatch_command, - .connection_closed = mock_based_ipc_closed, - .connection_destroyed = mock_based_ipc_destroy, - }; - crm_log_preinit(NULL, argc, argv); - crm_log_init(NULL, LOG_DEBUG, false, true, argc, argv, false); - qb_ipcs_service_t *ipcs_command = - mainloop_add_ipc_server(PCMK__SERVER_BASED_RW, QB_IPC_NATIVE, - &cib_ipc_callbacks); - g_main_loop_run(g_main_loop_new(NULL, false)); - qb_ipcs_destroy(ipcs_command); - } - - for (size_t c = ctxt->modules_cnt; c > 0; c--) { - if (ctxt->modules[c - 1]->hooks.destroy != NULL) { - ctxt->modules[c - 1]->hooks.destroy(ctxt->modules[c - 1]); - } - free(mock_based_context.modules[c - 1]); - } - - free(mock_based_context.modules); -} diff --git a/maint/mocked/based.h b/maint/mocked/based.h deleted file mode 100644 index c214c0858b..0000000000 --- a/maint/mocked/based.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2019-2020 the Pacemaker project contributors - * - * The version control history for this file may have further details. - * - * Licensed under the GNU General Public License version 2 or later (GPLv2+). - */ - -#pragma once - -#include /* size_t */ -#include /* bool */ - -#include /* pcmk__client_t */ - - -struct module_s; - -typedef struct mock_based_context_s { - size_t modules_cnt; - struct module_s** modules; -} mock_based_context_t; - - -typedef int (*mock_based_argparse_hook)(mock_based_context_t *, - bool, int, - const char *[]); - -typedef void (*mock_based_destroy_hook)(struct module_s *); - -/* specialized callbacks... */ -typedef void (*mock_based_cib_notify_hook)(pcmk__client_t *); - -typedef struct mock_based_hooks_s { - /* generic ones */ - mock_based_argparse_hook argparse; - mock_based_destroy_hook destroy; - - /* specialized callbacks... */ - mock_based_cib_notify_hook cib_notify; -} mock_based_hooks_t; - -typedef struct module_s { - char shortopt; - mock_based_hooks_t hooks; - void *priv; -} module_t; - -size_t mock_based_register_module(module_t mod);