Home | History | Annotate | Line # | Download | only in libdm
      1 /*	$NetBSD: libdm-deptree.c,v 1.4 2009/12/02 00:58:03 haad Exp $	*/
      2 
      3 /*
      4  * Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
      5  *
      6  * This file is part of the device-mapper userspace tools.
      7  *
      8  * This copyrighted material is made available to anyone wishing to use,
      9  * modify, copy, or redistribute it subject to the terms and conditions
     10  * of the GNU Lesser General Public License v.2.1.
     11  *
     12  * You should have received a copy of the GNU Lesser General Public License
     13  * along with this program; if not, write to the Free Software Foundation,
     14  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     15  */
     16 
     17 #include "dmlib.h"
     18 #include "libdm-targets.h"
     19 #include "libdm-common.h"
     20 #include "kdev_t.h"
     21 #include "dm-ioctl.h"
     22 
     23 #include <stdarg.h>
     24 #include <sys/param.h>
     25 #include <sys/utsname.h>
     26 
     27 #define MAX_TARGET_PARAMSIZE 500000
     28 
     29 /* FIXME Fix interface so this is used only by LVM */
     30 #define UUID_PREFIX "LVM-"
     31 
     32 /* Supported segment types */
     33 enum {
     34 	SEG_CRYPT,
     35 	SEG_ERROR,
     36 	SEG_LINEAR,
     37 	SEG_MIRRORED,
     38 	SEG_SNAPSHOT,
     39 	SEG_SNAPSHOT_ORIGIN,
     40 	SEG_STRIPED,
     41 	SEG_ZERO,
     42 };
     43 
     44 /* FIXME Add crypt and multipath support */
     45 
     46 struct {
     47 	unsigned type;
     48 	const char *target;
     49 } dm_segtypes[] = {
     50 	{ SEG_CRYPT, "crypt" },
     51 	{ SEG_ERROR, "error" },
     52 	{ SEG_LINEAR, "linear" },
     53 	{ SEG_MIRRORED, "mirror" },
     54 	{ SEG_SNAPSHOT, "snapshot" },
     55 	{ SEG_SNAPSHOT_ORIGIN, "snapshot-origin" },
     56 	{ SEG_STRIPED, "striped" },
     57 	{ SEG_ZERO, "zero"},
     58 };
     59 
     60 /* Some segment types have a list of areas of other devices attached */
     61 struct seg_area {
     62 	struct dm_list list;
     63 
     64 	struct dm_tree_node *dev_node;
     65 
     66 	uint64_t offset;
     67 };
     68 
     69 /* Per-segment properties */
     70 struct load_segment {
     71 	struct dm_list list;
     72 
     73 	unsigned type;
     74 
     75 	uint64_t size;
     76 
     77 	unsigned area_count;		/* Linear + Striped + Mirrored + Crypt */
     78 	struct dm_list areas;		/* Linear + Striped + Mirrored + Crypt */
     79 
     80 	uint32_t stripe_size;		/* Striped */
     81 
     82 	int persistent;			/* Snapshot */
     83 	uint32_t chunk_size;		/* Snapshot */
     84 	struct dm_tree_node *cow;	/* Snapshot */
     85 	struct dm_tree_node *origin;	/* Snapshot + Snapshot origin */
     86 
     87 	struct dm_tree_node *log;	/* Mirror */
     88 	uint32_t region_size;		/* Mirror */
     89 	unsigned clustered;		/* Mirror */
     90 	unsigned mirror_area_count;	/* Mirror */
     91 	uint32_t flags;			/* Mirror log */
     92 	char *uuid;			/* Clustered mirror log */
     93 
     94 	const char *cipher;		/* Crypt */
     95 	const char *chainmode;		/* Crypt */
     96 	const char *iv;			/* Crypt */
     97 	uint64_t iv_offset;		/* Crypt */
     98 	const char *key;		/* Crypt */
     99 };
    100 
    101 /* Per-device properties */
    102 struct load_properties {
    103 	int read_only;
    104 	uint32_t major;
    105 	uint32_t minor;
    106 
    107 	uint32_t read_ahead;
    108 	uint32_t read_ahead_flags;
    109 
    110 	unsigned segment_count;
    111 	unsigned size_changed;
    112 	struct dm_list segs;
    113 
    114 	const char *new_name;
    115 };
    116 
    117 /* Two of these used to join two nodes with uses and used_by. */
    118 struct dm_tree_link {
    119 	struct dm_list list;
    120 	struct dm_tree_node *node;
    121 };
    122 
    123 struct dm_tree_node {
    124 	struct dm_tree *dtree;
    125 
    126         const char *name;
    127         const char *uuid;
    128         struct dm_info info;
    129 
    130         struct dm_list uses;       	/* Nodes this node uses */
    131         struct dm_list used_by;    	/* Nodes that use this node */
    132 
    133 	int activation_priority;	/* 0 gets activated first */
    134 
    135 	uint16_t udev_flags;		/* Udev control flags */
    136 
    137 	void *context;			/* External supplied context */
    138 
    139 	struct load_properties props;	/* For creation/table (re)load */
    140 };
    141 
    142 struct dm_tree {
    143 	struct dm_pool *mem;
    144 	struct dm_hash_table *devs;
    145 	struct dm_hash_table *uuids;
    146 	struct dm_tree_node root;
    147 	int skip_lockfs;		/* 1 skips lockfs (for non-snapshots) */
    148 	int no_flush;		/* 1 sets noflush (mirrors/multipath) */
    149 	uint32_t cookie;
    150 };
    151 
    152 struct dm_tree *dm_tree_create(void)
    153 {
    154 	struct dm_tree *dtree;
    155 
    156 	if (!(dtree = dm_malloc(sizeof(*dtree)))) {
    157 		log_error("dm_tree_create malloc failed");
    158 		return NULL;
    159 	}
    160 
    161 	memset(dtree, 0, sizeof(*dtree));
    162 	dtree->root.dtree = dtree;
    163 	dm_list_init(&dtree->root.uses);
    164 	dm_list_init(&dtree->root.used_by);
    165 	dtree->skip_lockfs = 0;
    166 	dtree->no_flush = 0;
    167 
    168 	if (!(dtree->mem = dm_pool_create("dtree", 1024))) {
    169 		log_error("dtree pool creation failed");
    170 		dm_free(dtree);
    171 		return NULL;
    172 	}
    173 
    174 	if (!(dtree->devs = dm_hash_create(8))) {
    175 		log_error("dtree hash creation failed");
    176 		dm_pool_destroy(dtree->mem);
    177 		dm_free(dtree);
    178 		return NULL;
    179 	}
    180 
    181 	if (!(dtree->uuids = dm_hash_create(32))) {
    182 		log_error("dtree uuid hash creation failed");
    183 		dm_hash_destroy(dtree->devs);
    184 		dm_pool_destroy(dtree->mem);
    185 		dm_free(dtree);
    186 		return NULL;
    187 	}
    188 
    189 	return dtree;
    190 }
    191 
    192 void dm_tree_free(struct dm_tree *dtree)
    193 {
    194 	if (!dtree)
    195 		return;
    196 
    197 	dm_hash_destroy(dtree->uuids);
    198 	dm_hash_destroy(dtree->devs);
    199 	dm_pool_destroy(dtree->mem);
    200 	dm_free(dtree);
    201 }
    202 
    203 static int _nodes_are_linked(struct dm_tree_node *parent,
    204 			     struct dm_tree_node *child)
    205 {
    206 	struct dm_tree_link *dlink;
    207 
    208 	dm_list_iterate_items(dlink, &parent->uses)
    209 		if (dlink->node == child)
    210 			return 1;
    211 
    212 	return 0;
    213 }
    214 
    215 static int _link(struct dm_list *list, struct dm_tree_node *node)
    216 {
    217 	struct dm_tree_link *dlink;
    218 
    219 	if (!(dlink = dm_pool_alloc(node->dtree->mem, sizeof(*dlink)))) {
    220 		log_error("dtree link allocation failed");
    221 		return 0;
    222 	}
    223 
    224 	dlink->node = node;
    225 	dm_list_add(list, &dlink->list);
    226 
    227 	return 1;
    228 }
    229 
    230 static int _link_nodes(struct dm_tree_node *parent,
    231 		       struct dm_tree_node *child)
    232 {
    233 	if (_nodes_are_linked(parent, child))
    234 		return 1;
    235 
    236 	if (!_link(&parent->uses, child))
    237 		return 0;
    238 
    239 	if (!_link(&child->used_by, parent))
    240 		return 0;
    241 
    242 	return 1;
    243 }
    244 
    245 static void _unlink(struct dm_list *list, struct dm_tree_node *node)
    246 {
    247 	struct dm_tree_link *dlink;
    248 
    249 	dm_list_iterate_items(dlink, list)
    250 		if (dlink->node == node) {
    251 			dm_list_del(&dlink->list);
    252 			break;
    253 		}
    254 }
    255 
    256 static void _unlink_nodes(struct dm_tree_node *parent,
    257 			  struct dm_tree_node *child)
    258 {
    259 	if (!_nodes_are_linked(parent, child))
    260 		return;
    261 
    262 	_unlink(&parent->uses, child);
    263 	_unlink(&child->used_by, parent);
    264 }
    265 
    266 static int _add_to_toplevel(struct dm_tree_node *node)
    267 {
    268 	return _link_nodes(&node->dtree->root, node);
    269 }
    270 
    271 static void _remove_from_toplevel(struct dm_tree_node *node)
    272 {
    273 	return _unlink_nodes(&node->dtree->root, node);
    274 }
    275 
    276 static int _add_to_bottomlevel(struct dm_tree_node *node)
    277 {
    278 	return _link_nodes(node, &node->dtree->root);
    279 }
    280 
    281 static void _remove_from_bottomlevel(struct dm_tree_node *node)
    282 {
    283 	return _unlink_nodes(node, &node->dtree->root);
    284 }
    285 
    286 static int _link_tree_nodes(struct dm_tree_node *parent, struct dm_tree_node *child)
    287 {
    288 	/* Don't link to root node if child already has a parent */
    289 	if ((parent == &parent->dtree->root)) {
    290 		if (dm_tree_node_num_children(child, 1))
    291 			return 1;
    292 	} else
    293 		_remove_from_toplevel(child);
    294 
    295 	if ((child == &child->dtree->root)) {
    296 		if (dm_tree_node_num_children(parent, 0))
    297 			return 1;
    298 	} else
    299 		_remove_from_bottomlevel(parent);
    300 
    301 	return _link_nodes(parent, child);
    302 }
    303 
    304 static struct dm_tree_node *_create_dm_tree_node(struct dm_tree *dtree,
    305 						 const char *name,
    306 						 const char *uuid,
    307 						 struct dm_info *info,
    308 						 void *context,
    309 						 uint16_t udev_flags)
    310 {
    311 	struct dm_tree_node *node;
    312 	uint64_t dev;
    313 
    314 	if (!(node = dm_pool_zalloc(dtree->mem, sizeof(*node)))) {
    315 		log_error("_create_dm_tree_node alloc failed");
    316 		return NULL;
    317 	}
    318 
    319 	node->dtree = dtree;
    320 
    321 	node->name = name;
    322 	node->uuid = uuid;
    323 	node->info = *info;
    324 	node->context = context;
    325 	node->udev_flags = udev_flags;
    326 	node->activation_priority = 0;
    327 
    328 	dm_list_init(&node->uses);
    329 	dm_list_init(&node->used_by);
    330 	dm_list_init(&node->props.segs);
    331 
    332 	dev = MKDEV(info->major, info->minor);
    333 
    334 	if (!dm_hash_insert_binary(dtree->devs, (const char *) &dev,
    335 				sizeof(dev), node)) {
    336 		log_error("dtree node hash insertion failed");
    337 		dm_pool_free(dtree->mem, node);
    338 		return NULL;
    339 	}
    340 
    341 	if (uuid && *uuid &&
    342 	    !dm_hash_insert(dtree->uuids, uuid, node)) {
    343 		log_error("dtree uuid hash insertion failed");
    344 		dm_hash_remove_binary(dtree->devs, (const char *) &dev,
    345 				      sizeof(dev));
    346 		dm_pool_free(dtree->mem, node);
    347 		return NULL;
    348 	}
    349 
    350 	return node;
    351 }
    352 
    353 static struct dm_tree_node *_find_dm_tree_node(struct dm_tree *dtree,
    354 					       uint32_t major, uint32_t minor)
    355 {
    356 	uint64_t dev = MKDEV(major, minor);
    357 
    358 	return dm_hash_lookup_binary(dtree->devs, (const char *) &dev,
    359 				  sizeof(dev));
    360 }
    361 
    362 static struct dm_tree_node *_find_dm_tree_node_by_uuid(struct dm_tree *dtree,
    363 						       const char *uuid)
    364 {
    365 	struct dm_tree_node *node;
    366 
    367 	if ((node = dm_hash_lookup(dtree->uuids, uuid)))
    368 		return node;
    369 
    370 	if (strncmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1))
    371 		return NULL;
    372 
    373 	return dm_hash_lookup(dtree->uuids, uuid + sizeof(UUID_PREFIX) - 1);
    374 }
    375 
    376 static int _deps(struct dm_task **dmt, struct dm_pool *mem, uint32_t major, uint32_t minor,
    377 		 const char **name, const char **uuid,
    378 		 struct dm_info *info, struct dm_deps **deps)
    379 {
    380 	memset(info, 0, sizeof(*info));
    381 
    382 	if (!dm_is_dm_major(major)) {
    383 		*name = "";
    384 		*uuid = "";
    385 		*deps = NULL;
    386 		info->major = major;
    387 		info->minor = minor;
    388 		info->exists = 0;
    389 		info->live_table = 0;
    390 		info->inactive_table = 0;
    391 		info->read_only = 0;
    392 		return 1;
    393 	}
    394 
    395 	if (!(*dmt = dm_task_create(DM_DEVICE_DEPS))) {
    396 		log_error("deps dm_task creation failed");
    397 		return 0;
    398 	}
    399 
    400 	if (!dm_task_set_major(*dmt, major)) {
    401 		log_error("_deps: failed to set major for (%" PRIu32 ":%" PRIu32 ")",
    402 			  major, minor);
    403 		goto failed;
    404 	}
    405 
    406 	if (!dm_task_set_minor(*dmt, minor)) {
    407 		log_error("_deps: failed to set minor for (%" PRIu32 ":%" PRIu32 ")",
    408 			  major, minor);
    409 		goto failed;
    410 	}
    411 
    412 	if (!dm_task_run(*dmt)) {
    413 		log_error("_deps: task run failed for (%" PRIu32 ":%" PRIu32 ")",
    414 			  major, minor);
    415 		goto failed;
    416 	}
    417 
    418 	if (!dm_task_get_info(*dmt, info)) {
    419 		log_error("_deps: failed to get info for (%" PRIu32 ":%" PRIu32 ")",
    420 			  major, minor);
    421 		goto failed;
    422 	}
    423 
    424 	if (!info->exists) {
    425 		*name = "";
    426 		*uuid = "";
    427 		*deps = NULL;
    428 	} else {
    429 		if (info->major != major) {
    430 			log_error("Inconsistent dtree major number: %u != %u",
    431 				  major, info->major);
    432 			goto failed;
    433 		}
    434 		if (info->minor != minor) {
    435 			log_error("Inconsistent dtree minor number: %u != %u",
    436 				  minor, info->minor);
    437 			goto failed;
    438 		}
    439 		if (!(*name = dm_pool_strdup(mem, dm_task_get_name(*dmt)))) {
    440 			log_error("name pool_strdup failed");
    441 			goto failed;
    442 		}
    443 		if (!(*uuid = dm_pool_strdup(mem, dm_task_get_uuid(*dmt)))) {
    444 			log_error("uuid pool_strdup failed");
    445 			goto failed;
    446 		}
    447 		*deps = dm_task_get_deps(*dmt);
    448 	}
    449 
    450 	return 1;
    451 
    452 failed:
    453 	dm_task_destroy(*dmt);
    454 	return 0;
    455 }
    456 
    457 static struct dm_tree_node *_add_dev(struct dm_tree *dtree,
    458 				     struct dm_tree_node *parent,
    459 				     uint32_t major, uint32_t minor)
    460 {
    461 	struct dm_task *dmt = NULL;
    462 	struct dm_info info;
    463 	struct dm_deps *deps = NULL;
    464 	const char *name = NULL;
    465 	const char *uuid = NULL;
    466 	struct dm_tree_node *node = NULL;
    467 	uint32_t i;
    468 	int new = 0;
    469 
    470 	/* Already in tree? */
    471 	if (!(node = _find_dm_tree_node(dtree, major, minor))) {
    472 		if (!_deps(&dmt, dtree->mem, major, minor, &name, &uuid, &info, &deps))
    473 			return_NULL;
    474 
    475 		if (!(node = _create_dm_tree_node(dtree, name, uuid, &info,
    476 						  NULL, 0)))
    477 			goto_out;
    478 		new = 1;
    479 	}
    480 
    481 	if (!_link_tree_nodes(parent, node)) {
    482 		node = NULL;
    483 		goto_out;
    484 	}
    485 
    486 	/* If node was already in tree, no need to recurse. */
    487 	if (!new)
    488 		goto out;
    489 
    490 	/* Can't recurse if not a mapped device or there are no dependencies */
    491 	if (!node->info.exists || !deps->count) {
    492 		if (!_add_to_bottomlevel(node)) {
    493 			stack;
    494 			node = NULL;
    495 		}
    496 		goto out;
    497 	}
    498 
    499 	/* Add dependencies to tree */
    500 	for (i = 0; i < deps->count; i++)
    501 		if (!_add_dev(dtree, node, MAJOR(deps->device[i]),
    502 			      MINOR(deps->device[i]))) {
    503 			node = NULL;
    504 			goto_out;
    505 		}
    506 
    507 out:
    508 	if (dmt)
    509 		dm_task_destroy(dmt);
    510 
    511 	return node;
    512 }
    513 
    514 static int _node_clear_table(struct dm_tree_node *dnode)
    515 {
    516 	struct dm_task *dmt;
    517 	struct dm_info *info;
    518 	const char *name;
    519 	int r;
    520 
    521 	if (!(info = &dnode->info)) {
    522 		log_error("_node_clear_table failed: missing info");
    523 		return 0;
    524 	}
    525 
    526 	if (!(name = dm_tree_node_get_name(dnode))) {
    527 		log_error("_node_clear_table failed: missing name");
    528 		return 0;
    529 	}
    530 
    531 	/* Is there a table? */
    532 	if (!info->exists || !info->inactive_table)
    533 		return 1;
    534 
    535 	log_verbose("Clearing inactive table %s (%" PRIu32 ":%" PRIu32 ")",
    536 		    name, info->major, info->minor);
    537 
    538 	if (!(dmt = dm_task_create(DM_DEVICE_CLEAR))) {
    539 		dm_task_destroy(dmt);
    540 		log_error("Table clear dm_task creation failed for %s", name);
    541 		return 0;
    542 	}
    543 
    544 	if (!dm_task_set_major(dmt, info->major) ||
    545 	    !dm_task_set_minor(dmt, info->minor)) {
    546 		log_error("Failed to set device number for %s table clear", name);
    547 		dm_task_destroy(dmt);
    548 		return 0;
    549 	}
    550 
    551 	r = dm_task_run(dmt);
    552 
    553 	if (!dm_task_get_info(dmt, info)) {
    554 		log_error("_node_clear_table failed: info missing after running task for %s", name);
    555 		r = 0;
    556 	}
    557 
    558 	dm_task_destroy(dmt);
    559 
    560 	return r;
    561 }
    562 
    563 struct dm_tree_node *dm_tree_add_new_dev(struct dm_tree *dtree,
    564 					    const char *name,
    565 					    const char *uuid,
    566 					    uint32_t major, uint32_t minor,
    567 					    int read_only,
    568 					    int clear_inactive,
    569 					    void *context)
    570 {
    571 	struct dm_tree_node *dnode;
    572 	struct dm_info info;
    573 	const char *name2;
    574 	const char *uuid2;
    575 
    576 	/* Do we need to add node to tree? */
    577 	if (!(dnode = dm_tree_find_node_by_uuid(dtree, uuid))) {
    578 		if (!(name2 = dm_pool_strdup(dtree->mem, name))) {
    579 			log_error("name pool_strdup failed");
    580 			return NULL;
    581 		}
    582 		if (!(uuid2 = dm_pool_strdup(dtree->mem, uuid))) {
    583 			log_error("uuid pool_strdup failed");
    584 			return NULL;
    585 		}
    586 
    587 		info.major = 0;
    588 		info.minor = 0;
    589 		info.exists = 0;
    590 		info.live_table = 0;
    591 		info.inactive_table = 0;
    592 		info.read_only = 0;
    593 
    594 		if (!(dnode = _create_dm_tree_node(dtree, name2, uuid2, &info,
    595 						   context, 0)))
    596 			return_NULL;
    597 
    598 		/* Attach to root node until a table is supplied */
    599 		if (!_add_to_toplevel(dnode) || !_add_to_bottomlevel(dnode))
    600 			return_NULL;
    601 
    602 		dnode->props.major = major;
    603 		dnode->props.minor = minor;
    604 		dnode->props.new_name = NULL;
    605 		dnode->props.size_changed = 0;
    606 	} else if (strcmp(name, dnode->name)) {
    607 		/* Do we need to rename node? */
    608 		if (!(dnode->props.new_name = dm_pool_strdup(dtree->mem, name))) {
    609 			log_error("name pool_strdup failed");
    610 			return 0;
    611 		}
    612 	}
    613 
    614 	dnode->props.read_only = read_only ? 1 : 0;
    615 	dnode->props.read_ahead = DM_READ_AHEAD_AUTO;
    616 	dnode->props.read_ahead_flags = 0;
    617 
    618 	if (clear_inactive && !_node_clear_table(dnode))
    619 		return_NULL;
    620 
    621 	dnode->context = context;
    622 	dnode->udev_flags = 0;
    623 
    624 	return dnode;
    625 }
    626 
    627 struct dm_tree_node *dm_tree_add_new_dev_with_udev_flags(struct dm_tree *dtree,
    628 							 const char *name,
    629 							 const char *uuid,
    630 							 uint32_t major,
    631 							 uint32_t minor,
    632 							 int read_only,
    633 							 int clear_inactive,
    634 							 void *context,
    635 							 uint16_t udev_flags)
    636 {
    637 	struct dm_tree_node *node;
    638 
    639 	if ((node = dm_tree_add_new_dev(dtree, name, uuid, major, minor, read_only,
    640 				       clear_inactive, context)))
    641 		node->udev_flags = udev_flags;
    642 
    643 	return node;
    644 }
    645 
    646 
    647 void dm_tree_node_set_read_ahead(struct dm_tree_node *dnode,
    648 				 uint32_t read_ahead,
    649 				 uint32_t read_ahead_flags)
    650 {
    651 	dnode->props.read_ahead = read_ahead;
    652 	dnode->props.read_ahead_flags = read_ahead_flags;
    653 }
    654 
    655 int dm_tree_add_dev(struct dm_tree *dtree, uint32_t major, uint32_t minor)
    656 {
    657 	return _add_dev(dtree, &dtree->root, major, minor) ? 1 : 0;
    658 }
    659 
    660 const char *dm_tree_node_get_name(struct dm_tree_node *node)
    661 {
    662 	return node->info.exists ? node->name : "";
    663 }
    664 
    665 const char *dm_tree_node_get_uuid(struct dm_tree_node *node)
    666 {
    667 	return node->info.exists ? node->uuid : "";
    668 }
    669 
    670 const struct dm_info *dm_tree_node_get_info(struct dm_tree_node *node)
    671 {
    672 	return &node->info;
    673 }
    674 
    675 void *dm_tree_node_get_context(struct dm_tree_node *node)
    676 {
    677 	return node->context;
    678 }
    679 
    680 int dm_tree_node_size_changed(struct dm_tree_node *dnode)
    681 {
    682 	return dnode->props.size_changed;
    683 }
    684 
    685 int dm_tree_node_num_children(struct dm_tree_node *node, uint32_t inverted)
    686 {
    687 	if (inverted) {
    688 		if (_nodes_are_linked(&node->dtree->root, node))
    689 			return 0;
    690 		return dm_list_size(&node->used_by);
    691 	}
    692 
    693 	if (_nodes_are_linked(node, &node->dtree->root))
    694 		return 0;
    695 
    696 	return dm_list_size(&node->uses);
    697 }
    698 
    699 /*
    700  * Returns 1 if no prefix supplied
    701  */
    702 static int _uuid_prefix_matches(const char *uuid, const char *uuid_prefix, size_t uuid_prefix_len)
    703 {
    704 	if (!uuid_prefix)
    705 		return 1;
    706 
    707 	if (!strncmp(uuid, uuid_prefix, uuid_prefix_len))
    708 		return 1;
    709 
    710 	/* Handle transition: active device uuids might be missing the prefix */
    711 	if (uuid_prefix_len <= 4)
    712 		return 0;
    713 
    714 	if (!strncmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1))
    715 		return 0;
    716 
    717 	if (strncmp(uuid_prefix, UUID_PREFIX, sizeof(UUID_PREFIX) - 1))
    718 		return 0;
    719 
    720 	if (!strncmp(uuid, uuid_prefix + sizeof(UUID_PREFIX) - 1, uuid_prefix_len - (sizeof(UUID_PREFIX) - 1)))
    721 		return 1;
    722 
    723 	return 0;
    724 }
    725 
    726 /*
    727  * Returns 1 if no children.
    728  */
    729 static int _children_suspended(struct dm_tree_node *node,
    730 			       uint32_t inverted,
    731 			       const char *uuid_prefix,
    732 			       size_t uuid_prefix_len)
    733 {
    734 	struct dm_list *list;
    735 	struct dm_tree_link *dlink;
    736 	const struct dm_info *dinfo;
    737 	const char *uuid;
    738 
    739 	if (inverted) {
    740 		if (_nodes_are_linked(&node->dtree->root, node))
    741 			return 1;
    742 		list = &node->used_by;
    743 	} else {
    744 		if (_nodes_are_linked(node, &node->dtree->root))
    745 			return 1;
    746 		list = &node->uses;
    747 	}
    748 
    749 	dm_list_iterate_items(dlink, list) {
    750 		if (!(uuid = dm_tree_node_get_uuid(dlink->node))) {
    751 			stack;
    752 			continue;
    753 		}
    754 
    755 		/* Ignore if it doesn't belong to this VG */
    756 		if (!_uuid_prefix_matches(uuid, uuid_prefix, uuid_prefix_len))
    757 			continue;
    758 
    759 		if (!(dinfo = dm_tree_node_get_info(dlink->node))) {
    760 			stack;	/* FIXME Is this normal? */
    761 			return 0;
    762 		}
    763 
    764 		if (!dinfo->suspended)
    765 			return 0;
    766 	}
    767 
    768 	return 1;
    769 }
    770 
    771 /*
    772  * Set major and minor to zero for root of tree.
    773  */
    774 struct dm_tree_node *dm_tree_find_node(struct dm_tree *dtree,
    775 					  uint32_t major,
    776 					  uint32_t minor)
    777 {
    778 	if (!major && !minor)
    779 		return &dtree->root;
    780 
    781 	return _find_dm_tree_node(dtree, major, minor);
    782 }
    783 
    784 /*
    785  * Set uuid to NULL for root of tree.
    786  */
    787 struct dm_tree_node *dm_tree_find_node_by_uuid(struct dm_tree *dtree,
    788 						  const char *uuid)
    789 {
    790 	if (!uuid || !*uuid)
    791 		return &dtree->root;
    792 
    793 	return _find_dm_tree_node_by_uuid(dtree, uuid);
    794 }
    795 
    796 /*
    797  * First time set *handle to NULL.
    798  * Set inverted to invert the tree.
    799  */
    800 struct dm_tree_node *dm_tree_next_child(void **handle,
    801 					   struct dm_tree_node *parent,
    802 					   uint32_t inverted)
    803 {
    804 	struct dm_list **dlink = (struct dm_list **) handle;
    805 	struct dm_list *use_list;
    806 
    807 	if (inverted)
    808 		use_list = &parent->used_by;
    809 	else
    810 		use_list = &parent->uses;
    811 
    812 	if (!*dlink)
    813 		*dlink = dm_list_first(use_list);
    814 	else
    815 		*dlink = dm_list_next(use_list, *dlink);
    816 
    817 	return (*dlink) ? dm_list_item(*dlink, struct dm_tree_link)->node : NULL;
    818 }
    819 
    820 /*
    821  * Deactivate a device with its dependencies if the uuid prefix matches.
    822  */
    823 static int _info_by_dev(uint32_t major, uint32_t minor, int with_open_count,
    824 			struct dm_info *info)
    825 {
    826 	struct dm_task *dmt;
    827 	int r;
    828 
    829 	if (!(dmt = dm_task_create(DM_DEVICE_INFO))) {
    830 		log_error("_info_by_dev: dm_task creation failed");
    831 		return 0;
    832 	}
    833 
    834 	if (!dm_task_set_major(dmt, major) || !dm_task_set_minor(dmt, minor)) {
    835 		log_error("_info_by_dev: Failed to set device number");
    836 		dm_task_destroy(dmt);
    837 		return 0;
    838 	}
    839 
    840 	if (!with_open_count && !dm_task_no_open_count(dmt))
    841 		log_error("Failed to disable open_count");
    842 
    843 	if ((r = dm_task_run(dmt)))
    844 		r = dm_task_get_info(dmt, info);
    845 
    846 	dm_task_destroy(dmt);
    847 
    848 	return r;
    849 }
    850 
    851 static int _deactivate_node(const char *name, uint32_t major, uint32_t minor,
    852 			    uint32_t *cookie, uint16_t udev_flags)
    853 {
    854 	struct dm_task *dmt;
    855 	int r = 0;
    856 
    857 	log_verbose("Removing %s (%" PRIu32 ":%" PRIu32 ")", name, major, minor);
    858 
    859 	if (!(dmt = dm_task_create(DM_DEVICE_REMOVE))) {
    860 		log_error("Deactivation dm_task creation failed for %s", name);
    861 		return 0;
    862 	}
    863 
    864 	if (!dm_task_set_major(dmt, major) || !dm_task_set_minor(dmt, minor)) {
    865 		log_error("Failed to set device number for %s deactivation", name);
    866 		goto out;
    867 	}
    868 
    869 	if (!dm_task_no_open_count(dmt))
    870 		log_error("Failed to disable open_count");
    871 
    872 	if (!dm_task_set_cookie(dmt, cookie, udev_flags))
    873 		goto out;
    874 
    875 	r = dm_task_run(dmt);
    876 
    877 	/* FIXME Until kernel returns actual name so dm-ioctl.c can handle it */
    878 	rm_dev_node(name, dmt->cookie_set);
    879 
    880 	/* FIXME Remove node from tree or mark invalid? */
    881 
    882 out:
    883 	dm_task_destroy(dmt);
    884 
    885 	return r;
    886 }
    887 
    888 static int _rename_node(const char *old_name, const char *new_name, uint32_t major,
    889 			uint32_t minor, uint32_t *cookie, uint16_t udev_flags)
    890 {
    891 	struct dm_task *dmt;
    892 	int r = 0;
    893 
    894 	log_verbose("Renaming %s (%" PRIu32 ":%" PRIu32 ") to %s", old_name, major, minor, new_name);
    895 
    896 	if (!(dmt = dm_task_create(DM_DEVICE_RENAME))) {
    897 		log_error("Rename dm_task creation failed for %s", old_name);
    898 		return 0;
    899 	}
    900 
    901 	if (!dm_task_set_name(dmt, old_name)) {
    902 		log_error("Failed to set name for %s rename.", old_name);
    903 		goto out;
    904 	}
    905 
    906 	if (!dm_task_set_newname(dmt, new_name))
    907                 goto_out;
    908 
    909 	if (!dm_task_no_open_count(dmt))
    910 		log_error("Failed to disable open_count");
    911 
    912 	if (!dm_task_set_cookie(dmt, cookie, udev_flags))
    913 		goto out;
    914 
    915 	r = dm_task_run(dmt);
    916 
    917 out:
    918 	dm_task_destroy(dmt);
    919 
    920 	return r;
    921 }
    922 
    923 /* FIXME Merge with _suspend_node? */
    924 static int _resume_node(const char *name, uint32_t major, uint32_t minor,
    925 			uint32_t read_ahead, uint32_t read_ahead_flags,
    926 			struct dm_info *newinfo, uint32_t *cookie,
    927 			uint16_t udev_flags)
    928 {
    929 	struct dm_task *dmt;
    930 	int r = 0;
    931 
    932 	log_verbose("Resuming %s (%" PRIu32 ":%" PRIu32 ")", name, major, minor);
    933 
    934 	if (!(dmt = dm_task_create(DM_DEVICE_RESUME))) {
    935 		log_error("Suspend dm_task creation failed for %s", name);
    936 		return 0;
    937 	}
    938 
    939 	/* FIXME Kernel should fill in name on return instead */
    940 	if (!dm_task_set_name(dmt, name)) {
    941 		log_error("Failed to set readahead device name for %s", name);
    942 		goto out;
    943 	}
    944 
    945 	if (!dm_task_set_major(dmt, major) || !dm_task_set_minor(dmt, minor)) {
    946 		log_error("Failed to set device number for %s resumption.", name);
    947 		goto out;
    948 	}
    949 
    950 	if (!dm_task_no_open_count(dmt))
    951 		log_error("Failed to disable open_count");
    952 
    953 	if (!dm_task_set_read_ahead(dmt, read_ahead, read_ahead_flags))
    954 		log_error("Failed to set read ahead");
    955 
    956 	if (!dm_task_set_cookie(dmt, cookie, udev_flags))
    957 		goto out;
    958 
    959 	if ((r = dm_task_run(dmt)))
    960 		r = dm_task_get_info(dmt, newinfo);
    961 
    962 out:
    963 	dm_task_destroy(dmt);
    964 
    965 	return r;
    966 }
    967 
    968 static int _suspend_node(const char *name, uint32_t major, uint32_t minor,
    969 			 int skip_lockfs, int no_flush, struct dm_info *newinfo)
    970 {
    971 	struct dm_task *dmt;
    972 	int r;
    973 
    974 	log_verbose("Suspending %s (%" PRIu32 ":%" PRIu32 ")%s%s",
    975 		    name, major, minor,
    976 		    skip_lockfs ? "" : " with filesystem sync",
    977 		    no_flush ? "" : " with device flush");
    978 
    979 	if (!(dmt = dm_task_create(DM_DEVICE_SUSPEND))) {
    980 		log_error("Suspend dm_task creation failed for %s", name);
    981 		return 0;
    982 	}
    983 
    984 	if (!dm_task_set_major(dmt, major) || !dm_task_set_minor(dmt, minor)) {
    985 		log_error("Failed to set device number for %s suspension.", name);
    986 		dm_task_destroy(dmt);
    987 		return 0;
    988 	}
    989 
    990 	if (!dm_task_no_open_count(dmt))
    991 		log_error("Failed to disable open_count");
    992 
    993 	if (skip_lockfs && !dm_task_skip_lockfs(dmt))
    994 		log_error("Failed to set skip_lockfs flag.");
    995 
    996 	if (no_flush && !dm_task_no_flush(dmt))
    997 		log_error("Failed to set no_flush flag.");
    998 
    999 	if ((r = dm_task_run(dmt)))
   1000 		r = dm_task_get_info(dmt, newinfo);
   1001 
   1002 	dm_task_destroy(dmt);
   1003 
   1004 	return r;
   1005 }
   1006 
   1007 int dm_tree_deactivate_children(struct dm_tree_node *dnode,
   1008 				   const char *uuid_prefix,
   1009 				   size_t uuid_prefix_len)
   1010 {
   1011 	void *handle = NULL;
   1012 	struct dm_tree_node *child = dnode;
   1013 	struct dm_info info;
   1014 	const struct dm_info *dinfo;
   1015 	const char *name;
   1016 	const char *uuid;
   1017 
   1018 	while ((child = dm_tree_next_child(&handle, dnode, 0))) {
   1019 		if (!(dinfo = dm_tree_node_get_info(child))) {
   1020 			stack;
   1021 			continue;
   1022 		}
   1023 
   1024 		if (!(name = dm_tree_node_get_name(child))) {
   1025 			stack;
   1026 			continue;
   1027 		}
   1028 
   1029 		if (!(uuid = dm_tree_node_get_uuid(child))) {
   1030 			stack;
   1031 			continue;
   1032 		}
   1033 
   1034 		/* Ignore if it doesn't belong to this VG */
   1035 		if (!_uuid_prefix_matches(uuid, uuid_prefix, uuid_prefix_len))
   1036 			continue;
   1037 
   1038 		/* Refresh open_count */
   1039 		if (!_info_by_dev(dinfo->major, dinfo->minor, 1, &info) ||
   1040 		    !info.exists || info.open_count)
   1041 			continue;
   1042 
   1043 		if (!_deactivate_node(name, info.major, info.minor,
   1044 				      &child->dtree->cookie, child->udev_flags)) {
   1045 			log_error("Unable to deactivate %s (%" PRIu32
   1046 				  ":%" PRIu32 ")", name, info.major,
   1047 				  info.minor);
   1048 			continue;
   1049 		}
   1050 
   1051 		if (dm_tree_node_num_children(child, 0))
   1052 			dm_tree_deactivate_children(child, uuid_prefix, uuid_prefix_len);
   1053 	}
   1054 
   1055 	return 1;
   1056 }
   1057 
   1058 void dm_tree_skip_lockfs(struct dm_tree_node *dnode)
   1059 {
   1060 	dnode->dtree->skip_lockfs = 1;
   1061 }
   1062 
   1063 void dm_tree_use_no_flush_suspend(struct dm_tree_node *dnode)
   1064 {
   1065 	dnode->dtree->no_flush = 1;
   1066 }
   1067 
   1068 int dm_tree_suspend_children(struct dm_tree_node *dnode,
   1069 				   const char *uuid_prefix,
   1070 				   size_t uuid_prefix_len)
   1071 {
   1072 	void *handle = NULL;
   1073 	struct dm_tree_node *child = dnode;
   1074 	struct dm_info info, newinfo;
   1075 	const struct dm_info *dinfo;
   1076 	const char *name;
   1077 	const char *uuid;
   1078 
   1079 	/* Suspend nodes at this level of the tree */
   1080 	while ((child = dm_tree_next_child(&handle, dnode, 0))) {
   1081 		if (!(dinfo = dm_tree_node_get_info(child))) {
   1082 			stack;
   1083 			continue;
   1084 		}
   1085 
   1086 		if (!(name = dm_tree_node_get_name(child))) {
   1087 			stack;
   1088 			continue;
   1089 		}
   1090 
   1091 		if (!(uuid = dm_tree_node_get_uuid(child))) {
   1092 			stack;
   1093 			continue;
   1094 		}
   1095 
   1096 		/* Ignore if it doesn't belong to this VG */
   1097 		if (!_uuid_prefix_matches(uuid, uuid_prefix, uuid_prefix_len))
   1098 			continue;
   1099 
   1100 		/* Ensure immediate parents are already suspended */
   1101 		if (!_children_suspended(child, 1, uuid_prefix, uuid_prefix_len))
   1102 			continue;
   1103 
   1104 		if (!_info_by_dev(dinfo->major, dinfo->minor, 0, &info) ||
   1105 		    !info.exists || info.suspended)
   1106 			continue;
   1107 
   1108 		if (!_suspend_node(name, info.major, info.minor,
   1109 				   child->dtree->skip_lockfs,
   1110 				   child->dtree->no_flush, &newinfo)) {
   1111 			log_error("Unable to suspend %s (%" PRIu32
   1112 				  ":%" PRIu32 ")", name, info.major,
   1113 				  info.minor);
   1114 			continue;
   1115 		}
   1116 
   1117 		/* Update cached info */
   1118 		child->info = newinfo;
   1119 	}
   1120 
   1121 	/* Then suspend any child nodes */
   1122 	handle = NULL;
   1123 
   1124 	while ((child = dm_tree_next_child(&handle, dnode, 0))) {
   1125 		if (!(uuid = dm_tree_node_get_uuid(child))) {
   1126 			stack;
   1127 			continue;
   1128 		}
   1129 
   1130 		/* Ignore if it doesn't belong to this VG */
   1131 		if (!_uuid_prefix_matches(uuid, uuid_prefix, uuid_prefix_len))
   1132 			continue;
   1133 
   1134 		if (dm_tree_node_num_children(child, 0))
   1135 			dm_tree_suspend_children(child, uuid_prefix, uuid_prefix_len);
   1136 	}
   1137 
   1138 	return 1;
   1139 }
   1140 
   1141 int dm_tree_activate_children(struct dm_tree_node *dnode,
   1142 				 const char *uuid_prefix,
   1143 				 size_t uuid_prefix_len)
   1144 {
   1145 	void *handle = NULL;
   1146 	struct dm_tree_node *child = dnode;
   1147 	struct dm_info newinfo;
   1148 	const char *name;
   1149 	const char *uuid;
   1150 	int priority;
   1151 
   1152 	/* Activate children first */
   1153 	while ((child = dm_tree_next_child(&handle, dnode, 0))) {
   1154 		if (!(uuid = dm_tree_node_get_uuid(child))) {
   1155 			stack;
   1156 			continue;
   1157 		}
   1158 
   1159 		if (!_uuid_prefix_matches(uuid, uuid_prefix, uuid_prefix_len))
   1160 			continue;
   1161 
   1162 		if (dm_tree_node_num_children(child, 0))
   1163 			dm_tree_activate_children(child, uuid_prefix, uuid_prefix_len);
   1164 	}
   1165 
   1166 	handle = NULL;
   1167 
   1168 	for (priority = 0; priority < 2; priority++) {
   1169 		while ((child = dm_tree_next_child(&handle, dnode, 0))) {
   1170 			if (!(uuid = dm_tree_node_get_uuid(child))) {
   1171 				stack;
   1172 				continue;
   1173 			}
   1174 
   1175 			if (!_uuid_prefix_matches(uuid, uuid_prefix, uuid_prefix_len))
   1176 				continue;
   1177 
   1178 			if (priority != child->activation_priority)
   1179 				continue;
   1180 
   1181 			if (!(name = dm_tree_node_get_name(child))) {
   1182 				stack;
   1183 				continue;
   1184 			}
   1185 
   1186 			/* Rename? */
   1187 			if (child->props.new_name) {
   1188 				if (!_rename_node(name, child->props.new_name, child->info.major,
   1189 						  child->info.minor, &child->dtree->cookie,
   1190 						  child->udev_flags)) {
   1191 					log_error("Failed to rename %s (%" PRIu32
   1192 						  ":%" PRIu32 ") to %s", name, child->info.major,
   1193 						  child->info.minor, child->props.new_name);
   1194 					return 0;
   1195 				}
   1196 				child->name = child->props.new_name;
   1197 				child->props.new_name = NULL;
   1198 			}
   1199 
   1200 			if (!child->info.inactive_table && !child->info.suspended)
   1201 				continue;
   1202 
   1203 			if (!_resume_node(child->name, child->info.major, child->info.minor,
   1204 					  child->props.read_ahead, child->props.read_ahead_flags,
   1205 					  &newinfo, &child->dtree->cookie, child->udev_flags)) {
   1206 				log_error("Unable to resume %s (%" PRIu32
   1207 					  ":%" PRIu32 ")", child->name, child->info.major,
   1208 					  child->info.minor);
   1209 				continue;
   1210 			}
   1211 
   1212 			/* Update cached info */
   1213 			child->info = newinfo;
   1214 		}
   1215 	}
   1216 
   1217 	handle = NULL;
   1218 
   1219 	return 1;
   1220 }
   1221 
   1222 static int _create_node(struct dm_tree_node *dnode)
   1223 {
   1224 	int r = 0;
   1225 	struct dm_task *dmt;
   1226 
   1227 	log_verbose("Creating %s", dnode->name);
   1228 
   1229 	if (!(dmt = dm_task_create(DM_DEVICE_CREATE))) {
   1230 		log_error("Create dm_task creation failed for %s", dnode->name);
   1231 		return 0;
   1232 	}
   1233 
   1234 	if (!dm_task_set_name(dmt, dnode->name)) {
   1235 		log_error("Failed to set device name for %s", dnode->name);
   1236 		goto out;
   1237 	}
   1238 
   1239 	if (!dm_task_set_uuid(dmt, dnode->uuid)) {
   1240 		log_error("Failed to set uuid for %s", dnode->name);
   1241 		goto out;
   1242 	}
   1243 
   1244 	if (dnode->props.major &&
   1245 	    (!dm_task_set_major(dmt, dnode->props.major) ||
   1246 	     !dm_task_set_minor(dmt, dnode->props.minor))) {
   1247 		log_error("Failed to set device number for %s creation.", dnode->name);
   1248 		goto out;
   1249 	}
   1250 
   1251 	if (dnode->props.read_only && !dm_task_set_ro(dmt)) {
   1252 		log_error("Failed to set read only flag for %s", dnode->name);
   1253 		goto out;
   1254 	}
   1255 
   1256 	if (!dm_task_no_open_count(dmt))
   1257 		log_error("Failed to disable open_count");
   1258 
   1259 	if ((r = dm_task_run(dmt)))
   1260 		r = dm_task_get_info(dmt, &dnode->info);
   1261 
   1262 out:
   1263 	dm_task_destroy(dmt);
   1264 
   1265 	return r;
   1266 }
   1267 
   1268 
   1269 static int _build_dev_string(char *devbuf, size_t bufsize, struct dm_tree_node *node)
   1270 {
   1271 	if (!dm_format_dev(devbuf, bufsize, node->info.major, node->info.minor)) {
   1272                 log_error("Failed to format %s device number for %s as dm "
   1273                           "target (%u,%u)",
   1274                           node->name, node->uuid, node->info.major, node->info.minor);
   1275                 return 0;
   1276 	}
   1277 
   1278 	return 1;
   1279 }
   1280 
   1281 /* simplify string emiting code */
   1282 #define EMIT_PARAMS(p, str...)\
   1283 do {\
   1284 	int w;\
   1285 	if ((w = dm_snprintf(params + p, paramsize - (size_t) p, str)) < 0) {\
   1286 		stack; /* Out of space */\
   1287 		return -1;\
   1288 	}\
   1289 	p += w;\
   1290 } while (0)
   1291 
   1292 /*
   1293  * _emit_areas_line
   1294  *
   1295  * Returns: 1 on success, 0 on failure
   1296  */
   1297 static int _emit_areas_line(struct dm_task *dmt __attribute((unused)),
   1298 			    struct load_segment *seg, char *params,
   1299 			    size_t paramsize, int *pos)
   1300 {
   1301 	struct seg_area *area;
   1302 	char devbuf[DM_FORMAT_DEV_BUFSIZE];
   1303 	unsigned first_time = 1;
   1304 
   1305 	dm_list_iterate_items(area, &seg->areas) {
   1306 		if (!_build_dev_string(devbuf, sizeof(devbuf), area->dev_node))
   1307 			return_0;
   1308 
   1309 		EMIT_PARAMS(*pos, "%s%s %" PRIu64, first_time ? "" : " ",
   1310 			    devbuf, area->offset);
   1311 
   1312 		first_time = 0;
   1313 	}
   1314 
   1315 	return 1;
   1316 }
   1317 
   1318 /*
   1319  * Returns: 1 on success, 0 on failure
   1320  */
   1321 static int _mirror_emit_segment_line(struct dm_task *dmt, uint32_t major,
   1322 				     uint32_t minor, struct load_segment *seg,
   1323 				     uint64_t *seg_start, char *params,
   1324 				     size_t paramsize)
   1325 {
   1326 	int r;
   1327 	int block_on_error = 0;
   1328 	int handle_errors = 0;
   1329 	int dm_log_userspace = 0;
   1330 	struct utsname uts;
   1331 	unsigned log_parm_count;
   1332 	int pos = 0;
   1333 	char logbuf[DM_FORMAT_DEV_BUFSIZE];
   1334 	const char *logtype;
   1335 
   1336 	r = uname(&uts);
   1337 	if (r)
   1338 		return_0;
   1339 
   1340 	if ((seg->flags & DM_BLOCK_ON_ERROR)) {
   1341 		/*
   1342 		 * Originally, block_on_error was an argument to the log
   1343 		 * portion of the mirror CTR table.  It was renamed to
   1344 		 * "handle_errors" and now resides in the 'features'
   1345 		 * section of the mirror CTR table (i.e. at the end).
   1346 		 *
   1347 		 * We can identify whether to use "block_on_error" or
   1348 		 * "handle_errors" by the dm-mirror module's version
   1349 		 * number (>= 1.12) or by the kernel version (>= 2.6.22).
   1350 		 */
   1351 		if (strncmp(uts.release, "2.6.22", 6) >= 0)
   1352 			handle_errors = 1;
   1353 		else
   1354 			block_on_error = 1;
   1355 	}
   1356 
   1357 	if (seg->clustered) {
   1358 		/* Cluster mirrors require a UUID */
   1359 		if (!seg->uuid)
   1360 			return_0;
   1361 
   1362 		/*
   1363 		 * Cluster mirrors used to have their own log
   1364 		 * types.  Now they are accessed through the
   1365 		 * userspace log type.
   1366 		 *
   1367 		 * The dm-log-userspace module was added to the
   1368 		 * 2.6.31 kernel.
   1369 		 */
   1370 		if (strncmp(uts.release, "2.6.31", 6) >= 0)
   1371 			dm_log_userspace = 1;
   1372 	}
   1373 
   1374 	/* Region size */
   1375 	log_parm_count = 1;
   1376 
   1377 	/* [no]sync, block_on_error etc. */
   1378 	log_parm_count += hweight32(seg->flags);
   1379 
   1380 	/* "handle_errors" is a feature arg now */
   1381 	if (handle_errors)
   1382 		log_parm_count--;
   1383 
   1384 	/* DM_CORELOG does not count in the param list */
   1385 	if (seg->flags & DM_CORELOG)
   1386 		log_parm_count--;
   1387 
   1388 	if (seg->clustered) {
   1389 		log_parm_count++; /* For UUID */
   1390 
   1391 		if (!dm_log_userspace)
   1392 			EMIT_PARAMS(pos, "clustered-");
   1393 	}
   1394 
   1395 	if (!seg->log)
   1396 		logtype = "core";
   1397 	else {
   1398 		logtype = "disk";
   1399 		log_parm_count++;
   1400 		if (!_build_dev_string(logbuf, sizeof(logbuf), seg->log))
   1401 			return_0;
   1402 	}
   1403 
   1404 	if (dm_log_userspace)
   1405 		EMIT_PARAMS(pos, "userspace %u %s clustered-%s",
   1406 			    log_parm_count, seg->uuid, logtype);
   1407 	else
   1408 		EMIT_PARAMS(pos, "%s %u", logtype, log_parm_count);
   1409 
   1410 	if (seg->log)
   1411 		EMIT_PARAMS(pos, " %s", logbuf);
   1412 
   1413 	EMIT_PARAMS(pos, " %u", seg->region_size);
   1414 
   1415 	if (seg->clustered && !dm_log_userspace)
   1416 		EMIT_PARAMS(pos, " %s", seg->uuid);
   1417 
   1418 	if ((seg->flags & DM_NOSYNC))
   1419 		EMIT_PARAMS(pos, " nosync");
   1420 	else if ((seg->flags & DM_FORCESYNC))
   1421 		EMIT_PARAMS(pos, " sync");
   1422 
   1423 	if (block_on_error)
   1424 		EMIT_PARAMS(pos, " block_on_error");
   1425 
   1426 	EMIT_PARAMS(pos, " %u ", seg->mirror_area_count);
   1427 
   1428 	if ((r = _emit_areas_line(dmt, seg, params, paramsize, &pos)) <= 0)
   1429 		return_0;
   1430 
   1431 	if (handle_errors)
   1432 		EMIT_PARAMS(pos, " 1 handle_errors");
   1433 
   1434 	return 1;
   1435 }
   1436 
   1437 static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
   1438 			      uint32_t minor, struct load_segment *seg,
   1439 			      uint64_t *seg_start, char *params,
   1440 			      size_t paramsize)
   1441 {
   1442 	int pos = 0;
   1443 	int r;
   1444 	char originbuf[DM_FORMAT_DEV_BUFSIZE], cowbuf[DM_FORMAT_DEV_BUFSIZE];
   1445 
   1446 	switch(seg->type) {
   1447 	case SEG_ERROR:
   1448 	case SEG_ZERO:
   1449 	case SEG_LINEAR:
   1450 		break;
   1451 	case SEG_MIRRORED:
   1452 		/* Mirrors are pretty complicated - now in separate function */
   1453 		r = _mirror_emit_segment_line(dmt, major, minor, seg, seg_start,
   1454 					      params, paramsize);
   1455 		if (!r)
   1456 			return_0;
   1457 		break;
   1458 	case SEG_SNAPSHOT:
   1459 		if (!_build_dev_string(originbuf, sizeof(originbuf), seg->origin))
   1460 			return_0;
   1461 		if (!_build_dev_string(cowbuf, sizeof(cowbuf), seg->cow))
   1462 			return_0;
   1463 		EMIT_PARAMS(pos, "%s %s %c %d", originbuf, cowbuf,
   1464 			    seg->persistent ? 'P' : 'N', seg->chunk_size);
   1465 		break;
   1466 	case SEG_SNAPSHOT_ORIGIN:
   1467 		if (!_build_dev_string(originbuf, sizeof(originbuf), seg->origin))
   1468 			return_0;
   1469 		EMIT_PARAMS(pos, "%s", originbuf);
   1470 		break;
   1471 	case SEG_STRIPED:
   1472 		EMIT_PARAMS(pos, "%u %u ", seg->area_count, seg->stripe_size);
   1473 		break;
   1474 	case SEG_CRYPT:
   1475 		EMIT_PARAMS(pos, "%s%s%s%s%s %s %" PRIu64 " ", seg->cipher,
   1476 			    seg->chainmode ? "-" : "", seg->chainmode ?: "",
   1477 			    seg->iv ? "-" : "", seg->iv ?: "", seg->key,
   1478 			    seg->iv_offset != DM_CRYPT_IV_DEFAULT ?
   1479 			    seg->iv_offset : *seg_start);
   1480 		break;
   1481 	}
   1482 
   1483 	switch(seg->type) {
   1484 	case SEG_ERROR:
   1485 	case SEG_SNAPSHOT:
   1486 	case SEG_SNAPSHOT_ORIGIN:
   1487 	case SEG_ZERO:
   1488 		break;
   1489 	case SEG_CRYPT:
   1490 	case SEG_LINEAR:
   1491 	case SEG_STRIPED:
   1492 		if ((r = _emit_areas_line(dmt, seg, params, paramsize, &pos)) <= 0) {
   1493 			stack;
   1494 			return r;
   1495 		}
   1496 		break;
   1497 	}
   1498 
   1499 	log_debug("Adding target to (%" PRIu32 ":%" PRIu32 "): %" PRIu64
   1500 		  " %" PRIu64 " %s %s", major, minor,
   1501 		  *seg_start, seg->size, dm_segtypes[seg->type].target, params);
   1502 
   1503 	if (!dm_task_add_target(dmt, *seg_start, seg->size, dm_segtypes[seg->type].target, params))
   1504 		return_0;
   1505 
   1506 	*seg_start += seg->size;
   1507 
   1508 	return 1;
   1509 }
   1510 
   1511 #undef EMIT_PARAMS
   1512 
   1513 static int _emit_segment(struct dm_task *dmt, uint32_t major, uint32_t minor,
   1514 			 struct load_segment *seg, uint64_t *seg_start)
   1515 {
   1516 	char *params;
   1517 	size_t paramsize = 4096;
   1518 	int ret;
   1519 
   1520 	do {
   1521 		if (!(params = dm_malloc(paramsize))) {
   1522 			log_error("Insufficient space for target parameters.");
   1523 			return 0;
   1524 		}
   1525 
   1526 		params[0] = '\0';
   1527 		ret = _emit_segment_line(dmt, major, minor, seg, seg_start,
   1528 					 params, paramsize);
   1529 		dm_free(params);
   1530 
   1531 		if (!ret)
   1532 			stack;
   1533 
   1534 		if (ret >= 0)
   1535 			return ret;
   1536 
   1537 		log_debug("Insufficient space in params[%" PRIsize_t
   1538 			  "] for target parameters.", paramsize);
   1539 
   1540 		paramsize *= 2;
   1541 	} while (paramsize < MAX_TARGET_PARAMSIZE);
   1542 
   1543 	log_error("Target parameter size too big. Aborting.");
   1544 	return 0;
   1545 }
   1546 
   1547 static int _load_node(struct dm_tree_node *dnode)
   1548 {
   1549 	int r = 0;
   1550 	struct dm_task *dmt;
   1551 	struct load_segment *seg;
   1552 	uint64_t seg_start = 0;
   1553 
   1554 	log_verbose("Loading %s table (%" PRIu32 ":%" PRIu32 ")", dnode->name,
   1555 		    dnode->info.major, dnode->info.minor);
   1556 
   1557 	if (!(dmt = dm_task_create(DM_DEVICE_RELOAD))) {
   1558 		log_error("Reload dm_task creation failed for %s", dnode->name);
   1559 		return 0;
   1560 	}
   1561 
   1562 	if (!dm_task_set_major(dmt, dnode->info.major) ||
   1563 	    !dm_task_set_minor(dmt, dnode->info.minor)) {
   1564 		log_error("Failed to set device number for %s reload.", dnode->name);
   1565 		goto out;
   1566 	}
   1567 
   1568 	if (dnode->props.read_only && !dm_task_set_ro(dmt)) {
   1569 		log_error("Failed to set read only flag for %s", dnode->name);
   1570 		goto out;
   1571 	}
   1572 
   1573 	if (!dm_task_no_open_count(dmt))
   1574 		log_error("Failed to disable open_count");
   1575 
   1576 	dm_list_iterate_items(seg, &dnode->props.segs)
   1577 		if (!_emit_segment(dmt, dnode->info.major, dnode->info.minor,
   1578 				   seg, &seg_start))
   1579 			goto_out;
   1580 
   1581 	if (!dm_task_suppress_identical_reload(dmt))
   1582 		log_error("Failed to suppress reload of identical tables.");
   1583 
   1584 	if ((r = dm_task_run(dmt))) {
   1585 		r = dm_task_get_info(dmt, &dnode->info);
   1586 		if (r && !dnode->info.inactive_table)
   1587 			log_verbose("Suppressed %s identical table reload.",
   1588 				    dnode->name);
   1589 
   1590 		if ((dnode->props.size_changed =
   1591 		     (dm_task_get_existing_table_size(dmt) == seg_start) ? 0 : 1))
   1592 			log_debug("Table size changed from %" PRIu64 " to %"
   1593 				  PRIu64 " for %s",
   1594 				  dm_task_get_existing_table_size(dmt),
   1595 				  seg_start, dnode->name);
   1596 	}
   1597 
   1598 	dnode->props.segment_count = 0;
   1599 
   1600 out:
   1601 	dm_task_destroy(dmt);
   1602 
   1603 	return r;
   1604 }
   1605 
   1606 int dm_tree_preload_children(struct dm_tree_node *dnode,
   1607 			     const char *uuid_prefix,
   1608 			     size_t uuid_prefix_len)
   1609 {
   1610 	void *handle = NULL;
   1611 	struct dm_tree_node *child;
   1612 	struct dm_info newinfo;
   1613 
   1614 	/* Preload children first */
   1615 	while ((child = dm_tree_next_child(&handle, dnode, 0))) {
   1616 		/* Skip existing non-device-mapper devices */
   1617 		if (!child->info.exists && child->info.major)
   1618 			continue;
   1619 
   1620 		/* Ignore if it doesn't belong to this VG */
   1621 		if (child->info.exists &&
   1622 		    !_uuid_prefix_matches(child->uuid, uuid_prefix, uuid_prefix_len))
   1623 			continue;
   1624 
   1625 		if (dm_tree_node_num_children(child, 0))
   1626 			dm_tree_preload_children(child, uuid_prefix, uuid_prefix_len);
   1627 
   1628 		/* FIXME Cope if name exists with no uuid? */
   1629 		if (!child->info.exists) {
   1630 			if (!_create_node(child)) {
   1631 				stack;
   1632 				return 0;
   1633 			}
   1634 		}
   1635 
   1636 		if (!child->info.inactive_table && child->props.segment_count) {
   1637 			if (!_load_node(child)) {
   1638 				stack;
   1639 				return 0;
   1640 			}
   1641 		}
   1642 
   1643 		/* Propagate device size change change */
   1644 		if (child->props.size_changed)
   1645 			dnode->props.size_changed = 1;
   1646 
   1647 		/* Resume device immediately if it has parents and its size changed */
   1648 		if (!dm_tree_node_num_children(child, 1) || !child->props.size_changed)
   1649 			continue;
   1650 
   1651 		if (!child->info.inactive_table && !child->info.suspended)
   1652 			continue;
   1653 
   1654 		if (!_resume_node(child->name, child->info.major, child->info.minor,
   1655 				  child->props.read_ahead, child->props.read_ahead_flags,
   1656 				  &newinfo, &child->dtree->cookie, child->udev_flags)) {
   1657 			log_error("Unable to resume %s (%" PRIu32
   1658 				  ":%" PRIu32 ")", child->name, child->info.major,
   1659 				  child->info.minor);
   1660 			continue;
   1661 		}
   1662 
   1663 		/* Update cached info */
   1664 		child->info = newinfo;
   1665 	}
   1666 
   1667 	handle = NULL;
   1668 
   1669 	return 1;
   1670 }
   1671 
   1672 /*
   1673  * Returns 1 if unsure.
   1674  */
   1675 int dm_tree_children_use_uuid(struct dm_tree_node *dnode,
   1676 				 const char *uuid_prefix,
   1677 				 size_t uuid_prefix_len)
   1678 {
   1679 	void *handle = NULL;
   1680 	struct dm_tree_node *child = dnode;
   1681 	const char *uuid;
   1682 
   1683 	while ((child = dm_tree_next_child(&handle, dnode, 0))) {
   1684 		if (!(uuid = dm_tree_node_get_uuid(child))) {
   1685 			log_error("Failed to get uuid for dtree node.");
   1686 			return 1;
   1687 		}
   1688 
   1689 		if (_uuid_prefix_matches(uuid, uuid_prefix, uuid_prefix_len))
   1690 			return 1;
   1691 
   1692 		if (dm_tree_node_num_children(child, 0))
   1693 			dm_tree_children_use_uuid(child, uuid_prefix, uuid_prefix_len);
   1694 	}
   1695 
   1696 	return 0;
   1697 }
   1698 
   1699 /*
   1700  * Target functions
   1701  */
   1702 static struct load_segment *_add_segment(struct dm_tree_node *dnode, unsigned type, uint64_t size)
   1703 {
   1704 	struct load_segment *seg;
   1705 
   1706 	if (!(seg = dm_pool_zalloc(dnode->dtree->mem, sizeof(*seg)))) {
   1707 		log_error("dtree node segment allocation failed");
   1708 		return NULL;
   1709 	}
   1710 
   1711 	seg->type = type;
   1712 	seg->size = size;
   1713 	seg->area_count = 0;
   1714 	dm_list_init(&seg->areas);
   1715 	seg->stripe_size = 0;
   1716 	seg->persistent = 0;
   1717 	seg->chunk_size = 0;
   1718 	seg->cow = NULL;
   1719 	seg->origin = NULL;
   1720 
   1721 	dm_list_add(&dnode->props.segs, &seg->list);
   1722 	dnode->props.segment_count++;
   1723 
   1724 	return seg;
   1725 }
   1726 
   1727 int dm_tree_node_add_snapshot_origin_target(struct dm_tree_node *dnode,
   1728                                                uint64_t size,
   1729                                                const char *origin_uuid)
   1730 {
   1731 	struct load_segment *seg;
   1732 	struct dm_tree_node *origin_node;
   1733 
   1734 	if (!(seg = _add_segment(dnode, SEG_SNAPSHOT_ORIGIN, size)))
   1735 		return_0;
   1736 
   1737 	if (!(origin_node = dm_tree_find_node_by_uuid(dnode->dtree, origin_uuid))) {
   1738 		log_error("Couldn't find snapshot origin uuid %s.", origin_uuid);
   1739 		return 0;
   1740 	}
   1741 
   1742 	seg->origin = origin_node;
   1743 	if (!_link_tree_nodes(dnode, origin_node))
   1744 		return_0;
   1745 
   1746 	/* Resume snapshot origins after new snapshots */
   1747 	dnode->activation_priority = 1;
   1748 
   1749 	return 1;
   1750 }
   1751 
   1752 int dm_tree_node_add_snapshot_target(struct dm_tree_node *node,
   1753                                         uint64_t size,
   1754                                         const char *origin_uuid,
   1755                                         const char *cow_uuid,
   1756                                         int persistent,
   1757                                         uint32_t chunk_size)
   1758 {
   1759 	struct load_segment *seg;
   1760 	struct dm_tree_node *origin_node, *cow_node;
   1761 
   1762 	if (!(seg = _add_segment(node, SEG_SNAPSHOT, size)))
   1763 		return_0;
   1764 
   1765 	if (!(origin_node = dm_tree_find_node_by_uuid(node->dtree, origin_uuid))) {
   1766 		log_error("Couldn't find snapshot origin uuid %s.", origin_uuid);
   1767 		return 0;
   1768 	}
   1769 
   1770 	seg->origin = origin_node;
   1771 	if (!_link_tree_nodes(node, origin_node))
   1772 		return_0;
   1773 
   1774 	if (!(cow_node = dm_tree_find_node_by_uuid(node->dtree, cow_uuid))) {
   1775 		log_error("Couldn't find snapshot origin uuid %s.", cow_uuid);
   1776 		return 0;
   1777 	}
   1778 
   1779 	seg->cow = cow_node;
   1780 	if (!_link_tree_nodes(node, cow_node))
   1781 		return_0;
   1782 
   1783 	seg->persistent = persistent ? 1 : 0;
   1784 	seg->chunk_size = chunk_size;
   1785 
   1786 	return 1;
   1787 }
   1788 
   1789 int dm_tree_node_add_error_target(struct dm_tree_node *node,
   1790                                      uint64_t size)
   1791 {
   1792 	if (!_add_segment(node, SEG_ERROR, size))
   1793 		return_0;
   1794 
   1795 	return 1;
   1796 }
   1797 
   1798 int dm_tree_node_add_zero_target(struct dm_tree_node *node,
   1799                                     uint64_t size)
   1800 {
   1801 	if (!_add_segment(node, SEG_ZERO, size))
   1802 		return_0;
   1803 
   1804 	return 1;
   1805 }
   1806 
   1807 int dm_tree_node_add_linear_target(struct dm_tree_node *node,
   1808                                       uint64_t size)
   1809 {
   1810 	if (!_add_segment(node, SEG_LINEAR, size))
   1811 		return_0;
   1812 
   1813 	return 1;
   1814 }
   1815 
   1816 int dm_tree_node_add_striped_target(struct dm_tree_node *node,
   1817                                        uint64_t size,
   1818                                        uint32_t stripe_size)
   1819 {
   1820 	struct load_segment *seg;
   1821 
   1822 	if (!(seg = _add_segment(node, SEG_STRIPED, size)))
   1823 		return_0;
   1824 
   1825 	seg->stripe_size = stripe_size;
   1826 
   1827 	return 1;
   1828 }
   1829 
   1830 int dm_tree_node_add_crypt_target(struct dm_tree_node *node,
   1831 				  uint64_t size,
   1832 				  const char *cipher,
   1833 				  const char *chainmode,
   1834 				  const char *iv,
   1835 				  uint64_t iv_offset,
   1836 				  const char *key)
   1837 {
   1838 	struct load_segment *seg;
   1839 
   1840 	if (!(seg = _add_segment(node, SEG_CRYPT, size)))
   1841 		return_0;
   1842 
   1843 	seg->cipher = cipher;
   1844 	seg->chainmode = chainmode;
   1845 	seg->iv = iv;
   1846 	seg->iv_offset = iv_offset;
   1847 	seg->key = key;
   1848 
   1849 	return 1;
   1850 }
   1851 
   1852 int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node,
   1853 					  uint32_t region_size,
   1854 					  unsigned clustered,
   1855 					  const char *log_uuid,
   1856 					  unsigned area_count,
   1857 					  uint32_t flags)
   1858 {
   1859 	struct dm_tree_node *log_node = NULL;
   1860 	struct load_segment *seg;
   1861 
   1862 	if (!node->props.segment_count) {
   1863 		log_error("Internal error: Attempt to add target area to missing segment.");
   1864 		return 0;
   1865 	}
   1866 
   1867 	seg = dm_list_item(dm_list_last(&node->props.segs), struct load_segment);
   1868 
   1869 	if (log_uuid) {
   1870 		if (!(seg->uuid = dm_pool_strdup(node->dtree->mem, log_uuid))) {
   1871 			log_error("log uuid pool_strdup failed");
   1872 			return 0;
   1873 		}
   1874 		if (!(flags & DM_CORELOG)) {
   1875 			if (!(log_node = dm_tree_find_node_by_uuid(node->dtree, log_uuid))) {
   1876 				log_error("Couldn't find mirror log uuid %s.", log_uuid);
   1877 				return 0;
   1878 			}
   1879 
   1880 			if (!_link_tree_nodes(node, log_node))
   1881 				return_0;
   1882 		}
   1883 	}
   1884 
   1885 	seg->log = log_node;
   1886 	seg->region_size = region_size;
   1887 	seg->clustered = clustered;
   1888 	seg->mirror_area_count = area_count;
   1889 	seg->flags = flags;
   1890 
   1891 	return 1;
   1892 }
   1893 
   1894 int dm_tree_node_add_mirror_target(struct dm_tree_node *node,
   1895                                       uint64_t size)
   1896 {
   1897 	struct load_segment *seg;
   1898 
   1899 	if (!(seg = _add_segment(node, SEG_MIRRORED, size)))
   1900 		return_0;
   1901 
   1902 	return 1;
   1903 }
   1904 
   1905 static int _add_area(struct dm_tree_node *node, struct load_segment *seg, struct dm_tree_node *dev_node, uint64_t offset)
   1906 {
   1907 	struct seg_area *area;
   1908 
   1909 	if (!(area = dm_pool_zalloc(node->dtree->mem, sizeof (*area)))) {
   1910 		log_error("Failed to allocate target segment area.");
   1911 		return 0;
   1912 	}
   1913 
   1914 	area->dev_node = dev_node;
   1915 	area->offset = offset;
   1916 
   1917 	dm_list_add(&seg->areas, &area->list);
   1918 	seg->area_count++;
   1919 
   1920 	return 1;
   1921 }
   1922 
   1923 int dm_tree_node_add_target_area(struct dm_tree_node *node,
   1924                                     const char *dev_name,
   1925                                     const char *uuid,
   1926                                     uint64_t offset)
   1927 {
   1928 	struct load_segment *seg;
   1929 	struct stat info;
   1930 	struct dm_tree_node *dev_node;
   1931 
   1932 	if ((!dev_name || !*dev_name) && (!uuid || !*uuid)) {
   1933 		log_error("dm_tree_node_add_target_area called without device");
   1934 		return 0;
   1935 	}
   1936 
   1937 	if (uuid) {
   1938 		if (!(dev_node = dm_tree_find_node_by_uuid(node->dtree, uuid))) {
   1939 			log_error("Couldn't find area uuid %s.", uuid);
   1940 			return 0;
   1941 		}
   1942 		if (!_link_tree_nodes(node, dev_node))
   1943 			return_0;
   1944 	} else {
   1945         	if (stat(dev_name, &info) < 0) {
   1946 			log_error("Device %s not found.", dev_name);
   1947 			return 0;
   1948 		}
   1949 #ifndef __NetBSD__
   1950         	if (!S_ISBLK(info.st_mode)) {
   1951 			log_error("Device %s is not a block device.", dev_name);
   1952 			return 0;
   1953 		}
   1954 #else
   1955 		if (S_ISBLK(info.st_mode)) {
   1956 			log_error("Device %s is a block device. Use raw devices on NetBSD.", dev_name);
   1957 			return 0;
   1958 		}
   1959 #endif
   1960 		/* FIXME Check correct macro use */
   1961 		if (!(dev_node = _add_dev(node->dtree, node, MAJOR(info.st_rdev), MINOR(info.st_rdev))))
   1962 			return_0;
   1963 	}
   1964 
   1965 	if (!node->props.segment_count) {
   1966 		log_error("Internal error: Attempt to add target area to missing segment.");
   1967 		return 0;
   1968 	}
   1969 
   1970 	seg = dm_list_item(dm_list_last(&node->props.segs), struct load_segment);
   1971 
   1972 	if (!_add_area(node, seg, dev_node, offset))
   1973 		return_0;
   1974 
   1975 	return 1;
   1976 }
   1977 
   1978 void dm_tree_set_cookie(struct dm_tree_node *node, uint32_t cookie)
   1979 {
   1980 	node->dtree->cookie = cookie;
   1981 }
   1982 
   1983 uint32_t dm_tree_get_cookie(struct dm_tree_node *node)
   1984 {
   1985 	return node->dtree->cookie;
   1986 }
   1987