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