xref: /dflybsd-src/contrib/lvm2/dist/libdm/libdevmapper.h (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
186d7f5d3SJohn Marino /*	$NetBSD: libdevmapper.h,v 1.1.1.2 2009/12/02 00:26:09 haad Exp $	*/
286d7f5d3SJohn Marino 
386d7f5d3SJohn Marino /*
486d7f5d3SJohn Marino  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
586d7f5d3SJohn Marino  * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
686d7f5d3SJohn Marino  *
786d7f5d3SJohn Marino  * This file is part of the device-mapper userspace tools.
886d7f5d3SJohn Marino  *
986d7f5d3SJohn Marino  * This copyrighted material is made available to anyone wishing to use,
1086d7f5d3SJohn Marino  * modify, copy, or redistribute it subject to the terms and conditions
1186d7f5d3SJohn Marino  * of the GNU Lesser General Public License v.2.1.
1286d7f5d3SJohn Marino  *
1386d7f5d3SJohn Marino  * You should have received a copy of the GNU Lesser General Public License
1486d7f5d3SJohn Marino  * along with this program; if not, write to the Free Software Foundation,
1586d7f5d3SJohn Marino  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1686d7f5d3SJohn Marino  */
1786d7f5d3SJohn Marino 
1886d7f5d3SJohn Marino #ifndef LIB_DEVICE_MAPPER_H
1986d7f5d3SJohn Marino #define LIB_DEVICE_MAPPER_H
2086d7f5d3SJohn Marino 
2186d7f5d3SJohn Marino #include <inttypes.h>
2286d7f5d3SJohn Marino #include <stdarg.h>
2386d7f5d3SJohn Marino #include <sys/types.h>
2486d7f5d3SJohn Marino 
2586d7f5d3SJohn Marino #ifdef linux
2686d7f5d3SJohn Marino #  include <linux/types.h>
2786d7f5d3SJohn Marino #endif
2886d7f5d3SJohn Marino 
2986d7f5d3SJohn Marino #include <limits.h>
3086d7f5d3SJohn Marino #include <string.h>
3186d7f5d3SJohn Marino #include <stdlib.h>
3286d7f5d3SJohn Marino #include <stdio.h>
3386d7f5d3SJohn Marino 
3486d7f5d3SJohn Marino /*****************************************************************
3586d7f5d3SJohn Marino  * The first section of this file provides direct access to the
3686d7f5d3SJohn Marino  * individual device-mapper ioctls.  Since it is quite laborious to
3786d7f5d3SJohn Marino  * build the ioctl arguments for the device-mapper, people are
3886d7f5d3SJohn Marino  * encouraged to use this library.
3986d7f5d3SJohn Marino  ****************************************************************/
4086d7f5d3SJohn Marino 
4186d7f5d3SJohn Marino /*
4286d7f5d3SJohn Marino  * The library user may wish to register their own
4386d7f5d3SJohn Marino  * logging function.  By default errors go to stderr.
4486d7f5d3SJohn Marino  * Use dm_log_with_errno_init(NULL) to restore the default log fn.
4586d7f5d3SJohn Marino  */
4686d7f5d3SJohn Marino 
4786d7f5d3SJohn Marino typedef void (*dm_log_with_errno_fn) (int level, const char *file, int line,
4886d7f5d3SJohn Marino 				      int dm_errno, const char *f, ...)
4986d7f5d3SJohn Marino     __attribute__ ((format(printf, 5, 6)));
5086d7f5d3SJohn Marino 
5186d7f5d3SJohn Marino void dm_log_with_errno_init(dm_log_with_errno_fn fn);
5286d7f5d3SJohn Marino void dm_log_init_verbose(int level);
5386d7f5d3SJohn Marino 
5486d7f5d3SJohn Marino /*
5586d7f5d3SJohn Marino  * Original version of this function.
5686d7f5d3SJohn Marino  * dm_errno is set to 0.
5786d7f5d3SJohn Marino  *
5886d7f5d3SJohn Marino  * Deprecated: Use the _with_errno_ versions above instead.
5986d7f5d3SJohn Marino  */
6086d7f5d3SJohn Marino typedef void (*dm_log_fn) (int level, const char *file, int line,
6186d7f5d3SJohn Marino 			   const char *f, ...)
6286d7f5d3SJohn Marino     __attribute__ ((format(printf, 4, 5)));
6386d7f5d3SJohn Marino void dm_log_init(dm_log_fn fn);
6486d7f5d3SJohn Marino /*
6586d7f5d3SJohn Marino  * For backward-compatibility, indicate that dm_log_init() was used
6686d7f5d3SJohn Marino  * to set a non-default value of dm_log().
6786d7f5d3SJohn Marino  */
6886d7f5d3SJohn Marino int dm_log_is_non_default(void);
6986d7f5d3SJohn Marino 
7086d7f5d3SJohn Marino enum {
7186d7f5d3SJohn Marino 	DM_DEVICE_CREATE,
7286d7f5d3SJohn Marino 	DM_DEVICE_RELOAD,
7386d7f5d3SJohn Marino 	DM_DEVICE_REMOVE,
7486d7f5d3SJohn Marino 	DM_DEVICE_REMOVE_ALL,
7586d7f5d3SJohn Marino 
7686d7f5d3SJohn Marino 	DM_DEVICE_SUSPEND,
7786d7f5d3SJohn Marino 	DM_DEVICE_RESUME,
7886d7f5d3SJohn Marino 
7986d7f5d3SJohn Marino 	DM_DEVICE_INFO,
8086d7f5d3SJohn Marino 	DM_DEVICE_DEPS,
8186d7f5d3SJohn Marino 	DM_DEVICE_RENAME,
8286d7f5d3SJohn Marino 
8386d7f5d3SJohn Marino 	DM_DEVICE_VERSION,
8486d7f5d3SJohn Marino 
8586d7f5d3SJohn Marino 	DM_DEVICE_STATUS,
8686d7f5d3SJohn Marino 	DM_DEVICE_TABLE,
8786d7f5d3SJohn Marino 	DM_DEVICE_WAITEVENT,
8886d7f5d3SJohn Marino 
8986d7f5d3SJohn Marino 	DM_DEVICE_LIST,
9086d7f5d3SJohn Marino 
9186d7f5d3SJohn Marino 	DM_DEVICE_CLEAR,
9286d7f5d3SJohn Marino 
9386d7f5d3SJohn Marino 	DM_DEVICE_MKNODES,
9486d7f5d3SJohn Marino 
9586d7f5d3SJohn Marino 	DM_DEVICE_LIST_VERSIONS,
9686d7f5d3SJohn Marino 
9786d7f5d3SJohn Marino 	DM_DEVICE_TARGET_MSG,
9886d7f5d3SJohn Marino 
9986d7f5d3SJohn Marino 	DM_DEVICE_SET_GEOMETRY
10086d7f5d3SJohn Marino };
10186d7f5d3SJohn Marino 
10286d7f5d3SJohn Marino /*
10386d7f5d3SJohn Marino  * You will need to build a struct dm_task for
10486d7f5d3SJohn Marino  * each ioctl command you want to execute.
10586d7f5d3SJohn Marino  */
10686d7f5d3SJohn Marino 
10786d7f5d3SJohn Marino struct dm_task;
10886d7f5d3SJohn Marino 
10986d7f5d3SJohn Marino struct dm_task *dm_task_create(int type);
11086d7f5d3SJohn Marino void dm_task_destroy(struct dm_task *dmt);
11186d7f5d3SJohn Marino 
11286d7f5d3SJohn Marino int dm_task_set_name(struct dm_task *dmt, const char *name);
11386d7f5d3SJohn Marino int dm_task_set_uuid(struct dm_task *dmt, const char *uuid);
11486d7f5d3SJohn Marino 
11586d7f5d3SJohn Marino /*
11686d7f5d3SJohn Marino  * Retrieve attributes after an info.
11786d7f5d3SJohn Marino  */
11886d7f5d3SJohn Marino struct dm_info {
11986d7f5d3SJohn Marino 	int exists;
12086d7f5d3SJohn Marino 	int suspended;
12186d7f5d3SJohn Marino 	int live_table;
12286d7f5d3SJohn Marino 	int inactive_table;
12386d7f5d3SJohn Marino 	int32_t open_count;
12486d7f5d3SJohn Marino 	uint32_t event_nr;
12586d7f5d3SJohn Marino 	uint32_t major;
12686d7f5d3SJohn Marino 	uint32_t minor;		/* minor device number */
12786d7f5d3SJohn Marino 	int read_only;		/* 0:read-write; 1:read-only */
12886d7f5d3SJohn Marino 
12986d7f5d3SJohn Marino 	int32_t target_count;
13086d7f5d3SJohn Marino };
13186d7f5d3SJohn Marino 
13286d7f5d3SJohn Marino struct dm_deps {
13386d7f5d3SJohn Marino 	uint32_t count;
13486d7f5d3SJohn Marino 	uint32_t filler;
13586d7f5d3SJohn Marino 	uint64_t device[0];
13686d7f5d3SJohn Marino };
13786d7f5d3SJohn Marino 
13886d7f5d3SJohn Marino struct dm_names {
13986d7f5d3SJohn Marino 	uint64_t dev;
14086d7f5d3SJohn Marino 	uint32_t next;		/* Offset to next struct from start of this struct */
14186d7f5d3SJohn Marino 	char name[0];
14286d7f5d3SJohn Marino };
14386d7f5d3SJohn Marino 
14486d7f5d3SJohn Marino struct dm_versions {
14586d7f5d3SJohn Marino 	uint32_t next;		/* Offset to next struct from start of this struct */
14686d7f5d3SJohn Marino 	uint32_t version[3];
14786d7f5d3SJohn Marino 
14886d7f5d3SJohn Marino 	char name[0];
14986d7f5d3SJohn Marino };
15086d7f5d3SJohn Marino 
15186d7f5d3SJohn Marino int dm_get_library_version(char *version, size_t size);
15286d7f5d3SJohn Marino int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size);
15386d7f5d3SJohn Marino int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi);
15486d7f5d3SJohn Marino const char *dm_task_get_name(const struct dm_task *dmt);
15586d7f5d3SJohn Marino const char *dm_task_get_uuid(const struct dm_task *dmt);
15686d7f5d3SJohn Marino 
15786d7f5d3SJohn Marino struct dm_deps *dm_task_get_deps(struct dm_task *dmt);
15886d7f5d3SJohn Marino struct dm_names *dm_task_get_names(struct dm_task *dmt);
15986d7f5d3SJohn Marino struct dm_versions *dm_task_get_versions(struct dm_task *dmt);
16086d7f5d3SJohn Marino 
16186d7f5d3SJohn Marino int dm_task_set_ro(struct dm_task *dmt);
16286d7f5d3SJohn Marino int dm_task_set_newname(struct dm_task *dmt, const char *newname);
16386d7f5d3SJohn Marino int dm_task_set_minor(struct dm_task *dmt, int minor);
16486d7f5d3SJohn Marino int dm_task_set_major(struct dm_task *dmt, int major);
16586d7f5d3SJohn Marino int dm_task_set_major_minor(struct dm_task *dmt, int major, int minor, int allow_default_major_fallback);
16686d7f5d3SJohn Marino int dm_task_set_uid(struct dm_task *dmt, uid_t uid);
16786d7f5d3SJohn Marino int dm_task_set_gid(struct dm_task *dmt, gid_t gid);
16886d7f5d3SJohn Marino int dm_task_set_mode(struct dm_task *dmt, mode_t mode);
16986d7f5d3SJohn Marino int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags);
17086d7f5d3SJohn Marino int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr);
17186d7f5d3SJohn Marino int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads, const char *sectors, const char *start);
17286d7f5d3SJohn Marino int dm_task_set_message(struct dm_task *dmt, const char *message);
17386d7f5d3SJohn Marino int dm_task_set_sector(struct dm_task *dmt, uint64_t sector);
17486d7f5d3SJohn Marino int dm_task_no_flush(struct dm_task *dmt);
17586d7f5d3SJohn Marino int dm_task_no_open_count(struct dm_task *dmt);
17686d7f5d3SJohn Marino int dm_task_skip_lockfs(struct dm_task *dmt);
17786d7f5d3SJohn Marino int dm_task_query_inactive_table(struct dm_task *dmt);
17886d7f5d3SJohn Marino int dm_task_suppress_identical_reload(struct dm_task *dmt);
17986d7f5d3SJohn Marino 
18086d7f5d3SJohn Marino /*
18186d7f5d3SJohn Marino  * Control read_ahead.
18286d7f5d3SJohn Marino  */
18386d7f5d3SJohn Marino #define DM_READ_AHEAD_AUTO UINT32_MAX	/* Use kernel default readahead */
18486d7f5d3SJohn Marino #define DM_READ_AHEAD_NONE 0		/* Disable readahead */
18586d7f5d3SJohn Marino 
18686d7f5d3SJohn Marino #define DM_READ_AHEAD_MINIMUM_FLAG	0x1	/* Value supplied is minimum */
18786d7f5d3SJohn Marino 
18886d7f5d3SJohn Marino /*
18986d7f5d3SJohn Marino  * Read ahead is set with DM_DEVICE_CREATE with a table or DM_DEVICE_RESUME.
19086d7f5d3SJohn Marino  */
19186d7f5d3SJohn Marino int dm_task_set_read_ahead(struct dm_task *dmt, uint32_t read_ahead,
19286d7f5d3SJohn Marino 			   uint32_t read_ahead_flags);
19386d7f5d3SJohn Marino uint32_t dm_task_get_read_ahead(const struct dm_task *dmt,
19486d7f5d3SJohn Marino 				uint32_t *read_ahead);
19586d7f5d3SJohn Marino 
19686d7f5d3SJohn Marino /*
19786d7f5d3SJohn Marino  * Use these to prepare for a create or reload.
19886d7f5d3SJohn Marino  */
19986d7f5d3SJohn Marino int dm_task_add_target(struct dm_task *dmt,
20086d7f5d3SJohn Marino 		       uint64_t start,
20186d7f5d3SJohn Marino 		       uint64_t size, const char *ttype, const char *params);
20286d7f5d3SJohn Marino 
20386d7f5d3SJohn Marino /*
20486d7f5d3SJohn Marino  * Format major/minor numbers correctly for input to driver.
20586d7f5d3SJohn Marino  */
20686d7f5d3SJohn Marino #define DM_FORMAT_DEV_BUFSIZE	13	/* Minimum bufsize to handle worst case. */
20786d7f5d3SJohn Marino int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, uint32_t dev_minor);
20886d7f5d3SJohn Marino 
20986d7f5d3SJohn Marino /* Use this to retrive target information returned from a STATUS call */
21086d7f5d3SJohn Marino void *dm_get_next_target(struct dm_task *dmt,
21186d7f5d3SJohn Marino 			 void *next, uint64_t *start, uint64_t *length,
21286d7f5d3SJohn Marino 			 char **target_type, char **params);
21386d7f5d3SJohn Marino 
21486d7f5d3SJohn Marino /*
21586d7f5d3SJohn Marino  * Call this to actually run the ioctl.
21686d7f5d3SJohn Marino  */
21786d7f5d3SJohn Marino int dm_task_run(struct dm_task *dmt);
21886d7f5d3SJohn Marino 
21986d7f5d3SJohn Marino /*
22086d7f5d3SJohn Marino  * Call this to make or remove the device nodes associated with previously
22186d7f5d3SJohn Marino  * issued commands.
22286d7f5d3SJohn Marino  */
22386d7f5d3SJohn Marino void dm_task_update_nodes(void);
22486d7f5d3SJohn Marino 
22586d7f5d3SJohn Marino /*
22686d7f5d3SJohn Marino  * Configure the device-mapper directory
22786d7f5d3SJohn Marino  */
22886d7f5d3SJohn Marino int dm_set_dev_dir(const char *dir);
22986d7f5d3SJohn Marino const char *dm_dir(void);
23086d7f5d3SJohn Marino 
23186d7f5d3SJohn Marino /*
23286d7f5d3SJohn Marino  * Determine whether a major number belongs to device-mapper or not.
23386d7f5d3SJohn Marino  */
23486d7f5d3SJohn Marino int dm_is_dm_major(uint32_t major);
23586d7f5d3SJohn Marino 
23686d7f5d3SJohn Marino /*
23786d7f5d3SJohn Marino  * Release library resources
23886d7f5d3SJohn Marino  */
23986d7f5d3SJohn Marino void dm_lib_release(void);
24086d7f5d3SJohn Marino void dm_lib_exit(void) __attribute((destructor));
24186d7f5d3SJohn Marino 
24286d7f5d3SJohn Marino /*
24386d7f5d3SJohn Marino  * Use NULL for all devices.
24486d7f5d3SJohn Marino  */
24586d7f5d3SJohn Marino int dm_mknodes(const char *name);
24686d7f5d3SJohn Marino int dm_driver_version(char *version, size_t size);
24786d7f5d3SJohn Marino 
24886d7f5d3SJohn Marino /******************************************************
24986d7f5d3SJohn Marino  * Functions to build and manipulate trees of devices *
25086d7f5d3SJohn Marino  ******************************************************/
25186d7f5d3SJohn Marino struct dm_tree;
25286d7f5d3SJohn Marino struct dm_tree_node;
25386d7f5d3SJohn Marino 
25486d7f5d3SJohn Marino /*
25586d7f5d3SJohn Marino  * Initialise an empty dependency tree.
25686d7f5d3SJohn Marino  *
25786d7f5d3SJohn Marino  * The tree consists of a root node together with one node for each mapped
25886d7f5d3SJohn Marino  * device which has child nodes for each device referenced in its table.
25986d7f5d3SJohn Marino  *
26086d7f5d3SJohn Marino  * Every node in the tree has one or more children and one or more parents.
26186d7f5d3SJohn Marino  *
26286d7f5d3SJohn Marino  * The root node is the parent/child of every node that doesn't have other
26386d7f5d3SJohn Marino  * parents/children.
26486d7f5d3SJohn Marino  */
26586d7f5d3SJohn Marino struct dm_tree *dm_tree_create(void);
26686d7f5d3SJohn Marino void dm_tree_free(struct dm_tree *tree);
26786d7f5d3SJohn Marino 
26886d7f5d3SJohn Marino /*
26986d7f5d3SJohn Marino  * Add nodes to the tree for a given device and all the devices it uses.
27086d7f5d3SJohn Marino  */
27186d7f5d3SJohn Marino int dm_tree_add_dev(struct dm_tree *tree, uint32_t major, uint32_t minor);
27286d7f5d3SJohn Marino 
27386d7f5d3SJohn Marino /*
27486d7f5d3SJohn Marino  * Add a new node to the tree if it doesn't already exist.
27586d7f5d3SJohn Marino  */
27686d7f5d3SJohn Marino struct dm_tree_node *dm_tree_add_new_dev(struct dm_tree *tree,
27786d7f5d3SJohn Marino 					 const char *name,
27886d7f5d3SJohn Marino 					 const char *uuid,
27986d7f5d3SJohn Marino 					 uint32_t major, uint32_t minor,
28086d7f5d3SJohn Marino 					 int read_only,
28186d7f5d3SJohn Marino 					 int clear_inactive,
28286d7f5d3SJohn Marino 					 void *context);
28386d7f5d3SJohn Marino struct dm_tree_node *dm_tree_add_new_dev_with_udev_flags(struct dm_tree *tree,
28486d7f5d3SJohn Marino 							 const char *name,
28586d7f5d3SJohn Marino 							 const char *uuid,
28686d7f5d3SJohn Marino 							 uint32_t major,
28786d7f5d3SJohn Marino 							 uint32_t minor,
28886d7f5d3SJohn Marino 							 int read_only,
28986d7f5d3SJohn Marino 							 int clear_inactive,
29086d7f5d3SJohn Marino 							 void *context,
29186d7f5d3SJohn Marino 							 uint16_t udev_flags);
29286d7f5d3SJohn Marino 
29386d7f5d3SJohn Marino /*
29486d7f5d3SJohn Marino  * Search for a node in the tree.
29586d7f5d3SJohn Marino  * Set major and minor to 0 or uuid to NULL to get the root node.
29686d7f5d3SJohn Marino  */
29786d7f5d3SJohn Marino struct dm_tree_node *dm_tree_find_node(struct dm_tree *tree,
29886d7f5d3SJohn Marino 					  uint32_t major,
29986d7f5d3SJohn Marino 					  uint32_t minor);
30086d7f5d3SJohn Marino struct dm_tree_node *dm_tree_find_node_by_uuid(struct dm_tree *tree,
30186d7f5d3SJohn Marino 						  const char *uuid);
30286d7f5d3SJohn Marino 
30386d7f5d3SJohn Marino /*
30486d7f5d3SJohn Marino  * Use this to walk through all children of a given node.
30586d7f5d3SJohn Marino  * Set handle to NULL in first call.
30686d7f5d3SJohn Marino  * Returns NULL after the last child.
30786d7f5d3SJohn Marino  * Set inverted to use inverted tree.
30886d7f5d3SJohn Marino  */
30986d7f5d3SJohn Marino struct dm_tree_node *dm_tree_next_child(void **handle,
31086d7f5d3SJohn Marino 					   struct dm_tree_node *parent,
31186d7f5d3SJohn Marino 					   uint32_t inverted);
31286d7f5d3SJohn Marino 
31386d7f5d3SJohn Marino /*
31486d7f5d3SJohn Marino  * Get properties of a node.
31586d7f5d3SJohn Marino  */
31686d7f5d3SJohn Marino const char *dm_tree_node_get_name(struct dm_tree_node *node);
31786d7f5d3SJohn Marino const char *dm_tree_node_get_uuid(struct dm_tree_node *node);
31886d7f5d3SJohn Marino const struct dm_info *dm_tree_node_get_info(struct dm_tree_node *node);
31986d7f5d3SJohn Marino void *dm_tree_node_get_context(struct dm_tree_node *node);
32086d7f5d3SJohn Marino int dm_tree_node_size_changed(struct dm_tree_node *dnode);
32186d7f5d3SJohn Marino 
32286d7f5d3SJohn Marino /*
32386d7f5d3SJohn Marino  * Returns the number of children of the given node (excluding the root node).
32486d7f5d3SJohn Marino  * Set inverted for the number of parents.
32586d7f5d3SJohn Marino  */
32686d7f5d3SJohn Marino int dm_tree_node_num_children(struct dm_tree_node *node, uint32_t inverted);
32786d7f5d3SJohn Marino 
32886d7f5d3SJohn Marino /*
32986d7f5d3SJohn Marino  * Deactivate a device plus all dependencies.
33086d7f5d3SJohn Marino  * Ignores devices that don't have a uuid starting with uuid_prefix.
33186d7f5d3SJohn Marino  */
33286d7f5d3SJohn Marino int dm_tree_deactivate_children(struct dm_tree_node *dnode,
33386d7f5d3SJohn Marino 				   const char *uuid_prefix,
33486d7f5d3SJohn Marino 				   size_t uuid_prefix_len);
33586d7f5d3SJohn Marino /*
33686d7f5d3SJohn Marino  * Preload/create a device plus all dependencies.
33786d7f5d3SJohn Marino  * Ignores devices that don't have a uuid starting with uuid_prefix.
33886d7f5d3SJohn Marino  */
33986d7f5d3SJohn Marino int dm_tree_preload_children(struct dm_tree_node *dnode,
34086d7f5d3SJohn Marino 			     const char *uuid_prefix,
34186d7f5d3SJohn Marino 			     size_t uuid_prefix_len);
34286d7f5d3SJohn Marino 
34386d7f5d3SJohn Marino /*
34486d7f5d3SJohn Marino  * Resume a device plus all dependencies.
34586d7f5d3SJohn Marino  * Ignores devices that don't have a uuid starting with uuid_prefix.
34686d7f5d3SJohn Marino  */
34786d7f5d3SJohn Marino int dm_tree_activate_children(struct dm_tree_node *dnode,
34886d7f5d3SJohn Marino 			      const char *uuid_prefix,
34986d7f5d3SJohn Marino 			      size_t uuid_prefix_len);
35086d7f5d3SJohn Marino 
35186d7f5d3SJohn Marino /*
35286d7f5d3SJohn Marino  * Suspend a device plus all dependencies.
35386d7f5d3SJohn Marino  * Ignores devices that don't have a uuid starting with uuid_prefix.
35486d7f5d3SJohn Marino  */
35586d7f5d3SJohn Marino int dm_tree_suspend_children(struct dm_tree_node *dnode,
35686d7f5d3SJohn Marino 				   const char *uuid_prefix,
35786d7f5d3SJohn Marino 				   size_t uuid_prefix_len);
35886d7f5d3SJohn Marino 
35986d7f5d3SJohn Marino /*
36086d7f5d3SJohn Marino  * Skip the filesystem sync when suspending.
36186d7f5d3SJohn Marino  * Does nothing with other functions.
36286d7f5d3SJohn Marino  * Use this when no snapshots are involved.
36386d7f5d3SJohn Marino  */
36486d7f5d3SJohn Marino void dm_tree_skip_lockfs(struct dm_tree_node *dnode);
36586d7f5d3SJohn Marino 
36686d7f5d3SJohn Marino /*
36786d7f5d3SJohn Marino  * Set the 'noflush' flag when suspending devices.
36886d7f5d3SJohn Marino  * If the kernel supports it, instead of erroring outstanding I/O that
36986d7f5d3SJohn Marino  * cannot be completed, the I/O is queued and resubmitted when the
37086d7f5d3SJohn Marino  * device is resumed.  This affects multipath devices when all paths
37186d7f5d3SJohn Marino  * have failed and queue_if_no_path is set, and mirror devices when
37286d7f5d3SJohn Marino  * block_on_error is set and the mirror log has failed.
37386d7f5d3SJohn Marino  */
37486d7f5d3SJohn Marino void dm_tree_use_no_flush_suspend(struct dm_tree_node *dnode);
37586d7f5d3SJohn Marino 
37686d7f5d3SJohn Marino /*
37786d7f5d3SJohn Marino  * Is the uuid prefix present in the tree?
37886d7f5d3SJohn Marino  * Only returns 0 if every node was checked successfully.
37986d7f5d3SJohn Marino  * Returns 1 if the tree walk has to be aborted.
38086d7f5d3SJohn Marino  */
38186d7f5d3SJohn Marino int dm_tree_children_use_uuid(struct dm_tree_node *dnode,
38286d7f5d3SJohn Marino 				 const char *uuid_prefix,
38386d7f5d3SJohn Marino 				 size_t uuid_prefix_len);
38486d7f5d3SJohn Marino 
38586d7f5d3SJohn Marino /*
38686d7f5d3SJohn Marino  * Construct tables for new nodes before activating them.
38786d7f5d3SJohn Marino  */
38886d7f5d3SJohn Marino int dm_tree_node_add_snapshot_origin_target(struct dm_tree_node *dnode,
38986d7f5d3SJohn Marino 					       uint64_t size,
39086d7f5d3SJohn Marino 					       const char *origin_uuid);
39186d7f5d3SJohn Marino int dm_tree_node_add_snapshot_target(struct dm_tree_node *node,
39286d7f5d3SJohn Marino 					uint64_t size,
39386d7f5d3SJohn Marino 					const char *origin_uuid,
39486d7f5d3SJohn Marino 					const char *cow_uuid,
39586d7f5d3SJohn Marino 					int persistent,
39686d7f5d3SJohn Marino 					uint32_t chunk_size);
39786d7f5d3SJohn Marino int dm_tree_node_add_error_target(struct dm_tree_node *node,
39886d7f5d3SJohn Marino 				     uint64_t size);
39986d7f5d3SJohn Marino int dm_tree_node_add_zero_target(struct dm_tree_node *node,
40086d7f5d3SJohn Marino 				    uint64_t size);
40186d7f5d3SJohn Marino int dm_tree_node_add_linear_target(struct dm_tree_node *node,
40286d7f5d3SJohn Marino 				      uint64_t size);
40386d7f5d3SJohn Marino int dm_tree_node_add_striped_target(struct dm_tree_node *node,
40486d7f5d3SJohn Marino 				       uint64_t size,
40586d7f5d3SJohn Marino 				       uint32_t stripe_size);
40686d7f5d3SJohn Marino 
40786d7f5d3SJohn Marino #define DM_CRYPT_IV_DEFAULT	UINT64_C(-1)	/* iv_offset == seg offset */
40886d7f5d3SJohn Marino /*
40986d7f5d3SJohn Marino  * Function accepts one string in cipher specification
41086d7f5d3SJohn Marino  * (chainmode and iv should be NULL because included in cipher string)
41186d7f5d3SJohn Marino  *   or
41286d7f5d3SJohn Marino  * separate arguments which will be joined to "cipher-chainmode-iv"
41386d7f5d3SJohn Marino  */
41486d7f5d3SJohn Marino int dm_tree_node_add_crypt_target(struct dm_tree_node *node,
41586d7f5d3SJohn Marino 				  uint64_t size,
41686d7f5d3SJohn Marino 				  const char *cipher,
41786d7f5d3SJohn Marino 				  const char *chainmode,
41886d7f5d3SJohn Marino 				  const char *iv,
41986d7f5d3SJohn Marino 				  uint64_t iv_offset,
42086d7f5d3SJohn Marino 				  const char *key);
42186d7f5d3SJohn Marino int dm_tree_node_add_mirror_target(struct dm_tree_node *node,
42286d7f5d3SJohn Marino 				      uint64_t size);
42386d7f5d3SJohn Marino 
42486d7f5d3SJohn Marino /* Mirror log flags */
42586d7f5d3SJohn Marino #define DM_NOSYNC		0x00000001	/* Known already in sync */
42686d7f5d3SJohn Marino #define DM_FORCESYNC		0x00000002	/* Force resync */
42786d7f5d3SJohn Marino #define DM_BLOCK_ON_ERROR	0x00000004	/* On error, suspend I/O */
42886d7f5d3SJohn Marino #define DM_CORELOG		0x00000008	/* In-memory log */
42986d7f5d3SJohn Marino 
43086d7f5d3SJohn Marino int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node,
43186d7f5d3SJohn Marino 					  uint32_t region_size,
43286d7f5d3SJohn Marino 					  unsigned clustered,
43386d7f5d3SJohn Marino 					  const char *log_uuid,
43486d7f5d3SJohn Marino 					  unsigned area_count,
43586d7f5d3SJohn Marino 					  uint32_t flags);
43686d7f5d3SJohn Marino int dm_tree_node_add_target_area(struct dm_tree_node *node,
43786d7f5d3SJohn Marino 				    const char *dev_name,
43886d7f5d3SJohn Marino 				    const char *dlid,
43986d7f5d3SJohn Marino 				    uint64_t offset);
44086d7f5d3SJohn Marino 
44186d7f5d3SJohn Marino /*
44286d7f5d3SJohn Marino  * Set readahead (in sectors) after loading the node.
44386d7f5d3SJohn Marino  */
44486d7f5d3SJohn Marino void dm_tree_node_set_read_ahead(struct dm_tree_node *dnode,
44586d7f5d3SJohn Marino 				 uint32_t read_ahead,
44686d7f5d3SJohn Marino 				 uint32_t read_ahead_flags);
44786d7f5d3SJohn Marino 
44886d7f5d3SJohn Marino void dm_tree_set_cookie(struct dm_tree_node *node, uint32_t cookie);
44986d7f5d3SJohn Marino uint32_t dm_tree_get_cookie(struct dm_tree_node *node);
45086d7f5d3SJohn Marino 
45186d7f5d3SJohn Marino /*****************************************************************************
45286d7f5d3SJohn Marino  * Library functions
45386d7f5d3SJohn Marino  *****************************************************************************/
45486d7f5d3SJohn Marino 
45586d7f5d3SJohn Marino /*******************
45686d7f5d3SJohn Marino  * Memory management
45786d7f5d3SJohn Marino  *******************/
45886d7f5d3SJohn Marino 
45986d7f5d3SJohn Marino void *dm_malloc_aux(size_t s, const char *file, int line);
46086d7f5d3SJohn Marino void *dm_malloc_aux_debug(size_t s, const char *file, int line);
46186d7f5d3SJohn Marino char *dm_strdup_aux(const char *str, const char *file, int line);
46286d7f5d3SJohn Marino void dm_free_aux(void *p);
46386d7f5d3SJohn Marino void *dm_realloc_aux(void *p, unsigned int s, const char *file, int line);
46486d7f5d3SJohn Marino int dm_dump_memory_debug(void);
46586d7f5d3SJohn Marino void dm_bounds_check_debug(void);
46686d7f5d3SJohn Marino 
46786d7f5d3SJohn Marino #ifdef DEBUG_MEM
46886d7f5d3SJohn Marino 
46986d7f5d3SJohn Marino #  define dm_malloc(s) dm_malloc_aux_debug((s), __FILE__, __LINE__)
47086d7f5d3SJohn Marino #  define dm_strdup(s) dm_strdup_aux((s), __FILE__, __LINE__)
47186d7f5d3SJohn Marino #  define dm_free(p) dm_free_aux(p)
47286d7f5d3SJohn Marino #  define dm_realloc(p, s) dm_realloc_aux(p, s, __FILE__, __LINE__)
47386d7f5d3SJohn Marino #  define dm_dump_memory() dm_dump_memory_debug()
47486d7f5d3SJohn Marino #  define dm_bounds_check() dm_bounds_check_debug()
47586d7f5d3SJohn Marino 
47686d7f5d3SJohn Marino #else
47786d7f5d3SJohn Marino 
47886d7f5d3SJohn Marino #  define dm_malloc(s) dm_malloc_aux((s), __FILE__, __LINE__)
47986d7f5d3SJohn Marino #  define dm_strdup(s) strdup(s)
48086d7f5d3SJohn Marino #  define dm_free(p) free(p)
48186d7f5d3SJohn Marino #  define dm_realloc(p, s) realloc(p, s)
48286d7f5d3SJohn Marino #  define dm_dump_memory() {}
48386d7f5d3SJohn Marino #  define dm_bounds_check() {}
48486d7f5d3SJohn Marino 
48586d7f5d3SJohn Marino #endif
48686d7f5d3SJohn Marino 
48786d7f5d3SJohn Marino 
48886d7f5d3SJohn Marino /*
48986d7f5d3SJohn Marino  * The pool allocator is useful when you are going to allocate
49086d7f5d3SJohn Marino  * lots of memory, use the memory for a bit, and then free the
49186d7f5d3SJohn Marino  * memory in one go.  A surprising amount of code has this usage
49286d7f5d3SJohn Marino  * profile.
49386d7f5d3SJohn Marino  *
49486d7f5d3SJohn Marino  * You should think of the pool as an infinite, contiguous chunk
49586d7f5d3SJohn Marino  * of memory.  The front of this chunk of memory contains
49686d7f5d3SJohn Marino  * allocated objects, the second half is free.  dm_pool_alloc grabs
49786d7f5d3SJohn Marino  * the next 'size' bytes from the free half, in effect moving it
49886d7f5d3SJohn Marino  * into the allocated half.  This operation is very efficient.
49986d7f5d3SJohn Marino  *
50086d7f5d3SJohn Marino  * dm_pool_free frees the allocated object *and* all objects
50186d7f5d3SJohn Marino  * allocated after it.  It is important to note this semantic
50286d7f5d3SJohn Marino  * difference from malloc/free.  This is also extremely
50386d7f5d3SJohn Marino  * efficient, since a single dm_pool_free can dispose of a large
50486d7f5d3SJohn Marino  * complex object.
50586d7f5d3SJohn Marino  *
50686d7f5d3SJohn Marino  * dm_pool_destroy frees all allocated memory.
50786d7f5d3SJohn Marino  *
50886d7f5d3SJohn Marino  * eg, If you are building a binary tree in your program, and
50986d7f5d3SJohn Marino  * know that you are only ever going to insert into your tree,
51086d7f5d3SJohn Marino  * and not delete (eg, maintaining a symbol table for a
51186d7f5d3SJohn Marino  * compiler).  You can create yourself a pool, allocate the nodes
51286d7f5d3SJohn Marino  * from it, and when the tree becomes redundant call dm_pool_destroy
51386d7f5d3SJohn Marino  * (no nasty iterating through the tree to free nodes).
51486d7f5d3SJohn Marino  *
51586d7f5d3SJohn Marino  * eg, On the other hand if you wanted to repeatedly insert and
51686d7f5d3SJohn Marino  * remove objects into the tree, you would be better off
51786d7f5d3SJohn Marino  * allocating the nodes from a free list; you cannot free a
51886d7f5d3SJohn Marino  * single arbitrary node with pool.
51986d7f5d3SJohn Marino  */
52086d7f5d3SJohn Marino 
52186d7f5d3SJohn Marino struct dm_pool;
52286d7f5d3SJohn Marino 
52386d7f5d3SJohn Marino /* constructor and destructor */
52486d7f5d3SJohn Marino struct dm_pool *dm_pool_create(const char *name, size_t chunk_hint);
52586d7f5d3SJohn Marino void dm_pool_destroy(struct dm_pool *p);
52686d7f5d3SJohn Marino 
52786d7f5d3SJohn Marino /* simple allocation/free routines */
52886d7f5d3SJohn Marino void *dm_pool_alloc(struct dm_pool *p, size_t s);
52986d7f5d3SJohn Marino void *dm_pool_alloc_aligned(struct dm_pool *p, size_t s, unsigned alignment);
53086d7f5d3SJohn Marino void dm_pool_empty(struct dm_pool *p);
53186d7f5d3SJohn Marino void dm_pool_free(struct dm_pool *p, void *ptr);
53286d7f5d3SJohn Marino 
53386d7f5d3SJohn Marino /*
53486d7f5d3SJohn Marino  * Object building routines:
53586d7f5d3SJohn Marino  *
53686d7f5d3SJohn Marino  * These allow you to 'grow' an object, useful for
53786d7f5d3SJohn Marino  * building strings, or filling in dynamic
53886d7f5d3SJohn Marino  * arrays.
53986d7f5d3SJohn Marino  *
54086d7f5d3SJohn Marino  * It's probably best explained with an example:
54186d7f5d3SJohn Marino  *
54286d7f5d3SJohn Marino  * char *build_string(struct dm_pool *mem)
54386d7f5d3SJohn Marino  * {
54486d7f5d3SJohn Marino  *      int i;
54586d7f5d3SJohn Marino  *      char buffer[16];
54686d7f5d3SJohn Marino  *
54786d7f5d3SJohn Marino  *      if (!dm_pool_begin_object(mem, 128))
54886d7f5d3SJohn Marino  *              return NULL;
54986d7f5d3SJohn Marino  *
55086d7f5d3SJohn Marino  *      for (i = 0; i < 50; i++) {
55186d7f5d3SJohn Marino  *              snprintf(buffer, sizeof(buffer), "%d, ", i);
55286d7f5d3SJohn Marino  *              if (!dm_pool_grow_object(mem, buffer, 0))
55386d7f5d3SJohn Marino  *                      goto bad;
55486d7f5d3SJohn Marino  *      }
55586d7f5d3SJohn Marino  *
55686d7f5d3SJohn Marino  *	// add null
55786d7f5d3SJohn Marino  *      if (!dm_pool_grow_object(mem, "\0", 1))
55886d7f5d3SJohn Marino  *              goto bad;
55986d7f5d3SJohn Marino  *
56086d7f5d3SJohn Marino  *      return dm_pool_end_object(mem);
56186d7f5d3SJohn Marino  *
56286d7f5d3SJohn Marino  * bad:
56386d7f5d3SJohn Marino  *
56486d7f5d3SJohn Marino  *      dm_pool_abandon_object(mem);
56586d7f5d3SJohn Marino  *      return NULL;
56686d7f5d3SJohn Marino  *}
56786d7f5d3SJohn Marino  *
56886d7f5d3SJohn Marino  * So start an object by calling dm_pool_begin_object
56986d7f5d3SJohn Marino  * with a guess at the final object size - if in
57086d7f5d3SJohn Marino  * doubt make the guess too small.
57186d7f5d3SJohn Marino  *
57286d7f5d3SJohn Marino  * Then append chunks of data to your object with
57386d7f5d3SJohn Marino  * dm_pool_grow_object.  Finally get your object with
57486d7f5d3SJohn Marino  * a call to dm_pool_end_object.
57586d7f5d3SJohn Marino  *
57686d7f5d3SJohn Marino  * Setting delta to 0 means it will use strlen(extra).
57786d7f5d3SJohn Marino  */
57886d7f5d3SJohn Marino int dm_pool_begin_object(struct dm_pool *p, size_t hint);
57986d7f5d3SJohn Marino int dm_pool_grow_object(struct dm_pool *p, const void *extra, size_t delta);
58086d7f5d3SJohn Marino void *dm_pool_end_object(struct dm_pool *p);
58186d7f5d3SJohn Marino void dm_pool_abandon_object(struct dm_pool *p);
58286d7f5d3SJohn Marino 
58386d7f5d3SJohn Marino /* utilities */
58486d7f5d3SJohn Marino char *dm_pool_strdup(struct dm_pool *p, const char *str);
58586d7f5d3SJohn Marino char *dm_pool_strndup(struct dm_pool *p, const char *str, size_t n);
58686d7f5d3SJohn Marino void *dm_pool_zalloc(struct dm_pool *p, size_t s);
58786d7f5d3SJohn Marino 
58886d7f5d3SJohn Marino /******************
58986d7f5d3SJohn Marino  * bitset functions
59086d7f5d3SJohn Marino  ******************/
59186d7f5d3SJohn Marino 
59286d7f5d3SJohn Marino typedef uint32_t *dm_bitset_t;
59386d7f5d3SJohn Marino 
59486d7f5d3SJohn Marino dm_bitset_t dm_bitset_create(struct dm_pool *mem, unsigned num_bits);
59586d7f5d3SJohn Marino void dm_bitset_destroy(dm_bitset_t bs);
59686d7f5d3SJohn Marino 
59786d7f5d3SJohn Marino void dm_bit_union(dm_bitset_t out, dm_bitset_t in1, dm_bitset_t in2);
59886d7f5d3SJohn Marino int dm_bit_get_first(dm_bitset_t bs);
59986d7f5d3SJohn Marino int dm_bit_get_next(dm_bitset_t bs, int last_bit);
60086d7f5d3SJohn Marino 
60186d7f5d3SJohn Marino #define DM_BITS_PER_INT (sizeof(int) * CHAR_BIT)
60286d7f5d3SJohn Marino 
60386d7f5d3SJohn Marino #define dm_bit(bs, i) \
60486d7f5d3SJohn Marino    (bs[(i / DM_BITS_PER_INT) + 1] & (0x1 << (i & (DM_BITS_PER_INT - 1))))
60586d7f5d3SJohn Marino 
60686d7f5d3SJohn Marino #define dm_bit_set(bs, i) \
60786d7f5d3SJohn Marino    (bs[(i / DM_BITS_PER_INT) + 1] |= (0x1 << (i & (DM_BITS_PER_INT - 1))))
60886d7f5d3SJohn Marino 
60986d7f5d3SJohn Marino #define dm_bit_clear(bs, i) \
61086d7f5d3SJohn Marino    (bs[(i / DM_BITS_PER_INT) + 1] &= ~(0x1 << (i & (DM_BITS_PER_INT - 1))))
61186d7f5d3SJohn Marino 
61286d7f5d3SJohn Marino #define dm_bit_set_all(bs) \
61386d7f5d3SJohn Marino    memset(bs + 1, -1, ((*bs / DM_BITS_PER_INT) + 1) * sizeof(int))
61486d7f5d3SJohn Marino 
61586d7f5d3SJohn Marino #define dm_bit_clear_all(bs) \
61686d7f5d3SJohn Marino    memset(bs + 1, 0, ((*bs / DM_BITS_PER_INT) + 1) * sizeof(int))
61786d7f5d3SJohn Marino 
61886d7f5d3SJohn Marino #define dm_bit_copy(bs1, bs2) \
61986d7f5d3SJohn Marino    memcpy(bs1 + 1, bs2 + 1, ((*bs1 / DM_BITS_PER_INT) + 1) * sizeof(int))
62086d7f5d3SJohn Marino 
62186d7f5d3SJohn Marino /* Returns number of set bits */
hweight32(uint32_t i)62286d7f5d3SJohn Marino static inline unsigned hweight32(uint32_t i)
62386d7f5d3SJohn Marino {
62486d7f5d3SJohn Marino 	unsigned r = (i & 0x55555555) + ((i >> 1) & 0x55555555);
62586d7f5d3SJohn Marino 
62686d7f5d3SJohn Marino 	r =    (r & 0x33333333) + ((r >>  2) & 0x33333333);
62786d7f5d3SJohn Marino 	r =    (r & 0x0F0F0F0F) + ((r >>  4) & 0x0F0F0F0F);
62886d7f5d3SJohn Marino 	r =    (r & 0x00FF00FF) + ((r >>  8) & 0x00FF00FF);
62986d7f5d3SJohn Marino 	return (r & 0x0000FFFF) + ((r >> 16) & 0x0000FFFF);
63086d7f5d3SJohn Marino }
63186d7f5d3SJohn Marino 
63286d7f5d3SJohn Marino /****************
63386d7f5d3SJohn Marino  * hash functions
63486d7f5d3SJohn Marino  ****************/
63586d7f5d3SJohn Marino 
63686d7f5d3SJohn Marino struct dm_hash_table;
63786d7f5d3SJohn Marino struct dm_hash_node;
63886d7f5d3SJohn Marino 
63986d7f5d3SJohn Marino typedef void (*dm_hash_iterate_fn) (void *data);
64086d7f5d3SJohn Marino 
64186d7f5d3SJohn Marino struct dm_hash_table *dm_hash_create(unsigned size_hint);
64286d7f5d3SJohn Marino void dm_hash_destroy(struct dm_hash_table *t);
64386d7f5d3SJohn Marino void dm_hash_wipe(struct dm_hash_table *t);
64486d7f5d3SJohn Marino 
64586d7f5d3SJohn Marino void *dm_hash_lookup(struct dm_hash_table *t, const char *key);
64686d7f5d3SJohn Marino int dm_hash_insert(struct dm_hash_table *t, const char *key, void *data);
64786d7f5d3SJohn Marino void dm_hash_remove(struct dm_hash_table *t, const char *key);
64886d7f5d3SJohn Marino 
64986d7f5d3SJohn Marino void *dm_hash_lookup_binary(struct dm_hash_table *t, const char *key, uint32_t len);
65086d7f5d3SJohn Marino int dm_hash_insert_binary(struct dm_hash_table *t, const char *key, uint32_t len,
65186d7f5d3SJohn Marino 		       void *data);
65286d7f5d3SJohn Marino void dm_hash_remove_binary(struct dm_hash_table *t, const char *key, uint32_t len);
65386d7f5d3SJohn Marino 
65486d7f5d3SJohn Marino unsigned dm_hash_get_num_entries(struct dm_hash_table *t);
65586d7f5d3SJohn Marino void dm_hash_iter(struct dm_hash_table *t, dm_hash_iterate_fn f);
65686d7f5d3SJohn Marino 
65786d7f5d3SJohn Marino char *dm_hash_get_key(struct dm_hash_table *t, struct dm_hash_node *n);
65886d7f5d3SJohn Marino void *dm_hash_get_data(struct dm_hash_table *t, struct dm_hash_node *n);
65986d7f5d3SJohn Marino struct dm_hash_node *dm_hash_get_first(struct dm_hash_table *t);
66086d7f5d3SJohn Marino struct dm_hash_node *dm_hash_get_next(struct dm_hash_table *t, struct dm_hash_node *n);
66186d7f5d3SJohn Marino 
66286d7f5d3SJohn Marino #define dm_hash_iterate(v, h) \
66386d7f5d3SJohn Marino 	for (v = dm_hash_get_first(h); v; \
66486d7f5d3SJohn Marino 	     v = dm_hash_get_next(h, v))
66586d7f5d3SJohn Marino 
66686d7f5d3SJohn Marino /****************
66786d7f5d3SJohn Marino  * list functions
66886d7f5d3SJohn Marino  ****************/
66986d7f5d3SJohn Marino 
67086d7f5d3SJohn Marino /*
67186d7f5d3SJohn Marino  * A list consists of a list head plus elements.
67286d7f5d3SJohn Marino  * Each element has 'next' and 'previous' pointers.
67386d7f5d3SJohn Marino  * The list head's pointers point to the first and the last element.
67486d7f5d3SJohn Marino  */
67586d7f5d3SJohn Marino 
67686d7f5d3SJohn Marino struct dm_list {
67786d7f5d3SJohn Marino 	struct dm_list *n, *p;
67886d7f5d3SJohn Marino };
67986d7f5d3SJohn Marino 
68086d7f5d3SJohn Marino /*
68186d7f5d3SJohn Marino  * Initialise a list before use.
68286d7f5d3SJohn Marino  * The list head's next and previous pointers point back to itself.
68386d7f5d3SJohn Marino  */
68486d7f5d3SJohn Marino #define DM_LIST_INIT(name)	struct dm_list name = { &(name), &(name) }
68586d7f5d3SJohn Marino void dm_list_init(struct dm_list *head);
68686d7f5d3SJohn Marino 
68786d7f5d3SJohn Marino /*
68886d7f5d3SJohn Marino  * Insert an element before 'head'.
68986d7f5d3SJohn Marino  * If 'head' is the list head, this adds an element to the end of the list.
69086d7f5d3SJohn Marino  */
69186d7f5d3SJohn Marino void dm_list_add(struct dm_list *head, struct dm_list *elem);
69286d7f5d3SJohn Marino 
69386d7f5d3SJohn Marino /*
69486d7f5d3SJohn Marino  * Insert an element after 'head'.
69586d7f5d3SJohn Marino  * If 'head' is the list head, this adds an element to the front of the list.
69686d7f5d3SJohn Marino  */
69786d7f5d3SJohn Marino void dm_list_add_h(struct dm_list *head, struct dm_list *elem);
69886d7f5d3SJohn Marino 
69986d7f5d3SJohn Marino /*
70086d7f5d3SJohn Marino  * Delete an element from its list.
70186d7f5d3SJohn Marino  * Note that this doesn't change the element itself - it may still be safe
70286d7f5d3SJohn Marino  * to follow its pointers.
70386d7f5d3SJohn Marino  */
70486d7f5d3SJohn Marino void dm_list_del(struct dm_list *elem);
70586d7f5d3SJohn Marino 
70686d7f5d3SJohn Marino /*
70786d7f5d3SJohn Marino  * Remove an element from existing list and insert before 'head'.
70886d7f5d3SJohn Marino  */
70986d7f5d3SJohn Marino void dm_list_move(struct dm_list *head, struct dm_list *elem);
71086d7f5d3SJohn Marino 
71186d7f5d3SJohn Marino /*
71286d7f5d3SJohn Marino  * Is the list empty?
71386d7f5d3SJohn Marino  */
71486d7f5d3SJohn Marino int dm_list_empty(const struct dm_list *head);
71586d7f5d3SJohn Marino 
71686d7f5d3SJohn Marino /*
71786d7f5d3SJohn Marino  * Is this the first element of the list?
71886d7f5d3SJohn Marino  */
71986d7f5d3SJohn Marino int dm_list_start(const struct dm_list *head, const struct dm_list *elem);
72086d7f5d3SJohn Marino 
72186d7f5d3SJohn Marino /*
72286d7f5d3SJohn Marino  * Is this the last element of the list?
72386d7f5d3SJohn Marino  */
72486d7f5d3SJohn Marino int dm_list_end(const struct dm_list *head, const struct dm_list *elem);
72586d7f5d3SJohn Marino 
72686d7f5d3SJohn Marino /*
72786d7f5d3SJohn Marino  * Return first element of the list or NULL if empty
72886d7f5d3SJohn Marino  */
72986d7f5d3SJohn Marino struct dm_list *dm_list_first(const struct dm_list *head);
73086d7f5d3SJohn Marino 
73186d7f5d3SJohn Marino /*
73286d7f5d3SJohn Marino  * Return last element of the list or NULL if empty
73386d7f5d3SJohn Marino  */
73486d7f5d3SJohn Marino struct dm_list *dm_list_last(const struct dm_list *head);
73586d7f5d3SJohn Marino 
73686d7f5d3SJohn Marino /*
73786d7f5d3SJohn Marino  * Return the previous element of the list, or NULL if we've reached the start.
73886d7f5d3SJohn Marino  */
73986d7f5d3SJohn Marino struct dm_list *dm_list_prev(const struct dm_list *head, const struct dm_list *elem);
74086d7f5d3SJohn Marino 
74186d7f5d3SJohn Marino /*
74286d7f5d3SJohn Marino  * Return the next element of the list, or NULL if we've reached the end.
74386d7f5d3SJohn Marino  */
74486d7f5d3SJohn Marino struct dm_list *dm_list_next(const struct dm_list *head, const struct dm_list *elem);
74586d7f5d3SJohn Marino 
74686d7f5d3SJohn Marino /*
74786d7f5d3SJohn Marino  * Given the address v of an instance of 'struct dm_list' called 'head'
74886d7f5d3SJohn Marino  * contained in a structure of type t, return the containing structure.
74986d7f5d3SJohn Marino  */
75086d7f5d3SJohn Marino #define dm_list_struct_base(v, t, head) \
75186d7f5d3SJohn Marino     ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->head))
75286d7f5d3SJohn Marino 
75386d7f5d3SJohn Marino /*
75486d7f5d3SJohn Marino  * Given the address v of an instance of 'struct dm_list list' contained in
75586d7f5d3SJohn Marino  * a structure of type t, return the containing structure.
75686d7f5d3SJohn Marino  */
75786d7f5d3SJohn Marino #define dm_list_item(v, t) dm_list_struct_base((v), t, list)
75886d7f5d3SJohn Marino 
75986d7f5d3SJohn Marino /*
76086d7f5d3SJohn Marino  * Given the address v of one known element e in a known structure of type t,
76186d7f5d3SJohn Marino  * return another element f.
76286d7f5d3SJohn Marino  */
76386d7f5d3SJohn Marino #define dm_struct_field(v, t, e, f) \
76486d7f5d3SJohn Marino     (((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f)
76586d7f5d3SJohn Marino 
76686d7f5d3SJohn Marino /*
76786d7f5d3SJohn Marino  * Given the address v of a known element e in a known structure of type t,
76886d7f5d3SJohn Marino  * return the list head 'list'
76986d7f5d3SJohn Marino  */
77086d7f5d3SJohn Marino #define dm_list_head(v, t, e) dm_struct_field(v, t, e, list)
77186d7f5d3SJohn Marino 
77286d7f5d3SJohn Marino /*
77386d7f5d3SJohn Marino  * Set v to each element of a list in turn.
77486d7f5d3SJohn Marino  */
77586d7f5d3SJohn Marino #define dm_list_iterate(v, head) \
77686d7f5d3SJohn Marino 	for (v = (head)->n; v != head; v = v->n)
77786d7f5d3SJohn Marino 
77886d7f5d3SJohn Marino /*
77986d7f5d3SJohn Marino  * Set v to each element in a list in turn, starting from the element
78086d7f5d3SJohn Marino  * in front of 'start'.
78186d7f5d3SJohn Marino  * You can use this to 'unwind' a list_iterate and back out actions on
78286d7f5d3SJohn Marino  * already-processed elements.
78386d7f5d3SJohn Marino  * If 'start' is 'head' it walks the list backwards.
78486d7f5d3SJohn Marino  */
78586d7f5d3SJohn Marino #define dm_list_uniterate(v, head, start) \
78686d7f5d3SJohn Marino 	for (v = (start)->p; v != head; v = v->p)
78786d7f5d3SJohn Marino 
78886d7f5d3SJohn Marino /*
78986d7f5d3SJohn Marino  * A safe way to walk a list and delete and free some elements along
79086d7f5d3SJohn Marino  * the way.
79186d7f5d3SJohn Marino  * t must be defined as a temporary variable of the same type as v.
79286d7f5d3SJohn Marino  */
79386d7f5d3SJohn Marino #define dm_list_iterate_safe(v, t, head) \
79486d7f5d3SJohn Marino 	for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
79586d7f5d3SJohn Marino 
79686d7f5d3SJohn Marino /*
79786d7f5d3SJohn Marino  * Walk a list, setting 'v' in turn to the containing structure of each item.
79886d7f5d3SJohn Marino  * The containing structure should be the same type as 'v'.
79986d7f5d3SJohn Marino  * The 'struct dm_list' variable within the containing structure is 'field'.
80086d7f5d3SJohn Marino  */
80186d7f5d3SJohn Marino #define dm_list_iterate_items_gen(v, head, field) \
80286d7f5d3SJohn Marino 	for (v = dm_list_struct_base((head)->n, typeof(*v), field); \
80386d7f5d3SJohn Marino 	     &v->field != (head); \
80486d7f5d3SJohn Marino 	     v = dm_list_struct_base(v->field.n, typeof(*v), field))
80586d7f5d3SJohn Marino 
80686d7f5d3SJohn Marino /*
80786d7f5d3SJohn Marino  * Walk a list, setting 'v' in turn to the containing structure of each item.
80886d7f5d3SJohn Marino  * The containing structure should be the same type as 'v'.
80986d7f5d3SJohn Marino  * The list should be 'struct dm_list list' within the containing structure.
81086d7f5d3SJohn Marino  */
81186d7f5d3SJohn Marino #define dm_list_iterate_items(v, head) dm_list_iterate_items_gen(v, (head), list)
81286d7f5d3SJohn Marino 
81386d7f5d3SJohn Marino /*
81486d7f5d3SJohn Marino  * Walk a list, setting 'v' in turn to the containing structure of each item.
81586d7f5d3SJohn Marino  * The containing structure should be the same type as 'v'.
81686d7f5d3SJohn Marino  * The 'struct dm_list' variable within the containing structure is 'field'.
81786d7f5d3SJohn Marino  * t must be defined as a temporary variable of the same type as v.
81886d7f5d3SJohn Marino  */
81986d7f5d3SJohn Marino #define dm_list_iterate_items_gen_safe(v, t, head, field) \
82086d7f5d3SJohn Marino 	for (v = dm_list_struct_base((head)->n, typeof(*v), field), \
82186d7f5d3SJohn Marino 	     t = dm_list_struct_base(v->field.n, typeof(*v), field); \
82286d7f5d3SJohn Marino 	     &v->field != (head); \
82386d7f5d3SJohn Marino 	     v = t, t = dm_list_struct_base(v->field.n, typeof(*v), field))
82486d7f5d3SJohn Marino /*
82586d7f5d3SJohn Marino  * Walk a list, setting 'v' in turn to the containing structure of each item.
82686d7f5d3SJohn Marino  * The containing structure should be the same type as 'v'.
82786d7f5d3SJohn Marino  * The list should be 'struct dm_list list' within the containing structure.
82886d7f5d3SJohn Marino  * t must be defined as a temporary variable of the same type as v.
82986d7f5d3SJohn Marino  */
83086d7f5d3SJohn Marino #define dm_list_iterate_items_safe(v, t, head) \
83186d7f5d3SJohn Marino 	dm_list_iterate_items_gen_safe(v, t, (head), list)
83286d7f5d3SJohn Marino 
83386d7f5d3SJohn Marino /*
83486d7f5d3SJohn Marino  * Walk a list backwards, setting 'v' in turn to the containing structure
83586d7f5d3SJohn Marino  * of each item.
83686d7f5d3SJohn Marino  * The containing structure should be the same type as 'v'.
83786d7f5d3SJohn Marino  * The 'struct dm_list' variable within the containing structure is 'field'.
83886d7f5d3SJohn Marino  */
83986d7f5d3SJohn Marino #define dm_list_iterate_back_items_gen(v, head, field) \
84086d7f5d3SJohn Marino 	for (v = dm_list_struct_base((head)->p, typeof(*v), field); \
84186d7f5d3SJohn Marino 	     &v->field != (head); \
84286d7f5d3SJohn Marino 	     v = dm_list_struct_base(v->field.p, typeof(*v), field))
84386d7f5d3SJohn Marino 
84486d7f5d3SJohn Marino /*
84586d7f5d3SJohn Marino  * Walk a list backwards, setting 'v' in turn to the containing structure
84686d7f5d3SJohn Marino  * of each item.
84786d7f5d3SJohn Marino  * The containing structure should be the same type as 'v'.
84886d7f5d3SJohn Marino  * The list should be 'struct dm_list list' within the containing structure.
84986d7f5d3SJohn Marino  */
85086d7f5d3SJohn Marino #define dm_list_iterate_back_items(v, head) dm_list_iterate_back_items_gen(v, (head), list)
85186d7f5d3SJohn Marino 
85286d7f5d3SJohn Marino /*
85386d7f5d3SJohn Marino  * Return the number of elements in a list by walking it.
85486d7f5d3SJohn Marino  */
85586d7f5d3SJohn Marino unsigned int dm_list_size(const struct dm_list *head);
85686d7f5d3SJohn Marino 
85786d7f5d3SJohn Marino /*********
85886d7f5d3SJohn Marino  * selinux
85986d7f5d3SJohn Marino  *********/
86086d7f5d3SJohn Marino int dm_set_selinux_context(const char *path, mode_t mode);
86186d7f5d3SJohn Marino 
86286d7f5d3SJohn Marino /*********************
86386d7f5d3SJohn Marino  * string manipulation
86486d7f5d3SJohn Marino  *********************/
86586d7f5d3SJohn Marino 
86686d7f5d3SJohn Marino /*
86786d7f5d3SJohn Marino  * Break up the name of a mapped device into its constituent
86886d7f5d3SJohn Marino  * Volume Group, Logical Volume and Layer (if present).
86986d7f5d3SJohn Marino  * If mem is supplied, the result is allocated from the mempool.
87086d7f5d3SJohn Marino  * Otherwise the strings are changed in situ.
87186d7f5d3SJohn Marino  */
87286d7f5d3SJohn Marino int dm_split_lvm_name(struct dm_pool *mem, const char *dmname,
87386d7f5d3SJohn Marino 		      char **vgname, char **lvname, char **layer);
87486d7f5d3SJohn Marino 
87586d7f5d3SJohn Marino /*
87686d7f5d3SJohn Marino  * Destructively split buffer into NULL-separated words in argv.
87786d7f5d3SJohn Marino  * Returns number of words.
87886d7f5d3SJohn Marino  */
87986d7f5d3SJohn Marino int dm_split_words(char *buffer, unsigned max,
88086d7f5d3SJohn Marino 		   unsigned ignore_comments, /* Not implemented */
88186d7f5d3SJohn Marino 		   char **argv);
88286d7f5d3SJohn Marino 
88386d7f5d3SJohn Marino /*
88486d7f5d3SJohn Marino  * Returns -1 if buffer too small
88586d7f5d3SJohn Marino  */
88686d7f5d3SJohn Marino int dm_snprintf(char *buf, size_t bufsize, const char *format, ...);
88786d7f5d3SJohn Marino 
88886d7f5d3SJohn Marino /*
88986d7f5d3SJohn Marino  * Returns pointer to the last component of the path.
89086d7f5d3SJohn Marino  */
89186d7f5d3SJohn Marino char *dm_basename(const char *path);
89286d7f5d3SJohn Marino 
89386d7f5d3SJohn Marino /**************************
89486d7f5d3SJohn Marino  * file/stream manipulation
89586d7f5d3SJohn Marino  **************************/
89686d7f5d3SJohn Marino 
89786d7f5d3SJohn Marino /*
89886d7f5d3SJohn Marino  * Create a directory (with parent directories if necessary).
89986d7f5d3SJohn Marino  * Returns 1 on success, 0 on failure.
90086d7f5d3SJohn Marino  */
90186d7f5d3SJohn Marino int dm_create_dir(const char *dir);
90286d7f5d3SJohn Marino 
90386d7f5d3SJohn Marino /*
90486d7f5d3SJohn Marino  * Close a stream, with nicer error checking than fclose's.
90586d7f5d3SJohn Marino  * Derived from gnulib's close-stream.c.
90686d7f5d3SJohn Marino  *
90786d7f5d3SJohn Marino  * Close "stream".  Return 0 if successful, and EOF (setting errno)
90886d7f5d3SJohn Marino  * otherwise.  Upon failure, set errno to 0 if the error number
90986d7f5d3SJohn Marino  * cannot be determined.  Useful mainly for writable streams.
91086d7f5d3SJohn Marino  */
91186d7f5d3SJohn Marino int dm_fclose(FILE *stream);
91286d7f5d3SJohn Marino 
91386d7f5d3SJohn Marino /*
91486d7f5d3SJohn Marino  * Returns size of a buffer which is allocated with dm_malloc.
91586d7f5d3SJohn Marino  * Pointer to the buffer is stored in *buf.
91686d7f5d3SJohn Marino  * Returns -1 on failure leaving buf undefined.
91786d7f5d3SJohn Marino  */
91886d7f5d3SJohn Marino int dm_asprintf(char **buf, const char *format, ...);
91986d7f5d3SJohn Marino 
92086d7f5d3SJohn Marino /*********************
92186d7f5d3SJohn Marino  * regular expressions
92286d7f5d3SJohn Marino  *********************/
92386d7f5d3SJohn Marino struct dm_regex;
92486d7f5d3SJohn Marino 
92586d7f5d3SJohn Marino /*
92686d7f5d3SJohn Marino  * Initialise an array of num patterns for matching.
92786d7f5d3SJohn Marino  * Uses memory from mem.
92886d7f5d3SJohn Marino  */
92986d7f5d3SJohn Marino struct dm_regex *dm_regex_create(struct dm_pool *mem, const char **patterns,
93086d7f5d3SJohn Marino 				 unsigned num_patterns);
93186d7f5d3SJohn Marino 
93286d7f5d3SJohn Marino /*
93386d7f5d3SJohn Marino  * Match string s against the patterns.
93486d7f5d3SJohn Marino  * Returns the index of the highest pattern in the array that matches,
93586d7f5d3SJohn Marino  * or -1 if none match.
93686d7f5d3SJohn Marino  */
93786d7f5d3SJohn Marino int dm_regex_match(struct dm_regex *regex, const char *s);
93886d7f5d3SJohn Marino 
93986d7f5d3SJohn Marino /*********************
94086d7f5d3SJohn Marino  * reporting functions
94186d7f5d3SJohn Marino  *********************/
94286d7f5d3SJohn Marino 
94386d7f5d3SJohn Marino struct dm_report_object_type {
94486d7f5d3SJohn Marino 	uint32_t id;			/* Powers of 2 */
94586d7f5d3SJohn Marino 	const char *desc;
94686d7f5d3SJohn Marino 	const char *prefix;		/* field id string prefix (optional) */
94786d7f5d3SJohn Marino 	void *(*data_fn)(void *object);	/* callback from report_object() */
94886d7f5d3SJohn Marino };
94986d7f5d3SJohn Marino 
95086d7f5d3SJohn Marino struct dm_report_field;
95186d7f5d3SJohn Marino 
95286d7f5d3SJohn Marino /*
95386d7f5d3SJohn Marino  * dm_report_field_type flags
95486d7f5d3SJohn Marino  */
95586d7f5d3SJohn Marino #define DM_REPORT_FIELD_MASK		0x000000FF
95686d7f5d3SJohn Marino #define DM_REPORT_FIELD_ALIGN_MASK	0x0000000F
95786d7f5d3SJohn Marino #define DM_REPORT_FIELD_ALIGN_LEFT	0x00000001
95886d7f5d3SJohn Marino #define DM_REPORT_FIELD_ALIGN_RIGHT	0x00000002
95986d7f5d3SJohn Marino #define DM_REPORT_FIELD_TYPE_MASK	0x000000F0
96086d7f5d3SJohn Marino #define DM_REPORT_FIELD_TYPE_STRING	0x00000010
96186d7f5d3SJohn Marino #define DM_REPORT_FIELD_TYPE_NUMBER	0x00000020
96286d7f5d3SJohn Marino 
96386d7f5d3SJohn Marino struct dm_report;
96486d7f5d3SJohn Marino struct dm_report_field_type {
96586d7f5d3SJohn Marino 	uint32_t type;		/* object type id */
96686d7f5d3SJohn Marino 	uint32_t flags;		/* DM_REPORT_FIELD_* */
96786d7f5d3SJohn Marino 	uint32_t offset;	/* byte offset in the object */
96886d7f5d3SJohn Marino 	int32_t width;		/* default width */
96986d7f5d3SJohn Marino 	const char id[32];	/* string used to specify the field */
97086d7f5d3SJohn Marino 	const char heading[32];	/* string printed in header */
97186d7f5d3SJohn Marino 	int (*report_fn)(struct dm_report *rh, struct dm_pool *mem,
97286d7f5d3SJohn Marino 			 struct dm_report_field *field, const void *data,
97386d7f5d3SJohn Marino 			 void *private);
97486d7f5d3SJohn Marino 	const char *desc;	/* description of the field */
97586d7f5d3SJohn Marino };
97686d7f5d3SJohn Marino 
97786d7f5d3SJohn Marino /*
97886d7f5d3SJohn Marino  * dm_report_init output_flags
97986d7f5d3SJohn Marino  */
98086d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_MASK			0x000000FF
98186d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_ALIGNED		0x00000001
98286d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_BUFFERED		0x00000002
98386d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_HEADINGS		0x00000004
98486d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_FIELD_NAME_PREFIX	0x00000008
98586d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_FIELD_UNQUOTED		0x00000010
98686d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_COLUMNS_AS_ROWS	0x00000020
98786d7f5d3SJohn Marino 
98886d7f5d3SJohn Marino struct dm_report *dm_report_init(uint32_t *report_types,
98986d7f5d3SJohn Marino 				 const struct dm_report_object_type *types,
99086d7f5d3SJohn Marino 				 const struct dm_report_field_type *fields,
99186d7f5d3SJohn Marino 				 const char *output_fields,
99286d7f5d3SJohn Marino 				 const char *output_separator,
99386d7f5d3SJohn Marino 				 uint32_t output_flags,
99486d7f5d3SJohn Marino 				 const char *sort_keys,
99586d7f5d3SJohn Marino 				 void *private);
99686d7f5d3SJohn Marino int dm_report_object(struct dm_report *rh, void *object);
99786d7f5d3SJohn Marino int dm_report_output(struct dm_report *rh);
99886d7f5d3SJohn Marino void dm_report_free(struct dm_report *rh);
99986d7f5d3SJohn Marino 
100086d7f5d3SJohn Marino /*
100186d7f5d3SJohn Marino  * Prefix added to each field name with DM_REPORT_OUTPUT_FIELD_NAME_PREFIX
100286d7f5d3SJohn Marino  */
100386d7f5d3SJohn Marino int dm_report_set_output_field_name_prefix(struct dm_report *rh,
100486d7f5d3SJohn Marino 					   const char *report_prefix);
100586d7f5d3SJohn Marino 
100686d7f5d3SJohn Marino /*
100786d7f5d3SJohn Marino  * Report functions are provided for simple data types.
100886d7f5d3SJohn Marino  * They take care of allocating copies of the data.
100986d7f5d3SJohn Marino  */
101086d7f5d3SJohn Marino int dm_report_field_string(struct dm_report *rh, struct dm_report_field *field,
101186d7f5d3SJohn Marino 			   const char **data);
101286d7f5d3SJohn Marino int dm_report_field_int32(struct dm_report *rh, struct dm_report_field *field,
101386d7f5d3SJohn Marino 			  const int32_t *data);
101486d7f5d3SJohn Marino int dm_report_field_uint32(struct dm_report *rh, struct dm_report_field *field,
101586d7f5d3SJohn Marino 			   const uint32_t *data);
101686d7f5d3SJohn Marino int dm_report_field_int(struct dm_report *rh, struct dm_report_field *field,
101786d7f5d3SJohn Marino 			const int *data);
101886d7f5d3SJohn Marino int dm_report_field_uint64(struct dm_report *rh, struct dm_report_field *field,
101986d7f5d3SJohn Marino 			   const uint64_t *data);
102086d7f5d3SJohn Marino 
102186d7f5d3SJohn Marino /*
102286d7f5d3SJohn Marino  * For custom fields, allocate the data in 'mem' and use
102386d7f5d3SJohn Marino  * dm_report_field_set_value().
102486d7f5d3SJohn Marino  * 'sortvalue' may be NULL if it matches 'value'
102586d7f5d3SJohn Marino  */
102686d7f5d3SJohn Marino void dm_report_field_set_value(struct dm_report_field *field, const void *value,
102786d7f5d3SJohn Marino 			       const void *sortvalue);
102886d7f5d3SJohn Marino 
102986d7f5d3SJohn Marino /* Cookie prefixes.
103086d7f5d3SJohn Marino  * The cookie value consists of a prefix (16 bits) and a base (16 bits).
103186d7f5d3SJohn Marino  * We can use the prefix to store the flags. These flags are sent to
103286d7f5d3SJohn Marino  * kernel within given dm task. When returned back to userspace in
103386d7f5d3SJohn Marino  * DM_COOKIE udev environment variable, we can control several aspects
103486d7f5d3SJohn Marino  * of udev rules we use by decoding the cookie prefix. When doing the
103586d7f5d3SJohn Marino  * notification, we replace the cookie prefix with DM_COOKIE_MAGIC,
103686d7f5d3SJohn Marino  * so we notify the right semaphore.
103786d7f5d3SJohn Marino  * It is still possible to use cookies for passing the flags to udev
103886d7f5d3SJohn Marino  * rules even when udev_sync is disabled. The base part of the cookie
103986d7f5d3SJohn Marino  * will be zero (there's no notification semaphore) and prefix will be
104086d7f5d3SJohn Marino  * set then. However, having udev_sync enabled is highly recommended.
104186d7f5d3SJohn Marino  */
104286d7f5d3SJohn Marino #define DM_COOKIE_MAGIC 0x0D4D
104386d7f5d3SJohn Marino #define DM_UDEV_FLAGS_MASK 0xFFFF0000
104486d7f5d3SJohn Marino #define DM_UDEV_FLAGS_SHIFT 16
104586d7f5d3SJohn Marino 
104686d7f5d3SJohn Marino /*
104786d7f5d3SJohn Marino  * DM_UDEV_DISABLE_DM_RULES_FLAG is set in case we need to disable
104886d7f5d3SJohn Marino  * basic device-mapper udev rules that create symlinks in /dev/<DM_DIR>
104986d7f5d3SJohn Marino  * directory. However, we can't reliably prevent creating default
105086d7f5d3SJohn Marino  * nodes by udev (commonly /dev/dm-X, where X is a number).
105186d7f5d3SJohn Marino  */
105286d7f5d3SJohn Marino #define DM_UDEV_DISABLE_DM_RULES_FLAG 0x0001
105386d7f5d3SJohn Marino /*
105486d7f5d3SJohn Marino  * DM_UDEV_DISABLE_SUBSYTEM_RULES_FLAG is set in case we need to disable
105586d7f5d3SJohn Marino  * subsystem udev rules, but still we need the general DM udev rules to
105686d7f5d3SJohn Marino  * be applied (to create the nodes and symlinks under /dev and /dev/disk).
105786d7f5d3SJohn Marino  */
105886d7f5d3SJohn Marino #define DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG 0x0002
105986d7f5d3SJohn Marino /*
106086d7f5d3SJohn Marino  * DM_UDEV_DISABLE_DISK_RULES_FLAG is set in case we need to disable
106186d7f5d3SJohn Marino  * general DM rules that set symlinks in /dev/disk directory.
106286d7f5d3SJohn Marino  */
106386d7f5d3SJohn Marino #define DM_UDEV_DISABLE_DISK_RULES_FLAG 0x0004
106486d7f5d3SJohn Marino /*
106586d7f5d3SJohn Marino  * DM_UDEV_DISABLE_OTHER_RULES_FLAG is set in case we need to disable
106686d7f5d3SJohn Marino  * all the other rules that are not general device-mapper nor subsystem
106786d7f5d3SJohn Marino  * related (the rules belong to other software or packages). All foreign
106886d7f5d3SJohn Marino  * rules should check this flag directly and they should ignore further
106986d7f5d3SJohn Marino  * rule processing for such event.
107086d7f5d3SJohn Marino  */
107186d7f5d3SJohn Marino #define DM_UDEV_DISABLE_OTHER_RULES_FLAG 0x0008
107286d7f5d3SJohn Marino /*
107386d7f5d3SJohn Marino  * DM_UDEV_LOW_PRIORITY_FLAG is set in case we need to instruct the
107486d7f5d3SJohn Marino  * udev rules to give low priority to the device that is currently
107586d7f5d3SJohn Marino  * processed. For example, this provides a way to select which symlinks
107686d7f5d3SJohn Marino  * could be overwritten by high priority ones if their names are equal.
107786d7f5d3SJohn Marino  * Common situation is a name based on FS UUID while using origin and
107886d7f5d3SJohn Marino  * snapshot devices.
107986d7f5d3SJohn Marino  */
108086d7f5d3SJohn Marino #define DM_UDEV_LOW_PRIORITY_FLAG 0x0010
108186d7f5d3SJohn Marino 
108286d7f5d3SJohn Marino int dm_cookie_supported(void);
108386d7f5d3SJohn Marino 
108486d7f5d3SJohn Marino /*
108586d7f5d3SJohn Marino  * Udev synchronisation functions.
108686d7f5d3SJohn Marino  */
108786d7f5d3SJohn Marino void dm_udev_set_sync_support(int sync_with_udev);
108886d7f5d3SJohn Marino int dm_udev_get_sync_support(void);
108986d7f5d3SJohn Marino int dm_udev_complete(uint32_t cookie);
109086d7f5d3SJohn Marino int dm_udev_wait(uint32_t cookie);
109186d7f5d3SJohn Marino 
109286d7f5d3SJohn Marino #define DM_DEV_DIR_UMASK 0022
109386d7f5d3SJohn Marino 
109486d7f5d3SJohn Marino #endif				/* LIB_DEVICE_MAPPER_H */
1095