xref: /netbsd-src/external/gpl2/lvm2/dist/include/libdevmapper.h (revision 7c604eea85b4f330dc75ffe65e947f4d73758aa0)
1*7c604eeaShaad /*	$NetBSD: libdevmapper.h,v 1.1.1.2 2009/12/02 00:25:41 haad Exp $	*/
256a34939Shaad 
356a34939Shaad /*
456a34939Shaad  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
556a34939Shaad  * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
656a34939Shaad  *
756a34939Shaad  * This file is part of the device-mapper userspace tools.
856a34939Shaad  *
956a34939Shaad  * This copyrighted material is made available to anyone wishing to use,
1056a34939Shaad  * modify, copy, or redistribute it subject to the terms and conditions
1156a34939Shaad  * of the GNU Lesser General Public License v.2.1.
1256a34939Shaad  *
1356a34939Shaad  * You should have received a copy of the GNU Lesser General Public License
1456a34939Shaad  * along with this program; if not, write to the Free Software Foundation,
1556a34939Shaad  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1656a34939Shaad  */
1756a34939Shaad 
1856a34939Shaad #ifndef LIB_DEVICE_MAPPER_H
1956a34939Shaad #define LIB_DEVICE_MAPPER_H
2056a34939Shaad 
2156a34939Shaad #include <inttypes.h>
2256a34939Shaad #include <stdarg.h>
2356a34939Shaad #include <sys/types.h>
2456a34939Shaad 
2556a34939Shaad #ifdef linux
2656a34939Shaad #  include <linux/types.h>
2756a34939Shaad #endif
2856a34939Shaad 
2956a34939Shaad #include <limits.h>
3056a34939Shaad #include <string.h>
3156a34939Shaad #include <stdlib.h>
3256a34939Shaad #include <stdio.h>
3356a34939Shaad 
3456a34939Shaad /*****************************************************************
3556a34939Shaad  * The first section of this file provides direct access to the
36*7c604eeaShaad  * individual device-mapper ioctls.  Since it is quite laborious to
37*7c604eeaShaad  * build the ioctl arguments for the device-mapper, people are
38*7c604eeaShaad  * encouraged to use this library.
3956a34939Shaad  ****************************************************************/
4056a34939Shaad 
4156a34939Shaad /*
42*7c604eeaShaad  * The library user may wish to register their own
43*7c604eeaShaad  * logging function.  By default errors go to stderr.
44*7c604eeaShaad  * Use dm_log_with_errno_init(NULL) to restore the default log fn.
4556a34939Shaad  */
4656a34939Shaad 
47*7c604eeaShaad typedef void (*dm_log_with_errno_fn) (int level, const char *file, int line,
48*7c604eeaShaad 				      int dm_errno, const char *f, ...)
49*7c604eeaShaad     __attribute__ ((format(printf, 5, 6)));
50*7c604eeaShaad 
51*7c604eeaShaad void dm_log_with_errno_init(dm_log_with_errno_fn fn);
52*7c604eeaShaad void dm_log_init_verbose(int level);
53*7c604eeaShaad 
54*7c604eeaShaad /*
55*7c604eeaShaad  * Original version of this function.
56*7c604eeaShaad  * dm_errno is set to 0.
57*7c604eeaShaad  *
58*7c604eeaShaad  * Deprecated: Use the _with_errno_ versions above instead.
59*7c604eeaShaad  */
6056a34939Shaad typedef void (*dm_log_fn) (int level, const char *file, int line,
6156a34939Shaad 			   const char *f, ...)
6256a34939Shaad     __attribute__ ((format(printf, 4, 5)));
6356a34939Shaad void dm_log_init(dm_log_fn fn);
64*7c604eeaShaad /*
65*7c604eeaShaad  * For backward-compatibility, indicate that dm_log_init() was used
66*7c604eeaShaad  * to set a non-default value of dm_log().
67*7c604eeaShaad  */
68*7c604eeaShaad int dm_log_is_non_default(void);
6956a34939Shaad 
7056a34939Shaad enum {
7156a34939Shaad 	DM_DEVICE_CREATE,
7256a34939Shaad 	DM_DEVICE_RELOAD,
7356a34939Shaad 	DM_DEVICE_REMOVE,
7456a34939Shaad 	DM_DEVICE_REMOVE_ALL,
7556a34939Shaad 
7656a34939Shaad 	DM_DEVICE_SUSPEND,
7756a34939Shaad 	DM_DEVICE_RESUME,
7856a34939Shaad 
7956a34939Shaad 	DM_DEVICE_INFO,
8056a34939Shaad 	DM_DEVICE_DEPS,
8156a34939Shaad 	DM_DEVICE_RENAME,
8256a34939Shaad 
8356a34939Shaad 	DM_DEVICE_VERSION,
8456a34939Shaad 
8556a34939Shaad 	DM_DEVICE_STATUS,
8656a34939Shaad 	DM_DEVICE_TABLE,
8756a34939Shaad 	DM_DEVICE_WAITEVENT,
8856a34939Shaad 
8956a34939Shaad 	DM_DEVICE_LIST,
9056a34939Shaad 
9156a34939Shaad 	DM_DEVICE_CLEAR,
9256a34939Shaad 
9356a34939Shaad 	DM_DEVICE_MKNODES,
9456a34939Shaad 
9556a34939Shaad 	DM_DEVICE_LIST_VERSIONS,
9656a34939Shaad 
9756a34939Shaad 	DM_DEVICE_TARGET_MSG,
9856a34939Shaad 
9956a34939Shaad 	DM_DEVICE_SET_GEOMETRY
10056a34939Shaad };
10156a34939Shaad 
102*7c604eeaShaad /*
103*7c604eeaShaad  * You will need to build a struct dm_task for
104*7c604eeaShaad  * each ioctl command you want to execute.
105*7c604eeaShaad  */
106*7c604eeaShaad 
10756a34939Shaad struct dm_task;
10856a34939Shaad 
10956a34939Shaad struct dm_task *dm_task_create(int type);
11056a34939Shaad void dm_task_destroy(struct dm_task *dmt);
11156a34939Shaad 
11256a34939Shaad int dm_task_set_name(struct dm_task *dmt, const char *name);
11356a34939Shaad int dm_task_set_uuid(struct dm_task *dmt, const char *uuid);
11456a34939Shaad 
11556a34939Shaad /*
11656a34939Shaad  * Retrieve attributes after an info.
11756a34939Shaad  */
11856a34939Shaad struct dm_info {
11956a34939Shaad 	int exists;
12056a34939Shaad 	int suspended;
12156a34939Shaad 	int live_table;
12256a34939Shaad 	int inactive_table;
12356a34939Shaad 	int32_t open_count;
12456a34939Shaad 	uint32_t event_nr;
12556a34939Shaad 	uint32_t major;
12656a34939Shaad 	uint32_t minor;		/* minor device number */
12756a34939Shaad 	int read_only;		/* 0:read-write; 1:read-only */
12856a34939Shaad 
12956a34939Shaad 	int32_t target_count;
13056a34939Shaad };
13156a34939Shaad 
13256a34939Shaad struct dm_deps {
13356a34939Shaad 	uint32_t count;
13456a34939Shaad 	uint32_t filler;
13556a34939Shaad 	uint64_t device[0];
13656a34939Shaad };
13756a34939Shaad 
13856a34939Shaad struct dm_names {
13956a34939Shaad 	uint64_t dev;
14056a34939Shaad 	uint32_t next;		/* Offset to next struct from start of this struct */
14156a34939Shaad 	char name[0];
14256a34939Shaad };
14356a34939Shaad 
14456a34939Shaad struct dm_versions {
14556a34939Shaad 	uint32_t next;		/* Offset to next struct from start of this struct */
14656a34939Shaad 	uint32_t version[3];
14756a34939Shaad 
14856a34939Shaad 	char name[0];
14956a34939Shaad };
15056a34939Shaad 
15156a34939Shaad int dm_get_library_version(char *version, size_t size);
15256a34939Shaad int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size);
15356a34939Shaad int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi);
15456a34939Shaad const char *dm_task_get_name(const struct dm_task *dmt);
15556a34939Shaad const char *dm_task_get_uuid(const struct dm_task *dmt);
15656a34939Shaad 
15756a34939Shaad struct dm_deps *dm_task_get_deps(struct dm_task *dmt);
15856a34939Shaad struct dm_names *dm_task_get_names(struct dm_task *dmt);
15956a34939Shaad struct dm_versions *dm_task_get_versions(struct dm_task *dmt);
16056a34939Shaad 
16156a34939Shaad int dm_task_set_ro(struct dm_task *dmt);
16256a34939Shaad int dm_task_set_newname(struct dm_task *dmt, const char *newname);
16356a34939Shaad int dm_task_set_minor(struct dm_task *dmt, int minor);
16456a34939Shaad int dm_task_set_major(struct dm_task *dmt, int major);
165*7c604eeaShaad int dm_task_set_major_minor(struct dm_task *dmt, int major, int minor, int allow_default_major_fallback);
16656a34939Shaad int dm_task_set_uid(struct dm_task *dmt, uid_t uid);
16756a34939Shaad int dm_task_set_gid(struct dm_task *dmt, gid_t gid);
16856a34939Shaad int dm_task_set_mode(struct dm_task *dmt, mode_t mode);
169*7c604eeaShaad int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags);
17056a34939Shaad int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr);
17156a34939Shaad int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads, const char *sectors, const char *start);
17256a34939Shaad int dm_task_set_message(struct dm_task *dmt, const char *message);
17356a34939Shaad int dm_task_set_sector(struct dm_task *dmt, uint64_t sector);
17456a34939Shaad int dm_task_no_flush(struct dm_task *dmt);
17556a34939Shaad int dm_task_no_open_count(struct dm_task *dmt);
17656a34939Shaad int dm_task_skip_lockfs(struct dm_task *dmt);
177*7c604eeaShaad int dm_task_query_inactive_table(struct dm_task *dmt);
17856a34939Shaad int dm_task_suppress_identical_reload(struct dm_task *dmt);
17956a34939Shaad 
18056a34939Shaad /*
18156a34939Shaad  * Control read_ahead.
18256a34939Shaad  */
18356a34939Shaad #define DM_READ_AHEAD_AUTO UINT32_MAX	/* Use kernel default readahead */
18456a34939Shaad #define DM_READ_AHEAD_NONE 0		/* Disable readahead */
18556a34939Shaad 
18656a34939Shaad #define DM_READ_AHEAD_MINIMUM_FLAG	0x1	/* Value supplied is minimum */
18756a34939Shaad 
18856a34939Shaad /*
18956a34939Shaad  * Read ahead is set with DM_DEVICE_CREATE with a table or DM_DEVICE_RESUME.
19056a34939Shaad  */
19156a34939Shaad int dm_task_set_read_ahead(struct dm_task *dmt, uint32_t read_ahead,
19256a34939Shaad 			   uint32_t read_ahead_flags);
19356a34939Shaad uint32_t dm_task_get_read_ahead(const struct dm_task *dmt,
19456a34939Shaad 				uint32_t *read_ahead);
19556a34939Shaad 
19656a34939Shaad /*
19756a34939Shaad  * Use these to prepare for a create or reload.
19856a34939Shaad  */
19956a34939Shaad int dm_task_add_target(struct dm_task *dmt,
20056a34939Shaad 		       uint64_t start,
20156a34939Shaad 		       uint64_t size, const char *ttype, const char *params);
20256a34939Shaad 
20356a34939Shaad /*
20456a34939Shaad  * Format major/minor numbers correctly for input to driver.
20556a34939Shaad  */
20656a34939Shaad #define DM_FORMAT_DEV_BUFSIZE	13	/* Minimum bufsize to handle worst case. */
20756a34939Shaad int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, uint32_t dev_minor);
20856a34939Shaad 
20956a34939Shaad /* Use this to retrive target information returned from a STATUS call */
21056a34939Shaad void *dm_get_next_target(struct dm_task *dmt,
21156a34939Shaad 			 void *next, uint64_t *start, uint64_t *length,
21256a34939Shaad 			 char **target_type, char **params);
21356a34939Shaad 
21456a34939Shaad /*
21556a34939Shaad  * Call this to actually run the ioctl.
21656a34939Shaad  */
21756a34939Shaad int dm_task_run(struct dm_task *dmt);
21856a34939Shaad 
21956a34939Shaad /*
22056a34939Shaad  * Call this to make or remove the device nodes associated with previously
22156a34939Shaad  * issued commands.
22256a34939Shaad  */
22356a34939Shaad void dm_task_update_nodes(void);
22456a34939Shaad 
22556a34939Shaad /*
22656a34939Shaad  * Configure the device-mapper directory
22756a34939Shaad  */
22856a34939Shaad int dm_set_dev_dir(const char *dir);
22956a34939Shaad const char *dm_dir(void);
23056a34939Shaad 
23156a34939Shaad /*
23256a34939Shaad  * Determine whether a major number belongs to device-mapper or not.
23356a34939Shaad  */
23456a34939Shaad int dm_is_dm_major(uint32_t major);
23556a34939Shaad 
23656a34939Shaad /*
23756a34939Shaad  * Release library resources
23856a34939Shaad  */
23956a34939Shaad void dm_lib_release(void);
24056a34939Shaad void dm_lib_exit(void) __attribute((destructor));
24156a34939Shaad 
24256a34939Shaad /*
24356a34939Shaad  * Use NULL for all devices.
24456a34939Shaad  */
24556a34939Shaad int dm_mknodes(const char *name);
24656a34939Shaad int dm_driver_version(char *version, size_t size);
24756a34939Shaad 
24856a34939Shaad /******************************************************
24956a34939Shaad  * Functions to build and manipulate trees of devices *
25056a34939Shaad  ******************************************************/
25156a34939Shaad struct dm_tree;
25256a34939Shaad struct dm_tree_node;
25356a34939Shaad 
25456a34939Shaad /*
25556a34939Shaad  * Initialise an empty dependency tree.
25656a34939Shaad  *
25756a34939Shaad  * The tree consists of a root node together with one node for each mapped
25856a34939Shaad  * device which has child nodes for each device referenced in its table.
25956a34939Shaad  *
26056a34939Shaad  * Every node in the tree has one or more children and one or more parents.
26156a34939Shaad  *
26256a34939Shaad  * The root node is the parent/child of every node that doesn't have other
26356a34939Shaad  * parents/children.
26456a34939Shaad  */
26556a34939Shaad struct dm_tree *dm_tree_create(void);
26656a34939Shaad void dm_tree_free(struct dm_tree *tree);
26756a34939Shaad 
26856a34939Shaad /*
26956a34939Shaad  * Add nodes to the tree for a given device and all the devices it uses.
27056a34939Shaad  */
27156a34939Shaad int dm_tree_add_dev(struct dm_tree *tree, uint32_t major, uint32_t minor);
27256a34939Shaad 
27356a34939Shaad /*
27456a34939Shaad  * Add a new node to the tree if it doesn't already exist.
27556a34939Shaad  */
27656a34939Shaad struct dm_tree_node *dm_tree_add_new_dev(struct dm_tree *tree,
27756a34939Shaad 					 const char *name,
27856a34939Shaad 					 const char *uuid,
27956a34939Shaad 					 uint32_t major, uint32_t minor,
28056a34939Shaad 					 int read_only,
28156a34939Shaad 					 int clear_inactive,
28256a34939Shaad 					 void *context);
283*7c604eeaShaad struct dm_tree_node *dm_tree_add_new_dev_with_udev_flags(struct dm_tree *tree,
284*7c604eeaShaad 							 const char *name,
285*7c604eeaShaad 							 const char *uuid,
286*7c604eeaShaad 							 uint32_t major,
287*7c604eeaShaad 							 uint32_t minor,
288*7c604eeaShaad 							 int read_only,
289*7c604eeaShaad 							 int clear_inactive,
290*7c604eeaShaad 							 void *context,
291*7c604eeaShaad 							 uint16_t udev_flags);
29256a34939Shaad 
29356a34939Shaad /*
29456a34939Shaad  * Search for a node in the tree.
29556a34939Shaad  * Set major and minor to 0 or uuid to NULL to get the root node.
29656a34939Shaad  */
29756a34939Shaad struct dm_tree_node *dm_tree_find_node(struct dm_tree *tree,
29856a34939Shaad 					  uint32_t major,
29956a34939Shaad 					  uint32_t minor);
30056a34939Shaad struct dm_tree_node *dm_tree_find_node_by_uuid(struct dm_tree *tree,
30156a34939Shaad 						  const char *uuid);
30256a34939Shaad 
30356a34939Shaad /*
30456a34939Shaad  * Use this to walk through all children of a given node.
30556a34939Shaad  * Set handle to NULL in first call.
30656a34939Shaad  * Returns NULL after the last child.
30756a34939Shaad  * Set inverted to use inverted tree.
30856a34939Shaad  */
30956a34939Shaad struct dm_tree_node *dm_tree_next_child(void **handle,
31056a34939Shaad 					   struct dm_tree_node *parent,
31156a34939Shaad 					   uint32_t inverted);
31256a34939Shaad 
31356a34939Shaad /*
31456a34939Shaad  * Get properties of a node.
31556a34939Shaad  */
31656a34939Shaad const char *dm_tree_node_get_name(struct dm_tree_node *node);
31756a34939Shaad const char *dm_tree_node_get_uuid(struct dm_tree_node *node);
31856a34939Shaad const struct dm_info *dm_tree_node_get_info(struct dm_tree_node *node);
31956a34939Shaad void *dm_tree_node_get_context(struct dm_tree_node *node);
320*7c604eeaShaad int dm_tree_node_size_changed(struct dm_tree_node *dnode);
32156a34939Shaad 
32256a34939Shaad /*
32356a34939Shaad  * Returns the number of children of the given node (excluding the root node).
32456a34939Shaad  * Set inverted for the number of parents.
32556a34939Shaad  */
32656a34939Shaad int dm_tree_node_num_children(struct dm_tree_node *node, uint32_t inverted);
32756a34939Shaad 
32856a34939Shaad /*
32956a34939Shaad  * Deactivate a device plus all dependencies.
33056a34939Shaad  * Ignores devices that don't have a uuid starting with uuid_prefix.
33156a34939Shaad  */
33256a34939Shaad int dm_tree_deactivate_children(struct dm_tree_node *dnode,
33356a34939Shaad 				   const char *uuid_prefix,
33456a34939Shaad 				   size_t uuid_prefix_len);
33556a34939Shaad /*
33656a34939Shaad  * Preload/create a device plus all dependencies.
33756a34939Shaad  * Ignores devices that don't have a uuid starting with uuid_prefix.
33856a34939Shaad  */
33956a34939Shaad int dm_tree_preload_children(struct dm_tree_node *dnode,
34056a34939Shaad 			     const char *uuid_prefix,
34156a34939Shaad 			     size_t uuid_prefix_len);
34256a34939Shaad 
34356a34939Shaad /*
34456a34939Shaad  * Resume a device plus all dependencies.
34556a34939Shaad  * Ignores devices that don't have a uuid starting with uuid_prefix.
34656a34939Shaad  */
34756a34939Shaad int dm_tree_activate_children(struct dm_tree_node *dnode,
34856a34939Shaad 			      const char *uuid_prefix,
34956a34939Shaad 			      size_t uuid_prefix_len);
35056a34939Shaad 
35156a34939Shaad /*
35256a34939Shaad  * Suspend a device plus all dependencies.
35356a34939Shaad  * Ignores devices that don't have a uuid starting with uuid_prefix.
35456a34939Shaad  */
35556a34939Shaad int dm_tree_suspend_children(struct dm_tree_node *dnode,
35656a34939Shaad 				   const char *uuid_prefix,
35756a34939Shaad 				   size_t uuid_prefix_len);
35856a34939Shaad 
35956a34939Shaad /*
36056a34939Shaad  * Skip the filesystem sync when suspending.
36156a34939Shaad  * Does nothing with other functions.
36256a34939Shaad  * Use this when no snapshots are involved.
36356a34939Shaad  */
36456a34939Shaad void dm_tree_skip_lockfs(struct dm_tree_node *dnode);
36556a34939Shaad 
36656a34939Shaad /*
36756a34939Shaad  * Set the 'noflush' flag when suspending devices.
36856a34939Shaad  * If the kernel supports it, instead of erroring outstanding I/O that
36956a34939Shaad  * cannot be completed, the I/O is queued and resubmitted when the
37056a34939Shaad  * device is resumed.  This affects multipath devices when all paths
37156a34939Shaad  * have failed and queue_if_no_path is set, and mirror devices when
37256a34939Shaad  * block_on_error is set and the mirror log has failed.
37356a34939Shaad  */
37456a34939Shaad void dm_tree_use_no_flush_suspend(struct dm_tree_node *dnode);
37556a34939Shaad 
37656a34939Shaad /*
37756a34939Shaad  * Is the uuid prefix present in the tree?
37856a34939Shaad  * Only returns 0 if every node was checked successfully.
37956a34939Shaad  * Returns 1 if the tree walk has to be aborted.
38056a34939Shaad  */
38156a34939Shaad int dm_tree_children_use_uuid(struct dm_tree_node *dnode,
38256a34939Shaad 				 const char *uuid_prefix,
38356a34939Shaad 				 size_t uuid_prefix_len);
38456a34939Shaad 
38556a34939Shaad /*
38656a34939Shaad  * Construct tables for new nodes before activating them.
38756a34939Shaad  */
38856a34939Shaad int dm_tree_node_add_snapshot_origin_target(struct dm_tree_node *dnode,
38956a34939Shaad 					       uint64_t size,
39056a34939Shaad 					       const char *origin_uuid);
39156a34939Shaad int dm_tree_node_add_snapshot_target(struct dm_tree_node *node,
39256a34939Shaad 					uint64_t size,
39356a34939Shaad 					const char *origin_uuid,
39456a34939Shaad 					const char *cow_uuid,
39556a34939Shaad 					int persistent,
39656a34939Shaad 					uint32_t chunk_size);
39756a34939Shaad int dm_tree_node_add_error_target(struct dm_tree_node *node,
39856a34939Shaad 				     uint64_t size);
39956a34939Shaad int dm_tree_node_add_zero_target(struct dm_tree_node *node,
40056a34939Shaad 				    uint64_t size);
40156a34939Shaad int dm_tree_node_add_linear_target(struct dm_tree_node *node,
40256a34939Shaad 				      uint64_t size);
40356a34939Shaad int dm_tree_node_add_striped_target(struct dm_tree_node *node,
40456a34939Shaad 				       uint64_t size,
40556a34939Shaad 				       uint32_t stripe_size);
406*7c604eeaShaad 
407*7c604eeaShaad #define DM_CRYPT_IV_DEFAULT	UINT64_C(-1)	/* iv_offset == seg offset */
408*7c604eeaShaad /*
409*7c604eeaShaad  * Function accepts one string in cipher specification
410*7c604eeaShaad  * (chainmode and iv should be NULL because included in cipher string)
411*7c604eeaShaad  *   or
412*7c604eeaShaad  * separate arguments which will be joined to "cipher-chainmode-iv"
413*7c604eeaShaad  */
414*7c604eeaShaad int dm_tree_node_add_crypt_target(struct dm_tree_node *node,
415*7c604eeaShaad 				  uint64_t size,
416*7c604eeaShaad 				  const char *cipher,
417*7c604eeaShaad 				  const char *chainmode,
418*7c604eeaShaad 				  const char *iv,
419*7c604eeaShaad 				  uint64_t iv_offset,
420*7c604eeaShaad 				  const char *key);
42156a34939Shaad int dm_tree_node_add_mirror_target(struct dm_tree_node *node,
42256a34939Shaad 				      uint64_t size);
42356a34939Shaad 
42456a34939Shaad /* Mirror log flags */
42556a34939Shaad #define DM_NOSYNC		0x00000001	/* Known already in sync */
42656a34939Shaad #define DM_FORCESYNC		0x00000002	/* Force resync */
42756a34939Shaad #define DM_BLOCK_ON_ERROR	0x00000004	/* On error, suspend I/O */
42856a34939Shaad #define DM_CORELOG		0x00000008	/* In-memory log */
42956a34939Shaad 
43056a34939Shaad int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node,
43156a34939Shaad 					  uint32_t region_size,
43256a34939Shaad 					  unsigned clustered,
43356a34939Shaad 					  const char *log_uuid,
43456a34939Shaad 					  unsigned area_count,
43556a34939Shaad 					  uint32_t flags);
43656a34939Shaad int dm_tree_node_add_target_area(struct dm_tree_node *node,
43756a34939Shaad 				    const char *dev_name,
43856a34939Shaad 				    const char *dlid,
43956a34939Shaad 				    uint64_t offset);
44056a34939Shaad 
44156a34939Shaad /*
44256a34939Shaad  * Set readahead (in sectors) after loading the node.
44356a34939Shaad  */
44456a34939Shaad void dm_tree_node_set_read_ahead(struct dm_tree_node *dnode,
44556a34939Shaad 				 uint32_t read_ahead,
44656a34939Shaad 				 uint32_t read_ahead_flags);
44756a34939Shaad 
448*7c604eeaShaad void dm_tree_set_cookie(struct dm_tree_node *node, uint32_t cookie);
449*7c604eeaShaad uint32_t dm_tree_get_cookie(struct dm_tree_node *node);
450*7c604eeaShaad 
45156a34939Shaad /*****************************************************************************
45256a34939Shaad  * Library functions
45356a34939Shaad  *****************************************************************************/
45456a34939Shaad 
45556a34939Shaad /*******************
45656a34939Shaad  * Memory management
45756a34939Shaad  *******************/
45856a34939Shaad 
45956a34939Shaad void *dm_malloc_aux(size_t s, const char *file, int line);
46056a34939Shaad void *dm_malloc_aux_debug(size_t s, const char *file, int line);
46156a34939Shaad char *dm_strdup_aux(const char *str, const char *file, int line);
46256a34939Shaad void dm_free_aux(void *p);
46356a34939Shaad void *dm_realloc_aux(void *p, unsigned int s, const char *file, int line);
46456a34939Shaad int dm_dump_memory_debug(void);
46556a34939Shaad void dm_bounds_check_debug(void);
46656a34939Shaad 
46756a34939Shaad #ifdef DEBUG_MEM
46856a34939Shaad 
46956a34939Shaad #  define dm_malloc(s) dm_malloc_aux_debug((s), __FILE__, __LINE__)
47056a34939Shaad #  define dm_strdup(s) dm_strdup_aux((s), __FILE__, __LINE__)
47156a34939Shaad #  define dm_free(p) dm_free_aux(p)
47256a34939Shaad #  define dm_realloc(p, s) dm_realloc_aux(p, s, __FILE__, __LINE__)
47356a34939Shaad #  define dm_dump_memory() dm_dump_memory_debug()
47456a34939Shaad #  define dm_bounds_check() dm_bounds_check_debug()
47556a34939Shaad 
47656a34939Shaad #else
47756a34939Shaad 
47856a34939Shaad #  define dm_malloc(s) dm_malloc_aux((s), __FILE__, __LINE__)
47956a34939Shaad #  define dm_strdup(s) strdup(s)
48056a34939Shaad #  define dm_free(p) free(p)
48156a34939Shaad #  define dm_realloc(p, s) realloc(p, s)
48256a34939Shaad #  define dm_dump_memory() {}
48356a34939Shaad #  define dm_bounds_check() {}
48456a34939Shaad 
48556a34939Shaad #endif
48656a34939Shaad 
48756a34939Shaad 
48856a34939Shaad /*
48956a34939Shaad  * The pool allocator is useful when you are going to allocate
49056a34939Shaad  * lots of memory, use the memory for a bit, and then free the
49156a34939Shaad  * memory in one go.  A surprising amount of code has this usage
49256a34939Shaad  * profile.
49356a34939Shaad  *
49456a34939Shaad  * You should think of the pool as an infinite, contiguous chunk
49556a34939Shaad  * of memory.  The front of this chunk of memory contains
49656a34939Shaad  * allocated objects, the second half is free.  dm_pool_alloc grabs
49756a34939Shaad  * the next 'size' bytes from the free half, in effect moving it
49856a34939Shaad  * into the allocated half.  This operation is very efficient.
49956a34939Shaad  *
50056a34939Shaad  * dm_pool_free frees the allocated object *and* all objects
50156a34939Shaad  * allocated after it.  It is important to note this semantic
50256a34939Shaad  * difference from malloc/free.  This is also extremely
50356a34939Shaad  * efficient, since a single dm_pool_free can dispose of a large
50456a34939Shaad  * complex object.
50556a34939Shaad  *
50656a34939Shaad  * dm_pool_destroy frees all allocated memory.
50756a34939Shaad  *
50856a34939Shaad  * eg, If you are building a binary tree in your program, and
50956a34939Shaad  * know that you are only ever going to insert into your tree,
51056a34939Shaad  * and not delete (eg, maintaining a symbol table for a
51156a34939Shaad  * compiler).  You can create yourself a pool, allocate the nodes
51256a34939Shaad  * from it, and when the tree becomes redundant call dm_pool_destroy
51356a34939Shaad  * (no nasty iterating through the tree to free nodes).
51456a34939Shaad  *
51556a34939Shaad  * eg, On the other hand if you wanted to repeatedly insert and
51656a34939Shaad  * remove objects into the tree, you would be better off
51756a34939Shaad  * allocating the nodes from a free list; you cannot free a
51856a34939Shaad  * single arbitrary node with pool.
51956a34939Shaad  */
52056a34939Shaad 
52156a34939Shaad struct dm_pool;
52256a34939Shaad 
52356a34939Shaad /* constructor and destructor */
52456a34939Shaad struct dm_pool *dm_pool_create(const char *name, size_t chunk_hint);
52556a34939Shaad void dm_pool_destroy(struct dm_pool *p);
52656a34939Shaad 
52756a34939Shaad /* simple allocation/free routines */
52856a34939Shaad void *dm_pool_alloc(struct dm_pool *p, size_t s);
52956a34939Shaad void *dm_pool_alloc_aligned(struct dm_pool *p, size_t s, unsigned alignment);
53056a34939Shaad void dm_pool_empty(struct dm_pool *p);
53156a34939Shaad void dm_pool_free(struct dm_pool *p, void *ptr);
53256a34939Shaad 
53356a34939Shaad /*
53456a34939Shaad  * Object building routines:
53556a34939Shaad  *
53656a34939Shaad  * These allow you to 'grow' an object, useful for
53756a34939Shaad  * building strings, or filling in dynamic
53856a34939Shaad  * arrays.
53956a34939Shaad  *
54056a34939Shaad  * It's probably best explained with an example:
54156a34939Shaad  *
54256a34939Shaad  * char *build_string(struct dm_pool *mem)
54356a34939Shaad  * {
54456a34939Shaad  *      int i;
54556a34939Shaad  *      char buffer[16];
54656a34939Shaad  *
54756a34939Shaad  *      if (!dm_pool_begin_object(mem, 128))
54856a34939Shaad  *              return NULL;
54956a34939Shaad  *
55056a34939Shaad  *      for (i = 0; i < 50; i++) {
55156a34939Shaad  *              snprintf(buffer, sizeof(buffer), "%d, ", i);
55256a34939Shaad  *              if (!dm_pool_grow_object(mem, buffer, 0))
55356a34939Shaad  *                      goto bad;
55456a34939Shaad  *      }
55556a34939Shaad  *
55656a34939Shaad  *	// add null
55756a34939Shaad  *      if (!dm_pool_grow_object(mem, "\0", 1))
55856a34939Shaad  *              goto bad;
55956a34939Shaad  *
56056a34939Shaad  *      return dm_pool_end_object(mem);
56156a34939Shaad  *
56256a34939Shaad  * bad:
56356a34939Shaad  *
56456a34939Shaad  *      dm_pool_abandon_object(mem);
56556a34939Shaad  *      return NULL;
56656a34939Shaad  *}
56756a34939Shaad  *
56856a34939Shaad  * So start an object by calling dm_pool_begin_object
56956a34939Shaad  * with a guess at the final object size - if in
57056a34939Shaad  * doubt make the guess too small.
57156a34939Shaad  *
57256a34939Shaad  * Then append chunks of data to your object with
57356a34939Shaad  * dm_pool_grow_object.  Finally get your object with
57456a34939Shaad  * a call to dm_pool_end_object.
57556a34939Shaad  *
57656a34939Shaad  * Setting delta to 0 means it will use strlen(extra).
57756a34939Shaad  */
57856a34939Shaad int dm_pool_begin_object(struct dm_pool *p, size_t hint);
57956a34939Shaad int dm_pool_grow_object(struct dm_pool *p, const void *extra, size_t delta);
58056a34939Shaad void *dm_pool_end_object(struct dm_pool *p);
58156a34939Shaad void dm_pool_abandon_object(struct dm_pool *p);
58256a34939Shaad 
58356a34939Shaad /* utilities */
58456a34939Shaad char *dm_pool_strdup(struct dm_pool *p, const char *str);
58556a34939Shaad char *dm_pool_strndup(struct dm_pool *p, const char *str, size_t n);
58656a34939Shaad void *dm_pool_zalloc(struct dm_pool *p, size_t s);
58756a34939Shaad 
58856a34939Shaad /******************
58956a34939Shaad  * bitset functions
59056a34939Shaad  ******************/
59156a34939Shaad 
59256a34939Shaad typedef uint32_t *dm_bitset_t;
59356a34939Shaad 
59456a34939Shaad dm_bitset_t dm_bitset_create(struct dm_pool *mem, unsigned num_bits);
59556a34939Shaad void dm_bitset_destroy(dm_bitset_t bs);
59656a34939Shaad 
59756a34939Shaad void dm_bit_union(dm_bitset_t out, dm_bitset_t in1, dm_bitset_t in2);
59856a34939Shaad int dm_bit_get_first(dm_bitset_t bs);
59956a34939Shaad int dm_bit_get_next(dm_bitset_t bs, int last_bit);
60056a34939Shaad 
60156a34939Shaad #define DM_BITS_PER_INT (sizeof(int) * CHAR_BIT)
60256a34939Shaad 
60356a34939Shaad #define dm_bit(bs, i) \
60456a34939Shaad    (bs[(i / DM_BITS_PER_INT) + 1] & (0x1 << (i & (DM_BITS_PER_INT - 1))))
60556a34939Shaad 
60656a34939Shaad #define dm_bit_set(bs, i) \
60756a34939Shaad    (bs[(i / DM_BITS_PER_INT) + 1] |= (0x1 << (i & (DM_BITS_PER_INT - 1))))
60856a34939Shaad 
60956a34939Shaad #define dm_bit_clear(bs, i) \
61056a34939Shaad    (bs[(i / DM_BITS_PER_INT) + 1] &= ~(0x1 << (i & (DM_BITS_PER_INT - 1))))
61156a34939Shaad 
61256a34939Shaad #define dm_bit_set_all(bs) \
61356a34939Shaad    memset(bs + 1, -1, ((*bs / DM_BITS_PER_INT) + 1) * sizeof(int))
61456a34939Shaad 
61556a34939Shaad #define dm_bit_clear_all(bs) \
61656a34939Shaad    memset(bs + 1, 0, ((*bs / DM_BITS_PER_INT) + 1) * sizeof(int))
61756a34939Shaad 
61856a34939Shaad #define dm_bit_copy(bs1, bs2) \
61956a34939Shaad    memcpy(bs1 + 1, bs2 + 1, ((*bs1 / DM_BITS_PER_INT) + 1) * sizeof(int))
62056a34939Shaad 
62156a34939Shaad /* Returns number of set bits */
hweight32(uint32_t i)62256a34939Shaad static inline unsigned hweight32(uint32_t i)
62356a34939Shaad {
62456a34939Shaad 	unsigned r = (i & 0x55555555) + ((i >> 1) & 0x55555555);
62556a34939Shaad 
62656a34939Shaad 	r =    (r & 0x33333333) + ((r >>  2) & 0x33333333);
62756a34939Shaad 	r =    (r & 0x0F0F0F0F) + ((r >>  4) & 0x0F0F0F0F);
62856a34939Shaad 	r =    (r & 0x00FF00FF) + ((r >>  8) & 0x00FF00FF);
62956a34939Shaad 	return (r & 0x0000FFFF) + ((r >> 16) & 0x0000FFFF);
63056a34939Shaad }
63156a34939Shaad 
63256a34939Shaad /****************
63356a34939Shaad  * hash functions
63456a34939Shaad  ****************/
63556a34939Shaad 
63656a34939Shaad struct dm_hash_table;
63756a34939Shaad struct dm_hash_node;
63856a34939Shaad 
63956a34939Shaad typedef void (*dm_hash_iterate_fn) (void *data);
64056a34939Shaad 
64156a34939Shaad struct dm_hash_table *dm_hash_create(unsigned size_hint);
64256a34939Shaad void dm_hash_destroy(struct dm_hash_table *t);
64356a34939Shaad void dm_hash_wipe(struct dm_hash_table *t);
64456a34939Shaad 
64556a34939Shaad void *dm_hash_lookup(struct dm_hash_table *t, const char *key);
64656a34939Shaad int dm_hash_insert(struct dm_hash_table *t, const char *key, void *data);
64756a34939Shaad void dm_hash_remove(struct dm_hash_table *t, const char *key);
64856a34939Shaad 
64956a34939Shaad void *dm_hash_lookup_binary(struct dm_hash_table *t, const char *key, uint32_t len);
65056a34939Shaad int dm_hash_insert_binary(struct dm_hash_table *t, const char *key, uint32_t len,
65156a34939Shaad 		       void *data);
65256a34939Shaad void dm_hash_remove_binary(struct dm_hash_table *t, const char *key, uint32_t len);
65356a34939Shaad 
65456a34939Shaad unsigned dm_hash_get_num_entries(struct dm_hash_table *t);
65556a34939Shaad void dm_hash_iter(struct dm_hash_table *t, dm_hash_iterate_fn f);
65656a34939Shaad 
65756a34939Shaad char *dm_hash_get_key(struct dm_hash_table *t, struct dm_hash_node *n);
65856a34939Shaad void *dm_hash_get_data(struct dm_hash_table *t, struct dm_hash_node *n);
65956a34939Shaad struct dm_hash_node *dm_hash_get_first(struct dm_hash_table *t);
66056a34939Shaad struct dm_hash_node *dm_hash_get_next(struct dm_hash_table *t, struct dm_hash_node *n);
66156a34939Shaad 
66256a34939Shaad #define dm_hash_iterate(v, h) \
66356a34939Shaad 	for (v = dm_hash_get_first(h); v; \
66456a34939Shaad 	     v = dm_hash_get_next(h, v))
66556a34939Shaad 
66656a34939Shaad /****************
66756a34939Shaad  * list functions
66856a34939Shaad  ****************/
66956a34939Shaad 
67056a34939Shaad /*
67156a34939Shaad  * A list consists of a list head plus elements.
67256a34939Shaad  * Each element has 'next' and 'previous' pointers.
67356a34939Shaad  * The list head's pointers point to the first and the last element.
67456a34939Shaad  */
67556a34939Shaad 
67656a34939Shaad struct dm_list {
67756a34939Shaad 	struct dm_list *n, *p;
67856a34939Shaad };
67956a34939Shaad 
68056a34939Shaad /*
68156a34939Shaad  * Initialise a list before use.
68256a34939Shaad  * The list head's next and previous pointers point back to itself.
68356a34939Shaad  */
68456a34939Shaad #define DM_LIST_INIT(name)	struct dm_list name = { &(name), &(name) }
68556a34939Shaad void dm_list_init(struct dm_list *head);
68656a34939Shaad 
68756a34939Shaad /*
68856a34939Shaad  * Insert an element before 'head'.
68956a34939Shaad  * If 'head' is the list head, this adds an element to the end of the list.
69056a34939Shaad  */
69156a34939Shaad void dm_list_add(struct dm_list *head, struct dm_list *elem);
69256a34939Shaad 
69356a34939Shaad /*
69456a34939Shaad  * Insert an element after 'head'.
69556a34939Shaad  * If 'head' is the list head, this adds an element to the front of the list.
69656a34939Shaad  */
69756a34939Shaad void dm_list_add_h(struct dm_list *head, struct dm_list *elem);
69856a34939Shaad 
69956a34939Shaad /*
70056a34939Shaad  * Delete an element from its list.
70156a34939Shaad  * Note that this doesn't change the element itself - it may still be safe
70256a34939Shaad  * to follow its pointers.
70356a34939Shaad  */
70456a34939Shaad void dm_list_del(struct dm_list *elem);
70556a34939Shaad 
70656a34939Shaad /*
70756a34939Shaad  * Remove an element from existing list and insert before 'head'.
70856a34939Shaad  */
70956a34939Shaad void dm_list_move(struct dm_list *head, struct dm_list *elem);
71056a34939Shaad 
71156a34939Shaad /*
71256a34939Shaad  * Is the list empty?
71356a34939Shaad  */
71456a34939Shaad int dm_list_empty(const struct dm_list *head);
71556a34939Shaad 
71656a34939Shaad /*
71756a34939Shaad  * Is this the first element of the list?
71856a34939Shaad  */
71956a34939Shaad int dm_list_start(const struct dm_list *head, const struct dm_list *elem);
72056a34939Shaad 
72156a34939Shaad /*
72256a34939Shaad  * Is this the last element of the list?
72356a34939Shaad  */
72456a34939Shaad int dm_list_end(const struct dm_list *head, const struct dm_list *elem);
72556a34939Shaad 
72656a34939Shaad /*
72756a34939Shaad  * Return first element of the list or NULL if empty
72856a34939Shaad  */
72956a34939Shaad struct dm_list *dm_list_first(const struct dm_list *head);
73056a34939Shaad 
73156a34939Shaad /*
73256a34939Shaad  * Return last element of the list or NULL if empty
73356a34939Shaad  */
73456a34939Shaad struct dm_list *dm_list_last(const struct dm_list *head);
73556a34939Shaad 
73656a34939Shaad /*
73756a34939Shaad  * Return the previous element of the list, or NULL if we've reached the start.
73856a34939Shaad  */
73956a34939Shaad struct dm_list *dm_list_prev(const struct dm_list *head, const struct dm_list *elem);
74056a34939Shaad 
74156a34939Shaad /*
74256a34939Shaad  * Return the next element of the list, or NULL if we've reached the end.
74356a34939Shaad  */
74456a34939Shaad struct dm_list *dm_list_next(const struct dm_list *head, const struct dm_list *elem);
74556a34939Shaad 
74656a34939Shaad /*
74756a34939Shaad  * Given the address v of an instance of 'struct dm_list' called 'head'
74856a34939Shaad  * contained in a structure of type t, return the containing structure.
74956a34939Shaad  */
75056a34939Shaad #define dm_list_struct_base(v, t, head) \
75156a34939Shaad     ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->head))
75256a34939Shaad 
75356a34939Shaad /*
75456a34939Shaad  * Given the address v of an instance of 'struct dm_list list' contained in
75556a34939Shaad  * a structure of type t, return the containing structure.
75656a34939Shaad  */
75756a34939Shaad #define dm_list_item(v, t) dm_list_struct_base((v), t, list)
75856a34939Shaad 
75956a34939Shaad /*
76056a34939Shaad  * Given the address v of one known element e in a known structure of type t,
76156a34939Shaad  * return another element f.
76256a34939Shaad  */
76356a34939Shaad #define dm_struct_field(v, t, e, f) \
76456a34939Shaad     (((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f)
76556a34939Shaad 
76656a34939Shaad /*
76756a34939Shaad  * Given the address v of a known element e in a known structure of type t,
76856a34939Shaad  * return the list head 'list'
76956a34939Shaad  */
77056a34939Shaad #define dm_list_head(v, t, e) dm_struct_field(v, t, e, list)
77156a34939Shaad 
77256a34939Shaad /*
77356a34939Shaad  * Set v to each element of a list in turn.
77456a34939Shaad  */
77556a34939Shaad #define dm_list_iterate(v, head) \
77656a34939Shaad 	for (v = (head)->n; v != head; v = v->n)
77756a34939Shaad 
77856a34939Shaad /*
77956a34939Shaad  * Set v to each element in a list in turn, starting from the element
78056a34939Shaad  * in front of 'start'.
78156a34939Shaad  * You can use this to 'unwind' a list_iterate and back out actions on
78256a34939Shaad  * already-processed elements.
78356a34939Shaad  * If 'start' is 'head' it walks the list backwards.
78456a34939Shaad  */
78556a34939Shaad #define dm_list_uniterate(v, head, start) \
78656a34939Shaad 	for (v = (start)->p; v != head; v = v->p)
78756a34939Shaad 
78856a34939Shaad /*
78956a34939Shaad  * A safe way to walk a list and delete and free some elements along
79056a34939Shaad  * the way.
79156a34939Shaad  * t must be defined as a temporary variable of the same type as v.
79256a34939Shaad  */
79356a34939Shaad #define dm_list_iterate_safe(v, t, head) \
79456a34939Shaad 	for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
79556a34939Shaad 
79656a34939Shaad /*
79756a34939Shaad  * Walk a list, setting 'v' in turn to the containing structure of each item.
79856a34939Shaad  * The containing structure should be the same type as 'v'.
79956a34939Shaad  * The 'struct dm_list' variable within the containing structure is 'field'.
80056a34939Shaad  */
80156a34939Shaad #define dm_list_iterate_items_gen(v, head, field) \
80256a34939Shaad 	for (v = dm_list_struct_base((head)->n, typeof(*v), field); \
80356a34939Shaad 	     &v->field != (head); \
80456a34939Shaad 	     v = dm_list_struct_base(v->field.n, typeof(*v), field))
80556a34939Shaad 
80656a34939Shaad /*
80756a34939Shaad  * Walk a list, setting 'v' in turn to the containing structure of each item.
80856a34939Shaad  * The containing structure should be the same type as 'v'.
80956a34939Shaad  * The list should be 'struct dm_list list' within the containing structure.
81056a34939Shaad  */
81156a34939Shaad #define dm_list_iterate_items(v, head) dm_list_iterate_items_gen(v, (head), list)
81256a34939Shaad 
81356a34939Shaad /*
81456a34939Shaad  * Walk a list, setting 'v' in turn to the containing structure of each item.
81556a34939Shaad  * The containing structure should be the same type as 'v'.
81656a34939Shaad  * The 'struct dm_list' variable within the containing structure is 'field'.
81756a34939Shaad  * t must be defined as a temporary variable of the same type as v.
81856a34939Shaad  */
81956a34939Shaad #define dm_list_iterate_items_gen_safe(v, t, head, field) \
82056a34939Shaad 	for (v = dm_list_struct_base((head)->n, typeof(*v), field), \
82156a34939Shaad 	     t = dm_list_struct_base(v->field.n, typeof(*v), field); \
82256a34939Shaad 	     &v->field != (head); \
82356a34939Shaad 	     v = t, t = dm_list_struct_base(v->field.n, typeof(*v), field))
82456a34939Shaad /*
82556a34939Shaad  * Walk a list, setting 'v' in turn to the containing structure of each item.
82656a34939Shaad  * The containing structure should be the same type as 'v'.
82756a34939Shaad  * The list should be 'struct dm_list list' within the containing structure.
82856a34939Shaad  * t must be defined as a temporary variable of the same type as v.
82956a34939Shaad  */
83056a34939Shaad #define dm_list_iterate_items_safe(v, t, head) \
83156a34939Shaad 	dm_list_iterate_items_gen_safe(v, t, (head), list)
83256a34939Shaad 
83356a34939Shaad /*
83456a34939Shaad  * Walk a list backwards, setting 'v' in turn to the containing structure
83556a34939Shaad  * of each item.
83656a34939Shaad  * The containing structure should be the same type as 'v'.
83756a34939Shaad  * The 'struct dm_list' variable within the containing structure is 'field'.
83856a34939Shaad  */
83956a34939Shaad #define dm_list_iterate_back_items_gen(v, head, field) \
84056a34939Shaad 	for (v = dm_list_struct_base((head)->p, typeof(*v), field); \
84156a34939Shaad 	     &v->field != (head); \
84256a34939Shaad 	     v = dm_list_struct_base(v->field.p, typeof(*v), field))
84356a34939Shaad 
84456a34939Shaad /*
84556a34939Shaad  * Walk a list backwards, setting 'v' in turn to the containing structure
84656a34939Shaad  * of each item.
84756a34939Shaad  * The containing structure should be the same type as 'v'.
84856a34939Shaad  * The list should be 'struct dm_list list' within the containing structure.
84956a34939Shaad  */
85056a34939Shaad #define dm_list_iterate_back_items(v, head) dm_list_iterate_back_items_gen(v, (head), list)
85156a34939Shaad 
85256a34939Shaad /*
85356a34939Shaad  * Return the number of elements in a list by walking it.
85456a34939Shaad  */
85556a34939Shaad unsigned int dm_list_size(const struct dm_list *head);
85656a34939Shaad 
85756a34939Shaad /*********
85856a34939Shaad  * selinux
85956a34939Shaad  *********/
86056a34939Shaad int dm_set_selinux_context(const char *path, mode_t mode);
86156a34939Shaad 
86256a34939Shaad /*********************
86356a34939Shaad  * string manipulation
86456a34939Shaad  *********************/
86556a34939Shaad 
86656a34939Shaad /*
86756a34939Shaad  * Break up the name of a mapped device into its constituent
86856a34939Shaad  * Volume Group, Logical Volume and Layer (if present).
869*7c604eeaShaad  * If mem is supplied, the result is allocated from the mempool.
870*7c604eeaShaad  * Otherwise the strings are changed in situ.
87156a34939Shaad  */
87256a34939Shaad int dm_split_lvm_name(struct dm_pool *mem, const char *dmname,
87356a34939Shaad 		      char **vgname, char **lvname, char **layer);
87456a34939Shaad 
87556a34939Shaad /*
87656a34939Shaad  * Destructively split buffer into NULL-separated words in argv.
87756a34939Shaad  * Returns number of words.
87856a34939Shaad  */
87956a34939Shaad int dm_split_words(char *buffer, unsigned max,
88056a34939Shaad 		   unsigned ignore_comments, /* Not implemented */
88156a34939Shaad 		   char **argv);
88256a34939Shaad 
88356a34939Shaad /*
88456a34939Shaad  * Returns -1 if buffer too small
88556a34939Shaad  */
88656a34939Shaad int dm_snprintf(char *buf, size_t bufsize, const char *format, ...);
88756a34939Shaad 
88856a34939Shaad /*
88956a34939Shaad  * Returns pointer to the last component of the path.
89056a34939Shaad  */
89156a34939Shaad char *dm_basename(const char *path);
89256a34939Shaad 
89356a34939Shaad /**************************
89456a34939Shaad  * file/stream manipulation
89556a34939Shaad  **************************/
89656a34939Shaad 
89756a34939Shaad /*
89856a34939Shaad  * Create a directory (with parent directories if necessary).
89956a34939Shaad  * Returns 1 on success, 0 on failure.
90056a34939Shaad  */
90156a34939Shaad int dm_create_dir(const char *dir);
90256a34939Shaad 
90356a34939Shaad /*
90456a34939Shaad  * Close a stream, with nicer error checking than fclose's.
90556a34939Shaad  * Derived from gnulib's close-stream.c.
90656a34939Shaad  *
90756a34939Shaad  * Close "stream".  Return 0 if successful, and EOF (setting errno)
90856a34939Shaad  * otherwise.  Upon failure, set errno to 0 if the error number
90956a34939Shaad  * cannot be determined.  Useful mainly for writable streams.
91056a34939Shaad  */
91156a34939Shaad int dm_fclose(FILE *stream);
91256a34939Shaad 
91356a34939Shaad /*
91456a34939Shaad  * Returns size of a buffer which is allocated with dm_malloc.
91556a34939Shaad  * Pointer to the buffer is stored in *buf.
91656a34939Shaad  * Returns -1 on failure leaving buf undefined.
91756a34939Shaad  */
91856a34939Shaad int dm_asprintf(char **buf, const char *format, ...);
91956a34939Shaad 
92056a34939Shaad /*********************
92156a34939Shaad  * regular expressions
92256a34939Shaad  *********************/
92356a34939Shaad struct dm_regex;
92456a34939Shaad 
92556a34939Shaad /*
92656a34939Shaad  * Initialise an array of num patterns for matching.
92756a34939Shaad  * Uses memory from mem.
92856a34939Shaad  */
92956a34939Shaad struct dm_regex *dm_regex_create(struct dm_pool *mem, const char **patterns,
93056a34939Shaad 				 unsigned num_patterns);
93156a34939Shaad 
93256a34939Shaad /*
93356a34939Shaad  * Match string s against the patterns.
93456a34939Shaad  * Returns the index of the highest pattern in the array that matches,
93556a34939Shaad  * or -1 if none match.
93656a34939Shaad  */
93756a34939Shaad int dm_regex_match(struct dm_regex *regex, const char *s);
93856a34939Shaad 
93956a34939Shaad /*********************
94056a34939Shaad  * reporting functions
94156a34939Shaad  *********************/
94256a34939Shaad 
94356a34939Shaad struct dm_report_object_type {
94456a34939Shaad 	uint32_t id;			/* Powers of 2 */
94556a34939Shaad 	const char *desc;
94656a34939Shaad 	const char *prefix;		/* field id string prefix (optional) */
94756a34939Shaad 	void *(*data_fn)(void *object);	/* callback from report_object() */
94856a34939Shaad };
94956a34939Shaad 
95056a34939Shaad struct dm_report_field;
95156a34939Shaad 
95256a34939Shaad /*
95356a34939Shaad  * dm_report_field_type flags
95456a34939Shaad  */
95556a34939Shaad #define DM_REPORT_FIELD_MASK		0x000000FF
95656a34939Shaad #define DM_REPORT_FIELD_ALIGN_MASK	0x0000000F
95756a34939Shaad #define DM_REPORT_FIELD_ALIGN_LEFT	0x00000001
95856a34939Shaad #define DM_REPORT_FIELD_ALIGN_RIGHT	0x00000002
95956a34939Shaad #define DM_REPORT_FIELD_TYPE_MASK	0x000000F0
96056a34939Shaad #define DM_REPORT_FIELD_TYPE_STRING	0x00000010
96156a34939Shaad #define DM_REPORT_FIELD_TYPE_NUMBER	0x00000020
96256a34939Shaad 
96356a34939Shaad struct dm_report;
96456a34939Shaad struct dm_report_field_type {
96556a34939Shaad 	uint32_t type;		/* object type id */
96656a34939Shaad 	uint32_t flags;		/* DM_REPORT_FIELD_* */
96756a34939Shaad 	uint32_t offset;	/* byte offset in the object */
96856a34939Shaad 	int32_t width;		/* default width */
96956a34939Shaad 	const char id[32];	/* string used to specify the field */
97056a34939Shaad 	const char heading[32];	/* string printed in header */
97156a34939Shaad 	int (*report_fn)(struct dm_report *rh, struct dm_pool *mem,
97256a34939Shaad 			 struct dm_report_field *field, const void *data,
97356a34939Shaad 			 void *private);
97456a34939Shaad 	const char *desc;	/* description of the field */
97556a34939Shaad };
97656a34939Shaad 
97756a34939Shaad /*
97856a34939Shaad  * dm_report_init output_flags
97956a34939Shaad  */
98056a34939Shaad #define DM_REPORT_OUTPUT_MASK			0x000000FF
98156a34939Shaad #define DM_REPORT_OUTPUT_ALIGNED		0x00000001
98256a34939Shaad #define DM_REPORT_OUTPUT_BUFFERED		0x00000002
98356a34939Shaad #define DM_REPORT_OUTPUT_HEADINGS		0x00000004
98456a34939Shaad #define DM_REPORT_OUTPUT_FIELD_NAME_PREFIX	0x00000008
98556a34939Shaad #define DM_REPORT_OUTPUT_FIELD_UNQUOTED		0x00000010
98656a34939Shaad #define DM_REPORT_OUTPUT_COLUMNS_AS_ROWS	0x00000020
98756a34939Shaad 
98856a34939Shaad struct dm_report *dm_report_init(uint32_t *report_types,
98956a34939Shaad 				 const struct dm_report_object_type *types,
99056a34939Shaad 				 const struct dm_report_field_type *fields,
99156a34939Shaad 				 const char *output_fields,
99256a34939Shaad 				 const char *output_separator,
99356a34939Shaad 				 uint32_t output_flags,
99456a34939Shaad 				 const char *sort_keys,
99556a34939Shaad 				 void *private);
99656a34939Shaad int dm_report_object(struct dm_report *rh, void *object);
99756a34939Shaad int dm_report_output(struct dm_report *rh);
99856a34939Shaad void dm_report_free(struct dm_report *rh);
99956a34939Shaad 
100056a34939Shaad /*
100156a34939Shaad  * Prefix added to each field name with DM_REPORT_OUTPUT_FIELD_NAME_PREFIX
100256a34939Shaad  */
100356a34939Shaad int dm_report_set_output_field_name_prefix(struct dm_report *rh,
100456a34939Shaad 					   const char *report_prefix);
100556a34939Shaad 
100656a34939Shaad /*
100756a34939Shaad  * Report functions are provided for simple data types.
100856a34939Shaad  * They take care of allocating copies of the data.
100956a34939Shaad  */
101056a34939Shaad int dm_report_field_string(struct dm_report *rh, struct dm_report_field *field,
101156a34939Shaad 			   const char **data);
101256a34939Shaad int dm_report_field_int32(struct dm_report *rh, struct dm_report_field *field,
101356a34939Shaad 			  const int32_t *data);
101456a34939Shaad int dm_report_field_uint32(struct dm_report *rh, struct dm_report_field *field,
101556a34939Shaad 			   const uint32_t *data);
101656a34939Shaad int dm_report_field_int(struct dm_report *rh, struct dm_report_field *field,
101756a34939Shaad 			const int *data);
101856a34939Shaad int dm_report_field_uint64(struct dm_report *rh, struct dm_report_field *field,
101956a34939Shaad 			   const uint64_t *data);
102056a34939Shaad 
102156a34939Shaad /*
102256a34939Shaad  * For custom fields, allocate the data in 'mem' and use
102356a34939Shaad  * dm_report_field_set_value().
102456a34939Shaad  * 'sortvalue' may be NULL if it matches 'value'
102556a34939Shaad  */
102656a34939Shaad void dm_report_field_set_value(struct dm_report_field *field, const void *value,
102756a34939Shaad 			       const void *sortvalue);
102856a34939Shaad 
1029*7c604eeaShaad /* Cookie prefixes.
1030*7c604eeaShaad  * The cookie value consists of a prefix (16 bits) and a base (16 bits).
1031*7c604eeaShaad  * We can use the prefix to store the flags. These flags are sent to
1032*7c604eeaShaad  * kernel within given dm task. When returned back to userspace in
1033*7c604eeaShaad  * DM_COOKIE udev environment variable, we can control several aspects
1034*7c604eeaShaad  * of udev rules we use by decoding the cookie prefix. When doing the
1035*7c604eeaShaad  * notification, we replace the cookie prefix with DM_COOKIE_MAGIC,
1036*7c604eeaShaad  * so we notify the right semaphore.
1037*7c604eeaShaad  * It is still possible to use cookies for passing the flags to udev
1038*7c604eeaShaad  * rules even when udev_sync is disabled. The base part of the cookie
1039*7c604eeaShaad  * will be zero (there's no notification semaphore) and prefix will be
1040*7c604eeaShaad  * set then. However, having udev_sync enabled is highly recommended.
1041*7c604eeaShaad  */
1042*7c604eeaShaad #define DM_COOKIE_MAGIC 0x0D4D
1043*7c604eeaShaad #define DM_UDEV_FLAGS_MASK 0xFFFF0000
1044*7c604eeaShaad #define DM_UDEV_FLAGS_SHIFT 16
1045*7c604eeaShaad 
1046*7c604eeaShaad /*
1047*7c604eeaShaad  * DM_UDEV_DISABLE_DM_RULES_FLAG is set in case we need to disable
1048*7c604eeaShaad  * basic device-mapper udev rules that create symlinks in /dev/<DM_DIR>
1049*7c604eeaShaad  * directory. However, we can't reliably prevent creating default
1050*7c604eeaShaad  * nodes by udev (commonly /dev/dm-X, where X is a number).
1051*7c604eeaShaad  */
1052*7c604eeaShaad #define DM_UDEV_DISABLE_DM_RULES_FLAG 0x0001
1053*7c604eeaShaad /*
1054*7c604eeaShaad  * DM_UDEV_DISABLE_SUBSYTEM_RULES_FLAG is set in case we need to disable
1055*7c604eeaShaad  * subsystem udev rules, but still we need the general DM udev rules to
1056*7c604eeaShaad  * be applied (to create the nodes and symlinks under /dev and /dev/disk).
1057*7c604eeaShaad  */
1058*7c604eeaShaad #define DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG 0x0002
1059*7c604eeaShaad /*
1060*7c604eeaShaad  * DM_UDEV_DISABLE_DISK_RULES_FLAG is set in case we need to disable
1061*7c604eeaShaad  * general DM rules that set symlinks in /dev/disk directory.
1062*7c604eeaShaad  */
1063*7c604eeaShaad #define DM_UDEV_DISABLE_DISK_RULES_FLAG 0x0004
1064*7c604eeaShaad /*
1065*7c604eeaShaad  * DM_UDEV_DISABLE_OTHER_RULES_FLAG is set in case we need to disable
1066*7c604eeaShaad  * all the other rules that are not general device-mapper nor subsystem
1067*7c604eeaShaad  * related (the rules belong to other software or packages). All foreign
1068*7c604eeaShaad  * rules should check this flag directly and they should ignore further
1069*7c604eeaShaad  * rule processing for such event.
1070*7c604eeaShaad  */
1071*7c604eeaShaad #define DM_UDEV_DISABLE_OTHER_RULES_FLAG 0x0008
1072*7c604eeaShaad /*
1073*7c604eeaShaad  * DM_UDEV_LOW_PRIORITY_FLAG is set in case we need to instruct the
1074*7c604eeaShaad  * udev rules to give low priority to the device that is currently
1075*7c604eeaShaad  * processed. For example, this provides a way to select which symlinks
1076*7c604eeaShaad  * could be overwritten by high priority ones if their names are equal.
1077*7c604eeaShaad  * Common situation is a name based on FS UUID while using origin and
1078*7c604eeaShaad  * snapshot devices.
1079*7c604eeaShaad  */
1080*7c604eeaShaad #define DM_UDEV_LOW_PRIORITY_FLAG 0x0010
1081*7c604eeaShaad 
1082*7c604eeaShaad int dm_cookie_supported(void);
1083*7c604eeaShaad 
1084*7c604eeaShaad /*
1085*7c604eeaShaad  * Udev synchronisation functions.
1086*7c604eeaShaad  */
1087*7c604eeaShaad void dm_udev_set_sync_support(int sync_with_udev);
1088*7c604eeaShaad int dm_udev_get_sync_support(void);
1089*7c604eeaShaad int dm_udev_complete(uint32_t cookie);
1090*7c604eeaShaad int dm_udev_wait(uint32_t cookie);
1091*7c604eeaShaad 
1092*7c604eeaShaad #define DM_DEV_DIR_UMASK 0022
1093*7c604eeaShaad 
109456a34939Shaad #endif				/* LIB_DEVICE_MAPPER_H */
1095