This source file includes following definitions.
- ipc_already_running
- build_arg_context
- main
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <sys/param.h>
13 #include <stdio.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <unistd.h>
17
18 #include <stdlib.h>
19 #include <errno.h>
20 #include <fcntl.h>
21
22 #include <crm/crm.h>
23 #include <crm/common/cmdline_internal.h>
24 #include <crm/common/iso8601.h>
25 #include <crm/common/ipc.h>
26 #include <crm/common/ipc_internal.h>
27 #include <crm/common/output_internal.h>
28 #include <crm/common/xml.h>
29 #include <crm/cluster/internal.h>
30
31 #include <crm/common/attrs_internal.h>
32 #include "pacemaker-attrd.h"
33
34 #define SUMMARY "daemon for managing Pacemaker node attributes"
35
36 gboolean stand_alone = FALSE;
37 gchar **log_files = NULL;
38
39 static GOptionEntry entries[] = {
40 { "stand-alone", 's', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &stand_alone,
41 "(Advanced use only) Run in stand-alone mode", NULL },
42
43 { "logfile", 'l', G_OPTION_FLAG_NONE, G_OPTION_ARG_FILENAME_ARRAY,
44 &log_files, "Send logs to the additional named logfile", NULL },
45
46 { NULL }
47 };
48
49 static pcmk__output_t *out = NULL;
50
51 static pcmk__supported_format_t formats[] = {
52 PCMK__SUPPORTED_FORMAT_NONE,
53 PCMK__SUPPORTED_FORMAT_TEXT,
54 PCMK__SUPPORTED_FORMAT_XML,
55 { NULL, NULL, NULL }
56 };
57
58 lrmd_t *the_lrmd = NULL;
59 pcmk_cluster_t *attrd_cluster = NULL;
60 crm_trigger_t *attrd_config_read = NULL;
61 crm_exit_t attrd_exit_status = CRM_EX_OK;
62
63 static bool
64 ipc_already_running(void)
65 {
66 pcmk_ipc_api_t *old_instance = NULL;
67 int rc = pcmk_rc_ok;
68
69 rc = pcmk_new_ipc_api(&old_instance, pcmk_ipc_attrd);
70 if (rc != pcmk_rc_ok) {
71 return false;
72 }
73
74 rc = pcmk__connect_ipc(old_instance, pcmk_ipc_dispatch_sync, 2);
75 if (rc != pcmk_rc_ok) {
76 crm_debug("No existing %s manager instance found: %s",
77 pcmk_ipc_name(old_instance, true), pcmk_rc_str(rc));
78 pcmk_free_ipc_api(old_instance);
79 return false;
80 }
81
82 pcmk_disconnect_ipc(old_instance);
83 pcmk_free_ipc_api(old_instance);
84 return true;
85 }
86
87 static GOptionContext *
88 build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
89 GOptionContext *context = NULL;
90
91 context = pcmk__build_arg_context(args, "text (default), xml", group, NULL);
92 pcmk__add_main_args(context, entries);
93 return context;
94 }
95
96 int
97 main(int argc, char **argv)
98 {
99 int rc = pcmk_rc_ok;
100
101 GError *error = NULL;
102 bool initialized = false;
103
104 GOptionGroup *output_group = NULL;
105 pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
106 gchar **processed_args = pcmk__cmdline_preproc(argv, NULL);
107 GOptionContext *context = build_arg_context(args, &output_group);
108
109 attrd_init_mainloop();
110 crm_log_preinit(NULL, argc, argv);
111 mainloop_add_signal(SIGTERM, attrd_shutdown);
112
113 pcmk__register_formats(output_group, formats);
114 if (!g_option_context_parse_strv(context, &processed_args, &error)) {
115 attrd_exit_status = CRM_EX_USAGE;
116 goto done;
117 }
118
119 rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
120 if ((rc != pcmk_rc_ok) || (out == NULL)) {
121 attrd_exit_status = CRM_EX_ERROR;
122 g_set_error(&error, PCMK__EXITC_ERROR, attrd_exit_status,
123 "Error creating output format %s: %s",
124 args->output_ty, pcmk_rc_str(rc));
125 goto done;
126 }
127
128 if (args->version) {
129 out->version(out, false);
130 goto done;
131 }
132
133
134 pcmk__add_logfiles(log_files, out);
135
136 crm_log_init(PCMK__VALUE_ATTRD, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
137 crm_notice("Starting Pacemaker node attribute manager%s",
138 stand_alone ? " in standalone mode" : "");
139
140 if (ipc_already_running()) {
141 attrd_exit_status = CRM_EX_OK;
142 g_set_error(&error, PCMK__EXITC_ERROR, attrd_exit_status,
143 "Aborting start-up because an attribute manager "
144 "instance is already active");
145 crm_crit("%s", error->message);
146 goto done;
147 }
148
149 initialized = true;
150
151 attributes = pcmk__strkey_table(NULL, attrd_free_attribute);
152
153
154
155
156
157 if (!stand_alone) {
158 if (attrd_cib_connect(30) != pcmk_ok) {
159 attrd_exit_status = CRM_EX_FATAL;
160 g_set_error(&error, PCMK__EXITC_ERROR, attrd_exit_status,
161 "Could not connect to the CIB");
162 goto done;
163 }
164 crm_info("CIB connection active");
165 }
166
167 if (attrd_cluster_connect() != pcmk_ok) {
168 attrd_exit_status = CRM_EX_FATAL;
169 g_set_error(&error, PCMK__EXITC_ERROR, attrd_exit_status,
170 "Could not connect to the cluster");
171 goto done;
172 }
173 crm_info("Cluster connection active");
174
175
176 attrd_election_init();
177
178 if (!stand_alone) {
179 attrd_cib_init();
180 }
181
182
183
184
185
186
187 attrd_send_protocol(NULL);
188
189 attrd_init_ipc();
190 crm_notice("Pacemaker node attribute manager successfully started and accepting connections");
191 attrd_run_mainloop();
192
193 done:
194 if (initialized) {
195 crm_info("Shutting down attribute manager");
196
197 attrd_ipc_fini();
198 attrd_lrmd_disconnect();
199
200 if (!stand_alone) {
201 attrd_cib_disconnect();
202 }
203
204 attrd_free_waitlist();
205 pcmk_cluster_disconnect(attrd_cluster);
206 pcmk_cluster_free(attrd_cluster);
207 g_hash_table_destroy(attributes);
208 }
209
210 attrd_cleanup_xml_ids();
211
212 g_strfreev(processed_args);
213 pcmk__free_arg_context(context);
214
215 g_strfreev(log_files);
216
217 pcmk__output_and_clear_error(&error, out);
218
219 if (out != NULL) {
220 out->finish(out, attrd_exit_status, true, NULL);
221 pcmk__output_free(out);
222 }
223 pcmk__unregister_formats();
224 crm_exit(attrd_exit_status);
225 }