root/fencing/standalone_config.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. find_device
  2. find_topology
  3. add_device
  4. add_topology
  5. standalone_cfg_add_device
  6. standalone_cfg_add_device_options
  7. standalone_cfg_add_node
  8. standalone_cfg_add_node_priority
  9. destroy_topology
  10. destroy_devices
  11. cfg_register_topology
  12. cfg_register_device
  13. standalone_cfg_commit

   1 /* 
   2  * Copyright (C) 2012
   3  * David Vossel  <davidvossel@gmail.com>
   4  *
   5  * This program is crm_free software; you can redistribute it and/or modify
   6  * it under the terms of the GNU General Public License as published by
   7  * the Free Software Foundation; either version 2 of the License, or
   8  * (at your option) any later version.
   9  *
  10  * This program is distributed in the hope that it will be useful,
  11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  * GNU General Public License for more details.
  14  *
  15  * You should have received a copy of the GNU General Public
  16  * License along with this library; if not, write to the Free Software
  17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  18  */
  19 
  20 #include <crm_internal.h>
  21 #include <crm/common/xml.h>
  22 #include <crm/msg_xml.h>
  23 #include <crm/stonith-ng.h>
  24 #include <crm/fencing/internal.h>
  25 #include <internal.h>
  26 #include <standalone_config.h>
  27 
  28 struct device {
  29     char *name;
  30     char *agent;
  31     char *hostlist;
  32     char *hostmap;
  33 
  34     struct {
  35         char *key;
  36         char *val;
  37     } key_vals[STANDALONE_CFG_MAX_KEYVALS];
  38     int key_vals_count;
  39 
  40     struct device *next;
  41 };
  42 
  43 struct topology {
  44     char *node_name;
  45     struct {
  46         char *device_name;
  47         unsigned int level;
  48     } priority_levels[STANDALONE_CFG_MAX_KEYVALS];
  49     int priority_levels_count;
  50 
  51     struct topology *next;
  52 };
  53 
  54 static struct device *dev_list;
  55 static struct topology *topo_list;
  56 
  57 static struct device *
  58 find_device(const char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
  59 {
  60     struct device *dev = NULL;
  61 
  62     for (dev = dev_list; dev != NULL; dev = dev->next) {
  63         if (!strcasecmp(dev->name, name)) {
  64             break;
  65         }
  66     }
  67 
  68     return dev;
  69 }
  70 
  71 static struct topology *
  72 find_topology(const char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
  73 {
  74     struct topology *topo = NULL;
  75 
  76     for (topo = topo_list; topo != NULL; topo = topo->next) {
  77         if (!strcasecmp(topo->node_name, name)) {
  78             break;
  79         }
  80     }
  81 
  82     return topo;
  83 }
  84 
  85 static void
  86 add_device(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88     dev->next = dev_list;
  89     dev_list = dev;
  90 }
  91 
  92 static void
  93 add_topology(struct topology *topo)
     /* [previous][next][first][last][top][bottom][index][help] */
  94 {
  95     topo->next = topo_list;
  96     topo_list = topo;
  97 }
  98 
  99 int
 100 standalone_cfg_add_device(const char *device, const char *agent)
     /* [previous][next][first][last][top][bottom][index][help] */
 101 {
 102     struct device *dev = NULL;
 103 
 104     if (!device || !agent) {
 105         return -1;
 106     }
 107 
 108     /* just ignore duplicates */
 109     if (find_device(device)) {
 110         return 0;
 111     }
 112     dev = calloc(1, sizeof(struct device));
 113 
 114     dev->name = strdup(device);
 115     dev->agent = strdup(agent);
 116     add_device(dev);
 117 
 118     return 0;
 119 }
 120 
 121 int
 122 standalone_cfg_add_device_options(const char *device, const char *key, const char *value)
     /* [previous][next][first][last][top][bottom][index][help] */
 123 {
 124     struct device *dev;
 125 
 126     if (!device || !key || !value) {
 127         return -1;
 128     } else if (!(dev = find_device(device))) {
 129         crm_err("Standalone config error, could not find device %s to add key value %s=%s to",
 130                 device, key, value);
 131         return -1;
 132     } else if (dev->key_vals_count >= STANDALONE_CFG_MAX_KEYVALS) {
 133         return -1;
 134     }
 135 
 136     dev->key_vals[dev->key_vals_count].key = strdup(key);
 137     dev->key_vals[dev->key_vals_count].val = strdup(value);
 138     dev->key_vals_count++;
 139 
 140     return 0;
 141 }
 142 
 143 int
 144 standalone_cfg_add_node(const char *node, const char *device, const char *ports)
     /* [previous][next][first][last][top][bottom][index][help] */
 145 {
 146     struct device *dev;
 147     char **ptr;
 148     char *tmp;
 149     size_t len = strlen(":;") + 1;
 150     size_t offset = 0;
 151 
 152     /* note that ports may be NULL, it is not a required argument */
 153     if (!node || !device) {
 154         return -1;
 155     } else if (!(dev = find_device(device))) {
 156         crm_err("Standalone config error, could not find device %s to add mode %s to",
 157                 device, node);
 158         return -1;
 159     }
 160 
 161     ptr = &dev->hostlist;
 162 
 163     len += strlen(node);
 164     if (ports) {
 165         ptr = &dev->hostmap;
 166         len += strlen(ports);
 167     }
 168 
 169     tmp = *ptr;
 170 
 171     if (tmp) {
 172         offset = strlen(tmp);
 173         tmp = realloc_safe(tmp, len + offset + 1);
 174     } else {
 175         tmp = malloc(len);
 176     }
 177 
 178     *ptr = tmp;
 179     tmp += offset;
 180 
 181     if (ports) {
 182         sprintf(tmp, "%s:%s;", node, ports);
 183     } else {
 184         sprintf(tmp, "%s ", node);
 185     }
 186 
 187     return 0;
 188 }
 189 
 190 int
 191 standalone_cfg_add_node_priority(const char *node, const char *device, unsigned int level)
     /* [previous][next][first][last][top][bottom][index][help] */
 192 {
 193     struct topology *topo = NULL;
 194     int new = 0;
 195 
 196     if (!node || !device) {
 197         return -1;
 198     }
 199 
 200     if (!(topo = find_topology(node))) {
 201         new = 1;
 202         topo = calloc(1, sizeof(struct topology));
 203         topo->node_name = strdup(node);
 204     } else if (topo->priority_levels_count >= STANDALONE_CFG_MAX_KEYVALS) {
 205         return -1;
 206     }
 207 
 208     topo->priority_levels[topo->priority_levels_count].device_name = strdup(device);
 209     topo->priority_levels[topo->priority_levels_count].level = level;
 210     topo->priority_levels_count++;
 211 
 212     if (new) {
 213         add_topology(topo);
 214     }
 215 
 216     return 0;
 217 }
 218 
 219 static int
 220 destroy_topology(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 221 {
 222     struct topology *topo = NULL;
 223     int i;
 224 
 225     while (topo_list) {
 226         topo = topo_list;
 227 
 228         free(topo->node_name);
 229         for (i = 0; i < topo->priority_levels_count; i++) {
 230             free(topo->priority_levels[i].device_name);
 231         }
 232 
 233         topo_list = topo->next;
 234         free(topo);
 235     }
 236     return 0;
 237 }
 238 
 239 static int
 240 destroy_devices(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 241 {
 242     struct device *dev = NULL;
 243     int i;
 244 
 245     while (dev_list) {
 246         dev = dev_list;
 247 
 248         free(dev->name);
 249         free(dev->agent);
 250         free(dev->hostlist);
 251         free(dev->hostmap);
 252         for (i = 0; i < dev->key_vals_count; i++) {
 253             free(dev->key_vals[i].key);
 254             free(dev->key_vals[i].val);
 255         }
 256         dev_list = dev->next;
 257         free(dev);
 258     }
 259 
 260     return 0;
 261 }
 262 
 263 static int
 264 cfg_register_topology(struct topology *topo)
     /* [previous][next][first][last][top][bottom][index][help] */
 265 {
 266     stonith_key_value_t *devices = NULL;
 267     xmlNode *data;
 268     char *dump;
 269     int i;
 270     int res = 0;
 271 
 272     for (i = 0; i < topo->priority_levels_count; i++) {
 273         devices = stonith_key_value_add(devices, NULL, topo->priority_levels[i].device_name);
 274 
 275         data = create_level_registration_xml(topo->node_name, NULL, NULL, NULL,
 276                                              topo->priority_levels[i].level, devices);
 277 
 278         dump = dump_xml_formatted(data);
 279         crm_info("Standalone config level being added:\n%s", dump);
 280 
 281         res |= stonith_level_register(data, NULL);
 282         free(dump);
 283         free_xml(data);
 284         stonith_key_value_freeall(devices, 1, 1);
 285     }
 286 
 287     return res;
 288 }
 289 
 290 static int
 291 cfg_register_device(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 292 {
 293     stonith_key_value_t *params = NULL;
 294     xmlNode *data;
 295     char *dump;
 296     int i;
 297     int res;
 298 
 299     /* create the parameter list */
 300     if (dev->hostlist) {
 301         params = stonith_key_value_add(params, STONITH_ATTR_HOSTLIST, dev->hostlist);
 302     }
 303     if (dev->hostmap) {
 304         params = stonith_key_value_add(params, STONITH_ATTR_HOSTMAP, dev->hostmap);
 305     }
 306     for (i = 0; i < dev->key_vals_count; i++) {
 307         params stonith_key_value_add(params, dev->key_vals[i].key, dev->key_vals[i].val);
 308     }
 309 
 310     /* generate xml */
 311     data = create_device_registration_xml(dev->name, __FUNCTION__, dev->agent, params);
 312 
 313     dump = dump_xml_formatted(data);
 314     crm_info("Standalone device being added:\n%s", dump);
 315 
 316     res = stonith_device_register(data, NULL, FALSE);
 317 
 318     free(dump);
 319     free_xml(data);
 320     stonith_key_value_freeall(params, 1, 1);
 321     return res;
 322 }
 323 
 324 int
 325 standalone_cfg_commit(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 326 {
 327     struct device *dev = NULL;
 328     struct topology *topo = NULL;
 329 
 330     for (dev = dev_list; dev != NULL; dev = dev->next) {
 331         cfg_register_device(dev);
 332     }
 333 
 334     for (topo = topo_list; topo != NULL; topo = topo->next) {
 335         cfg_register_topology(topo);
 336     }
 337 
 338     destroy_devices();
 339     destroy_topology();
 340     return 0;
 341 }

/* [previous][next][first][last][top][bottom][index][help] */