@@ -237,19 +237,27 @@ find_hash_entry(xmlNode * msg)
237
237
static void
238
238
local_clear_failure (xmlNode * xml )
239
239
{
240
- const char * rsc = crm_element_value (xml , F_ATTRD_ATTRIBUTE );
240
+ const char * rsc = crm_element_value (xml , F_ATTRD_RESOURCE );
241
241
const char * what = rsc ? rsc : "all resources" ;
242
+ const char * op = crm_element_value (xml , F_ATTRD_OPERATION );
243
+ const char * interval_s = crm_element_value (xml , F_ATTRD_INTERVAL );
244
+ int interval = crm_get_interval (interval_s );
242
245
regex_t regex ;
243
246
GHashTableIter iter ;
244
247
attr_hash_entry_t * hash_entry = NULL ;
245
248
246
- if (attrd_failure_regex (& regex , rsc ) != pcmk_ok ) {
249
+ if (attrd_failure_regex (& regex , rsc , op , interval ) != pcmk_ok ) {
247
250
crm_info ("Ignoring invalid request to clear %s" ,
248
251
(rsc ? rsc : "all resources" ));
249
252
return ;
250
253
}
251
254
crm_debug ("Clearing %s locally" , what );
252
255
256
+ /* Make sure value is not set, so we delete */
257
+ if (crm_element_value (xml , F_ATTRD_VALUE )) {
258
+ crm_xml_replace (xml , F_ATTRD_VALUE , NULL );
259
+ }
260
+
253
261
g_hash_table_iter_init (& iter , attr_hash );
254
262
while (g_hash_table_iter_next (& iter , NULL , (gpointer * ) & hash_entry )) {
255
263
if (regexec (& regex , hash_entry -> id , 0 , NULL , 0 ) == 0 ) {
@@ -282,15 +290,40 @@ remote_clear_callback(xmlNode *msg, int call_id, int rc, xmlNode *output,
282
290
"/" XML_CIB_TAG_STATE "[@" XML_NODE_IS_REMOTE "='true']" x \
283
291
"/" XML_TAG_TRANSIENT_NODEATTRS "/" XML_TAG_ATTR_SETS "/" XML_CIB_TAG_NVPAIR
284
292
293
+ /* xpath component to match an attribute name exactly */
294
+ #define XPATH_NAME_IS (x ) "@" XML_NVPAIR_ATTR_NAME "='" x "'"
295
+
296
+ /* xpath component to match an attribute name by prefix */
297
+ #define XPATH_NAME_START (x ) "starts-with(@" XML_NVPAIR_ATTR_NAME ", '" x "')"
298
+
285
299
/* xpath ending to clear all resources */
286
300
#define XPATH_CLEAR_ALL \
287
- "[starts-with(@" XML_NVPAIR_ATTR_NAME ", '" CRM_FAIL_COUNT_PREFIX "-') " \
288
- "or starts-with(@" XML_NVPAIR_ATTR_NAME ", '" CRM_LAST_FAILURE_PREFIX "-') ]"
301
+ "[" XPATH_NAME_START( CRM_FAIL_COUNT_PREFIX "-") \
302
+ " or " XPATH_NAME_START( CRM_LAST_FAILURE_PREFIX "-") " ]"
289
303
290
- /* xpath ending to clear one resource (format takes resource name x 2) */
304
+ /* xpath ending to clear all operations for one resource
305
+ * (format takes resource name x 4)
306
+ *
307
+ * @COMPAT attributes set < 1.1.17:
308
+ * also match older attributes that do not have the operation part
309
+ */
291
310
#define XPATH_CLEAR_ONE \
292
- "[@" XML_NVPAIR_ATTR_NAME "='" CRM_FAIL_COUNT_PREFIX "-%s' " \
293
- "or @" XML_NVPAIR_ATTR_NAME "='" CRM_LAST_FAILURE_PREFIX "-%s']"
311
+ "[" XPATH_NAME_IS(CRM_FAIL_COUNT_PREFIX "-%s") \
312
+ " or " XPATH_NAME_IS(CRM_LAST_FAILURE_PREFIX "-%s") \
313
+ " or " XPATH_NAME_START(CRM_FAIL_COUNT_PREFIX "-%s#") \
314
+ " or " XPATH_NAME_START(CRM_LAST_FAILURE_PREFIX "-%s#") "]"
315
+
316
+ /* xpath ending to clear one operation for one resource
317
+ * (format takes resource name x 2, resource name + operation + interval x 2)
318
+ *
319
+ * @COMPAT attributes set < 1.1.17:
320
+ * also match older attributes that do not have the operation part
321
+ */
322
+ #define XPATH_CLEAR_OP \
323
+ "[" XPATH_NAME_IS(CRM_FAIL_COUNT_PREFIX "-%s") \
324
+ " or " XPATH_NAME_IS(CRM_LAST_FAILURE_PREFIX "-%s") \
325
+ " or " XPATH_NAME_IS(CRM_FAIL_COUNT_PREFIX "-%s#%s_%d") \
326
+ " or " XPATH_NAME_IS(CRM_LAST_FAILURE_PREFIX "-%s#%s_%d") "]"
294
327
295
328
/*!
296
329
* \internal
@@ -301,8 +334,9 @@ remote_clear_callback(xmlNode *msg, int call_id, int rc, xmlNode *output,
301
334
static void
302
335
remote_clear_failure (xmlNode * xml )
303
336
{
304
- const char * rsc = crm_element_value (xml , F_ATTRD_ATTRIBUTE );
337
+ const char * rsc = crm_element_value (xml , F_ATTRD_RESOURCE );
305
338
const char * host = crm_element_value (xml , F_ATTRD_HOST );
339
+ const char * op = crm_element_value (xml , F_ATTRD_OPERATION );
306
340
int rc = pcmk_ok ;
307
341
char * xpath ;
308
342
@@ -313,18 +347,44 @@ remote_clear_failure(xmlNode *xml)
313
347
return ;
314
348
}
315
349
316
- if ((rsc == NULL ) && (host == NULL )) {
317
- xpath = crm_strdup_printf (XPATH_REMOTE_ATTR ("" ) XPATH_CLEAR_ALL );
350
+ /* Build an xpath to clear appropriate attributes */
351
+
352
+ if (rsc == NULL ) {
353
+ /* No resource specified, clear all resources */
354
+
355
+ if (host == NULL ) {
356
+ xpath = crm_strdup_printf (XPATH_REMOTE_ATTR ("" ) XPATH_CLEAR_ALL );
357
+ } else {
358
+ xpath = crm_strdup_printf (XPATH_REMOTE_ATTR (XPATH_ID ) XPATH_CLEAR_ALL ,
359
+ host );
360
+ }
361
+
362
+ } else if (op == NULL ) {
363
+ /* Resource but no operation specified, clear all operations */
364
+
365
+ if (host == NULL ) {
366
+ xpath = crm_strdup_printf (XPATH_REMOTE_ATTR ("" ) XPATH_CLEAR_ONE ,
367
+ rsc , rsc , rsc , rsc );
368
+ } else {
369
+ xpath = crm_strdup_printf (XPATH_REMOTE_ATTR (XPATH_ID ) XPATH_CLEAR_ONE ,
370
+ host , rsc , rsc , rsc , rsc );
371
+ }
318
372
319
- } else if (rsc == NULL ) {
320
- xpath = crm_strdup_printf (XPATH_REMOTE_ATTR (XPATH_ID ) XPATH_CLEAR_ALL ,
321
- host );
322
- } else if (host == NULL ) {
323
- xpath = crm_strdup_printf (XPATH_REMOTE_ATTR ("" ) XPATH_CLEAR_ONE ,
324
- rsc , rsc );
325
373
} else {
326
- xpath = crm_strdup_printf (XPATH_REMOTE_ATTR (XPATH_ID ) XPATH_CLEAR_ONE ,
327
- host , rsc , rsc );
374
+ /* Resource and operation specified */
375
+
376
+ const char * interval_s = crm_element_value (xml , F_ATTRD_INTERVAL );
377
+ int interval = crm_get_interval (interval_s );
378
+
379
+ if (host == NULL ) {
380
+ xpath = crm_strdup_printf (XPATH_REMOTE_ATTR ("" ) XPATH_CLEAR_OP ,
381
+ rsc , rsc , rsc , op , interval ,
382
+ rsc , op , interval );
383
+ } else {
384
+ xpath = crm_strdup_printf (XPATH_REMOTE_ATTR (XPATH_ID ) XPATH_CLEAR_OP ,
385
+ host , rsc , rsc , rsc , op , interval ,
386
+ rsc , op , interval );
387
+ }
328
388
}
329
389
330
390
crm_trace ("Clearing attributes matching %s" , xpath );
0 commit comments