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