2001-11-21 15:47:42 +03:00
/*
2004-03-30 23:08:57 +04:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2007-08-21 20:26:07 +04:00
* Copyright ( C ) 2004 - 2007 Red Hat , Inc . All rights reserved .
2001-11-21 15:47:42 +03:00
*
2004-03-30 23:08:57 +04:00
* This file is part of the device - mapper userspace tools .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v .2 .1 .
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
2001-11-21 15:47:42 +03:00
*/
# ifndef LIB_DEVICE_MAPPER_H
# define LIB_DEVICE_MAPPER_H
2001-12-05 19:41:52 +03:00
# include <inttypes.h>
2006-08-21 16:52:39 +04:00
# include <stdarg.h>
2002-01-15 18:21:57 +03:00
# include <sys/types.h>
2003-11-12 20:30:32 +03:00
# ifdef linux
# include <linux / types.h>
# endif
2001-12-05 19:41:52 +03:00
2005-10-17 02:57:20 +04:00
# include <limits.h>
# include <string.h>
# include <stdlib.h>
2007-07-24 18:15:45 +04:00
# include <stdio.h>
2005-10-17 02:57:20 +04:00
2005-11-09 17:10:50 +03:00
/*****************************************************************
2009-07-10 13:59:37 +04:00
* The first section of this file provides direct access to the
* individual device - mapper ioctls . Since it is quite laborious to
* build the ioctl arguments for the device - mapper , people are
* encouraged to use this library .
2005-11-09 17:10:50 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-21 15:47:42 +03:00
/*
2009-07-10 13:59:37 +04:00
* The library user may wish to register their own
* logging function . By default errors go to stderr .
* Use dm_log_with_errno_init ( NULL ) to restore the default log fn .
2001-11-21 15:47:42 +03:00
*/
2009-07-10 13:59:37 +04:00
typedef void ( * dm_log_with_errno_fn ) ( int level , const char * file , int line ,
int dm_errno , const char * f , . . . )
__attribute__ ( ( format ( printf , 5 , 6 ) ) ) ;
void dm_log_with_errno_init ( dm_log_with_errno_fn fn ) ;
void dm_log_init_verbose ( int level ) ;
/*
* Original version of this function .
* dm_errno is set to 0.
*
* Deprecated : Use the _with_errno_ versions above instead .
*/
2002-03-07 23:56:10 +03:00
typedef void ( * dm_log_fn ) ( int level , const char * file , int line ,
2006-01-31 17:50:38 +03:00
const char * f , . . . )
__attribute__ ( ( format ( printf , 4 , 5 ) ) ) ;
2009-07-10 13:59:37 +04:00
void dm_log_init ( dm_log_fn fn ) ;
2001-11-21 15:47:42 +03:00
/*
2009-07-10 13:59:37 +04:00
* For backward - compatibility , indicate that dm_log_init ( ) was used
* to set a non - default value of dm_log ( ) .
2001-11-21 15:47:42 +03:00
*/
2009-07-10 13:59:37 +04:00
int dm_log_is_non_default ( void ) ;
2001-11-21 15:47:42 +03:00
enum {
DM_DEVICE_CREATE ,
DM_DEVICE_RELOAD ,
DM_DEVICE_REMOVE ,
2002-03-07 23:56:10 +03:00
DM_DEVICE_REMOVE_ALL ,
2001-11-21 15:47:42 +03:00
DM_DEVICE_SUSPEND ,
DM_DEVICE_RESUME ,
DM_DEVICE_INFO ,
2002-03-06 17:38:25 +03:00
DM_DEVICE_DEPS ,
2002-01-11 02:29:16 +03:00
DM_DEVICE_RENAME ,
2002-01-15 18:21:57 +03:00
DM_DEVICE_VERSION ,
2002-05-03 15:55:58 +04:00
DM_DEVICE_STATUS ,
DM_DEVICE_TABLE ,
2003-07-02 01:20:58 +04:00
DM_DEVICE_WAITEVENT ,
DM_DEVICE_LIST ,
2003-11-13 16:14:28 +03:00
DM_DEVICE_CLEAR ,
2004-01-23 17:37:47 +03:00
DM_DEVICE_MKNODES ,
2004-06-09 00:34:40 +04:00
DM_DEVICE_LIST_VERSIONS ,
2006-02-21 02:55:58 +03:00
DM_DEVICE_TARGET_MSG ,
DM_DEVICE_SET_GEOMETRY
2001-11-21 15:47:42 +03:00
} ;
2009-07-10 13:59:37 +04:00
/*
* You will need to build a struct dm_task for
* each ioctl command you want to execute .
*/
2001-11-21 15:47:42 +03:00
struct dm_task ;
struct dm_task * dm_task_create ( int type ) ;
void dm_task_destroy ( struct dm_task * dmt ) ;
int dm_task_set_name ( struct dm_task * dmt , const char * name ) ;
2002-03-12 01:44:36 +03:00
int dm_task_set_uuid ( struct dm_task * dmt , const char * uuid ) ;
2001-11-21 15:47:42 +03:00
/*
* Retrieve attributes after an info .
*/
struct dm_info {
int exists ;
int suspended ;
2003-07-02 01:20:58 +04:00
int live_table ;
int inactive_table ;
2003-03-28 21:58:59 +03:00
int32_t open_count ;
2003-04-29 15:34:23 +04:00
uint32_t event_nr ;
2003-03-28 21:58:59 +03:00
uint32_t major ;
uint32_t minor ; /* minor device number */
2002-01-03 18:12:02 +03:00
int read_only ; /* 0:read-write; 1:read-only */
2002-01-03 13:39:21 +03:00
2003-03-28 21:58:59 +03:00
int32_t target_count ;
2001-11-21 15:47:42 +03:00
} ;
2002-03-06 17:38:25 +03:00
struct dm_deps {
2003-03-28 21:58:59 +03:00
uint32_t count ;
uint32_t filler ;
uint64_t device [ 0 ] ;
2002-03-06 17:38:25 +03:00
} ;
2003-07-02 01:20:58 +04:00
struct dm_names {
uint64_t dev ;
uint32_t next ; /* Offset to next struct from start of this struct */
char name [ 0 ] ;
} ;
2004-01-23 17:37:47 +03:00
struct dm_versions {
2007-01-16 21:04:15 +03:00
uint32_t next ; /* Offset to next struct from start of this struct */
uint32_t version [ 3 ] ;
2004-01-23 17:37:47 +03:00
2007-01-16 21:04:15 +03:00
char name [ 0 ] ;
2004-01-23 17:37:47 +03:00
} ;
2002-01-17 17:13:25 +03:00
int dm_get_library_version ( char * version , size_t size ) ;
2002-03-07 23:56:10 +03:00
int dm_task_get_driver_version ( struct dm_task * dmt , char * version , size_t size ) ;
2001-11-21 15:47:42 +03:00
int dm_task_get_info ( struct dm_task * dmt , struct dm_info * dmi ) ;
2007-04-27 18:52:41 +04:00
const char * dm_task_get_name ( const struct dm_task * dmt ) ;
const char * dm_task_get_uuid ( const struct dm_task * dmt ) ;
2001-11-21 15:47:42 +03:00
2002-03-06 17:38:25 +03:00
struct dm_deps * dm_task_get_deps ( struct dm_task * dmt ) ;
2003-07-02 01:20:58 +04:00
struct dm_names * dm_task_get_names ( struct dm_task * dmt ) ;
2004-01-23 17:37:47 +03:00
struct dm_versions * dm_task_get_versions ( struct dm_task * dmt ) ;
2002-03-06 17:38:25 +03:00
2002-01-03 13:39:21 +03:00
int dm_task_set_ro ( struct dm_task * dmt ) ;
2002-01-11 02:29:16 +03:00
int dm_task_set_newname ( struct dm_task * dmt , const char * newname ) ;
2002-01-11 15:12:46 +03:00
int dm_task_set_minor ( struct dm_task * dmt , int minor ) ;
2003-04-02 23:03:00 +04:00
int dm_task_set_major ( struct dm_task * dmt , int major ) ;
2009-06-18 00:55:24 +04:00
int dm_task_set_major_minor ( struct dm_task * dmt , int major , int minor , int allow_default_major_fallback ) ;
2006-02-03 17:23:22 +03:00
int dm_task_set_uid ( struct dm_task * dmt , uid_t uid ) ;
int dm_task_set_gid ( struct dm_task * dmt , gid_t gid ) ;
int dm_task_set_mode ( struct dm_task * dmt , mode_t mode ) ;
2009-10-22 16:55:47 +04:00
int dm_task_set_cookie ( struct dm_task * dmt , uint32_t * cookie , uint16_t flags ) ;
2003-04-29 15:34:23 +04:00
int dm_task_set_event_nr ( struct dm_task * dmt , uint32_t event_nr ) ;
2006-02-21 02:55:58 +03:00
int dm_task_set_geometry ( struct dm_task * dmt , const char * cylinders , const char * heads , const char * sectors , const char * start ) ;
2004-06-09 00:34:40 +04:00
int dm_task_set_message ( struct dm_task * dmt , const char * message ) ;
int dm_task_set_sector ( struct dm_task * dmt , uint64_t sector ) ;
2006-10-12 19:42:25 +04:00
int dm_task_no_flush ( struct dm_task * dmt ) ;
2005-01-13 01:10:14 +03:00
int dm_task_no_open_count ( struct dm_task * dmt ) ;
2005-10-05 00:12:32 +04:00
int dm_task_skip_lockfs ( struct dm_task * dmt ) ;
2009-11-06 03:43:08 +03:00
int dm_task_query_inactive_table ( struct dm_task * dmt ) ;
2005-11-22 21:43:12 +03:00
int dm_task_suppress_identical_reload ( struct dm_task * dmt ) ;
2002-01-11 02:29:16 +03:00
2007-11-27 23:57:05 +03:00
/*
* Control read_ahead .
*/
# define DM_READ_AHEAD_AUTO UINT32_MAX /* Use kernel default readahead */
# define DM_READ_AHEAD_NONE 0 /* Disable readahead */
# define DM_READ_AHEAD_MINIMUM_FLAG 0x1 /* Value supplied is minimum */
2007-12-05 19:28:19 +03:00
/*
* Read ahead is set with DM_DEVICE_CREATE with a table or DM_DEVICE_RESUME .
*/
2007-11-27 23:57:05 +03:00
int dm_task_set_read_ahead ( struct dm_task * dmt , uint32_t read_ahead ,
uint32_t read_ahead_flags ) ;
2007-11-30 17:59:57 +03:00
uint32_t dm_task_get_read_ahead ( const struct dm_task * dmt ,
uint32_t * read_ahead ) ;
2007-11-27 23:57:05 +03:00
2001-11-21 15:47:42 +03:00
/*
* Use these to prepare for a create or reload .
*/
int dm_task_add_target ( struct dm_task * dmt ,
2001-12-05 19:41:52 +03:00
uint64_t start ,
2002-03-07 23:56:10 +03:00
uint64_t size , const char * ttype , const char * params ) ;
2001-11-21 15:47:42 +03:00
2003-07-02 01:20:58 +04:00
/*
2008-09-02 16:16:07 +04:00
* Format major / minor numbers correctly for input to driver .
2003-07-02 01:20:58 +04:00
*/
2008-09-02 16:16:07 +04:00
# define DM_FORMAT_DEV_BUFSIZE 13 /* Minimum bufsize to handle worst case. */
2003-07-02 01:20:58 +04:00
int dm_format_dev ( char * buf , int bufsize , uint32_t dev_major , uint32_t dev_minor ) ;
2002-05-03 15:55:58 +04:00
/* Use this to retrive target information returned from a STATUS call */
void * dm_get_next_target ( struct dm_task * dmt ,
2002-05-10 19:25:38 +04:00
void * next , uint64_t * start , uint64_t * length ,
char * * target_type , char * * params ) ;
2002-05-03 15:55:58 +04:00
2001-11-21 15:47:42 +03:00
/*
* Call this to actually run the ioctl .
*/
int dm_task_run ( struct dm_task * dmt ) ;
2005-12-02 02:11:41 +03:00
/*
* Call this to make or remove the device nodes associated with previously
* issued commands .
*/
void dm_task_update_nodes ( void ) ;
2001-11-21 15:47:42 +03:00
/*
2001-11-21 20:08:37 +03:00
* Configure the device - mapper directory
2001-11-21 15:47:42 +03:00
*/
2001-11-21 20:08:37 +03:00
int dm_set_dev_dir ( const char * dir ) ;
2001-11-21 15:47:42 +03:00
const char * dm_dir ( void ) ;
2005-10-16 18:33:22 +04:00
/*
* Determine whether a major number belongs to device - mapper or not .
*/
int dm_is_dm_major ( uint32_t major ) ;
/*
* Release library resources
*/
2003-07-02 01:20:58 +04:00
void dm_lib_release ( void ) ;
2005-05-16 19:15:34 +04:00
void dm_lib_exit ( void ) __attribute ( ( destructor ) ) ;
2003-07-02 01:20:58 +04:00
2005-10-17 02:57:20 +04:00
/*
* Use NULL for all devices .
*/
int dm_mknodes ( const char * name ) ;
2005-10-17 22:05:39 +04:00
int dm_driver_version ( char * version , size_t size ) ;
2005-10-17 02:57:20 +04:00
2005-11-09 17:10:50 +03:00
/******************************************************
* Functions to build and manipulate trees of devices *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct dm_tree ;
struct dm_tree_node ;
2005-10-16 18:33:22 +04:00
/*
* Initialise an empty dependency tree .
*
* The tree consists of a root node together with one node for each mapped
* device which has child nodes for each device referenced in its table .
*
* Every node in the tree has one or more children and one or more parents .
*
* The root node is the parent / child of every node that doesn ' t have other
* parents / children .
*/
2005-11-09 17:10:50 +03:00
struct dm_tree * dm_tree_create ( void ) ;
void dm_tree_free ( struct dm_tree * tree ) ;
2005-10-16 18:33:22 +04:00
/*
* Add nodes to the tree for a given device and all the devices it uses .
*/
2005-11-09 17:10:50 +03:00
int dm_tree_add_dev ( struct dm_tree * tree , uint32_t major , uint32_t minor ) ;
2010-01-07 22:54:21 +03:00
int dm_tree_add_dev_with_udev_flags ( struct dm_tree * tree , uint32_t major ,
uint32_t minor , uint16_t udev_flags ) ;
2005-10-16 18:33:22 +04:00
2005-11-09 01:50:11 +03:00
/*
* Add a new node to the tree if it doesn ' t already exist .
*/
2005-11-09 17:10:50 +03:00
struct dm_tree_node * dm_tree_add_new_dev ( struct dm_tree * tree ,
2007-01-16 21:04:15 +03:00
const char * name ,
const char * uuid ,
uint32_t major , uint32_t minor ,
int read_only ,
int clear_inactive ,
void * context ) ;
2009-10-22 17:00:07 +04:00
struct dm_tree_node * dm_tree_add_new_dev_with_udev_flags ( struct dm_tree * tree ,
const char * name ,
const char * uuid ,
uint32_t major ,
uint32_t minor ,
int read_only ,
int clear_inactive ,
void * context ,
uint16_t udev_flags ) ;
2005-11-09 01:50:11 +03:00
2005-10-16 18:33:22 +04:00
/*
* Search for a node in the tree .
2005-11-09 01:50:11 +03:00
* Set major and minor to 0 or uuid to NULL to get the root node .
2005-10-16 18:33:22 +04:00
*/
2005-11-09 17:10:50 +03:00
struct dm_tree_node * dm_tree_find_node ( struct dm_tree * tree ,
2005-10-16 18:33:22 +04:00
uint32_t major ,
uint32_t minor ) ;
2005-11-09 17:10:50 +03:00
struct dm_tree_node * dm_tree_find_node_by_uuid ( struct dm_tree * tree ,
2005-11-09 01:50:11 +03:00
const char * uuid ) ;
2005-10-16 18:33:22 +04:00
/*
* Use this to walk through all children of a given node .
* Set handle to NULL in first call .
* Returns NULL after the last child .
* Set inverted to use inverted tree .
*/
2005-11-09 17:10:50 +03:00
struct dm_tree_node * dm_tree_next_child ( void * * handle ,
struct dm_tree_node * parent ,
2005-10-16 18:33:22 +04:00
uint32_t inverted ) ;
/*
* Get properties of a node .
*/
2005-11-09 17:10:50 +03:00
const char * dm_tree_node_get_name ( struct dm_tree_node * node ) ;
const char * dm_tree_node_get_uuid ( struct dm_tree_node * node ) ;
const struct dm_info * dm_tree_node_get_info ( struct dm_tree_node * node ) ;
void * dm_tree_node_get_context ( struct dm_tree_node * node ) ;
2009-05-20 13:52:37 +04:00
int dm_tree_node_size_changed ( struct dm_tree_node * dnode ) ;
2005-10-16 18:33:22 +04:00
/*
* Returns the number of children of the given node ( excluding the root node ) .
* Set inverted for the number of parents .
*/
2005-11-09 17:10:50 +03:00
int dm_tree_node_num_children ( struct dm_tree_node * node , uint32_t inverted ) ;
2005-10-16 18:33:22 +04:00
2005-10-18 16:37:53 +04:00
/*
2005-10-18 17:57:11 +04:00
* Deactivate a device plus all dependencies .
* Ignores devices that don ' t have a uuid starting with uuid_prefix .
2005-10-18 16:37:53 +04:00
*/
2005-11-09 17:10:50 +03:00
int dm_tree_deactivate_children ( struct dm_tree_node * dnode ,
2005-10-18 16:37:53 +04:00
const char * uuid_prefix ,
size_t uuid_prefix_len ) ;
2005-11-09 01:50:11 +03:00
/*
* Preload / create a device plus all dependencies .
* Ignores devices that don ' t have a uuid starting with uuid_prefix .
*/
2005-11-09 17:10:50 +03:00
int dm_tree_preload_children ( struct dm_tree_node * dnode ,
2007-01-16 21:04:15 +03:00
const char * uuid_prefix ,
size_t uuid_prefix_len ) ;
2005-11-09 01:50:11 +03:00
/*
* Resume a device plus all dependencies .
* Ignores devices that don ' t have a uuid starting with uuid_prefix .
*/
2005-11-09 17:10:50 +03:00
int dm_tree_activate_children ( struct dm_tree_node * dnode ,
2007-01-16 21:04:15 +03:00
const char * uuid_prefix ,
size_t uuid_prefix_len ) ;
2005-10-18 16:37:53 +04:00
2005-10-25 23:09:41 +04:00
/*
* Suspend a device plus all dependencies .
* Ignores devices that don ' t have a uuid starting with uuid_prefix .
*/
2005-11-09 17:10:50 +03:00
int dm_tree_suspend_children ( struct dm_tree_node * dnode ,
2005-10-25 23:09:41 +04:00
const char * uuid_prefix ,
size_t uuid_prefix_len ) ;
2006-01-31 02:36:04 +03:00
/*
* Skip the filesystem sync when suspending .
* Does nothing with other functions .
* Use this when no snapshots are involved .
*/
void dm_tree_skip_lockfs ( struct dm_tree_node * dnode ) ;
2007-01-09 22:44:07 +03:00
/*
* Set the ' noflush ' flag when suspending devices .
* If the kernel supports it , instead of erroring outstanding I / O that
* cannot be completed , the I / O is queued and resubmitted when the
* device is resumed . This affects multipath devices when all paths
* have failed and queue_if_no_path is set , and mirror devices when
* block_on_error is set and the mirror log has failed .
*/
void dm_tree_use_no_flush_suspend ( struct dm_tree_node * dnode ) ;
2005-10-25 23:09:41 +04:00
/*
* Is the uuid prefix present in the tree ?
* Only returns 0 if every node was checked successfully .
* Returns 1 if the tree walk has to be aborted .
*/
2005-11-09 17:10:50 +03:00
int dm_tree_children_use_uuid ( struct dm_tree_node * dnode ,
2005-10-25 23:09:41 +04:00
const char * uuid_prefix ,
size_t uuid_prefix_len ) ;
2005-11-09 01:50:11 +03:00
/*
2005-11-09 17:10:50 +03:00
* Construct tables for new nodes before activating them .
2005-11-09 01:50:11 +03:00
*/
2005-11-09 17:10:50 +03:00
int dm_tree_node_add_snapshot_origin_target ( struct dm_tree_node * dnode ,
2005-11-09 01:50:11 +03:00
uint64_t size ,
const char * origin_uuid ) ;
2005-11-09 17:10:50 +03:00
int dm_tree_node_add_snapshot_target ( struct dm_tree_node * node ,
2005-11-09 01:50:11 +03:00
uint64_t size ,
const char * origin_uuid ,
const char * cow_uuid ,
int persistent ,
uint32_t chunk_size ) ;
2005-11-09 17:10:50 +03:00
int dm_tree_node_add_error_target ( struct dm_tree_node * node ,
2005-11-09 01:50:11 +03:00
uint64_t size ) ;
2005-11-09 17:10:50 +03:00
int dm_tree_node_add_zero_target ( struct dm_tree_node * node ,
2005-11-09 01:50:11 +03:00
uint64_t size ) ;
2005-11-09 17:10:50 +03:00
int dm_tree_node_add_linear_target ( struct dm_tree_node * node ,
2005-11-09 01:50:11 +03:00
uint64_t size ) ;
2005-11-09 17:10:50 +03:00
int dm_tree_node_add_striped_target ( struct dm_tree_node * node ,
2005-11-09 01:50:11 +03:00
uint64_t size ,
uint32_t stripe_size ) ;
2009-06-09 20:10:20 +04:00
# define DM_CRYPT_IV_DEFAULT UINT64_C(-1) /* iv_offset == seg offset */
/*
* Function accepts one string in cipher specification
* ( chainmode and iv should be NULL because included in cipher string )
* or
* separate arguments which will be joined to " cipher-chainmode-iv "
*/
int dm_tree_node_add_crypt_target ( struct dm_tree_node * node ,
uint64_t size ,
const char * cipher ,
const char * chainmode ,
const char * iv ,
uint64_t iv_offset ,
const char * key ) ;
2005-11-09 17:10:50 +03:00
int dm_tree_node_add_mirror_target ( struct dm_tree_node * node ,
2005-11-09 01:50:11 +03:00
uint64_t size ) ;
2005-12-13 18:49:27 +03:00
/* Mirror log flags */
# define DM_NOSYNC 0x00000001 /* Known already in sync */
# define DM_FORCESYNC 0x00000002 /* Force resync */
# define DM_BLOCK_ON_ERROR 0x00000004 /* On error, suspend I/O */
2006-05-11 23:10:55 +04:00
# define DM_CORELOG 0x00000008 /* In-memory log */
2005-12-13 18:49:27 +03:00
2005-11-09 17:10:50 +03:00
int dm_tree_node_add_mirror_target_log ( struct dm_tree_node * node ,
2005-11-09 01:50:11 +03:00
uint32_t region_size ,
unsigned clustered ,
const char * log_uuid ,
2005-12-20 00:03:17 +03:00
unsigned area_count ,
uint32_t flags ) ;
2005-11-09 17:10:50 +03:00
int dm_tree_node_add_target_area ( struct dm_tree_node * node ,
2005-11-09 01:50:11 +03:00
const char * dev_name ,
const char * dlid ,
uint64_t offset ) ;
2007-11-27 23:57:05 +03:00
/*
* Set readahead ( in sectors ) after loading the node .
*/
void dm_tree_node_set_read_ahead ( struct dm_tree_node * dnode ,
uint32_t read_ahead ,
uint32_t read_ahead_flags ) ;
2009-07-31 22:30:31 +04:00
void dm_tree_set_cookie ( struct dm_tree_node * node , uint32_t cookie ) ;
uint32_t dm_tree_get_cookie ( struct dm_tree_node * node ) ;
2005-10-17 02:57:20 +04:00
/*****************************************************************************
* Library functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-11-09 17:10:50 +03:00
/*******************
* Memory management
* * * * * * * * * * * * * * * * * * */
2005-11-10 19:33:04 +03:00
void * dm_malloc_aux ( size_t s , const char * file , int line ) ;
void * dm_malloc_aux_debug ( size_t s , const char * file , int line ) ;
2006-02-23 22:11:51 +03:00
char * dm_strdup_aux ( const char * str , const char * file , int line ) ;
2005-10-17 02:57:20 +04:00
void dm_free_aux ( void * p ) ;
void * dm_realloc_aux ( void * p , unsigned int s , const char * file , int line ) ;
2005-11-10 19:33:04 +03:00
int dm_dump_memory_debug ( void ) ;
void dm_bounds_check_debug ( void ) ;
# ifdef DEBUG_MEM
2005-10-17 02:57:20 +04:00
2005-11-10 19:33:04 +03:00
# define dm_malloc(s) dm_malloc_aux_debug((s), __FILE__, __LINE__)
2006-02-23 22:11:51 +03:00
# define dm_strdup(s) dm_strdup_aux((s), __FILE__, __LINE__)
2005-10-17 02:57:20 +04:00
# define dm_free(p) dm_free_aux(p)
# define dm_realloc(p, s) dm_realloc_aux(p, s, __FILE__, __LINE__)
2005-11-11 19:16:37 +03:00
# define dm_dump_memory() dm_dump_memory_debug()
# define dm_bounds_check() dm_bounds_check_debug()
2005-10-17 02:57:20 +04:00
# else
2005-11-10 19:33:04 +03:00
# define dm_malloc(s) dm_malloc_aux((s), __FILE__, __LINE__)
2006-01-11 01:19:41 +03:00
# define dm_strdup(s) strdup(s)
2005-10-17 02:57:20 +04:00
# define dm_free(p) free(p)
# define dm_realloc(p, s) realloc(p, s)
2005-11-11 19:16:37 +03:00
# define dm_dump_memory() {}
# define dm_bounds_check() {}
2005-10-17 02:57:20 +04:00
# endif
2005-11-10 19:33:04 +03:00
2005-10-17 02:57:20 +04:00
/*
* The pool allocator is useful when you are going to allocate
* lots of memory , use the memory for a bit , and then free the
* memory in one go . A surprising amount of code has this usage
* profile .
*
* You should think of the pool as an infinite , contiguous chunk
* of memory . The front of this chunk of memory contains
* allocated objects , the second half is free . dm_pool_alloc grabs
* the next ' size ' bytes from the free half , in effect moving it
* into the allocated half . This operation is very efficient .
*
* dm_pool_free frees the allocated object * and * all objects
* allocated after it . It is important to note this semantic
* difference from malloc / free . This is also extremely
* efficient , since a single dm_pool_free can dispose of a large
* complex object .
*
* dm_pool_destroy frees all allocated memory .
*
* eg , If you are building a binary tree in your program , and
* know that you are only ever going to insert into your tree ,
* and not delete ( eg , maintaining a symbol table for a
* compiler ) . You can create yourself a pool , allocate the nodes
* from it , and when the tree becomes redundant call dm_pool_destroy
* ( no nasty iterating through the tree to free nodes ) .
*
* eg , On the other hand if you wanted to repeatedly insert and
* remove objects into the tree , you would be better off
* allocating the nodes from a free list ; you cannot free a
* single arbitrary node with pool .
*/
struct dm_pool ;
/* constructor and destructor */
struct dm_pool * dm_pool_create ( const char * name , size_t chunk_hint ) ;
void dm_pool_destroy ( struct dm_pool * p ) ;
/* simple allocation/free routines */
void * dm_pool_alloc ( struct dm_pool * p , size_t s ) ;
void * dm_pool_alloc_aligned ( struct dm_pool * p , size_t s , unsigned alignment ) ;
void dm_pool_empty ( struct dm_pool * p ) ;
void dm_pool_free ( struct dm_pool * p , void * ptr ) ;
/*
* Object building routines :
*
* These allow you to ' grow ' an object , useful for
* building strings , or filling in dynamic
* arrays .
*
* It ' s probably best explained with an example :
*
* char * build_string ( struct dm_pool * mem )
* {
* int i ;
* char buffer [ 16 ] ;
*
* if ( ! dm_pool_begin_object ( mem , 128 ) )
* return NULL ;
*
* for ( i = 0 ; i < 50 ; i + + ) {
* snprintf ( buffer , sizeof ( buffer ) , " %d, " , i ) ;
2008-04-19 19:50:18 +04:00
* if ( ! dm_pool_grow_object ( mem , buffer , 0 ) )
2005-10-17 02:57:20 +04:00
* goto bad ;
* }
*
* // add null
* if ( ! dm_pool_grow_object ( mem , " \0 " , 1 ) )
* goto bad ;
*
* return dm_pool_end_object ( mem ) ;
*
* bad :
*
* dm_pool_abandon_object ( mem ) ;
* return NULL ;
* }
*
* So start an object by calling dm_pool_begin_object
* with a guess at the final object size - if in
* doubt make the guess too small .
*
* Then append chunks of data to your object with
* dm_pool_grow_object . Finally get your object with
* a call to dm_pool_end_object .
*
2008-04-19 19:50:18 +04:00
* Setting delta to 0 means it will use strlen ( extra ) .
2005-10-17 02:57:20 +04:00
*/
int dm_pool_begin_object ( struct dm_pool * p , size_t hint ) ;
int dm_pool_grow_object ( struct dm_pool * p , const void * extra , size_t delta ) ;
void * dm_pool_end_object ( struct dm_pool * p ) ;
void dm_pool_abandon_object ( struct dm_pool * p ) ;
/* utilities */
char * dm_pool_strdup ( struct dm_pool * p , const char * str ) ;
char * dm_pool_strndup ( struct dm_pool * p , const char * str , size_t n ) ;
void * dm_pool_zalloc ( struct dm_pool * p , size_t s ) ;
/******************
* bitset functions
* * * * * * * * * * * * * * * * * */
typedef uint32_t * dm_bitset_t ;
dm_bitset_t dm_bitset_create ( struct dm_pool * mem , unsigned num_bits ) ;
void dm_bitset_destroy ( dm_bitset_t bs ) ;
void dm_bit_union ( dm_bitset_t out , dm_bitset_t in1 , dm_bitset_t in2 ) ;
int dm_bit_get_first ( dm_bitset_t bs ) ;
int dm_bit_get_next ( dm_bitset_t bs , int last_bit ) ;
# define DM_BITS_PER_INT (sizeof(int) * CHAR_BIT)
# define dm_bit(bs, i) \
( bs [ ( i / DM_BITS_PER_INT ) + 1 ] & ( 0x1 < < ( i & ( DM_BITS_PER_INT - 1 ) ) ) )
# define dm_bit_set(bs, i) \
( bs [ ( i / DM_BITS_PER_INT ) + 1 ] | = ( 0x1 < < ( i & ( DM_BITS_PER_INT - 1 ) ) ) )
# define dm_bit_clear(bs, i) \
( bs [ ( i / DM_BITS_PER_INT ) + 1 ] & = ~ ( 0x1 < < ( i & ( DM_BITS_PER_INT - 1 ) ) ) )
# define dm_bit_set_all(bs) \
memset ( bs + 1 , - 1 , ( ( * bs / DM_BITS_PER_INT ) + 1 ) * sizeof ( int ) )
# define dm_bit_clear_all(bs) \
memset ( bs + 1 , 0 , ( ( * bs / DM_BITS_PER_INT ) + 1 ) * sizeof ( int ) )
# define dm_bit_copy(bs1, bs2) \
memcpy ( bs1 + 1 , bs2 + 1 , ( ( * bs1 / DM_BITS_PER_INT ) + 1 ) * sizeof ( int ) )
2005-12-13 18:49:27 +03:00
/* Returns number of set bits */
static inline unsigned hweight32 ( uint32_t i )
{
unsigned r = ( i & 0x55555555 ) + ( ( i > > 1 ) & 0x55555555 ) ;
r = ( r & 0x33333333 ) + ( ( r > > 2 ) & 0x33333333 ) ;
r = ( r & 0x0F0F0F0F ) + ( ( r > > 4 ) & 0x0F0F0F0F ) ;
r = ( r & 0x00FF00FF ) + ( ( r > > 8 ) & 0x00FF00FF ) ;
return ( r & 0x0000FFFF ) + ( ( r > > 16 ) & 0x0000FFFF ) ;
}
2005-10-17 02:57:20 +04:00
/****************
* hash functions
* * * * * * * * * * * * * * * */
struct dm_hash_table ;
struct dm_hash_node ;
typedef void ( * dm_hash_iterate_fn ) ( void * data ) ;
struct dm_hash_table * dm_hash_create ( unsigned size_hint ) ;
void dm_hash_destroy ( struct dm_hash_table * t ) ;
void dm_hash_wipe ( struct dm_hash_table * t ) ;
void * dm_hash_lookup ( struct dm_hash_table * t , const char * key ) ;
int dm_hash_insert ( struct dm_hash_table * t , const char * key , void * data ) ;
void dm_hash_remove ( struct dm_hash_table * t , const char * key ) ;
void * dm_hash_lookup_binary ( struct dm_hash_table * t , const char * key , uint32_t len ) ;
int dm_hash_insert_binary ( struct dm_hash_table * t , const char * key , uint32_t len ,
void * data ) ;
void dm_hash_remove_binary ( struct dm_hash_table * t , const char * key , uint32_t len ) ;
unsigned dm_hash_get_num_entries ( struct dm_hash_table * t ) ;
void dm_hash_iter ( struct dm_hash_table * t , dm_hash_iterate_fn f ) ;
char * dm_hash_get_key ( struct dm_hash_table * t , struct dm_hash_node * n ) ;
void * dm_hash_get_data ( struct dm_hash_table * t , struct dm_hash_node * n ) ;
struct dm_hash_node * dm_hash_get_first ( struct dm_hash_table * t ) ;
struct dm_hash_node * dm_hash_get_next ( struct dm_hash_table * t , struct dm_hash_node * n ) ;
# define dm_hash_iterate(v, h) \
for ( v = dm_hash_get_first ( h ) ; v ; \
v = dm_hash_get_next ( h , v ) )
2008-11-04 17:57:06 +03:00
/****************
* list functions
* * * * * * * * * * * * * * * */
/*
* A list consists of a list head plus elements .
* Each element has ' next ' and ' previous ' pointers .
* The list head ' s pointers point to the first and the last element .
*/
struct dm_list {
struct dm_list * n , * p ;
} ;
/*
* Initialise a list before use .
* The list head ' s next and previous pointers point back to itself .
*/
# define DM_LIST_INIT(name) struct dm_list name = { &(name), &(name) }
void dm_list_init ( struct dm_list * head ) ;
/*
* Insert an element before ' head ' .
* If ' head ' is the list head , this adds an element to the end of the list .
*/
void dm_list_add ( struct dm_list * head , struct dm_list * elem ) ;
/*
* Insert an element after ' head ' .
* If ' head ' is the list head , this adds an element to the front of the list .
*/
void dm_list_add_h ( struct dm_list * head , struct dm_list * elem ) ;
/*
* Delete an element from its list .
* Note that this doesn ' t change the element itself - it may still be safe
* to follow its pointers .
*/
void dm_list_del ( struct dm_list * elem ) ;
/*
* Remove an element from existing list and insert before ' head ' .
*/
void dm_list_move ( struct dm_list * head , struct dm_list * elem ) ;
/*
* Is the list empty ?
*/
int dm_list_empty ( const struct dm_list * head ) ;
/*
* Is this the first element of the list ?
*/
int dm_list_start ( const struct dm_list * head , const struct dm_list * elem ) ;
/*
* Is this the last element of the list ?
*/
int dm_list_end ( const struct dm_list * head , const struct dm_list * elem ) ;
/*
* Return first element of the list or NULL if empty
*/
struct dm_list * dm_list_first ( const struct dm_list * head ) ;
/*
* Return last element of the list or NULL if empty
*/
struct dm_list * dm_list_last ( const struct dm_list * head ) ;
/*
* Return the previous element of the list , or NULL if we ' ve reached the start .
*/
struct dm_list * dm_list_prev ( const struct dm_list * head , const struct dm_list * elem ) ;
/*
* Return the next element of the list , or NULL if we ' ve reached the end .
*/
struct dm_list * dm_list_next ( const struct dm_list * head , const struct dm_list * elem ) ;
/*
* Given the address v of an instance of ' struct dm_list ' called ' head '
* contained in a structure of type t , return the containing structure .
*/
# define dm_list_struct_base(v, t, head) \
( ( t * ) ( ( uintptr_t ) ( v ) - ( uintptr_t ) & ( ( t * ) 0 ) - > head ) )
/*
* Given the address v of an instance of ' struct dm_list list ' contained in
* a structure of type t , return the containing structure .
*/
# define dm_list_item(v, t) dm_list_struct_base((v), t, list)
/*
* Given the address v of one known element e in a known structure of type t ,
* return another element f .
*/
# define dm_struct_field(v, t, e, f) \
( ( ( t * ) ( ( uintptr_t ) ( v ) - ( uintptr_t ) & ( ( t * ) 0 ) - > e ) ) - > f )
/*
* Given the address v of a known element e in a known structure of type t ,
* return the list head ' list '
*/
# define dm_list_head(v, t, e) dm_struct_field(v, t, e, list)
/*
* Set v to each element of a list in turn .
*/
# define dm_list_iterate(v, head) \
for ( v = ( head ) - > n ; v ! = head ; v = v - > n )
/*
* Set v to each element in a list in turn , starting from the element
* in front of ' start ' .
* You can use this to ' unwind ' a list_iterate and back out actions on
* already - processed elements .
* If ' start ' is ' head ' it walks the list backwards .
*/
# define dm_list_uniterate(v, head, start) \
for ( v = ( start ) - > p ; v ! = head ; v = v - > p )
/*
* A safe way to walk a list and delete and free some elements along
* the way .
* t must be defined as a temporary variable of the same type as v .
*/
# define dm_list_iterate_safe(v, t, head) \
for ( v = ( head ) - > n , t = v - > n ; v ! = head ; v = t , t = v - > n )
/*
* Walk a list , setting ' v ' in turn to the containing structure of each item .
* The containing structure should be the same type as ' v ' .
* The ' struct dm_list ' variable within the containing structure is ' field ' .
*/
# define dm_list_iterate_items_gen(v, head, field) \
for ( v = dm_list_struct_base ( ( head ) - > n , typeof ( * v ) , field ) ; \
& v - > field ! = ( head ) ; \
v = dm_list_struct_base ( v - > field . n , typeof ( * v ) , field ) )
/*
* Walk a list , setting ' v ' in turn to the containing structure of each item .
* The containing structure should be the same type as ' v ' .
* The list should be ' struct dm_list list ' within the containing structure .
*/
# define dm_list_iterate_items(v, head) dm_list_iterate_items_gen(v, (head), list)
/*
* Walk a list , setting ' v ' in turn to the containing structure of each item .
* The containing structure should be the same type as ' v ' .
* The ' struct dm_list ' variable within the containing structure is ' field ' .
* t must be defined as a temporary variable of the same type as v .
*/
# define dm_list_iterate_items_gen_safe(v, t, head, field) \
for ( v = dm_list_struct_base ( ( head ) - > n , typeof ( * v ) , field ) , \
t = dm_list_struct_base ( v - > field . n , typeof ( * v ) , field ) ; \
& v - > field ! = ( head ) ; \
v = t , t = dm_list_struct_base ( v - > field . n , typeof ( * v ) , field ) )
/*
* Walk a list , setting ' v ' in turn to the containing structure of each item .
* The containing structure should be the same type as ' v ' .
* The list should be ' struct dm_list list ' within the containing structure .
* t must be defined as a temporary variable of the same type as v .
*/
# define dm_list_iterate_items_safe(v, t, head) \
dm_list_iterate_items_gen_safe ( v , t , ( head ) , list )
/*
* Walk a list backwards , setting ' v ' in turn to the containing structure
* of each item .
* The containing structure should be the same type as ' v ' .
* The ' struct dm_list ' variable within the containing structure is ' field ' .
*/
# define dm_list_iterate_back_items_gen(v, head, field) \
for ( v = dm_list_struct_base ( ( head ) - > p , typeof ( * v ) , field ) ; \
& v - > field ! = ( head ) ; \
v = dm_list_struct_base ( v - > field . p , typeof ( * v ) , field ) )
/*
* Walk a list backwards , setting ' v ' in turn to the containing structure
* of each item .
* The containing structure should be the same type as ' v ' .
* The list should be ' struct dm_list list ' within the containing structure .
*/
2008-11-04 18:07:45 +03:00
# define dm_list_iterate_back_items(v, head) dm_list_iterate_back_items_gen(v, (head), list)
2008-11-04 17:57:06 +03:00
/*
* Return the number of elements in a list by walking it .
*/
unsigned int dm_list_size ( const struct dm_list * head ) ;
2005-11-09 17:10:50 +03:00
/*********
2005-10-25 21:30:00 +04:00
* selinux
2005-11-09 17:10:50 +03:00
* * * * * * * * */
2005-10-25 21:30:00 +04:00
int dm_set_selinux_context ( const char * path , mode_t mode ) ;
2006-01-04 19:05:44 +03:00
2006-08-21 16:07:03 +04:00
/*********************
* string manipulation
* * * * * * * * * * * * * * * * * * * * */
/*
* Break up the name of a mapped device into its constituent
* Volume Group , Logical Volume and Layer ( if present ) .
2009-06-03 15:40:23 +04:00
* If mem is supplied , the result is allocated from the mempool .
* Otherwise the strings are changed in situ .
2006-08-21 16:07:03 +04:00
*/
int dm_split_lvm_name ( struct dm_pool * mem , const char * dmname ,
char * * vgname , char * * lvname , char * * layer ) ;
/*
* Destructively split buffer into NULL - separated words in argv .
* Returns number of words .
*/
int dm_split_words ( char * buffer , unsigned max ,
unsigned ignore_comments , /* Not implemented */
char * * argv ) ;
2006-08-21 16:52:39 +04:00
/*
* Returns - 1 if buffer too small
*/
int dm_snprintf ( char * buf , size_t bufsize , const char * format , . . . ) ;
2007-01-08 18:18:52 +03:00
/*
* Returns pointer to the last component of the path .
*/
char * dm_basename ( const char * path ) ;
2007-07-24 18:15:45 +04:00
/**************************
* file / stream manipulation
* * * * * * * * * * * * * * * * * * * * * * * * * */
2007-07-28 14:48:36 +04:00
/*
* Create a directory ( with parent directories if necessary ) .
* Returns 1 on success , 0 on failure .
*/
int dm_create_dir ( const char * dir ) ;
2007-07-24 18:15:45 +04:00
/*
* Close a stream , with nicer error checking than fclose ' s .
* Derived from gnulib ' s close - stream . c .
*
* Close " stream " . Return 0 if successful , and EOF ( setting errno )
* otherwise . Upon failure , set errno to 0 if the error number
* cannot be determined . Useful mainly for writable streams .
*/
int dm_fclose ( FILE * stream ) ;
2007-01-12 00:54:53 +03:00
/*
* Returns size of a buffer which is allocated with dm_malloc .
* Pointer to the buffer is stored in * buf .
2007-01-15 21:21:01 +03:00
* Returns - 1 on failure leaving buf undefined .
2007-01-12 00:54:53 +03:00
*/
2007-01-15 21:21:01 +03:00
int dm_asprintf ( char * * buf , const char * format , . . . ) ;
2007-01-12 00:54:53 +03:00
2007-04-27 22:40:23 +04:00
/*********************
* regular expressions
* * * * * * * * * * * * * * * * * * * * */
struct dm_regex ;
/*
* Initialise an array of num patterns for matching .
* Uses memory from mem .
*/
struct dm_regex * dm_regex_create ( struct dm_pool * mem , const char * * patterns ,
unsigned num_patterns ) ;
/*
* Match string s against the patterns .
* Returns the index of the highest pattern in the array that matches ,
* or - 1 if none match .
*/
int dm_regex_match ( struct dm_regex * regex , const char * s ) ;
2007-01-16 21:04:15 +03:00
/*********************
* reporting functions
* * * * * * * * * * * * * * * * * * * * */
struct dm_report_object_type {
uint32_t id ; /* Powers of 2 */
const char * desc ;
const char * prefix ; /* field id string prefix (optional) */
void * ( * data_fn ) ( void * object ) ; /* callback from report_object() */
} ;
struct dm_report_field ;
/*
* dm_report_field_type flags
*/
2007-01-18 20:47:58 +03:00
# define DM_REPORT_FIELD_MASK 0x000000FF
# define DM_REPORT_FIELD_ALIGN_MASK 0x0000000F
2007-01-16 21:04:15 +03:00
# define DM_REPORT_FIELD_ALIGN_LEFT 0x00000001
# define DM_REPORT_FIELD_ALIGN_RIGHT 0x00000002
2007-01-18 20:47:58 +03:00
# define DM_REPORT_FIELD_TYPE_MASK 0x000000F0
# define DM_REPORT_FIELD_TYPE_STRING 0x00000010
# define DM_REPORT_FIELD_TYPE_NUMBER 0x00000020
2007-01-16 21:04:15 +03:00
struct dm_report ;
struct dm_report_field_type {
uint32_t type ; /* object type id */
2007-01-29 20:23:54 +03:00
uint32_t flags ; /* DM_REPORT_FIELD_* */
uint32_t offset ; /* byte offset in the object */
int32_t width ; /* default width */
2007-01-16 21:04:15 +03:00
const char id [ 32 ] ; /* string used to specify the field */
const char heading [ 32 ] ; /* string printed in header */
int ( * report_fn ) ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field , const void * data ,
void * private ) ;
2007-01-23 22:18:52 +03:00
const char * desc ; /* description of the field */
2007-01-16 21:04:15 +03:00
} ;
/*
* dm_report_init output_flags
*/
2008-04-20 04:11:08 +04:00
# define DM_REPORT_OUTPUT_MASK 0x000000FF
# define DM_REPORT_OUTPUT_ALIGNED 0x00000001
# define DM_REPORT_OUTPUT_BUFFERED 0x00000002
# define DM_REPORT_OUTPUT_HEADINGS 0x00000004
# define DM_REPORT_OUTPUT_FIELD_NAME_PREFIX 0x00000008
2008-06-25 00:16:47 +04:00
# define DM_REPORT_OUTPUT_FIELD_UNQUOTED 0x00000010
2008-06-25 02:53:48 +04:00
# define DM_REPORT_OUTPUT_COLUMNS_AS_ROWS 0x00000020
2007-01-16 21:04:15 +03:00
struct dm_report * dm_report_init ( uint32_t * report_types ,
const struct dm_report_object_type * types ,
const struct dm_report_field_type * fields ,
const char * output_fields ,
const char * output_separator ,
uint32_t output_flags ,
const char * sort_keys ,
void * private ) ;
int dm_report_object ( struct dm_report * rh , void * object ) ;
int dm_report_output ( struct dm_report * rh ) ;
void dm_report_free ( struct dm_report * rh ) ;
2008-04-20 04:11:08 +04:00
/*
* Prefix added to each field name with DM_REPORT_OUTPUT_FIELD_NAME_PREFIX
*/
int dm_report_set_output_field_name_prefix ( struct dm_report * rh ,
const char * report_prefix ) ;
2007-01-16 21:04:15 +03:00
/*
2007-01-22 18:03:57 +03:00
* Report functions are provided for simple data types .
* They take care of allocating copies of the data .
2007-01-16 21:04:15 +03:00
*/
2007-01-22 18:03:57 +03:00
int dm_report_field_string ( struct dm_report * rh , struct dm_report_field * field ,
const char * * data ) ;
int dm_report_field_int32 ( struct dm_report * rh , struct dm_report_field * field ,
const int32_t * data ) ;
int dm_report_field_uint32 ( struct dm_report * rh , struct dm_report_field * field ,
const uint32_t * data ) ;
int dm_report_field_int ( struct dm_report * rh , struct dm_report_field * field ,
const int * data ) ;
int dm_report_field_uint64 ( struct dm_report * rh , struct dm_report_field * field ,
const uint64_t * data ) ;
2007-01-16 21:04:15 +03:00
/*
2007-01-22 18:03:57 +03:00
* For custom fields , allocate the data in ' mem ' and use
* dm_report_field_set_value ( ) .
* ' sortvalue ' may be NULL if it matches ' value '
2007-01-16 21:04:15 +03:00
*/
2007-01-22 18:03:57 +03:00
void dm_report_field_set_value ( struct dm_report_field * field , const void * value ,
const void * sortvalue ) ;
2007-01-16 21:04:15 +03:00
2009-10-22 16:55:47 +04:00
/* Cookie prefixes.
* The cookie value consists of a prefix ( 16 bits ) and a base ( 16 bits ) .
* We can use the prefix to store the flags . These flags are sent to
* kernel within given dm task . When returned back to userspace in
* DM_COOKIE udev environment variable , we can control several aspects
* of udev rules we use by decoding the cookie prefix . When doing the
* notification , we replace the cookie prefix with DM_COOKIE_MAGIC ,
* so we notify the right semaphore .
2009-11-13 15:43:21 +03:00
* It is still possible to use cookies for passing the flags to udev
* rules even when udev_sync is disabled . The base part of the cookie
* will be zero ( there ' s no notification semaphore ) and prefix will be
* set then . However , having udev_sync enabled is highly recommended .
2009-10-22 16:55:47 +04:00
*/
2009-08-06 19:04:30 +04:00
# define DM_COOKIE_MAGIC 0x0D4D
2009-10-22 16:55:47 +04:00
# define DM_UDEV_FLAGS_MASK 0xFFFF0000
# define DM_UDEV_FLAGS_SHIFT 16
2009-10-26 17:29:33 +03:00
/*
* DM_UDEV_DISABLE_DM_RULES_FLAG is set in case we need to disable
* basic device - mapper udev rules that create symlinks in / dev / < DM_DIR >
* directory . However , we can ' t reliably prevent creating default
* nodes by udev ( commonly / dev / dm - X , where X is a number ) .
*/
# define DM_UDEV_DISABLE_DM_RULES_FLAG 0x0001
2009-10-22 16:55:47 +04:00
/*
* DM_UDEV_DISABLE_SUBSYTEM_RULES_FLAG is set in case we need to disable
* subsystem udev rules , but still we need the general DM udev rules to
* be applied ( to create the nodes and symlinks under / dev and / dev / disk ) .
*/
2009-10-26 17:29:33 +03:00
# define DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG 0x0002
2009-10-22 16:55:47 +04:00
/*
* DM_UDEV_DISABLE_DISK_RULES_FLAG is set in case we need to disable
* general DM rules that set symlinks in / dev / disk directory .
*/
2009-10-26 17:29:33 +03:00
# define DM_UDEV_DISABLE_DISK_RULES_FLAG 0x0004
/*
* DM_UDEV_DISABLE_OTHER_RULES_FLAG is set in case we need to disable
* all the other rules that are not general device - mapper nor subsystem
2009-11-13 15:33:27 +03:00
* related ( the rules belong to other software or packages ) . All foreign
* rules should check this flag directly and they should ignore further
* rule processing for such event .
2009-10-26 17:29:33 +03:00
*/
# define DM_UDEV_DISABLE_OTHER_RULES_FLAG 0x0008
2009-10-22 16:55:47 +04:00
/*
* DM_UDEV_LOW_PRIORITY_FLAG is set in case we need to instruct the
* udev rules to give low priority to the device that is currently
* processed . For example , this provides a way to select which symlinks
* could be overwritten by high priority ones if their names are equal .
* Common situation is a name based on FS UUID while using origin and
* snapshot devices .
*/
2009-10-26 17:29:33 +03:00
# define DM_UDEV_LOW_PRIORITY_FLAG 0x0010
2009-08-06 19:04:30 +04:00
2009-07-31 19:53:11 +04:00
int dm_cookie_supported ( void ) ;
/*
2009-11-13 15:43:21 +03:00
* Udev synchronisation functions .
2009-07-31 19:53:11 +04:00
*/
void dm_udev_set_sync_support ( int sync_with_udev ) ;
int dm_udev_get_sync_support ( void ) ;
2009-07-31 21:51:45 +04:00
int dm_udev_complete ( uint32_t cookie ) ;
2009-07-31 19:53:11 +04:00
int dm_udev_wait ( uint32_t cookie ) ;
2009-09-25 15:58:00 +04:00
# define DM_DEV_DIR_UMASK 0022
2006-01-04 19:05:44 +03:00
# endif /* LIB_DEVICE_MAPPER_H */