This file is indexed.

/usr/include/pacemaker/crm/services.h is in libcrmservice-dev 1.1.18-0ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
/*
 * Copyright (C) 2010 Andrew Beekhof <andrew@beekhof.net>
 *
 * This program 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 software 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
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/**
 * \file
 * \brief Services API
 * \ingroup core
 */

#ifndef __PCMK_SERVICES__
#  define __PCMK_SERVICES__

#  ifdef __cplusplus
extern "C" {
#  endif

#  include <glib.h>
#  include <stdio.h>
#  include <string.h>
#  include <stdbool.h>
#  include <sys/types.h>

#  ifndef OCF_ROOT_DIR
#    define OCF_ROOT_DIR "/usr/lib/ocf"
#  endif

#  ifndef LSB_ROOT_DIR
#    define LSB_ROOT_DIR "/etc/init.d"
#  endif

/* TODO: Autodetect these two ?*/
#  ifndef SYSTEMCTL
#    define SYSTEMCTL "/bin/systemctl"
#  endif

/* Deprecated and unused by Pacemaker, kept for API backward compatibility */
#  ifndef SERVICE_SCRIPT
#    define SERVICE_SCRIPT "/sbin/service"
#  endif

/* Known resource classes */
#define PCMK_RESOURCE_CLASS_OCF     "ocf"
#define PCMK_RESOURCE_CLASS_SERVICE "service"
#define PCMK_RESOURCE_CLASS_LSB     "lsb"
#define PCMK_RESOURCE_CLASS_SYSTEMD "systemd"
#define PCMK_RESOURCE_CLASS_UPSTART "upstart"
#define PCMK_RESOURCE_CLASS_HB      "heartbeat"
#define PCMK_RESOURCE_CLASS_NAGIOS  "nagios"
#define PCMK_RESOURCE_CLASS_STONITH "stonith"

/* This is the string passed in the OCF_EXIT_REASON_PREFIX
 * environment variable. The stderr output that occurs
 * after this prefix is encountered is considered the exit
 * reason for a completed operationt */
#define PCMK_OCF_REASON_PREFIX "ocf-exit-reason:"

// Agent version to use if agent doesn't specify one
#define PCMK_DEFAULT_AGENT_VERSION "0.1"

enum lsb_exitcode {
    PCMK_LSB_OK                  = 0,
    PCMK_LSB_UNKNOWN_ERROR       = 1,
    PCMK_LSB_INVALID_PARAM       = 2,
    PCMK_LSB_UNIMPLEMENT_FEATURE = 3,
    PCMK_LSB_INSUFFICIENT_PRIV   = 4,
    PCMK_LSB_NOT_INSTALLED       = 5,
    PCMK_LSB_NOT_CONFIGURED      = 6,
    PCMK_LSB_NOT_RUNNING         = 7,
};

/* The return codes for the status operation are not the same for other
 * operatios - go figure
 */
enum lsb_status_exitcode {
    PCMK_LSB_STATUS_OK             = 0,
    PCMK_LSB_STATUS_VAR_PID        = 1,
    PCMK_LSB_STATUS_VAR_LOCK       = 2,
    PCMK_LSB_STATUS_NOT_RUNNING    = 3,
    PCMK_LSB_STATUS_UNKNOWN        = 4,

    /* custom codes should be in the 150-199 range reserved for application use */
    PCMK_LSB_STATUS_NOT_INSTALLED      = 150,
    PCMK_LSB_STATUS_INSUFFICIENT_PRIV  = 151,
};

/* Uniform exit codes
 * Everything is mapped to its OCF equivalent so that Pacemaker only deals with one set of codes
 */
enum ocf_exitcode {
    PCMK_OCF_OK                   = 0,
    PCMK_OCF_UNKNOWN_ERROR        = 1,
    PCMK_OCF_INVALID_PARAM        = 2,
    PCMK_OCF_UNIMPLEMENT_FEATURE  = 3,
    PCMK_OCF_INSUFFICIENT_PRIV    = 4,
    PCMK_OCF_NOT_INSTALLED        = 5,
    PCMK_OCF_NOT_CONFIGURED       = 6,
    PCMK_OCF_NOT_RUNNING          = 7,  /* End of overlap with LSB */
    PCMK_OCF_RUNNING_MASTER       = 8,
    PCMK_OCF_FAILED_MASTER        = 9,


    /* 150-199	reserved for application use */
    PCMK_OCF_CONNECTION_DIED = 189, /* Operation failure implied by disconnection of the LRM API to a local or remote node */

    PCMK_OCF_DEGRADED        = 190, /* Active resource that is no longer 100% functional */
    PCMK_OCF_DEGRADED_MASTER = 191, /* Promoted resource that is no longer 100% functional */

    PCMK_OCF_EXEC_ERROR    = 192, /* Generic problem invoking the agent */
    PCMK_OCF_UNKNOWN       = 193, /* State of the service is unknown - used for recording in-flight operations */
    PCMK_OCF_SIGNAL        = 194,
    PCMK_OCF_NOT_SUPPORTED = 195,
    PCMK_OCF_PENDING       = 196,
    PCMK_OCF_CANCELLED     = 197,
    PCMK_OCF_TIMEOUT       = 198,
    PCMK_OCF_OTHER_ERROR   = 199, /* Keep the same codes as PCMK_LSB */
};

enum op_status {
    PCMK_LRM_OP_PENDING = -1,
    PCMK_LRM_OP_DONE,
    PCMK_LRM_OP_CANCELLED,
    PCMK_LRM_OP_TIMEOUT,
    PCMK_LRM_OP_NOTSUPPORTED,
    PCMK_LRM_OP_ERROR,
    PCMK_LRM_OP_ERROR_HARD,
    PCMK_LRM_OP_ERROR_FATAL,
    PCMK_LRM_OP_NOT_INSTALLED,
};

enum nagios_exitcode {
    NAGIOS_STATE_OK        = 0,
    NAGIOS_STATE_WARNING   = 1,
    NAGIOS_STATE_CRITICAL  = 2,
    NAGIOS_STATE_UNKNOWN   = 3,
    NAGIOS_STATE_DEPENDENT = 4,

    NAGIOS_INSUFFICIENT_PRIV = 100,
    NAGIOS_NOT_INSTALLED     = 101,
};

enum svc_action_flags {
    /* On timeout, only kill pid, do not kill entire pid group */
    SVC_ACTION_LEAVE_GROUP = 0x01,
};

typedef struct svc_action_private_s svc_action_private_t;
typedef struct svc_action_s {
    char *id;
    char *rsc;
    char *action;
    int interval;

    char *standard;
    char *provider;
    char *agent;

    int timeout;
    GHashTable *params; /* used by OCF agents and alert agents */

    int rc;
    int pid;
    int cancel;
    int status;
    int sequence;
    int expected_rc;
    int synchronous;
    enum svc_action_flags flags;

    char *stderr_data;
    char *stdout_data;

    /*!
     * Data stored by the creator of the action.
     *
     * This may be used to hold data that is needed later on by a callback,
     * for example.
     */
    void *cb_data;

    svc_action_private_t *opaque;
} svc_action_t;

/**
 * \brief Get a list of files or directories in a given path
 *
 * \param[in] root       full path to a directory to read
 * \param[in] files      return list of files if TRUE or directories if FALSE
 * \param[in] executable if TRUE and files is TRUE, only return executable files
 *
 * \return a list of what was found.  The list items are char *.
 * \note It is the caller's responsibility to free the result with g_list_free_full(list, free).
 */
    GList *get_directory_list(const char *root, gboolean files, gboolean executable);

/**
 * Get a list of services
 *
 * \return a list of services.  The list items are gchar *.  This list _must_
 *         be destroyed using g_list_free_full(list, free).
 */
    GList *services_list(void);

/**
 * \brief Get a list of providers
 *
 * \param[in] standard  list providers of this standard (e.g. ocf, lsb, etc.)
 *
 * \return a list of providers as char * list items (or NULL if standard does not support providers)
 * \note The caller is responsible for freeing the result using g_list_free_full(list, free).
 */
    GList *resources_list_providers(const char *standard);

/**
 * \brief Get a list of resource agents
 *
 * \param[in] standard  list agents using this standard (e.g. ocf, lsb, etc.) (or NULL for all)
 * \param[in] provider  list agents from this provider (or NULL for all)
 *
 * \return a list of resource agents.  The list items are char *.
 * \note The caller is responsible for freeing the result using g_list_free_full(list, free).
 */
    GList *resources_list_agents(const char *standard, const char *provider);

/**
 * Get list of available standards
 *
 * \return a list of resource standards. The list items are char *. This list _must_
 *         be destroyed using g_list_free_full(list, free).
 */
    GList *resources_list_standards(void);

    svc_action_t *services_action_create(const char *name, const char *action,
                                         int interval /* ms */ , int timeout /* ms */ );

/**
 * \brief Create a new resource action
 *
 * \param[in] name     name of resource
 * \param[in] standard resource agent standard (ocf, lsb, etc.)
 * \param[in] provider resource agent provider
 * \param[in] agent    resource agent name
 * \param[in] action   action (start, stop, monitor, etc.)
 * \param[in] interval how often to repeat this action, in milliseconds (if 0, execute only once)
 * \param[in] timeout  consider action failed if it does not complete in this many milliseconds
 * \param[in] params   action parameters
 *
 * \return newly allocated action instance
 *
 * \post After the call, 'params' is owned, and later free'd by the svc_action_t result
 * \note The caller is responsible for freeing the return value using
 *       services_action_free().
 */
    svc_action_t *resources_action_create(const char *name, const char *standard,
                                          const char *provider, const char *agent,
                                          const char *action, int interval /* ms */ ,
                                          int timeout /* ms */ , GHashTable * params,
                                          enum svc_action_flags flags);

/**
 * Kick a recurring action so it is scheduled immediately for re-execution
 */
    gboolean services_action_kick(const char *name, const char *action, int interval /* ms */);

    const char *resources_find_service_class(const char *agent);

/**
 * Utilize services API to execute an arbitrary command.
 *
 * This API has useful infrastructure in place to be able to run a command
 * in the background and get notified via a callback when the command finishes.
 *
 * \param[in] exec command to execute
 * \param[in] args arguments to the command, NULL terminated
 *
 * \return a svc_action_t object, used to pass to the execute function
 * (services_action_sync() or services_action_async()) and is
 * provided to the callback.
 */
    svc_action_t *services_action_create_generic(const char *exec, const char *args[]);

    void services_action_cleanup(svc_action_t * op);
    void services_action_free(svc_action_t * op);
    int services_action_user(svc_action_t *op, const char *user);

    gboolean services_action_sync(svc_action_t * op);

/**
 * Run an action asynchronously.
 *
 * \param[in] op services action data
 * \param[in] action_callback callback for when the action completes
 *
 * \retval TRUE succesfully started execution
 * \retval FALSE failed to start execution, no callback will be received
 */
    gboolean services_action_async(svc_action_t * op, void (*action_callback) (svc_action_t *));

    gboolean services_action_cancel(const char *name, const char *action, int interval);

/* functions for alert agents */
svc_action_t *services_alert_create(const char *id, const char *exec,
                                   int timeout, GHashTable *params,
                                   int sequence, void *cb_data);
gboolean services_alert_async(svc_action_t *action,
                              void (*cb)(svc_action_t *op));

    static inline const char *services_lrm_status_str(enum op_status status) {
        switch (status) {
            case PCMK_LRM_OP_PENDING:
                return "pending";
                case PCMK_LRM_OP_DONE:return "complete";
                case PCMK_LRM_OP_CANCELLED:return "Cancelled";
                case PCMK_LRM_OP_TIMEOUT:return "Timed Out";
                case PCMK_LRM_OP_NOTSUPPORTED:return "NOT SUPPORTED";
                case PCMK_LRM_OP_ERROR:return "Error";
                case PCMK_LRM_OP_NOT_INSTALLED:return "Not installed";
                default:return "UNKNOWN!";
        }
    }

    static inline const char *services_ocf_exitcode_str(enum ocf_exitcode code) {
        switch (code) {
            case PCMK_OCF_OK:
                return "ok";
            case PCMK_OCF_UNKNOWN_ERROR:
                return "unknown error";
            case PCMK_OCF_INVALID_PARAM:
                return "invalid parameter";
            case PCMK_OCF_UNIMPLEMENT_FEATURE:
                return "unimplemented feature";
            case PCMK_OCF_INSUFFICIENT_PRIV:
                return "insufficient privileges";
            case PCMK_OCF_NOT_INSTALLED:
                return "not installed";
            case PCMK_OCF_NOT_CONFIGURED:
                return "not configured";
            case PCMK_OCF_NOT_RUNNING:
                return "not running";
            case PCMK_OCF_RUNNING_MASTER:
                return "master";
            case PCMK_OCF_FAILED_MASTER:
                return "master (failed)";
            case PCMK_OCF_SIGNAL:
                return "OCF_SIGNAL";
            case PCMK_OCF_NOT_SUPPORTED:
                return "OCF_NOT_SUPPORTED";
            case PCMK_OCF_PENDING:
                return "OCF_PENDING";
            case PCMK_OCF_CANCELLED:
                return "OCF_CANCELLED";
            case PCMK_OCF_TIMEOUT:
                return "OCF_TIMEOUT";
            case PCMK_OCF_OTHER_ERROR:
                return "OCF_OTHER_ERROR";
            case PCMK_OCF_DEGRADED:
                return "OCF_DEGRADED";
            case PCMK_OCF_DEGRADED_MASTER:
                return "OCF_DEGRADED_MASTER";
            default:
                return "unknown";
        }
    }

    /**
     * \brief Get OCF equivalent of LSB exit code
     *
     * \param[in] action        LSB action that produced exit code
     * \param[in] lsb_exitcode  Exit code of LSB action
     *
     * \return PCMK_OCF_* constant that corresponds to LSB exit code
     */
    static inline enum ocf_exitcode
    services_get_ocf_exitcode(const char *action, int lsb_exitcode)
    {
        /* For non-status actions, LSB and OCF share error code meaning <= 7 */
        if (action && strcmp(action, "status") && strcmp(action, "monitor")) {
            if ((lsb_exitcode < 0) || (lsb_exitcode > PCMK_LSB_NOT_RUNNING)) {
                return PCMK_OCF_UNKNOWN_ERROR;
            }
            return (enum ocf_exitcode)lsb_exitcode;
        }

        /* status has different return codes */
        switch (lsb_exitcode) {
            case PCMK_LSB_STATUS_OK:
                return PCMK_OCF_OK;
            case PCMK_LSB_STATUS_NOT_INSTALLED:
                return PCMK_OCF_NOT_INSTALLED;
            case PCMK_LSB_STATUS_INSUFFICIENT_PRIV:
                return PCMK_OCF_INSUFFICIENT_PRIV;
            case PCMK_LSB_STATUS_VAR_PID:
            case PCMK_LSB_STATUS_VAR_LOCK:
            case PCMK_LSB_STATUS_NOT_RUNNING:
                return PCMK_OCF_NOT_RUNNING;
        }
        return PCMK_OCF_UNKNOWN_ERROR;
    }

#  ifdef __cplusplus
}
#  endif

#endif                          /* __PCMK_SERVICES__ */