Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F1841784
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lrmd/main.c b/lrmd/main.c
index 605a42104b..8467b5bfd1 100644
--- a/lrmd/main.c
+++ b/lrmd/main.c
@@ -1,259 +1,297 @@
/*
* Copyright (c) 2012 David Vossel <dvossel@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <crm_internal.h>
#include <glib.h>
#include <unistd.h>
#include <crm/crm.h>
#include <crm/msg_xml.h>
#include <crm/services.h>
#include <crm/common/mainloop.h>
#include <crm/common/ipc.h>
#include <lrmd_private.h>
GMainLoop *mainloop = NULL;
qb_ipcs_service_t *ipcs = NULL;
stonith_t *stonith_api = NULL;
stonith_t *
get_stonith_connection(void)
{
if (stonith_api && stonith_api->state == stonith_disconnected) {
stonith_api_delete(stonith_api);
stonith_api = NULL;
}
if (!stonith_api) {
int rc = 0;
int tries = 10;
stonith_api = stonith_api_new();
do {
rc = stonith_api->cmds->connect(stonith_api, "lrmd", NULL);
if (rc == pcmk_ok) {
break;
}
sleep(1);
tries--;
} while (tries);
if (rc) {
crm_err("Unable to connect to stonith daemon to execute command. error: %s",
pcmk_strerror(rc));
stonith_api_delete(stonith_api);
stonith_api = NULL;
}
}
return stonith_api;
}
static int32_t
lrmd_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
{
struct qb_ipcs_connection_stats stats = { 0, };
qb_ipcs_connection_stats_get(c, &stats, 1);
crm_info("Accepting client connection: %p pid=%d for uid=%d gid=%d",
c, stats.client_pid, uid, gid);
return 0;
}
static void
lrmd_ipc_created(qb_ipcs_connection_t * c)
{
lrmd_client_t *new_client = NULL;
new_client = calloc(1, sizeof(lrmd_client_t));
new_client->channel = c;
new_client->id = crm_generate_uuid();
crm_trace("LRMD client connection established. %p id: %s", c, new_client->id);
g_hash_table_insert(client_list, new_client->id, new_client);
qb_ipcs_context_set(c, new_client);
}
static int32_t
lrmd_ipc_dispatch(qb_ipcs_connection_t * c, void *data, size_t size)
{
xmlNode *request = crm_ipcs_recv(c, data, size);
lrmd_client_t *client = (lrmd_client_t *) qb_ipcs_context_get(c);
CRM_CHECK(client != NULL, crm_err("Invalid client");
return FALSE);
CRM_CHECK(client->id != NULL, crm_err("Invalid client: %p", client);
return FALSE);
if (!request) {
return 0;
}
if (!client->name) {
const char *value = crm_element_value(request, F_LRMD_CLIENTNAME);
if (value == NULL) {
client->name = crm_itoa(crm_ipcs_client_pid(c));
} else {
client->name = strdup(value);
}
}
crm_xml_add(request, F_LRMD_CLIENTID, client->id);
crm_xml_add(request, F_LRMD_CLIENTNAME, client->name);
process_lrmd_message(client, request);
free_xml(request);
return 0;
}
static int32_t
lrmd_ipc_closed(qb_ipcs_connection_t * c)
{
lrmd_client_t *client = (lrmd_client_t *) qb_ipcs_context_get(c);
int found = 0;
if (!client) {
crm_err("No client for ipc");
return 0;
}
if (client->id) {
found = g_hash_table_remove(client_list, client->id);
}
if (!found) {
crm_err("Asked to remove unknown client with id %d", client->id);
}
return 0;
}
static void
lrmd_ipc_destroy(qb_ipcs_connection_t * c)
{
lrmd_client_t *client = (lrmd_client_t *) qb_ipcs_context_get(c);
if (!client) {
crm_err("No client for ipc");
return;
}
crm_info("LRMD client disconnecting %p - name: %s id: %s", c, client->name, client->id);
qb_ipcs_context_set(c, NULL);
free(client->name);
free(client->id);
free(client);
}
static struct qb_ipcs_service_handlers lrmd_ipc_callbacks = {
.connection_accept = lrmd_ipc_accept,
.connection_created = lrmd_ipc_created,
.msg_process = lrmd_ipc_dispatch,
.connection_closed = lrmd_ipc_closed,
.connection_destroyed = lrmd_ipc_destroy
};
void
lrmd_shutdown(int nsig)
{
crm_info("Terminating with %d clients", g_hash_table_size(client_list));
if (ipcs) {
mainloop_del_ipc_server(ipcs);
}
exit(0);
}
static int
try_server_create(void)
{
int tries = 10;
/*
* This should complete on the first iteration. The only
* known reason for why this would fail is if another lrmd process
* already exists on the system. To avoid this situation
* we attempt to connect to the old lrmd process and shut it down
* using the client library.
*/
do {
ipcs = mainloop_add_ipc_server(CRM_SYSTEM_LRMD, QB_IPC_SHM, &lrmd_ipc_callbacks);
if (ipcs == NULL) {
xmlNode *reply = NULL;
xmlNode *hello = create_xml_node(NULL, "lrmd_command");
crm_ipc_t *ipc = crm_ipc_new("lrmd", 0);
if (ipc && crm_ipc_connect(ipc)) {
crm_xml_add(hello, F_TYPE, T_LRMD);
crm_xml_add(hello, F_LRMD_OPERATION, CRM_OP_QUIT);
crm_xml_add(hello, F_LRMD_CLIENTNAME, "new_lrmd");
crm_ipc_send(ipc, hello, &reply, -1);
crm_ipc_close(ipc);
crm_ipc_destroy(ipc);
}
free_xml(reply);
free_xml(hello);
crm_err
("New IPC server could not be created because another lrmd process exists, sending shutdown command to old lrmd process.");
}
tries--;
} while (!ipcs && tries);
return ipcs ? 0 : -1;
}
+/* *INDENT-OFF* */
+static struct crm_option long_options[] = {
+ /* Top-level Options */
+ {"help", 0, 0, '?', "\tThis text"},
+ {"version", 0, 0, '$', "\tVersion information" },
+ {"verbose", 0, 0, 'V', "\tIncrease debug output"},
+
+ {"logfile", 1, 0, 'l', "\tSend logs to the additional named logfile"},
+ {0, 0, 0, 0}
+};
+/* *INDENT-ON* */
+
int
main(int argc, char **argv)
{
int rc = 0;
+ int flag = 0;
+ int index = 0;
crm_log_init("lrmd", LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
+ crm_set_options(NULL, "[options]", long_options, "Daemon for controlling services confirming to different standards");
+
+ while (1) {
+ flag = crm_get_option(argc, argv, &index);
+ if (flag == -1) {
+ break;
+ }
+
+ switch (flag) {
+ case 'l':
+ crm_add_logfile(optarg);
+ break;
+ case 'V':
+ set_crm_log_level(crm_log_level+1);
+ break;
+ case '?':
+ case '$':
+ crm_help(flag, EX_OK);
+ break;
+ default:
+ crm_help('?', EX_USAGE);
+ break;
+ }
+ }
rsc_list = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, free_rsc);
client_list = g_hash_table_new(crm_str_hash, g_str_equal);
if (try_server_create()) {
crm_err("Failed to allocate lrmd server. shutting down");
exit(-1);
}
mainloop_add_signal(SIGTERM, lrmd_shutdown);
mainloop = g_main_new(FALSE);
crm_info("Starting");
g_main_run(mainloop);
mainloop_del_ipc_server(ipcs);
g_hash_table_destroy(client_list);
g_hash_table_destroy(rsc_list);
if (stonith_api) {
stonith_api->cmds->disconnect(stonith_api);
stonith_api_delete(stonith_api);
}
return rc;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 23, 7:28 AM (22 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1018451
Default Alt Text
(8 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment