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