xref: /dflybsd-src/contrib/lvm2/dist/include/libdevmapper.h (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino /*	$NetBSD: libdevmapper.h,v 1.1.1.2 2009/12/02 00:25:41 haad Exp $	*/
2*86d7f5d3SJohn Marino 
3*86d7f5d3SJohn Marino /*
4*86d7f5d3SJohn Marino  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5*86d7f5d3SJohn Marino  * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
6*86d7f5d3SJohn Marino  *
7*86d7f5d3SJohn Marino  * This file is part of the device-mapper userspace tools.
8*86d7f5d3SJohn Marino  *
9*86d7f5d3SJohn Marino  * This copyrighted material is made available to anyone wishing to use,
10*86d7f5d3SJohn Marino  * modify, copy, or redistribute it subject to the terms and conditions
11*86d7f5d3SJohn Marino  * of the GNU Lesser General Public License v.2.1.
12*86d7f5d3SJohn Marino  *
13*86d7f5d3SJohn Marino  * You should have received a copy of the GNU Lesser General Public License
14*86d7f5d3SJohn Marino  * along with this program; if not, write to the Free Software Foundation,
15*86d7f5d3SJohn Marino  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16*86d7f5d3SJohn Marino  */
17*86d7f5d3SJohn Marino 
18*86d7f5d3SJohn Marino #ifndef LIB_DEVICE_MAPPER_H
19*86d7f5d3SJohn Marino #define LIB_DEVICE_MAPPER_H
20*86d7f5d3SJohn Marino 
21*86d7f5d3SJohn Marino #include <inttypes.h>
22*86d7f5d3SJohn Marino #include <stdarg.h>
23*86d7f5d3SJohn Marino #include <sys/types.h>
24*86d7f5d3SJohn Marino 
25*86d7f5d3SJohn Marino #ifdef linux
26*86d7f5d3SJohn Marino #  include <linux/types.h>
27*86d7f5d3SJohn Marino #endif
28*86d7f5d3SJohn Marino 
29*86d7f5d3SJohn Marino #include <limits.h>
30*86d7f5d3SJohn Marino #include <string.h>
31*86d7f5d3SJohn Marino #include <stdlib.h>
32*86d7f5d3SJohn Marino #include <stdio.h>
33*86d7f5d3SJohn Marino 
34*86d7f5d3SJohn Marino /*****************************************************************
35*86d7f5d3SJohn Marino  * The first section of this file provides direct access to the
36*86d7f5d3SJohn Marino  * individual device-mapper ioctls.  Since it is quite laborious to
37*86d7f5d3SJohn Marino  * build the ioctl arguments for the device-mapper, people are
38*86d7f5d3SJohn Marino  * encouraged to use this library.
39*86d7f5d3SJohn Marino  ****************************************************************/
40*86d7f5d3SJohn Marino 
41*86d7f5d3SJohn Marino /*
42*86d7f5d3SJohn Marino  * The library user may wish to register their own
43*86d7f5d3SJohn Marino  * logging function.  By default errors go to stderr.
44*86d7f5d3SJohn Marino  * Use dm_log_with_errno_init(NULL) to restore the default log fn.
45*86d7f5d3SJohn Marino  */
46*86d7f5d3SJohn Marino 
47*86d7f5d3SJohn Marino typedef void (*dm_log_with_errno_fn) (int level, const char *file, int line,
48*86d7f5d3SJohn Marino 				      int dm_errno, const char *f, ...)
49*86d7f5d3SJohn Marino     __attribute__ ((format(printf, 5, 6)));
50*86d7f5d3SJohn Marino 
51*86d7f5d3SJohn Marino void dm_log_with_errno_init(dm_log_with_errno_fn fn);
52*86d7f5d3SJohn Marino void dm_log_init_verbose(int level);
53*86d7f5d3SJohn Marino 
54*86d7f5d3SJohn Marino /*
55*86d7f5d3SJohn Marino  * Original version of this function.
56*86d7f5d3SJohn Marino  * dm_errno is set to 0.
57*86d7f5d3SJohn Marino  *
58*86d7f5d3SJohn Marino  * Deprecated: Use the _with_errno_ versions above instead.
59*86d7f5d3SJohn Marino  */
60*86d7f5d3SJohn Marino typedef void (*dm_log_fn) (int level, const char *file, int line,
61*86d7f5d3SJohn Marino 			   const char *f, ...)
62*86d7f5d3SJohn Marino     __attribute__ ((format(printf, 4, 5)));
63*86d7f5d3SJohn Marino void dm_log_init(dm_log_fn fn);
64*86d7f5d3SJohn Marino /*
65*86d7f5d3SJohn Marino  * For backward-compatibility, indicate that dm_log_init() was used
66*86d7f5d3SJohn Marino  * to set a non-default value of dm_log().
67*86d7f5d3SJohn Marino  */
68*86d7f5d3SJohn Marino int dm_log_is_non_default(void);
69*86d7f5d3SJohn Marino 
70*86d7f5d3SJohn Marino enum {
71*86d7f5d3SJohn Marino 	DM_DEVICE_CREATE,
72*86d7f5d3SJohn Marino 	DM_DEVICE_RELOAD,
73*86d7f5d3SJohn Marino 	DM_DEVICE_REMOVE,
74*86d7f5d3SJohn Marino 	DM_DEVICE_REMOVE_ALL,
75*86d7f5d3SJohn Marino 
76*86d7f5d3SJohn Marino 	DM_DEVICE_SUSPEND,
77*86d7f5d3SJohn Marino 	DM_DEVICE_RESUME,
78*86d7f5d3SJohn Marino 
79*86d7f5d3SJohn Marino 	DM_DEVICE_INFO,
80*86d7f5d3SJohn Marino 	DM_DEVICE_DEPS,
81*86d7f5d3SJohn Marino 	DM_DEVICE_RENAME,
82*86d7f5d3SJohn Marino 
83*86d7f5d3SJohn Marino 	DM_DEVICE_VERSION,
84*86d7f5d3SJohn Marino 
85*86d7f5d3SJohn Marino 	DM_DEVICE_STATUS,
86*86d7f5d3SJohn Marino 	DM_DEVICE_TABLE,
87*86d7f5d3SJohn Marino 	DM_DEVICE_WAITEVENT,
88*86d7f5d3SJohn Marino 
89*86d7f5d3SJohn Marino 	DM_DEVICE_LIST,
90*86d7f5d3SJohn Marino 
91*86d7f5d3SJohn Marino 	DM_DEVICE_CLEAR,
92*86d7f5d3SJohn Marino 
93*86d7f5d3SJohn Marino 	DM_DEVICE_MKNODES,
94*86d7f5d3SJohn Marino 
95*86d7f5d3SJohn Marino 	DM_DEVICE_LIST_VERSIONS,
96*86d7f5d3SJohn Marino 
97*86d7f5d3SJohn Marino 	DM_DEVICE_TARGET_MSG,
98*86d7f5d3SJohn Marino 
99*86d7f5d3SJohn Marino 	DM_DEVICE_SET_GEOMETRY
100*86d7f5d3SJohn Marino };
101*86d7f5d3SJohn Marino 
102*86d7f5d3SJohn Marino /*
103*86d7f5d3SJohn Marino  * You will need to build a struct dm_task for
104*86d7f5d3SJohn Marino  * each ioctl command you want to execute.
105*86d7f5d3SJohn Marino  */
106*86d7f5d3SJohn Marino 
107*86d7f5d3SJohn Marino struct dm_task;
108*86d7f5d3SJohn Marino 
109*86d7f5d3SJohn Marino struct dm_task *dm_task_create(int type);
110*86d7f5d3SJohn Marino void dm_task_destroy(struct dm_task *dmt);
111*86d7f5d3SJohn Marino 
112*86d7f5d3SJohn Marino int dm_task_set_name(struct dm_task *dmt, const char *name);
113*86d7f5d3SJohn Marino int dm_task_set_uuid(struct dm_task *dmt, const char *uuid);
114*86d7f5d3SJohn Marino 
115*86d7f5d3SJohn Marino /*
116*86d7f5d3SJohn Marino  * Retrieve attributes after an info.
117*86d7f5d3SJohn Marino  */
118*86d7f5d3SJohn Marino struct dm_info {
119*86d7f5d3SJohn Marino 	int exists;
120*86d7f5d3SJohn Marino 	int suspended;
121*86d7f5d3SJohn Marino 	int live_table;
122*86d7f5d3SJohn Marino 	int inactive_table;
123*86d7f5d3SJohn Marino 	int32_t open_count;
124*86d7f5d3SJohn Marino 	uint32_t event_nr;
125*86d7f5d3SJohn Marino 	uint32_t major;
126*86d7f5d3SJohn Marino 	uint32_t minor;		/* minor device number */
127*86d7f5d3SJohn Marino 	int read_only;		/* 0:read-write; 1:read-only */
128*86d7f5d3SJohn Marino 
129*86d7f5d3SJohn Marino 	int32_t target_count;
130*86d7f5d3SJohn Marino };
131*86d7f5d3SJohn Marino 
132*86d7f5d3SJohn Marino struct dm_deps {
133*86d7f5d3SJohn Marino 	uint32_t count;
134*86d7f5d3SJohn Marino 	uint32_t filler;
135*86d7f5d3SJohn Marino 	uint64_t device[0];
136*86d7f5d3SJohn Marino };
137*86d7f5d3SJohn Marino 
138*86d7f5d3SJohn Marino struct dm_names {
139*86d7f5d3SJohn Marino 	uint64_t dev;
140*86d7f5d3SJohn Marino 	uint32_t next;		/* Offset to next struct from start of this struct */
141*86d7f5d3SJohn Marino 	char name[0];
142*86d7f5d3SJohn Marino };
143*86d7f5d3SJohn Marino 
144*86d7f5d3SJohn Marino struct dm_versions {
145*86d7f5d3SJohn Marino 	uint32_t next;		/* Offset to next struct from start of this struct */
146*86d7f5d3SJohn Marino 	uint32_t version[3];
147*86d7f5d3SJohn Marino 
148*86d7f5d3SJohn Marino 	char name[0];
149*86d7f5d3SJohn Marino };
150*86d7f5d3SJohn Marino 
151*86d7f5d3SJohn Marino int dm_get_library_version(char *version, size_t size);
152*86d7f5d3SJohn Marino int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size);
153*86d7f5d3SJohn Marino int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi);
154*86d7f5d3SJohn Marino const char *dm_task_get_name(const struct dm_task *dmt);
155*86d7f5d3SJohn Marino const char *dm_task_get_uuid(const struct dm_task *dmt);
156*86d7f5d3SJohn Marino 
157*86d7f5d3SJohn Marino struct dm_deps *dm_task_get_deps(struct dm_task *dmt);
158*86d7f5d3SJohn Marino struct dm_names *dm_task_get_names(struct dm_task *dmt);
159*86d7f5d3SJohn Marino struct dm_versions *dm_task_get_versions(struct dm_task *dmt);
160*86d7f5d3SJohn Marino 
161*86d7f5d3SJohn Marino int dm_task_set_ro(struct dm_task *dmt);
162*86d7f5d3SJohn Marino int dm_task_set_newname(struct dm_task *dmt, const char *newname);
163*86d7f5d3SJohn Marino int dm_task_set_minor(struct dm_task *dmt, int minor);
164*86d7f5d3SJohn Marino int dm_task_set_major(struct dm_task *dmt, int major);
165*86d7f5d3SJohn Marino int dm_task_set_major_minor(struct dm_task *dmt, int major, int minor, int allow_default_major_fallback);
166*86d7f5d3SJohn Marino int dm_task_set_uid(struct dm_task *dmt, uid_t uid);
167*86d7f5d3SJohn Marino int dm_task_set_gid(struct dm_task *dmt, gid_t gid);
168*86d7f5d3SJohn Marino int dm_task_set_mode(struct dm_task *dmt, mode_t mode);
169*86d7f5d3SJohn Marino int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags);
170*86d7f5d3SJohn Marino int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr);
171*86d7f5d3SJohn Marino int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads, const char *sectors, const char *start);
172*86d7f5d3SJohn Marino int dm_task_set_message(struct dm_task *dmt, const char *message);
173*86d7f5d3SJohn Marino int dm_task_set_sector(struct dm_task *dmt, uint64_t sector);
174*86d7f5d3SJohn Marino int dm_task_no_flush(struct dm_task *dmt);
175*86d7f5d3SJohn Marino int dm_task_no_open_count(struct dm_task *dmt);
176*86d7f5d3SJohn Marino int dm_task_skip_lockfs(struct dm_task *dmt);
177*86d7f5d3SJohn Marino int dm_task_query_inactive_table(struct dm_task *dmt);
178*86d7f5d3SJohn Marino int dm_task_suppress_identical_reload(struct dm_task *dmt);
179*86d7f5d3SJohn Marino 
180*86d7f5d3SJohn Marino /*
181*86d7f5d3SJohn Marino  * Control read_ahead.
182*86d7f5d3SJohn Marino  */
183*86d7f5d3SJohn Marino #define DM_READ_AHEAD_AUTO UINT32_MAX	/* Use kernel default readahead */
184*86d7f5d3SJohn Marino #define DM_READ_AHEAD_NONE 0		/* Disable readahead */
185*86d7f5d3SJohn Marino 
186*86d7f5d3SJohn Marino #define DM_READ_AHEAD_MINIMUM_FLAG	0x1	/* Value supplied is minimum */
187*86d7f5d3SJohn Marino 
188*86d7f5d3SJohn Marino /*
189*86d7f5d3SJohn Marino  * Read ahead is set with DM_DEVICE_CREATE with a table or DM_DEVICE_RESUME.
190*86d7f5d3SJohn Marino  */
191*86d7f5d3SJohn Marino int dm_task_set_read_ahead(struct dm_task *dmt, uint32_t read_ahead,
192*86d7f5d3SJohn Marino 			   uint32_t read_ahead_flags);
193*86d7f5d3SJohn Marino uint32_t dm_task_get_read_ahead(const struct dm_task *dmt,
194*86d7f5d3SJohn Marino 				uint32_t *read_ahead);
195*86d7f5d3SJohn Marino 
196*86d7f5d3SJohn Marino /*
197*86d7f5d3SJohn Marino  * Use these to prepare for a create or reload.
198*86d7f5d3SJohn Marino  */
199*86d7f5d3SJohn Marino int dm_task_add_target(struct dm_task *dmt,
200*86d7f5d3SJohn Marino 		       uint64_t start,
201*86d7f5d3SJohn Marino 		       uint64_t size, const char *ttype, const char *params);
202*86d7f5d3SJohn Marino 
203*86d7f5d3SJohn Marino /*
204*86d7f5d3SJohn Marino  * Format major/minor numbers correctly for input to driver.
205*86d7f5d3SJohn Marino  */
206*86d7f5d3SJohn Marino #define DM_FORMAT_DEV_BUFSIZE	13	/* Minimum bufsize to handle worst case. */
207*86d7f5d3SJohn Marino int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, uint32_t dev_minor);
208*86d7f5d3SJohn Marino 
209*86d7f5d3SJohn Marino /* Use this to retrive target information returned from a STATUS call */
210*86d7f5d3SJohn Marino void *dm_get_next_target(struct dm_task *dmt,
211*86d7f5d3SJohn Marino 			 void *next, uint64_t *start, uint64_t *length,
212*86d7f5d3SJohn Marino 			 char **target_type, char **params);
213*86d7f5d3SJohn Marino 
214*86d7f5d3SJohn Marino /*
215*86d7f5d3SJohn Marino  * Call this to actually run the ioctl.
216*86d7f5d3SJohn Marino  */
217*86d7f5d3SJohn Marino int dm_task_run(struct dm_task *dmt);
218*86d7f5d3SJohn Marino 
219*86d7f5d3SJohn Marino /*
220*86d7f5d3SJohn Marino  * Call this to make or remove the device nodes associated with previously
221*86d7f5d3SJohn Marino  * issued commands.
222*86d7f5d3SJohn Marino  */
223*86d7f5d3SJohn Marino void dm_task_update_nodes(void);
224*86d7f5d3SJohn Marino 
225*86d7f5d3SJohn Marino /*
226*86d7f5d3SJohn Marino  * Configure the device-mapper directory
227*86d7f5d3SJohn Marino  */
228*86d7f5d3SJohn Marino int dm_set_dev_dir(const char *dir);
229*86d7f5d3SJohn Marino const char *dm_dir(void);
230*86d7f5d3SJohn Marino 
231*86d7f5d3SJohn Marino /*
232*86d7f5d3SJohn Marino  * Determine whether a major number belongs to device-mapper or not.
233*86d7f5d3SJohn Marino  */
234*86d7f5d3SJohn Marino int dm_is_dm_major(uint32_t major);
235*86d7f5d3SJohn Marino 
236*86d7f5d3SJohn Marino /*
237*86d7f5d3SJohn Marino  * Release library resources
238*86d7f5d3SJohn Marino  */
239*86d7f5d3SJohn Marino void dm_lib_release(void);
240*86d7f5d3SJohn Marino void dm_lib_exit(void) __attribute((destructor));
241*86d7f5d3SJohn Marino 
242*86d7f5d3SJohn Marino /*
243*86d7f5d3SJohn Marino  * Use NULL for all devices.
244*86d7f5d3SJohn Marino  */
245*86d7f5d3SJohn Marino int dm_mknodes(const char *name);
246*86d7f5d3SJohn Marino int dm_driver_version(char *version, size_t size);
247*86d7f5d3SJohn Marino 
248*86d7f5d3SJohn Marino /******************************************************
249*86d7f5d3SJohn Marino  * Functions to build and manipulate trees of devices *
250*86d7f5d3SJohn Marino  ******************************************************/
251*86d7f5d3SJohn Marino struct dm_tree;
252*86d7f5d3SJohn Marino struct dm_tree_node;
253*86d7f5d3SJohn Marino 
254*86d7f5d3SJohn Marino /*
255*86d7f5d3SJohn Marino  * Initialise an empty dependency tree.
256*86d7f5d3SJohn Marino  *
257*86d7f5d3SJohn Marino  * The tree consists of a root node together with one node for each mapped
258*86d7f5d3SJohn Marino  * device which has child nodes for each device referenced in its table.
259*86d7f5d3SJohn Marino  *
260*86d7f5d3SJohn Marino  * Every node in the tree has one or more children and one or more parents.
261*86d7f5d3SJohn Marino  *
262*86d7f5d3SJohn Marino  * The root node is the parent/child of every node that doesn't have other
263*86d7f5d3SJohn Marino  * parents/children.
264*86d7f5d3SJohn Marino  */
265*86d7f5d3SJohn Marino struct dm_tree *dm_tree_create(void);
266*86d7f5d3SJohn Marino void dm_tree_free(struct dm_tree *tree);
267*86d7f5d3SJohn Marino 
268*86d7f5d3SJohn Marino /*
269*86d7f5d3SJohn Marino  * Add nodes to the tree for a given device and all the devices it uses.
270*86d7f5d3SJohn Marino  */
271*86d7f5d3SJohn Marino int dm_tree_add_dev(struct dm_tree *tree, uint32_t major, uint32_t minor);
272*86d7f5d3SJohn Marino 
273*86d7f5d3SJohn Marino /*
274*86d7f5d3SJohn Marino  * Add a new node to the tree if it doesn't already exist.
275*86d7f5d3SJohn Marino  */
276*86d7f5d3SJohn Marino struct dm_tree_node *dm_tree_add_new_dev(struct dm_tree *tree,
277*86d7f5d3SJohn Marino 					 const char *name,
278*86d7f5d3SJohn Marino 					 const char *uuid,
279*86d7f5d3SJohn Marino 					 uint32_t major, uint32_t minor,
280*86d7f5d3SJohn Marino 					 int read_only,
281*86d7f5d3SJohn Marino 					 int clear_inactive,
282*86d7f5d3SJohn Marino 					 void *context);
283*86d7f5d3SJohn Marino struct dm_tree_node *dm_tree_add_new_dev_with_udev_flags(struct dm_tree *tree,
284*86d7f5d3SJohn Marino 							 const char *name,
285*86d7f5d3SJohn Marino 							 const char *uuid,
286*86d7f5d3SJohn Marino 							 uint32_t major,
287*86d7f5d3SJohn Marino 							 uint32_t minor,
288*86d7f5d3SJohn Marino 							 int read_only,
289*86d7f5d3SJohn Marino 							 int clear_inactive,
290*86d7f5d3SJohn Marino 							 void *context,
291*86d7f5d3SJohn Marino 							 uint16_t udev_flags);
292*86d7f5d3SJohn Marino 
293*86d7f5d3SJohn Marino /*
294*86d7f5d3SJohn Marino  * Search for a node in the tree.
295*86d7f5d3SJohn Marino  * Set major and minor to 0 or uuid to NULL to get the root node.
296*86d7f5d3SJohn Marino  */
297*86d7f5d3SJohn Marino struct dm_tree_node *dm_tree_find_node(struct dm_tree *tree,
298*86d7f5d3SJohn Marino 					  uint32_t major,
299*86d7f5d3SJohn Marino 					  uint32_t minor);
300*86d7f5d3SJohn Marino struct dm_tree_node *dm_tree_find_node_by_uuid(struct dm_tree *tree,
301*86d7f5d3SJohn Marino 						  const char *uuid);
302*86d7f5d3SJohn Marino 
303*86d7f5d3SJohn Marino /*
304*86d7f5d3SJohn Marino  * Use this to walk through all children of a given node.
305*86d7f5d3SJohn Marino  * Set handle to NULL in first call.
306*86d7f5d3SJohn Marino  * Returns NULL after the last child.
307*86d7f5d3SJohn Marino  * Set inverted to use inverted tree.
308*86d7f5d3SJohn Marino  */
309*86d7f5d3SJohn Marino struct dm_tree_node *dm_tree_next_child(void **handle,
310*86d7f5d3SJohn Marino 					   struct dm_tree_node *parent,
311*86d7f5d3SJohn Marino 					   uint32_t inverted);
312*86d7f5d3SJohn Marino 
313*86d7f5d3SJohn Marino /*
314*86d7f5d3SJohn Marino  * Get properties of a node.
315*86d7f5d3SJohn Marino  */
316*86d7f5d3SJohn Marino const char *dm_tree_node_get_name(struct dm_tree_node *node);
317*86d7f5d3SJohn Marino const char *dm_tree_node_get_uuid(struct dm_tree_node *node);
318*86d7f5d3SJohn Marino const struct dm_info *dm_tree_node_get_info(struct dm_tree_node *node);
319*86d7f5d3SJohn Marino void *dm_tree_node_get_context(struct dm_tree_node *node);
320*86d7f5d3SJohn Marino int dm_tree_node_size_changed(struct dm_tree_node *dnode);
321*86d7f5d3SJohn Marino 
322*86d7f5d3SJohn Marino /*
323*86d7f5d3SJohn Marino  * Returns the number of children of the given node (excluding the root node).
324*86d7f5d3SJohn Marino  * Set inverted for the number of parents.
325*86d7f5d3SJohn Marino  */
326*86d7f5d3SJohn Marino int dm_tree_node_num_children(struct dm_tree_node *node, uint32_t inverted);
327*86d7f5d3SJohn Marino 
328*86d7f5d3SJohn Marino /*
329*86d7f5d3SJohn Marino  * Deactivate a device plus all dependencies.
330*86d7f5d3SJohn Marino  * Ignores devices that don't have a uuid starting with uuid_prefix.
331*86d7f5d3SJohn Marino  */
332*86d7f5d3SJohn Marino int dm_tree_deactivate_children(struct dm_tree_node *dnode,
333*86d7f5d3SJohn Marino 				   const char *uuid_prefix,
334*86d7f5d3SJohn Marino 				   size_t uuid_prefix_len);
335*86d7f5d3SJohn Marino /*
336*86d7f5d3SJohn Marino  * Preload/create a device plus all dependencies.
337*86d7f5d3SJohn Marino  * Ignores devices that don't have a uuid starting with uuid_prefix.
338*86d7f5d3SJohn Marino  */
339*86d7f5d3SJohn Marino int dm_tree_preload_children(struct dm_tree_node *dnode,
340*86d7f5d3SJohn Marino 			     const char *uuid_prefix,
341*86d7f5d3SJohn Marino 			     size_t uuid_prefix_len);
342*86d7f5d3SJohn Marino 
343*86d7f5d3SJohn Marino /*
344*86d7f5d3SJohn Marino  * Resume a device plus all dependencies.
345*86d7f5d3SJohn Marino  * Ignores devices that don't have a uuid starting with uuid_prefix.
346*86d7f5d3SJohn Marino  */
347*86d7f5d3SJohn Marino int dm_tree_activate_children(struct dm_tree_node *dnode,
348*86d7f5d3SJohn Marino 			      const char *uuid_prefix,
349*86d7f5d3SJohn Marino 			      size_t uuid_prefix_len);
350*86d7f5d3SJohn Marino 
351*86d7f5d3SJohn Marino /*
352*86d7f5d3SJohn Marino  * Suspend a device plus all dependencies.
353*86d7f5d3SJohn Marino  * Ignores devices that don't have a uuid starting with uuid_prefix.
354*86d7f5d3SJohn Marino  */
355*86d7f5d3SJohn Marino int dm_tree_suspend_children(struct dm_tree_node *dnode,
356*86d7f5d3SJohn Marino 				   const char *uuid_prefix,
357*86d7f5d3SJohn Marino 				   size_t uuid_prefix_len);
358*86d7f5d3SJohn Marino 
359*86d7f5d3SJohn Marino /*
360*86d7f5d3SJohn Marino  * Skip the filesystem sync when suspending.
361*86d7f5d3SJohn Marino  * Does nothing with other functions.
362*86d7f5d3SJohn Marino  * Use this when no snapshots are involved.
363*86d7f5d3SJohn Marino  */
364*86d7f5d3SJohn Marino void dm_tree_skip_lockfs(struct dm_tree_node *dnode);
365*86d7f5d3SJohn Marino 
366*86d7f5d3SJohn Marino /*
367*86d7f5d3SJohn Marino  * Set the 'noflush' flag when suspending devices.
368*86d7f5d3SJohn Marino  * If the kernel supports it, instead of erroring outstanding I/O that
369*86d7f5d3SJohn Marino  * cannot be completed, the I/O is queued and resubmitted when the
370*86d7f5d3SJohn Marino  * device is resumed.  This affects multipath devices when all paths
371*86d7f5d3SJohn Marino  * have failed and queue_if_no_path is set, and mirror devices when
372*86d7f5d3SJohn Marino  * block_on_error is set and the mirror log has failed.
373*86d7f5d3SJohn Marino  */
374*86d7f5d3SJohn Marino void dm_tree_use_no_flush_suspend(struct dm_tree_node *dnode);
375*86d7f5d3SJohn Marino 
376*86d7f5d3SJohn Marino /*
377*86d7f5d3SJohn Marino  * Is the uuid prefix present in the tree?
378*86d7f5d3SJohn Marino  * Only returns 0 if every node was checked successfully.
379*86d7f5d3SJohn Marino  * Returns 1 if the tree walk has to be aborted.
380*86d7f5d3SJohn Marino  */
381*86d7f5d3SJohn Marino int dm_tree_children_use_uuid(struct dm_tree_node *dnode,
382*86d7f5d3SJohn Marino 				 const char *uuid_prefix,
383*86d7f5d3SJohn Marino 				 size_t uuid_prefix_len);
384*86d7f5d3SJohn Marino 
385*86d7f5d3SJohn Marino /*
386*86d7f5d3SJohn Marino  * Construct tables for new nodes before activating them.
387*86d7f5d3SJohn Marino  */
388*86d7f5d3SJohn Marino int dm_tree_node_add_snapshot_origin_target(struct dm_tree_node *dnode,
389*86d7f5d3SJohn Marino 					       uint64_t size,
390*86d7f5d3SJohn Marino 					       const char *origin_uuid);
391*86d7f5d3SJohn Marino int dm_tree_node_add_snapshot_target(struct dm_tree_node *node,
392*86d7f5d3SJohn Marino 					uint64_t size,
393*86d7f5d3SJohn Marino 					const char *origin_uuid,
394*86d7f5d3SJohn Marino 					const char *cow_uuid,
395*86d7f5d3SJohn Marino 					int persistent,
396*86d7f5d3SJohn Marino 					uint32_t chunk_size);
397*86d7f5d3SJohn Marino int dm_tree_node_add_error_target(struct dm_tree_node *node,
398*86d7f5d3SJohn Marino 				     uint64_t size);
399*86d7f5d3SJohn Marino int dm_tree_node_add_zero_target(struct dm_tree_node *node,
400*86d7f5d3SJohn Marino 				    uint64_t size);
401*86d7f5d3SJohn Marino int dm_tree_node_add_linear_target(struct dm_tree_node *node,
402*86d7f5d3SJohn Marino 				      uint64_t size);
403*86d7f5d3SJohn Marino int dm_tree_node_add_striped_target(struct dm_tree_node *node,
404*86d7f5d3SJohn Marino 				       uint64_t size,
405*86d7f5d3SJohn Marino 				       uint32_t stripe_size);
406*86d7f5d3SJohn Marino 
407*86d7f5d3SJohn Marino #define DM_CRYPT_IV_DEFAULT	UINT64_C(-1)	/* iv_offset == seg offset */
408*86d7f5d3SJohn Marino /*
409*86d7f5d3SJohn Marino  * Function accepts one string in cipher specification
410*86d7f5d3SJohn Marino  * (chainmode and iv should be NULL because included in cipher string)
411*86d7f5d3SJohn Marino  *   or
412*86d7f5d3SJohn Marino  * separate arguments which will be joined to "cipher-chainmode-iv"
413*86d7f5d3SJohn Marino  */
414*86d7f5d3SJohn Marino int dm_tree_node_add_crypt_target(struct dm_tree_node *node,
415*86d7f5d3SJohn Marino 				  uint64_t size,
416*86d7f5d3SJohn Marino 				  const char *cipher,
417*86d7f5d3SJohn Marino 				  const char *chainmode,
418*86d7f5d3SJohn Marino 				  const char *iv,
419*86d7f5d3SJohn Marino 				  uint64_t iv_offset,
420*86d7f5d3SJohn Marino 				  const char *key);
421*86d7f5d3SJohn Marino int dm_tree_node_add_mirror_target(struct dm_tree_node *node,
422*86d7f5d3SJohn Marino 				      uint64_t size);
423*86d7f5d3SJohn Marino 
424*86d7f5d3SJohn Marino /* Mirror log flags */
425*86d7f5d3SJohn Marino #define DM_NOSYNC		0x00000001	/* Known already in sync */
426*86d7f5d3SJohn Marino #define DM_FORCESYNC		0x00000002	/* Force resync */
427*86d7f5d3SJohn Marino #define DM_BLOCK_ON_ERROR	0x00000004	/* On error, suspend I/O */
428*86d7f5d3SJohn Marino #define DM_CORELOG		0x00000008	/* In-memory log */
429*86d7f5d3SJohn Marino 
430*86d7f5d3SJohn Marino int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node,
431*86d7f5d3SJohn Marino 					  uint32_t region_size,
432*86d7f5d3SJohn Marino 					  unsigned clustered,
433*86d7f5d3SJohn Marino 					  const char *log_uuid,
434*86d7f5d3SJohn Marino 					  unsigned area_count,
435*86d7f5d3SJohn Marino 					  uint32_t flags);
436*86d7f5d3SJohn Marino int dm_tree_node_add_target_area(struct dm_tree_node *node,
437*86d7f5d3SJohn Marino 				    const char *dev_name,
438*86d7f5d3SJohn Marino 				    const char *dlid,
439*86d7f5d3SJohn Marino 				    uint64_t offset);
440*86d7f5d3SJohn Marino 
441*86d7f5d3SJohn Marino /*
442*86d7f5d3SJohn Marino  * Set readahead (in sectors) after loading the node.
443*86d7f5d3SJohn Marino  */
444*86d7f5d3SJohn Marino void dm_tree_node_set_read_ahead(struct dm_tree_node *dnode,
445*86d7f5d3SJohn Marino 				 uint32_t read_ahead,
446*86d7f5d3SJohn Marino 				 uint32_t read_ahead_flags);
447*86d7f5d3SJohn Marino 
448*86d7f5d3SJohn Marino void dm_tree_set_cookie(struct dm_tree_node *node, uint32_t cookie);
449*86d7f5d3SJohn Marino uint32_t dm_tree_get_cookie(struct dm_tree_node *node);
450*86d7f5d3SJohn Marino 
451*86d7f5d3SJohn Marino /*****************************************************************************
452*86d7f5d3SJohn Marino  * Library functions
453*86d7f5d3SJohn Marino  *****************************************************************************/
454*86d7f5d3SJohn Marino 
455*86d7f5d3SJohn Marino /*******************
456*86d7f5d3SJohn Marino  * Memory management
457*86d7f5d3SJohn Marino  *******************/
458*86d7f5d3SJohn Marino 
459*86d7f5d3SJohn Marino void *dm_malloc_aux(size_t s, const char *file, int line);
460*86d7f5d3SJohn Marino void *dm_malloc_aux_debug(size_t s, const char *file, int line);
461*86d7f5d3SJohn Marino char *dm_strdup_aux(const char *str, const char *file, int line);
462*86d7f5d3SJohn Marino void dm_free_aux(void *p);
463*86d7f5d3SJohn Marino void *dm_realloc_aux(void *p, unsigned int s, const char *file, int line);
464*86d7f5d3SJohn Marino int dm_dump_memory_debug(void);
465*86d7f5d3SJohn Marino void dm_bounds_check_debug(void);
466*86d7f5d3SJohn Marino 
467*86d7f5d3SJohn Marino #ifdef DEBUG_MEM
468*86d7f5d3SJohn Marino 
469*86d7f5d3SJohn Marino #  define dm_malloc(s) dm_malloc_aux_debug((s), __FILE__, __LINE__)
470*86d7f5d3SJohn Marino #  define dm_strdup(s) dm_strdup_aux((s), __FILE__, __LINE__)
471*86d7f5d3SJohn Marino #  define dm_free(p) dm_free_aux(p)
472*86d7f5d3SJohn Marino #  define dm_realloc(p, s) dm_realloc_aux(p, s, __FILE__, __LINE__)
473*86d7f5d3SJohn Marino #  define dm_dump_memory() dm_dump_memory_debug()
474*86d7f5d3SJohn Marino #  define dm_bounds_check() dm_bounds_check_debug()
475*86d7f5d3SJohn Marino 
476*86d7f5d3SJohn Marino #else
477*86d7f5d3SJohn Marino 
478*86d7f5d3SJohn Marino #  define dm_malloc(s) dm_malloc_aux((s), __FILE__, __LINE__)
479*86d7f5d3SJohn Marino #  define dm_strdup(s) strdup(s)
480*86d7f5d3SJohn Marino #  define dm_free(p) free(p)
481*86d7f5d3SJohn Marino #  define dm_realloc(p, s) realloc(p, s)
482*86d7f5d3SJohn Marino #  define dm_dump_memory() {}
483*86d7f5d3SJohn Marino #  define dm_bounds_check() {}
484*86d7f5d3SJohn Marino 
485*86d7f5d3SJohn Marino #endif
486*86d7f5d3SJohn Marino 
487*86d7f5d3SJohn Marino 
488*86d7f5d3SJohn Marino /*
489*86d7f5d3SJohn Marino  * The pool allocator is useful when you are going to allocate
490*86d7f5d3SJohn Marino  * lots of memory, use the memory for a bit, and then free the
491*86d7f5d3SJohn Marino  * memory in one go.  A surprising amount of code has this usage
492*86d7f5d3SJohn Marino  * profile.
493*86d7f5d3SJohn Marino  *
494*86d7f5d3SJohn Marino  * You should think of the pool as an infinite, contiguous chunk
495*86d7f5d3SJohn Marino  * of memory.  The front of this chunk of memory contains
496*86d7f5d3SJohn Marino  * allocated objects, the second half is free.  dm_pool_alloc grabs
497*86d7f5d3SJohn Marino  * the next 'size' bytes from the free half, in effect moving it
498*86d7f5d3SJohn Marino  * into the allocated half.  This operation is very efficient.
499*86d7f5d3SJohn Marino  *
500*86d7f5d3SJohn Marino  * dm_pool_free frees the allocated object *and* all objects
501*86d7f5d3SJohn Marino  * allocated after it.  It is important to note this semantic
502*86d7f5d3SJohn Marino  * difference from malloc/free.  This is also extremely
503*86d7f5d3SJohn Marino  * efficient, since a single dm_pool_free can dispose of a large
504*86d7f5d3SJohn Marino  * complex object.
505*86d7f5d3SJohn Marino  *
506*86d7f5d3SJohn Marino  * dm_pool_destroy frees all allocated memory.
507*86d7f5d3SJohn Marino  *
508*86d7f5d3SJohn Marino  * eg, If you are building a binary tree in your program, and
509*86d7f5d3SJohn Marino  * know that you are only ever going to insert into your tree,
510*86d7f5d3SJohn Marino  * and not delete (eg, maintaining a symbol table for a
511*86d7f5d3SJohn Marino  * compiler).  You can create yourself a pool, allocate the nodes
512*86d7f5d3SJohn Marino  * from it, and when the tree becomes redundant call dm_pool_destroy
513*86d7f5d3SJohn Marino  * (no nasty iterating through the tree to free nodes).
514*86d7f5d3SJohn Marino  *
515*86d7f5d3SJohn Marino  * eg, On the other hand if you wanted to repeatedly insert and
516*86d7f5d3SJohn Marino  * remove objects into the tree, you would be better off
517*86d7f5d3SJohn Marino  * allocating the nodes from a free list; you cannot free a
518*86d7f5d3SJohn Marino  * single arbitrary node with pool.
519*86d7f5d3SJohn Marino  */
520*86d7f5d3SJohn Marino 
521*86d7f5d3SJohn Marino struct dm_pool;
522*86d7f5d3SJohn Marino 
523*86d7f5d3SJohn Marino /* constructor and destructor */
524*86d7f5d3SJohn Marino struct dm_pool *dm_pool_create(const char *name, size_t chunk_hint);
525*86d7f5d3SJohn Marino void dm_pool_destroy(struct dm_pool *p);
526*86d7f5d3SJohn Marino 
527*86d7f5d3SJohn Marino /* simple allocation/free routines */
528*86d7f5d3SJohn Marino void *dm_pool_alloc(struct dm_pool *p, size_t s);
529*86d7f5d3SJohn Marino void *dm_pool_alloc_aligned(struct dm_pool *p, size_t s, unsigned alignment);
530*86d7f5d3SJohn Marino void dm_pool_empty(struct dm_pool *p);
531*86d7f5d3SJohn Marino void dm_pool_free(struct dm_pool *p, void *ptr);
532*86d7f5d3SJohn Marino 
533*86d7f5d3SJohn Marino /*
534*86d7f5d3SJohn Marino  * Object building routines:
535*86d7f5d3SJohn Marino  *
536*86d7f5d3SJohn Marino  * These allow you to 'grow' an object, useful for
537*86d7f5d3SJohn Marino  * building strings, or filling in dynamic
538*86d7f5d3SJohn Marino  * arrays.
539*86d7f5d3SJohn Marino  *
540*86d7f5d3SJohn Marino  * It's probably best explained with an example:
541*86d7f5d3SJohn Marino  *
542*86d7f5d3SJohn Marino  * char *build_string(struct dm_pool *mem)
543*86d7f5d3SJohn Marino  * {
544*86d7f5d3SJohn Marino  *      int i;
545*86d7f5d3SJohn Marino  *      char buffer[16];
546*86d7f5d3SJohn Marino  *
547*86d7f5d3SJohn Marino  *      if (!dm_pool_begin_object(mem, 128))
548*86d7f5d3SJohn Marino  *              return NULL;
549*86d7f5d3SJohn Marino  *
550*86d7f5d3SJohn Marino  *      for (i = 0; i < 50; i++) {
551*86d7f5d3SJohn Marino  *              snprintf(buffer, sizeof(buffer), "%d, ", i);
552*86d7f5d3SJohn Marino  *              if (!dm_pool_grow_object(mem, buffer, 0))
553*86d7f5d3SJohn Marino  *                      goto bad;
554*86d7f5d3SJohn Marino  *      }
555*86d7f5d3SJohn Marino  *
556*86d7f5d3SJohn Marino  *	// add null
557*86d7f5d3SJohn Marino  *      if (!dm_pool_grow_object(mem, "\0", 1))
558*86d7f5d3SJohn Marino  *              goto bad;
559*86d7f5d3SJohn Marino  *
560*86d7f5d3SJohn Marino  *      return dm_pool_end_object(mem);
561*86d7f5d3SJohn Marino  *
562*86d7f5d3SJohn Marino  * bad:
563*86d7f5d3SJohn Marino  *
564*86d7f5d3SJohn Marino  *      dm_pool_abandon_object(mem);
565*86d7f5d3SJohn Marino  *      return NULL;
566*86d7f5d3SJohn Marino  *}
567*86d7f5d3SJohn Marino  *
568*86d7f5d3SJohn Marino  * So start an object by calling dm_pool_begin_object
569*86d7f5d3SJohn Marino  * with a guess at the final object size - if in
570*86d7f5d3SJohn Marino  * doubt make the guess too small.
571*86d7f5d3SJohn Marino  *
572*86d7f5d3SJohn Marino  * Then append chunks of data to your object with
573*86d7f5d3SJohn Marino  * dm_pool_grow_object.  Finally get your object with
574*86d7f5d3SJohn Marino  * a call to dm_pool_end_object.
575*86d7f5d3SJohn Marino  *
576*86d7f5d3SJohn Marino  * Setting delta to 0 means it will use strlen(extra).
577*86d7f5d3SJohn Marino  */
578*86d7f5d3SJohn Marino int dm_pool_begin_object(struct dm_pool *p, size_t hint);
579*86d7f5d3SJohn Marino int dm_pool_grow_object(struct dm_pool *p, const void *extra, size_t delta);
580*86d7f5d3SJohn Marino void *dm_pool_end_object(struct dm_pool *p);
581*86d7f5d3SJohn Marino void dm_pool_abandon_object(struct dm_pool *p);
582*86d7f5d3SJohn Marino 
583*86d7f5d3SJohn Marino /* utilities */
584*86d7f5d3SJohn Marino char *dm_pool_strdup(struct dm_pool *p, const char *str);
585*86d7f5d3SJohn Marino char *dm_pool_strndup(struct dm_pool *p, const char *str, size_t n);
586*86d7f5d3SJohn Marino void *dm_pool_zalloc(struct dm_pool *p, size_t s);
587*86d7f5d3SJohn Marino 
588*86d7f5d3SJohn Marino /******************
589*86d7f5d3SJohn Marino  * bitset functions
590*86d7f5d3SJohn Marino  ******************/
591*86d7f5d3SJohn Marino 
592*86d7f5d3SJohn Marino typedef uint32_t *dm_bitset_t;
593*86d7f5d3SJohn Marino 
594*86d7f5d3SJohn Marino dm_bitset_t dm_bitset_create(struct dm_pool *mem, unsigned num_bits);
595*86d7f5d3SJohn Marino void dm_bitset_destroy(dm_bitset_t bs);
596*86d7f5d3SJohn Marino 
597*86d7f5d3SJohn Marino void dm_bit_union(dm_bitset_t out, dm_bitset_t in1, dm_bitset_t in2);
598*86d7f5d3SJohn Marino int dm_bit_get_first(dm_bitset_t bs);
599*86d7f5d3SJohn Marino int dm_bit_get_next(dm_bitset_t bs, int last_bit);
600*86d7f5d3SJohn Marino 
601*86d7f5d3SJohn Marino #define DM_BITS_PER_INT (sizeof(int) * CHAR_BIT)
602*86d7f5d3SJohn Marino 
603*86d7f5d3SJohn Marino #define dm_bit(bs, i) \
604*86d7f5d3SJohn Marino    (bs[(i / DM_BITS_PER_INT) + 1] & (0x1 << (i & (DM_BITS_PER_INT - 1))))
605*86d7f5d3SJohn Marino 
606*86d7f5d3SJohn Marino #define dm_bit_set(bs, i) \
607*86d7f5d3SJohn Marino    (bs[(i / DM_BITS_PER_INT) + 1] |= (0x1 << (i & (DM_BITS_PER_INT - 1))))
608*86d7f5d3SJohn Marino 
609*86d7f5d3SJohn Marino #define dm_bit_clear(bs, i) \
610*86d7f5d3SJohn Marino    (bs[(i / DM_BITS_PER_INT) + 1] &= ~(0x1 << (i & (DM_BITS_PER_INT - 1))))
611*86d7f5d3SJohn Marino 
612*86d7f5d3SJohn Marino #define dm_bit_set_all(bs) \
613*86d7f5d3SJohn Marino    memset(bs + 1, -1, ((*bs / DM_BITS_PER_INT) + 1) * sizeof(int))
614*86d7f5d3SJohn Marino 
615*86d7f5d3SJohn Marino #define dm_bit_clear_all(bs) \
616*86d7f5d3SJohn Marino    memset(bs + 1, 0, ((*bs / DM_BITS_PER_INT) + 1) * sizeof(int))
617*86d7f5d3SJohn Marino 
618*86d7f5d3SJohn Marino #define dm_bit_copy(bs1, bs2) \
619*86d7f5d3SJohn Marino    memcpy(bs1 + 1, bs2 + 1, ((*bs1 / DM_BITS_PER_INT) + 1) * sizeof(int))
620*86d7f5d3SJohn Marino 
621*86d7f5d3SJohn Marino /* Returns number of set bits */
hweight32(uint32_t i)622*86d7f5d3SJohn Marino static inline unsigned hweight32(uint32_t i)
623*86d7f5d3SJohn Marino {
624*86d7f5d3SJohn Marino 	unsigned r = (i & 0x55555555) + ((i >> 1) & 0x55555555);
625*86d7f5d3SJohn Marino 
626*86d7f5d3SJohn Marino 	r =    (r & 0x33333333) + ((r >>  2) & 0x33333333);
627*86d7f5d3SJohn Marino 	r =    (r & 0x0F0F0F0F) + ((r >>  4) & 0x0F0F0F0F);
628*86d7f5d3SJohn Marino 	r =    (r & 0x00FF00FF) + ((r >>  8) & 0x00FF00FF);
629*86d7f5d3SJohn Marino 	return (r & 0x0000FFFF) + ((r >> 16) & 0x0000FFFF);
630*86d7f5d3SJohn Marino }
631*86d7f5d3SJohn Marino 
632*86d7f5d3SJohn Marino /****************
633*86d7f5d3SJohn Marino  * hash functions
634*86d7f5d3SJohn Marino  ****************/
635*86d7f5d3SJohn Marino 
636*86d7f5d3SJohn Marino struct dm_hash_table;
637*86d7f5d3SJohn Marino struct dm_hash_node;
638*86d7f5d3SJohn Marino 
639*86d7f5d3SJohn Marino typedef void (*dm_hash_iterate_fn) (void *data);
640*86d7f5d3SJohn Marino 
641*86d7f5d3SJohn Marino struct dm_hash_table *dm_hash_create(unsigned size_hint);
642*86d7f5d3SJohn Marino void dm_hash_destroy(struct dm_hash_table *t);
643*86d7f5d3SJohn Marino void dm_hash_wipe(struct dm_hash_table *t);
644*86d7f5d3SJohn Marino 
645*86d7f5d3SJohn Marino void *dm_hash_lookup(struct dm_hash_table *t, const char *key);
646*86d7f5d3SJohn Marino int dm_hash_insert(struct dm_hash_table *t, const char *key, void *data);
647*86d7f5d3SJohn Marino void dm_hash_remove(struct dm_hash_table *t, const char *key);
648*86d7f5d3SJohn Marino 
649*86d7f5d3SJohn Marino void *dm_hash_lookup_binary(struct dm_hash_table *t, const char *key, uint32_t len);
650*86d7f5d3SJohn Marino int dm_hash_insert_binary(struct dm_hash_table *t, const char *key, uint32_t len,
651*86d7f5d3SJohn Marino 		       void *data);
652*86d7f5d3SJohn Marino void dm_hash_remove_binary(struct dm_hash_table *t, const char *key, uint32_t len);
653*86d7f5d3SJohn Marino 
654*86d7f5d3SJohn Marino unsigned dm_hash_get_num_entries(struct dm_hash_table *t);
655*86d7f5d3SJohn Marino void dm_hash_iter(struct dm_hash_table *t, dm_hash_iterate_fn f);
656*86d7f5d3SJohn Marino 
657*86d7f5d3SJohn Marino char *dm_hash_get_key(struct dm_hash_table *t, struct dm_hash_node *n);
658*86d7f5d3SJohn Marino void *dm_hash_get_data(struct dm_hash_table *t, struct dm_hash_node *n);
659*86d7f5d3SJohn Marino struct dm_hash_node *dm_hash_get_first(struct dm_hash_table *t);
660*86d7f5d3SJohn Marino struct dm_hash_node *dm_hash_get_next(struct dm_hash_table *t, struct dm_hash_node *n);
661*86d7f5d3SJohn Marino 
662*86d7f5d3SJohn Marino #define dm_hash_iterate(v, h) \
663*86d7f5d3SJohn Marino 	for (v = dm_hash_get_first(h); v; \
664*86d7f5d3SJohn Marino 	     v = dm_hash_get_next(h, v))
665*86d7f5d3SJohn Marino 
666*86d7f5d3SJohn Marino /****************
667*86d7f5d3SJohn Marino  * list functions
668*86d7f5d3SJohn Marino  ****************/
669*86d7f5d3SJohn Marino 
670*86d7f5d3SJohn Marino /*
671*86d7f5d3SJohn Marino  * A list consists of a list head plus elements.
672*86d7f5d3SJohn Marino  * Each element has 'next' and 'previous' pointers.
673*86d7f5d3SJohn Marino  * The list head's pointers point to the first and the last element.
674*86d7f5d3SJohn Marino  */
675*86d7f5d3SJohn Marino 
676*86d7f5d3SJohn Marino struct dm_list {
677*86d7f5d3SJohn Marino 	struct dm_list *n, *p;
678*86d7f5d3SJohn Marino };
679*86d7f5d3SJohn Marino 
680*86d7f5d3SJohn Marino /*
681*86d7f5d3SJohn Marino  * Initialise a list before use.
682*86d7f5d3SJohn Marino  * The list head's next and previous pointers point back to itself.
683*86d7f5d3SJohn Marino  */
684*86d7f5d3SJohn Marino #define DM_LIST_INIT(name)	struct dm_list name = { &(name), &(name) }
685*86d7f5d3SJohn Marino void dm_list_init(struct dm_list *head);
686*86d7f5d3SJohn Marino 
687*86d7f5d3SJohn Marino /*
688*86d7f5d3SJohn Marino  * Insert an element before 'head'.
689*86d7f5d3SJohn Marino  * If 'head' is the list head, this adds an element to the end of the list.
690*86d7f5d3SJohn Marino  */
691*86d7f5d3SJohn Marino void dm_list_add(struct dm_list *head, struct dm_list *elem);
692*86d7f5d3SJohn Marino 
693*86d7f5d3SJohn Marino /*
694*86d7f5d3SJohn Marino  * Insert an element after 'head'.
695*86d7f5d3SJohn Marino  * If 'head' is the list head, this adds an element to the front of the list.
696*86d7f5d3SJohn Marino  */
697*86d7f5d3SJohn Marino void dm_list_add_h(struct dm_list *head, struct dm_list *elem);
698*86d7f5d3SJohn Marino 
699*86d7f5d3SJohn Marino /*
700*86d7f5d3SJohn Marino  * Delete an element from its list.
701*86d7f5d3SJohn Marino  * Note that this doesn't change the element itself - it may still be safe
702*86d7f5d3SJohn Marino  * to follow its pointers.
703*86d7f5d3SJohn Marino  */
704*86d7f5d3SJohn Marino void dm_list_del(struct dm_list *elem);
705*86d7f5d3SJohn Marino 
706*86d7f5d3SJohn Marino /*
707*86d7f5d3SJohn Marino  * Remove an element from existing list and insert before 'head'.
708*86d7f5d3SJohn Marino  */
709*86d7f5d3SJohn Marino void dm_list_move(struct dm_list *head, struct dm_list *elem);
710*86d7f5d3SJohn Marino 
711*86d7f5d3SJohn Marino /*
712*86d7f5d3SJohn Marino  * Is the list empty?
713*86d7f5d3SJohn Marino  */
714*86d7f5d3SJohn Marino int dm_list_empty(const struct dm_list *head);
715*86d7f5d3SJohn Marino 
716*86d7f5d3SJohn Marino /*
717*86d7f5d3SJohn Marino  * Is this the first element of the list?
718*86d7f5d3SJohn Marino  */
719*86d7f5d3SJohn Marino int dm_list_start(const struct dm_list *head, const struct dm_list *elem);
720*86d7f5d3SJohn Marino 
721*86d7f5d3SJohn Marino /*
722*86d7f5d3SJohn Marino  * Is this the last element of the list?
723*86d7f5d3SJohn Marino  */
724*86d7f5d3SJohn Marino int dm_list_end(const struct dm_list *head, const struct dm_list *elem);
725*86d7f5d3SJohn Marino 
726*86d7f5d3SJohn Marino /*
727*86d7f5d3SJohn Marino  * Return first element of the list or NULL if empty
728*86d7f5d3SJohn Marino  */
729*86d7f5d3SJohn Marino struct dm_list *dm_list_first(const struct dm_list *head);
730*86d7f5d3SJohn Marino 
731*86d7f5d3SJohn Marino /*
732*86d7f5d3SJohn Marino  * Return last element of the list or NULL if empty
733*86d7f5d3SJohn Marino  */
734*86d7f5d3SJohn Marino struct dm_list *dm_list_last(const struct dm_list *head);
735*86d7f5d3SJohn Marino 
736*86d7f5d3SJohn Marino /*
737*86d7f5d3SJohn Marino  * Return the previous element of the list, or NULL if we've reached the start.
738*86d7f5d3SJohn Marino  */
739*86d7f5d3SJohn Marino struct dm_list *dm_list_prev(const struct dm_list *head, const struct dm_list *elem);
740*86d7f5d3SJohn Marino 
741*86d7f5d3SJohn Marino /*
742*86d7f5d3SJohn Marino  * Return the next element of the list, or NULL if we've reached the end.
743*86d7f5d3SJohn Marino  */
744*86d7f5d3SJohn Marino struct dm_list *dm_list_next(const struct dm_list *head, const struct dm_list *elem);
745*86d7f5d3SJohn Marino 
746*86d7f5d3SJohn Marino /*
747*86d7f5d3SJohn Marino  * Given the address v of an instance of 'struct dm_list' called 'head'
748*86d7f5d3SJohn Marino  * contained in a structure of type t, return the containing structure.
749*86d7f5d3SJohn Marino  */
750*86d7f5d3SJohn Marino #define dm_list_struct_base(v, t, head) \
751*86d7f5d3SJohn Marino     ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->head))
752*86d7f5d3SJohn Marino 
753*86d7f5d3SJohn Marino /*
754*86d7f5d3SJohn Marino  * Given the address v of an instance of 'struct dm_list list' contained in
755*86d7f5d3SJohn Marino  * a structure of type t, return the containing structure.
756*86d7f5d3SJohn Marino  */
757*86d7f5d3SJohn Marino #define dm_list_item(v, t) dm_list_struct_base((v), t, list)
758*86d7f5d3SJohn Marino 
759*86d7f5d3SJohn Marino /*
760*86d7f5d3SJohn Marino  * Given the address v of one known element e in a known structure of type t,
761*86d7f5d3SJohn Marino  * return another element f.
762*86d7f5d3SJohn Marino  */
763*86d7f5d3SJohn Marino #define dm_struct_field(v, t, e, f) \
764*86d7f5d3SJohn Marino     (((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f)
765*86d7f5d3SJohn Marino 
766*86d7f5d3SJohn Marino /*
767*86d7f5d3SJohn Marino  * Given the address v of a known element e in a known structure of type t,
768*86d7f5d3SJohn Marino  * return the list head 'list'
769*86d7f5d3SJohn Marino  */
770*86d7f5d3SJohn Marino #define dm_list_head(v, t, e) dm_struct_field(v, t, e, list)
771*86d7f5d3SJohn Marino 
772*86d7f5d3SJohn Marino /*
773*86d7f5d3SJohn Marino  * Set v to each element of a list in turn.
774*86d7f5d3SJohn Marino  */
775*86d7f5d3SJohn Marino #define dm_list_iterate(v, head) \
776*86d7f5d3SJohn Marino 	for (v = (head)->n; v != head; v = v->n)
777*86d7f5d3SJohn Marino 
778*86d7f5d3SJohn Marino /*
779*86d7f5d3SJohn Marino  * Set v to each element in a list in turn, starting from the element
780*86d7f5d3SJohn Marino  * in front of 'start'.
781*86d7f5d3SJohn Marino  * You can use this to 'unwind' a list_iterate and back out actions on
782*86d7f5d3SJohn Marino  * already-processed elements.
783*86d7f5d3SJohn Marino  * If 'start' is 'head' it walks the list backwards.
784*86d7f5d3SJohn Marino  */
785*86d7f5d3SJohn Marino #define dm_list_uniterate(v, head, start) \
786*86d7f5d3SJohn Marino 	for (v = (start)->p; v != head; v = v->p)
787*86d7f5d3SJohn Marino 
788*86d7f5d3SJohn Marino /*
789*86d7f5d3SJohn Marino  * A safe way to walk a list and delete and free some elements along
790*86d7f5d3SJohn Marino  * the way.
791*86d7f5d3SJohn Marino  * t must be defined as a temporary variable of the same type as v.
792*86d7f5d3SJohn Marino  */
793*86d7f5d3SJohn Marino #define dm_list_iterate_safe(v, t, head) \
794*86d7f5d3SJohn Marino 	for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
795*86d7f5d3SJohn Marino 
796*86d7f5d3SJohn Marino /*
797*86d7f5d3SJohn Marino  * Walk a list, setting 'v' in turn to the containing structure of each item.
798*86d7f5d3SJohn Marino  * The containing structure should be the same type as 'v'.
799*86d7f5d3SJohn Marino  * The 'struct dm_list' variable within the containing structure is 'field'.
800*86d7f5d3SJohn Marino  */
801*86d7f5d3SJohn Marino #define dm_list_iterate_items_gen(v, head, field) \
802*86d7f5d3SJohn Marino 	for (v = dm_list_struct_base((head)->n, typeof(*v), field); \
803*86d7f5d3SJohn Marino 	     &v->field != (head); \
804*86d7f5d3SJohn Marino 	     v = dm_list_struct_base(v->field.n, typeof(*v), field))
805*86d7f5d3SJohn Marino 
806*86d7f5d3SJohn Marino /*
807*86d7f5d3SJohn Marino  * Walk a list, setting 'v' in turn to the containing structure of each item.
808*86d7f5d3SJohn Marino  * The containing structure should be the same type as 'v'.
809*86d7f5d3SJohn Marino  * The list should be 'struct dm_list list' within the containing structure.
810*86d7f5d3SJohn Marino  */
811*86d7f5d3SJohn Marino #define dm_list_iterate_items(v, head) dm_list_iterate_items_gen(v, (head), list)
812*86d7f5d3SJohn Marino 
813*86d7f5d3SJohn Marino /*
814*86d7f5d3SJohn Marino  * Walk a list, setting 'v' in turn to the containing structure of each item.
815*86d7f5d3SJohn Marino  * The containing structure should be the same type as 'v'.
816*86d7f5d3SJohn Marino  * The 'struct dm_list' variable within the containing structure is 'field'.
817*86d7f5d3SJohn Marino  * t must be defined as a temporary variable of the same type as v.
818*86d7f5d3SJohn Marino  */
819*86d7f5d3SJohn Marino #define dm_list_iterate_items_gen_safe(v, t, head, field) \
820*86d7f5d3SJohn Marino 	for (v = dm_list_struct_base((head)->n, typeof(*v), field), \
821*86d7f5d3SJohn Marino 	     t = dm_list_struct_base(v->field.n, typeof(*v), field); \
822*86d7f5d3SJohn Marino 	     &v->field != (head); \
823*86d7f5d3SJohn Marino 	     v = t, t = dm_list_struct_base(v->field.n, typeof(*v), field))
824*86d7f5d3SJohn Marino /*
825*86d7f5d3SJohn Marino  * Walk a list, setting 'v' in turn to the containing structure of each item.
826*86d7f5d3SJohn Marino  * The containing structure should be the same type as 'v'.
827*86d7f5d3SJohn Marino  * The list should be 'struct dm_list list' within the containing structure.
828*86d7f5d3SJohn Marino  * t must be defined as a temporary variable of the same type as v.
829*86d7f5d3SJohn Marino  */
830*86d7f5d3SJohn Marino #define dm_list_iterate_items_safe(v, t, head) \
831*86d7f5d3SJohn Marino 	dm_list_iterate_items_gen_safe(v, t, (head), list)
832*86d7f5d3SJohn Marino 
833*86d7f5d3SJohn Marino /*
834*86d7f5d3SJohn Marino  * Walk a list backwards, setting 'v' in turn to the containing structure
835*86d7f5d3SJohn Marino  * of each item.
836*86d7f5d3SJohn Marino  * The containing structure should be the same type as 'v'.
837*86d7f5d3SJohn Marino  * The 'struct dm_list' variable within the containing structure is 'field'.
838*86d7f5d3SJohn Marino  */
839*86d7f5d3SJohn Marino #define dm_list_iterate_back_items_gen(v, head, field) \
840*86d7f5d3SJohn Marino 	for (v = dm_list_struct_base((head)->p, typeof(*v), field); \
841*86d7f5d3SJohn Marino 	     &v->field != (head); \
842*86d7f5d3SJohn Marino 	     v = dm_list_struct_base(v->field.p, typeof(*v), field))
843*86d7f5d3SJohn Marino 
844*86d7f5d3SJohn Marino /*
845*86d7f5d3SJohn Marino  * Walk a list backwards, setting 'v' in turn to the containing structure
846*86d7f5d3SJohn Marino  * of each item.
847*86d7f5d3SJohn Marino  * The containing structure should be the same type as 'v'.
848*86d7f5d3SJohn Marino  * The list should be 'struct dm_list list' within the containing structure.
849*86d7f5d3SJohn Marino  */
850*86d7f5d3SJohn Marino #define dm_list_iterate_back_items(v, head) dm_list_iterate_back_items_gen(v, (head), list)
851*86d7f5d3SJohn Marino 
852*86d7f5d3SJohn Marino /*
853*86d7f5d3SJohn Marino  * Return the number of elements in a list by walking it.
854*86d7f5d3SJohn Marino  */
855*86d7f5d3SJohn Marino unsigned int dm_list_size(const struct dm_list *head);
856*86d7f5d3SJohn Marino 
857*86d7f5d3SJohn Marino /*********
858*86d7f5d3SJohn Marino  * selinux
859*86d7f5d3SJohn Marino  *********/
860*86d7f5d3SJohn Marino int dm_set_selinux_context(const char *path, mode_t mode);
861*86d7f5d3SJohn Marino 
862*86d7f5d3SJohn Marino /*********************
863*86d7f5d3SJohn Marino  * string manipulation
864*86d7f5d3SJohn Marino  *********************/
865*86d7f5d3SJohn Marino 
866*86d7f5d3SJohn Marino /*
867*86d7f5d3SJohn Marino  * Break up the name of a mapped device into its constituent
868*86d7f5d3SJohn Marino  * Volume Group, Logical Volume and Layer (if present).
869*86d7f5d3SJohn Marino  * If mem is supplied, the result is allocated from the mempool.
870*86d7f5d3SJohn Marino  * Otherwise the strings are changed in situ.
871*86d7f5d3SJohn Marino  */
872*86d7f5d3SJohn Marino int dm_split_lvm_name(struct dm_pool *mem, const char *dmname,
873*86d7f5d3SJohn Marino 		      char **vgname, char **lvname, char **layer);
874*86d7f5d3SJohn Marino 
875*86d7f5d3SJohn Marino /*
876*86d7f5d3SJohn Marino  * Destructively split buffer into NULL-separated words in argv.
877*86d7f5d3SJohn Marino  * Returns number of words.
878*86d7f5d3SJohn Marino  */
879*86d7f5d3SJohn Marino int dm_split_words(char *buffer, unsigned max,
880*86d7f5d3SJohn Marino 		   unsigned ignore_comments, /* Not implemented */
881*86d7f5d3SJohn Marino 		   char **argv);
882*86d7f5d3SJohn Marino 
883*86d7f5d3SJohn Marino /*
884*86d7f5d3SJohn Marino  * Returns -1 if buffer too small
885*86d7f5d3SJohn Marino  */
886*86d7f5d3SJohn Marino int dm_snprintf(char *buf, size_t bufsize, const char *format, ...);
887*86d7f5d3SJohn Marino 
888*86d7f5d3SJohn Marino /*
889*86d7f5d3SJohn Marino  * Returns pointer to the last component of the path.
890*86d7f5d3SJohn Marino  */
891*86d7f5d3SJohn Marino char *dm_basename(const char *path);
892*86d7f5d3SJohn Marino 
893*86d7f5d3SJohn Marino /**************************
894*86d7f5d3SJohn Marino  * file/stream manipulation
895*86d7f5d3SJohn Marino  **************************/
896*86d7f5d3SJohn Marino 
897*86d7f5d3SJohn Marino /*
898*86d7f5d3SJohn Marino  * Create a directory (with parent directories if necessary).
899*86d7f5d3SJohn Marino  * Returns 1 on success, 0 on failure.
900*86d7f5d3SJohn Marino  */
901*86d7f5d3SJohn Marino int dm_create_dir(const char *dir);
902*86d7f5d3SJohn Marino 
903*86d7f5d3SJohn Marino /*
904*86d7f5d3SJohn Marino  * Close a stream, with nicer error checking than fclose's.
905*86d7f5d3SJohn Marino  * Derived from gnulib's close-stream.c.
906*86d7f5d3SJohn Marino  *
907*86d7f5d3SJohn Marino  * Close "stream".  Return 0 if successful, and EOF (setting errno)
908*86d7f5d3SJohn Marino  * otherwise.  Upon failure, set errno to 0 if the error number
909*86d7f5d3SJohn Marino  * cannot be determined.  Useful mainly for writable streams.
910*86d7f5d3SJohn Marino  */
911*86d7f5d3SJohn Marino int dm_fclose(FILE *stream);
912*86d7f5d3SJohn Marino 
913*86d7f5d3SJohn Marino /*
914*86d7f5d3SJohn Marino  * Returns size of a buffer which is allocated with dm_malloc.
915*86d7f5d3SJohn Marino  * Pointer to the buffer is stored in *buf.
916*86d7f5d3SJohn Marino  * Returns -1 on failure leaving buf undefined.
917*86d7f5d3SJohn Marino  */
918*86d7f5d3SJohn Marino int dm_asprintf(char **buf, const char *format, ...);
919*86d7f5d3SJohn Marino 
920*86d7f5d3SJohn Marino /*********************
921*86d7f5d3SJohn Marino  * regular expressions
922*86d7f5d3SJohn Marino  *********************/
923*86d7f5d3SJohn Marino struct dm_regex;
924*86d7f5d3SJohn Marino 
925*86d7f5d3SJohn Marino /*
926*86d7f5d3SJohn Marino  * Initialise an array of num patterns for matching.
927*86d7f5d3SJohn Marino  * Uses memory from mem.
928*86d7f5d3SJohn Marino  */
929*86d7f5d3SJohn Marino struct dm_regex *dm_regex_create(struct dm_pool *mem, const char **patterns,
930*86d7f5d3SJohn Marino 				 unsigned num_patterns);
931*86d7f5d3SJohn Marino 
932*86d7f5d3SJohn Marino /*
933*86d7f5d3SJohn Marino  * Match string s against the patterns.
934*86d7f5d3SJohn Marino  * Returns the index of the highest pattern in the array that matches,
935*86d7f5d3SJohn Marino  * or -1 if none match.
936*86d7f5d3SJohn Marino  */
937*86d7f5d3SJohn Marino int dm_regex_match(struct dm_regex *regex, const char *s);
938*86d7f5d3SJohn Marino 
939*86d7f5d3SJohn Marino /*********************
940*86d7f5d3SJohn Marino  * reporting functions
941*86d7f5d3SJohn Marino  *********************/
942*86d7f5d3SJohn Marino 
943*86d7f5d3SJohn Marino struct dm_report_object_type {
944*86d7f5d3SJohn Marino 	uint32_t id;			/* Powers of 2 */
945*86d7f5d3SJohn Marino 	const char *desc;
946*86d7f5d3SJohn Marino 	const char *prefix;		/* field id string prefix (optional) */
947*86d7f5d3SJohn Marino 	void *(*data_fn)(void *object);	/* callback from report_object() */
948*86d7f5d3SJohn Marino };
949*86d7f5d3SJohn Marino 
950*86d7f5d3SJohn Marino struct dm_report_field;
951*86d7f5d3SJohn Marino 
952*86d7f5d3SJohn Marino /*
953*86d7f5d3SJohn Marino  * dm_report_field_type flags
954*86d7f5d3SJohn Marino  */
955*86d7f5d3SJohn Marino #define DM_REPORT_FIELD_MASK		0x000000FF
956*86d7f5d3SJohn Marino #define DM_REPORT_FIELD_ALIGN_MASK	0x0000000F
957*86d7f5d3SJohn Marino #define DM_REPORT_FIELD_ALIGN_LEFT	0x00000001
958*86d7f5d3SJohn Marino #define DM_REPORT_FIELD_ALIGN_RIGHT	0x00000002
959*86d7f5d3SJohn Marino #define DM_REPORT_FIELD_TYPE_MASK	0x000000F0
960*86d7f5d3SJohn Marino #define DM_REPORT_FIELD_TYPE_STRING	0x00000010
961*86d7f5d3SJohn Marino #define DM_REPORT_FIELD_TYPE_NUMBER	0x00000020
962*86d7f5d3SJohn Marino 
963*86d7f5d3SJohn Marino struct dm_report;
964*86d7f5d3SJohn Marino struct dm_report_field_type {
965*86d7f5d3SJohn Marino 	uint32_t type;		/* object type id */
966*86d7f5d3SJohn Marino 	uint32_t flags;		/* DM_REPORT_FIELD_* */
967*86d7f5d3SJohn Marino 	uint32_t offset;	/* byte offset in the object */
968*86d7f5d3SJohn Marino 	int32_t width;		/* default width */
969*86d7f5d3SJohn Marino 	const char id[32];	/* string used to specify the field */
970*86d7f5d3SJohn Marino 	const char heading[32];	/* string printed in header */
971*86d7f5d3SJohn Marino 	int (*report_fn)(struct dm_report *rh, struct dm_pool *mem,
972*86d7f5d3SJohn Marino 			 struct dm_report_field *field, const void *data,
973*86d7f5d3SJohn Marino 			 void *private);
974*86d7f5d3SJohn Marino 	const char *desc;	/* description of the field */
975*86d7f5d3SJohn Marino };
976*86d7f5d3SJohn Marino 
977*86d7f5d3SJohn Marino /*
978*86d7f5d3SJohn Marino  * dm_report_init output_flags
979*86d7f5d3SJohn Marino  */
980*86d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_MASK			0x000000FF
981*86d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_ALIGNED		0x00000001
982*86d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_BUFFERED		0x00000002
983*86d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_HEADINGS		0x00000004
984*86d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_FIELD_NAME_PREFIX	0x00000008
985*86d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_FIELD_UNQUOTED		0x00000010
986*86d7f5d3SJohn Marino #define DM_REPORT_OUTPUT_COLUMNS_AS_ROWS	0x00000020
987*86d7f5d3SJohn Marino 
988*86d7f5d3SJohn Marino struct dm_report *dm_report_init(uint32_t *report_types,
989*86d7f5d3SJohn Marino 				 const struct dm_report_object_type *types,
990*86d7f5d3SJohn Marino 				 const struct dm_report_field_type *fields,
991*86d7f5d3SJohn Marino 				 const char *output_fields,
992*86d7f5d3SJohn Marino 				 const char *output_separator,
993*86d7f5d3SJohn Marino 				 uint32_t output_flags,
994*86d7f5d3SJohn Marino 				 const char *sort_keys,
995*86d7f5d3SJohn Marino 				 void *private);
996*86d7f5d3SJohn Marino int dm_report_object(struct dm_report *rh, void *object);
997*86d7f5d3SJohn Marino int dm_report_output(struct dm_report *rh);
998*86d7f5d3SJohn Marino void dm_report_free(struct dm_report *rh);
999*86d7f5d3SJohn Marino 
1000*86d7f5d3SJohn Marino /*
1001*86d7f5d3SJohn Marino  * Prefix added to each field name with DM_REPORT_OUTPUT_FIELD_NAME_PREFIX
1002*86d7f5d3SJohn Marino  */
1003*86d7f5d3SJohn Marino int dm_report_set_output_field_name_prefix(struct dm_report *rh,
1004*86d7f5d3SJohn Marino 					   const char *report_prefix);
1005*86d7f5d3SJohn Marino 
1006*86d7f5d3SJohn Marino /*
1007*86d7f5d3SJohn Marino  * Report functions are provided for simple data types.
1008*86d7f5d3SJohn Marino  * They take care of allocating copies of the data.
1009*86d7f5d3SJohn Marino  */
1010*86d7f5d3SJohn Marino int dm_report_field_string(struct dm_report *rh, struct dm_report_field *field,
1011*86d7f5d3SJohn Marino 			   const char **data);
1012*86d7f5d3SJohn Marino int dm_report_field_int32(struct dm_report *rh, struct dm_report_field *field,
1013*86d7f5d3SJohn Marino 			  const int32_t *data);
1014*86d7f5d3SJohn Marino int dm_report_field_uint32(struct dm_report *rh, struct dm_report_field *field,
1015*86d7f5d3SJohn Marino 			   const uint32_t *data);
1016*86d7f5d3SJohn Marino int dm_report_field_int(struct dm_report *rh, struct dm_report_field *field,
1017*86d7f5d3SJohn Marino 			const int *data);
1018*86d7f5d3SJohn Marino int dm_report_field_uint64(struct dm_report *rh, struct dm_report_field *field,
1019*86d7f5d3SJohn Marino 			   const uint64_t *data);
1020*86d7f5d3SJohn Marino 
1021*86d7f5d3SJohn Marino /*
1022*86d7f5d3SJohn Marino  * For custom fields, allocate the data in 'mem' and use
1023*86d7f5d3SJohn Marino  * dm_report_field_set_value().
1024*86d7f5d3SJohn Marino  * 'sortvalue' may be NULL if it matches 'value'
1025*86d7f5d3SJohn Marino  */
1026*86d7f5d3SJohn Marino void dm_report_field_set_value(struct dm_report_field *field, const void *value,
1027*86d7f5d3SJohn Marino 			       const void *sortvalue);
1028*86d7f5d3SJohn Marino 
1029*86d7f5d3SJohn Marino /* Cookie prefixes.
1030*86d7f5d3SJohn Marino  * The cookie value consists of a prefix (16 bits) and a base (16 bits).
1031*86d7f5d3SJohn Marino  * We can use the prefix to store the flags. These flags are sent to
1032*86d7f5d3SJohn Marino  * kernel within given dm task. When returned back to userspace in
1033*86d7f5d3SJohn Marino  * DM_COOKIE udev environment variable, we can control several aspects
1034*86d7f5d3SJohn Marino  * of udev rules we use by decoding the cookie prefix. When doing the
1035*86d7f5d3SJohn Marino  * notification, we replace the cookie prefix with DM_COOKIE_MAGIC,
1036*86d7f5d3SJohn Marino  * so we notify the right semaphore.
1037*86d7f5d3SJohn Marino  * It is still possible to use cookies for passing the flags to udev
1038*86d7f5d3SJohn Marino  * rules even when udev_sync is disabled. The base part of the cookie
1039*86d7f5d3SJohn Marino  * will be zero (there's no notification semaphore) and prefix will be
1040*86d7f5d3SJohn Marino  * set then. However, having udev_sync enabled is highly recommended.
1041*86d7f5d3SJohn Marino  */
1042*86d7f5d3SJohn Marino #define DM_COOKIE_MAGIC 0x0D4D
1043*86d7f5d3SJohn Marino #define DM_UDEV_FLAGS_MASK 0xFFFF0000
1044*86d7f5d3SJohn Marino #define DM_UDEV_FLAGS_SHIFT 16
1045*86d7f5d3SJohn Marino 
1046*86d7f5d3SJohn Marino /*
1047*86d7f5d3SJohn Marino  * DM_UDEV_DISABLE_DM_RULES_FLAG is set in case we need to disable
1048*86d7f5d3SJohn Marino  * basic device-mapper udev rules that create symlinks in /dev/<DM_DIR>
1049*86d7f5d3SJohn Marino  * directory. However, we can't reliably prevent creating default
1050*86d7f5d3SJohn Marino  * nodes by udev (commonly /dev/dm-X, where X is a number).
1051*86d7f5d3SJohn Marino  */
1052*86d7f5d3SJohn Marino #define DM_UDEV_DISABLE_DM_RULES_FLAG 0x0001
1053*86d7f5d3SJohn Marino /*
1054*86d7f5d3SJohn Marino  * DM_UDEV_DISABLE_SUBSYTEM_RULES_FLAG is set in case we need to disable
1055*86d7f5d3SJohn Marino  * subsystem udev rules, but still we need the general DM udev rules to
1056*86d7f5d3SJohn Marino  * be applied (to create the nodes and symlinks under /dev and /dev/disk).
1057*86d7f5d3SJohn Marino  */
1058*86d7f5d3SJohn Marino #define DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG 0x0002
1059*86d7f5d3SJohn Marino /*
1060*86d7f5d3SJohn Marino  * DM_UDEV_DISABLE_DISK_RULES_FLAG is set in case we need to disable
1061*86d7f5d3SJohn Marino  * general DM rules that set symlinks in /dev/disk directory.
1062*86d7f5d3SJohn Marino  */
1063*86d7f5d3SJohn Marino #define DM_UDEV_DISABLE_DISK_RULES_FLAG 0x0004
1064*86d7f5d3SJohn Marino /*
1065*86d7f5d3SJohn Marino  * DM_UDEV_DISABLE_OTHER_RULES_FLAG is set in case we need to disable
1066*86d7f5d3SJohn Marino  * all the other rules that are not general device-mapper nor subsystem
1067*86d7f5d3SJohn Marino  * related (the rules belong to other software or packages). All foreign
1068*86d7f5d3SJohn Marino  * rules should check this flag directly and they should ignore further
1069*86d7f5d3SJohn Marino  * rule processing for such event.
1070*86d7f5d3SJohn Marino  */
1071*86d7f5d3SJohn Marino #define DM_UDEV_DISABLE_OTHER_RULES_FLAG 0x0008
1072*86d7f5d3SJohn Marino /*
1073*86d7f5d3SJohn Marino  * DM_UDEV_LOW_PRIORITY_FLAG is set in case we need to instruct the
1074*86d7f5d3SJohn Marino  * udev rules to give low priority to the device that is currently
1075*86d7f5d3SJohn Marino  * processed. For example, this provides a way to select which symlinks
1076*86d7f5d3SJohn Marino  * could be overwritten by high priority ones if their names are equal.
1077*86d7f5d3SJohn Marino  * Common situation is a name based on FS UUID while using origin and
1078*86d7f5d3SJohn Marino  * snapshot devices.
1079*86d7f5d3SJohn Marino  */
1080*86d7f5d3SJohn Marino #define DM_UDEV_LOW_PRIORITY_FLAG 0x0010
1081*86d7f5d3SJohn Marino 
1082*86d7f5d3SJohn Marino int dm_cookie_supported(void);
1083*86d7f5d3SJohn Marino 
1084*86d7f5d3SJohn Marino /*
1085*86d7f5d3SJohn Marino  * Udev synchronisation functions.
1086*86d7f5d3SJohn Marino  */
1087*86d7f5d3SJohn Marino void dm_udev_set_sync_support(int sync_with_udev);
1088*86d7f5d3SJohn Marino int dm_udev_get_sync_support(void);
1089*86d7f5d3SJohn Marino int dm_udev_complete(uint32_t cookie);
1090*86d7f5d3SJohn Marino int dm_udev_wait(uint32_t cookie);
1091*86d7f5d3SJohn Marino 
1092*86d7f5d3SJohn Marino #define DM_DEV_DIR_UMASK 0022
1093*86d7f5d3SJohn Marino 
1094*86d7f5d3SJohn Marino #endif				/* LIB_DEVICE_MAPPER_H */
1095