home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / libdevmapper.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-10-04  |  23.9 KB  |  789 lines

  1. /*
  2.  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
  3.  * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
  4.  *
  5.  * This file is part of the device-mapper userspace tools.
  6.  *
  7.  * This copyrighted material is made available to anyone wishing to use,
  8.  * modify, copy, or redistribute it subject to the terms and conditions
  9.  * of the GNU Lesser General Public License v.2.1.
  10.  *
  11.  * You should have received a copy of the GNU Lesser General Public License
  12.  * along with this program; if not, write to the Free Software Foundation,
  13.  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  14.  */
  15.  
  16. #ifndef LIB_DEVICE_MAPPER_H
  17. #define LIB_DEVICE_MAPPER_H
  18.  
  19. #include <inttypes.h>
  20. #include <stdarg.h>
  21. #include <sys/types.h>
  22.  
  23. #ifdef linux
  24. #  include <linux/types.h>
  25. #endif
  26.  
  27. #include <limits.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31.  
  32. /*****************************************************************
  33.  * The first section of this file provides direct access to the 
  34.  * individual device-mapper ioctls.
  35.  ****************************************************************/
  36.  
  37. /*
  38.  * Since it is quite laborious to build the ioctl
  39.  * arguments for the device-mapper people are
  40.  * encouraged to use this library.
  41.  *
  42.  * You will need to build a struct dm_task for
  43.  * each ioctl command you want to execute.
  44.  */
  45.  
  46. typedef void (*dm_log_fn) (int level, const char *file, int line,
  47.                const char *f, ...)
  48.     __attribute__ ((format(printf, 4, 5)));
  49.  
  50. /*
  51.  * The library user may wish to register their own
  52.  * logging function, by default errors go to stderr.
  53.  * Use dm_log_init(NULL) to restore the default log fn.
  54.  */
  55. void dm_log_init(dm_log_fn fn);
  56. void dm_log_init_verbose(int level);
  57.  
  58. enum {
  59.     DM_DEVICE_CREATE,
  60.     DM_DEVICE_RELOAD,
  61.     DM_DEVICE_REMOVE,
  62.     DM_DEVICE_REMOVE_ALL,
  63.  
  64.     DM_DEVICE_SUSPEND,
  65.     DM_DEVICE_RESUME,
  66.  
  67.     DM_DEVICE_INFO,
  68.     DM_DEVICE_DEPS,
  69.     DM_DEVICE_RENAME,
  70.  
  71.     DM_DEVICE_VERSION,
  72.  
  73.     DM_DEVICE_STATUS,
  74.     DM_DEVICE_TABLE,
  75.     DM_DEVICE_WAITEVENT,
  76.  
  77.     DM_DEVICE_LIST,
  78.  
  79.     DM_DEVICE_CLEAR,
  80.  
  81.     DM_DEVICE_MKNODES,
  82.  
  83.     DM_DEVICE_LIST_VERSIONS,
  84.     
  85.     DM_DEVICE_TARGET_MSG,
  86.  
  87.     DM_DEVICE_SET_GEOMETRY
  88. };
  89.  
  90. struct dm_task;
  91.  
  92. struct dm_task *dm_task_create(int type);
  93. void dm_task_destroy(struct dm_task *dmt);
  94.  
  95. int dm_task_set_name(struct dm_task *dmt, const char *name);
  96. int dm_task_set_uuid(struct dm_task *dmt, const char *uuid);
  97.  
  98. /*
  99.  * Retrieve attributes after an info.
  100.  */
  101. struct dm_info {
  102.     int exists;
  103.     int suspended;
  104.     int live_table;
  105.     int inactive_table;
  106.     int32_t open_count;
  107.     uint32_t event_nr;
  108.     uint32_t major;
  109.     uint32_t minor;        /* minor device number */
  110.     int read_only;        /* 0:read-write; 1:read-only */
  111.  
  112.     int32_t target_count;
  113. };
  114.  
  115. struct dm_deps {
  116.     uint32_t count;
  117.     uint32_t filler;
  118.     uint64_t device[0];
  119. };
  120.  
  121. struct dm_names {
  122.     uint64_t dev;
  123.     uint32_t next;        /* Offset to next struct from start of this struct */
  124.     char name[0];
  125. };
  126.  
  127. struct dm_versions {
  128.     uint32_t next;        /* Offset to next struct from start of this struct */
  129.     uint32_t version[3];
  130.  
  131.     char name[0];
  132. };
  133.  
  134. int dm_get_library_version(char *version, size_t size);
  135. int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size);
  136. int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi);
  137. const char *dm_task_get_name(const struct dm_task *dmt);
  138. const char *dm_task_get_uuid(const struct dm_task *dmt);
  139.  
  140. struct dm_deps *dm_task_get_deps(struct dm_task *dmt);
  141. struct dm_names *dm_task_get_names(struct dm_task *dmt);
  142. struct dm_versions *dm_task_get_versions(struct dm_task *dmt);
  143.  
  144. int dm_task_set_ro(struct dm_task *dmt);
  145. int dm_task_set_newname(struct dm_task *dmt, const char *newname);
  146. int dm_task_set_minor(struct dm_task *dmt, int minor);
  147. int dm_task_set_major(struct dm_task *dmt, int major);
  148. int dm_task_set_uid(struct dm_task *dmt, uid_t uid);
  149. int dm_task_set_gid(struct dm_task *dmt, gid_t gid);
  150. int dm_task_set_mode(struct dm_task *dmt, mode_t mode);
  151. int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr);
  152. int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads, const char *sectors, const char *start);
  153. int dm_task_set_message(struct dm_task *dmt, const char *message);
  154. int dm_task_set_sector(struct dm_task *dmt, uint64_t sector);
  155. int dm_task_no_flush(struct dm_task *dmt);
  156. int dm_task_no_open_count(struct dm_task *dmt);
  157. int dm_task_skip_lockfs(struct dm_task *dmt);
  158. int dm_task_suppress_identical_reload(struct dm_task *dmt);
  159.  
  160. /*
  161.  * Control read_ahead.
  162.  */
  163. #define DM_READ_AHEAD_AUTO UINT32_MAX    /* Use kernel default readahead */
  164. #define DM_READ_AHEAD_NONE 0        /* Disable readahead */
  165.  
  166. #define DM_READ_AHEAD_MINIMUM_FLAG    0x1    /* Value supplied is minimum */
  167.  
  168. /*
  169.  * Read ahead is set with DM_DEVICE_CREATE with a table or DM_DEVICE_RESUME.
  170.  */
  171. int dm_task_set_read_ahead(struct dm_task *dmt, uint32_t read_ahead,
  172.                uint32_t read_ahead_flags);
  173. uint32_t dm_task_get_read_ahead(const struct dm_task *dmt,
  174.                 uint32_t *read_ahead);
  175.  
  176. /*
  177.  * Use these to prepare for a create or reload.
  178.  */
  179. int dm_task_add_target(struct dm_task *dmt,
  180.                uint64_t start,
  181.                uint64_t size, const char *ttype, const char *params);
  182.  
  183. /*
  184.  * Format major/minor numbers correctly for input to driver.
  185.  */
  186. #define DM_FORMAT_DEV_BUFSIZE    13    /* Minimum bufsize to handle worst case. */
  187. int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, uint32_t dev_minor);
  188.  
  189. /* Use this to retrive target information returned from a STATUS call */
  190. void *dm_get_next_target(struct dm_task *dmt,
  191.              void *next, uint64_t *start, uint64_t *length,
  192.              char **target_type, char **params);
  193.  
  194. /*
  195.  * Call this to actually run the ioctl.
  196.  */
  197. int dm_task_run(struct dm_task *dmt);
  198.  
  199. /*
  200.  * Call this to make or remove the device nodes associated with previously
  201.  * issued commands.
  202.  */
  203. void dm_task_update_nodes(void);
  204.  
  205. /*
  206.  * Configure the device-mapper directory
  207.  */
  208. int dm_set_dev_dir(const char *dir);
  209. const char *dm_dir(void);
  210.  
  211. /*
  212.  * Determine whether a major number belongs to device-mapper or not.
  213.  */
  214. int dm_is_dm_major(uint32_t major);
  215.  
  216. /*
  217.  * Release library resources
  218.  */
  219. void dm_lib_release(void);
  220. void dm_lib_exit(void) __attribute((destructor));
  221.  
  222. /*
  223.  * Use NULL for all devices.
  224.  */
  225. int dm_mknodes(const char *name);
  226. int dm_driver_version(char *version, size_t size);
  227.  
  228. /******************************************************
  229.  * Functions to build and manipulate trees of devices *
  230.  ******************************************************/
  231. struct dm_tree;
  232. struct dm_tree_node;
  233.  
  234. /*
  235.  * Initialise an empty dependency tree.
  236.  *
  237.  * The tree consists of a root node together with one node for each mapped 
  238.  * device which has child nodes for each device referenced in its table.
  239.  *
  240.  * Every node in the tree has one or more children and one or more parents.
  241.  *
  242.  * The root node is the parent/child of every node that doesn't have other 
  243.  * parents/children.
  244.  */
  245. struct dm_tree *dm_tree_create(void);
  246. void dm_tree_free(struct dm_tree *tree);
  247.  
  248. /*
  249.  * Add nodes to the tree for a given device and all the devices it uses.
  250.  */
  251. int dm_tree_add_dev(struct dm_tree *tree, uint32_t major, uint32_t minor);
  252.  
  253. /*
  254.  * Add a new node to the tree if it doesn't already exist.
  255.  */
  256. struct dm_tree_node *dm_tree_add_new_dev(struct dm_tree *tree,
  257.                      const char *name,
  258.                      const char *uuid,
  259.                      uint32_t major, uint32_t minor,
  260.                      int read_only,
  261.                      int clear_inactive,
  262.                      void *context);
  263.  
  264. /*
  265.  * Search for a node in the tree.
  266.  * Set major and minor to 0 or uuid to NULL to get the root node.
  267.  */
  268. struct dm_tree_node *dm_tree_find_node(struct dm_tree *tree,
  269.                       uint32_t major,
  270.                       uint32_t minor);
  271. struct dm_tree_node *dm_tree_find_node_by_uuid(struct dm_tree *tree,
  272.                           const char *uuid);
  273.  
  274. /*
  275.  * Use this to walk through all children of a given node.
  276.  * Set handle to NULL in first call.
  277.  * Returns NULL after the last child.
  278.  * Set inverted to use inverted tree.
  279.  */
  280. struct dm_tree_node *dm_tree_next_child(void **handle,
  281.                        struct dm_tree_node *parent,
  282.                        uint32_t inverted);
  283.  
  284. /*
  285.  * Get properties of a node.
  286.  */
  287. const char *dm_tree_node_get_name(struct dm_tree_node *node);
  288. const char *dm_tree_node_get_uuid(struct dm_tree_node *node);
  289. const struct dm_info *dm_tree_node_get_info(struct dm_tree_node *node);
  290. void *dm_tree_node_get_context(struct dm_tree_node *node);
  291.  
  292. /*
  293.  * Returns the number of children of the given node (excluding the root node).
  294.  * Set inverted for the number of parents.
  295.  */
  296. int dm_tree_node_num_children(struct dm_tree_node *node, uint32_t inverted);
  297.  
  298. /*
  299.  * Deactivate a device plus all dependencies.
  300.  * Ignores devices that don't have a uuid starting with uuid_prefix.
  301.  */
  302. int dm_tree_deactivate_children(struct dm_tree_node *dnode,
  303.                    const char *uuid_prefix,
  304.                    size_t uuid_prefix_len);
  305. /*
  306.  * Preload/create a device plus all dependencies.
  307.  * Ignores devices that don't have a uuid starting with uuid_prefix.
  308.  */
  309. int dm_tree_preload_children(struct dm_tree_node *dnode,
  310.                  const char *uuid_prefix,
  311.                  size_t uuid_prefix_len);
  312.  
  313. /*
  314.  * Resume a device plus all dependencies.
  315.  * Ignores devices that don't have a uuid starting with uuid_prefix.
  316.  */
  317. int dm_tree_activate_children(struct dm_tree_node *dnode,
  318.                   const char *uuid_prefix,
  319.                   size_t uuid_prefix_len);
  320.  
  321. /*
  322.  * Suspend a device plus all dependencies.
  323.  * Ignores devices that don't have a uuid starting with uuid_prefix.
  324.  */
  325. int dm_tree_suspend_children(struct dm_tree_node *dnode,
  326.                    const char *uuid_prefix,
  327.                    size_t uuid_prefix_len);
  328.  
  329. /*
  330.  * Skip the filesystem sync when suspending.
  331.  * Does nothing with other functions.
  332.  * Use this when no snapshots are involved.
  333.  */ 
  334. void dm_tree_skip_lockfs(struct dm_tree_node *dnode);
  335.  
  336. /*
  337.  * Set the 'noflush' flag when suspending devices.
  338.  * If the kernel supports it, instead of erroring outstanding I/O that
  339.  * cannot be completed, the I/O is queued and resubmitted when the
  340.  * device is resumed.  This affects multipath devices when all paths
  341.  * have failed and queue_if_no_path is set, and mirror devices when
  342.  * block_on_error is set and the mirror log has failed.
  343.  */
  344. void dm_tree_use_no_flush_suspend(struct dm_tree_node *dnode);
  345.  
  346. /*
  347.  * Is the uuid prefix present in the tree?
  348.  * Only returns 0 if every node was checked successfully.
  349.  * Returns 1 if the tree walk has to be aborted.
  350.  */
  351. int dm_tree_children_use_uuid(struct dm_tree_node *dnode,
  352.                  const char *uuid_prefix,
  353.                  size_t uuid_prefix_len);
  354.  
  355. /*
  356.  * Construct tables for new nodes before activating them.
  357.  */
  358. int dm_tree_node_add_snapshot_origin_target(struct dm_tree_node *dnode,
  359.                            uint64_t size,
  360.                            const char *origin_uuid);
  361. int dm_tree_node_add_snapshot_target(struct dm_tree_node *node,
  362.                     uint64_t size,
  363.                     const char *origin_uuid,
  364.                     const char *cow_uuid,
  365.                     int persistent,
  366.                     uint32_t chunk_size);
  367. int dm_tree_node_add_error_target(struct dm_tree_node *node,
  368.                      uint64_t size);
  369. int dm_tree_node_add_zero_target(struct dm_tree_node *node,
  370.                     uint64_t size);
  371. int dm_tree_node_add_linear_target(struct dm_tree_node *node,
  372.                       uint64_t size);
  373. int dm_tree_node_add_striped_target(struct dm_tree_node *node,
  374.                        uint64_t size,
  375.                        uint32_t stripe_size);
  376. int dm_tree_node_add_mirror_target(struct dm_tree_node *node,
  377.                       uint64_t size);
  378.  
  379. /* Mirror log flags */
  380. #define DM_NOSYNC        0x00000001    /* Known already in sync */
  381. #define DM_FORCESYNC        0x00000002    /* Force resync */
  382. #define DM_BLOCK_ON_ERROR    0x00000004    /* On error, suspend I/O */
  383. #define DM_CORELOG        0x00000008    /* In-memory log */
  384.  
  385. int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node,
  386.                       uint32_t region_size,
  387.                       unsigned clustered,
  388.                       const char *log_uuid,
  389.                       unsigned area_count,
  390.                       uint32_t flags);
  391. int dm_tree_node_add_target_area(struct dm_tree_node *node,
  392.                     const char *dev_name,
  393.                     const char *dlid,
  394.                     uint64_t offset);
  395.  
  396. /*
  397.  * Set readahead (in sectors) after loading the node.
  398.  */
  399. void dm_tree_node_set_read_ahead(struct dm_tree_node *dnode,
  400.                  uint32_t read_ahead,
  401.                  uint32_t read_ahead_flags);
  402.  
  403. /*****************************************************************************
  404.  * Library functions
  405.  *****************************************************************************/
  406.  
  407. /*******************
  408.  * Memory management
  409.  *******************/
  410.  
  411. void *dm_malloc_aux(size_t s, const char *file, int line);
  412. void *dm_malloc_aux_debug(size_t s, const char *file, int line);
  413. char *dm_strdup_aux(const char *str, const char *file, int line);
  414. void dm_free_aux(void *p);
  415. void *dm_realloc_aux(void *p, unsigned int s, const char *file, int line);
  416. int dm_dump_memory_debug(void);
  417. void dm_bounds_check_debug(void);
  418.  
  419. #ifdef DEBUG_MEM
  420.  
  421. #  define dm_malloc(s) dm_malloc_aux_debug((s), __FILE__, __LINE__)
  422. #  define dm_strdup(s) dm_strdup_aux((s), __FILE__, __LINE__)
  423. #  define dm_free(p) dm_free_aux(p)
  424. #  define dm_realloc(p, s) dm_realloc_aux(p, s, __FILE__, __LINE__)
  425. #  define dm_dump_memory() dm_dump_memory_debug()
  426. #  define dm_bounds_check() dm_bounds_check_debug()
  427.  
  428. #else
  429.  
  430. #  define dm_malloc(s) dm_malloc_aux((s), __FILE__, __LINE__)
  431. #  define dm_strdup(s) strdup(s)
  432. #  define dm_free(p) free(p)
  433. #  define dm_realloc(p, s) realloc(p, s)
  434. #  define dm_dump_memory() {}
  435. #  define dm_bounds_check() {}
  436.  
  437. #endif
  438.  
  439.  
  440. /*
  441.  * The pool allocator is useful when you are going to allocate
  442.  * lots of memory, use the memory for a bit, and then free the
  443.  * memory in one go.  A surprising amount of code has this usage
  444.  * profile.
  445.  *
  446.  * You should think of the pool as an infinite, contiguous chunk
  447.  * of memory.  The front of this chunk of memory contains
  448.  * allocated objects, the second half is free.  dm_pool_alloc grabs
  449.  * the next 'size' bytes from the free half, in effect moving it
  450.  * into the allocated half.  This operation is very efficient.
  451.  *
  452.  * dm_pool_free frees the allocated object *and* all objects
  453.  * allocated after it.  It is important to note this semantic
  454.  * difference from malloc/free.  This is also extremely
  455.  * efficient, since a single dm_pool_free can dispose of a large
  456.  * complex object.
  457.  *
  458.  * dm_pool_destroy frees all allocated memory.
  459.  *
  460.  * eg, If you are building a binary tree in your program, and
  461.  * know that you are only ever going to insert into your tree,
  462.  * and not delete (eg, maintaining a symbol table for a
  463.  * compiler).  You can create yourself a pool, allocate the nodes
  464.  * from it, and when the tree becomes redundant call dm_pool_destroy
  465.  * (no nasty iterating through the tree to free nodes).
  466.  *
  467.  * eg, On the other hand if you wanted to repeatedly insert and
  468.  * remove objects into the tree, you would be better off
  469.  * allocating the nodes from a free list; you cannot free a
  470.  * single arbitrary node with pool.
  471.  */
  472.  
  473. struct dm_pool;
  474.  
  475. /* constructor and destructor */
  476. struct dm_pool *dm_pool_create(const char *name, size_t chunk_hint);
  477. void dm_pool_destroy(struct dm_pool *p);
  478.  
  479. /* simple allocation/free routines */
  480. void *dm_pool_alloc(struct dm_pool *p, size_t s);
  481. void *dm_pool_alloc_aligned(struct dm_pool *p, size_t s, unsigned alignment);
  482. void dm_pool_empty(struct dm_pool *p);
  483. void dm_pool_free(struct dm_pool *p, void *ptr);
  484.  
  485. /*
  486.  * Object building routines:
  487.  *
  488.  * These allow you to 'grow' an object, useful for
  489.  * building strings, or filling in dynamic
  490.  * arrays.
  491.  *
  492.  * It's probably best explained with an example:
  493.  *
  494.  * char *build_string(struct dm_pool *mem)
  495.  * {
  496.  *      int i;
  497.  *      char buffer[16];
  498.  *
  499.  *      if (!dm_pool_begin_object(mem, 128))
  500.  *              return NULL;
  501.  *
  502.  *      for (i = 0; i < 50; i++) {
  503.  *              snprintf(buffer, sizeof(buffer), "%d, ", i);
  504.  *              if (!dm_pool_grow_object(mem, buffer, 0))
  505.  *                      goto bad;
  506.  *      }
  507.  *
  508.  *    // add null
  509.  *      if (!dm_pool_grow_object(mem, "\0", 1))
  510.  *              goto bad;
  511.  *
  512.  *      return dm_pool_end_object(mem);
  513.  *
  514.  * bad:
  515.  *
  516.  *      dm_pool_abandon_object(mem);
  517.  *      return NULL;
  518.  *}
  519.  *
  520.  * So start an object by calling dm_pool_begin_object
  521.  * with a guess at the final object size - if in
  522.  * doubt make the guess too small.
  523.  *
  524.  * Then append chunks of data to your object with
  525.  * dm_pool_grow_object.  Finally get your object with
  526.  * a call to dm_pool_end_object.
  527.  *
  528.  * Setting delta to 0 means it will use strlen(extra).
  529.  */
  530. int dm_pool_begin_object(struct dm_pool *p, size_t hint);
  531. int dm_pool_grow_object(struct dm_pool *p, const void *extra, size_t delta);
  532. void *dm_pool_end_object(struct dm_pool *p);
  533. void dm_pool_abandon_object(struct dm_pool *p);
  534.  
  535. /* utilities */
  536. char *dm_pool_strdup(struct dm_pool *p, const char *str);
  537. char *dm_pool_strndup(struct dm_pool *p, const char *str, size_t n);
  538. void *dm_pool_zalloc(struct dm_pool *p, size_t s);
  539.  
  540. /******************
  541.  * bitset functions
  542.  ******************/
  543.  
  544. typedef uint32_t *dm_bitset_t;
  545.  
  546. dm_bitset_t dm_bitset_create(struct dm_pool *mem, unsigned num_bits);
  547. void dm_bitset_destroy(dm_bitset_t bs);
  548.  
  549. void dm_bit_union(dm_bitset_t out, dm_bitset_t in1, dm_bitset_t in2);
  550. int dm_bit_get_first(dm_bitset_t bs);
  551. int dm_bit_get_next(dm_bitset_t bs, int last_bit);
  552.  
  553. #define DM_BITS_PER_INT (sizeof(int) * CHAR_BIT)
  554.  
  555. #define dm_bit(bs, i) \
  556.    (bs[(i / DM_BITS_PER_INT) + 1] & (0x1 << (i & (DM_BITS_PER_INT - 1))))
  557.  
  558. #define dm_bit_set(bs, i) \
  559.    (bs[(i / DM_BITS_PER_INT) + 1] |= (0x1 << (i & (DM_BITS_PER_INT - 1))))
  560.  
  561. #define dm_bit_clear(bs, i) \
  562.    (bs[(i / DM_BITS_PER_INT) + 1] &= ~(0x1 << (i & (DM_BITS_PER_INT - 1))))
  563.  
  564. #define dm_bit_set_all(bs) \
  565.    memset(bs + 1, -1, ((*bs / DM_BITS_PER_INT) + 1) * sizeof(int))
  566.  
  567. #define dm_bit_clear_all(bs) \
  568.    memset(bs + 1, 0, ((*bs / DM_BITS_PER_INT) + 1) * sizeof(int))
  569.  
  570. #define dm_bit_copy(bs1, bs2) \
  571.    memcpy(bs1 + 1, bs2 + 1, ((*bs1 / DM_BITS_PER_INT) + 1) * sizeof(int))
  572.  
  573. /* Returns number of set bits */
  574. static inline unsigned hweight32(uint32_t i)
  575. {
  576.     unsigned r = (i & 0x55555555) + ((i >> 1) & 0x55555555);
  577.  
  578.     r =    (r & 0x33333333) + ((r >>  2) & 0x33333333);
  579.     r =    (r & 0x0F0F0F0F) + ((r >>  4) & 0x0F0F0F0F);
  580.     r =    (r & 0x00FF00FF) + ((r >>  8) & 0x00FF00FF);
  581.     return (r & 0x0000FFFF) + ((r >> 16) & 0x0000FFFF);
  582. }
  583.  
  584. /****************
  585.  * hash functions
  586.  ****************/
  587.  
  588. struct dm_hash_table;
  589. struct dm_hash_node;
  590.  
  591. typedef void (*dm_hash_iterate_fn) (void *data);
  592.  
  593. struct dm_hash_table *dm_hash_create(unsigned size_hint);
  594. void dm_hash_destroy(struct dm_hash_table *t);
  595. void dm_hash_wipe(struct dm_hash_table *t);
  596.  
  597. void *dm_hash_lookup(struct dm_hash_table *t, const char *key);
  598. int dm_hash_insert(struct dm_hash_table *t, const char *key, void *data);
  599. void dm_hash_remove(struct dm_hash_table *t, const char *key);
  600.  
  601. void *dm_hash_lookup_binary(struct dm_hash_table *t, const char *key, uint32_t len);
  602. int dm_hash_insert_binary(struct dm_hash_table *t, const char *key, uint32_t len,
  603.                void *data);
  604. void dm_hash_remove_binary(struct dm_hash_table *t, const char *key, uint32_t len);
  605.  
  606. unsigned dm_hash_get_num_entries(struct dm_hash_table *t);
  607. void dm_hash_iter(struct dm_hash_table *t, dm_hash_iterate_fn f);
  608.  
  609. char *dm_hash_get_key(struct dm_hash_table *t, struct dm_hash_node *n);
  610. void *dm_hash_get_data(struct dm_hash_table *t, struct dm_hash_node *n);
  611. struct dm_hash_node *dm_hash_get_first(struct dm_hash_table *t);
  612. struct dm_hash_node *dm_hash_get_next(struct dm_hash_table *t, struct dm_hash_node *n);
  613.  
  614. #define dm_hash_iterate(v, h) \
  615.     for (v = dm_hash_get_first(h); v; \
  616.          v = dm_hash_get_next(h, v))
  617.  
  618. /*********
  619.  * selinux
  620.  *********/
  621. int dm_set_selinux_context(const char *path, mode_t mode);
  622.  
  623. /*********************
  624.  * string manipulation
  625.  *********************/
  626.  
  627. /*
  628.  * Break up the name of a mapped device into its constituent
  629.  * Volume Group, Logical Volume and Layer (if present).
  630.  */
  631. int dm_split_lvm_name(struct dm_pool *mem, const char *dmname,
  632.               char **vgname, char **lvname, char **layer);
  633.  
  634. /*
  635.  * Destructively split buffer into NULL-separated words in argv.
  636.  * Returns number of words.
  637.  */
  638. int dm_split_words(char *buffer, unsigned max,
  639.            unsigned ignore_comments, /* Not implemented */
  640.            char **argv);
  641.  
  642. /* 
  643.  * Returns -1 if buffer too small
  644.  */
  645. int dm_snprintf(char *buf, size_t bufsize, const char *format, ...);
  646.  
  647. /*
  648.  * Returns pointer to the last component of the path.
  649.  */
  650. char *dm_basename(const char *path);
  651.  
  652. /**************************
  653.  * file/stream manipulation
  654.  **************************/
  655.  
  656. /*
  657.  * Create a directory (with parent directories if necessary).
  658.  * Returns 1 on success, 0 on failure.
  659.  */
  660. int dm_create_dir(const char *dir);
  661.  
  662. /*
  663.  * Close a stream, with nicer error checking than fclose's.
  664.  * Derived from gnulib's close-stream.c.
  665.  *
  666.  * Close "stream".  Return 0 if successful, and EOF (setting errno)
  667.  * otherwise.  Upon failure, set errno to 0 if the error number
  668.  * cannot be determined.  Useful mainly for writable streams.
  669.  */
  670. int dm_fclose(FILE *stream);
  671.  
  672. /*
  673.  * Returns size of a buffer which is allocated with dm_malloc.
  674.  * Pointer to the buffer is stored in *buf.
  675.  * Returns -1 on failure leaving buf undefined.
  676.  */
  677. int dm_asprintf(char **buf, const char *format, ...);
  678.  
  679. /*********************
  680.  * regular expressions
  681.  *********************/
  682. struct dm_regex;
  683.  
  684. /*
  685.  * Initialise an array of num patterns for matching.
  686.  * Uses memory from mem.
  687.  */
  688. struct dm_regex *dm_regex_create(struct dm_pool *mem, const char **patterns,
  689.                  unsigned num_patterns);
  690.  
  691. /*
  692.  * Match string s against the patterns.
  693.  * Returns the index of the highest pattern in the array that matches,
  694.  * or -1 if none match.
  695.  */
  696. int dm_regex_match(struct dm_regex *regex, const char *s);
  697.  
  698. /*********************
  699.  * reporting functions
  700.  *********************/
  701.  
  702. struct dm_report_object_type {
  703.     uint32_t id;            /* Powers of 2 */
  704.     const char *desc;
  705.     const char *prefix;        /* field id string prefix (optional) */
  706.     void *(*data_fn)(void *object);    /* callback from report_object() */
  707. };
  708.  
  709. struct dm_report_field;
  710.  
  711. /*
  712.  * dm_report_field_type flags
  713.  */
  714. #define DM_REPORT_FIELD_MASK        0x000000FF
  715. #define DM_REPORT_FIELD_ALIGN_MASK    0x0000000F
  716. #define DM_REPORT_FIELD_ALIGN_LEFT    0x00000001
  717. #define DM_REPORT_FIELD_ALIGN_RIGHT    0x00000002
  718. #define DM_REPORT_FIELD_TYPE_MASK    0x000000F0
  719. #define DM_REPORT_FIELD_TYPE_STRING    0x00000010
  720. #define DM_REPORT_FIELD_TYPE_NUMBER    0x00000020
  721.  
  722. struct dm_report;
  723. struct dm_report_field_type {
  724.     uint32_t type;        /* object type id */
  725.     uint32_t flags;        /* DM_REPORT_FIELD_* */
  726.     uint32_t offset;    /* byte offset in the object */
  727.     int32_t width;        /* default width */
  728.     const char id[32];    /* string used to specify the field */
  729.     const char heading[32];    /* string printed in header */
  730.     int (*report_fn)(struct dm_report *rh, struct dm_pool *mem,
  731.              struct dm_report_field *field, const void *data,
  732.              void *private);
  733.     const char *desc;    /* description of the field */
  734. };
  735.  
  736. /*
  737.  * dm_report_init output_flags
  738.  */
  739. #define DM_REPORT_OUTPUT_MASK            0x000000FF
  740. #define DM_REPORT_OUTPUT_ALIGNED        0x00000001
  741. #define DM_REPORT_OUTPUT_BUFFERED        0x00000002
  742. #define DM_REPORT_OUTPUT_HEADINGS        0x00000004
  743. #define DM_REPORT_OUTPUT_FIELD_NAME_PREFIX    0x00000008
  744. #define DM_REPORT_OUTPUT_FIELD_UNQUOTED        0x00000010
  745. #define DM_REPORT_OUTPUT_COLUMNS_AS_ROWS    0x00000020
  746.  
  747. struct dm_report *dm_report_init(uint32_t *report_types,
  748.                  const struct dm_report_object_type *types,
  749.                  const struct dm_report_field_type *fields,
  750.                  const char *output_fields,
  751.                  const char *output_separator,
  752.                  uint32_t output_flags,
  753.                  const char *sort_keys,
  754.                  void *private);
  755. int dm_report_object(struct dm_report *rh, void *object);
  756. int dm_report_output(struct dm_report *rh);
  757. void dm_report_free(struct dm_report *rh);
  758.  
  759. /*
  760.  * Prefix added to each field name with DM_REPORT_OUTPUT_FIELD_NAME_PREFIX
  761.  */
  762. int dm_report_set_output_field_name_prefix(struct dm_report *rh,
  763.                        const char *report_prefix);
  764.  
  765. /*
  766.  * Report functions are provided for simple data types.
  767.  * They take care of allocating copies of the data.
  768.  */
  769. int dm_report_field_string(struct dm_report *rh, struct dm_report_field *field,
  770.                const char **data);
  771. int dm_report_field_int32(struct dm_report *rh, struct dm_report_field *field,
  772.               const int32_t *data);
  773. int dm_report_field_uint32(struct dm_report *rh, struct dm_report_field *field,
  774.                const uint32_t *data);
  775. int dm_report_field_int(struct dm_report *rh, struct dm_report_field *field,
  776.             const int *data);
  777. int dm_report_field_uint64(struct dm_report *rh, struct dm_report_field *field,
  778.                const uint64_t *data);
  779.  
  780. /*
  781.  * For custom fields, allocate the data in 'mem' and use
  782.  * dm_report_field_set_value().
  783.  * 'sortvalue' may be NULL if it matches 'value'
  784.  */
  785. void dm_report_field_set_value(struct dm_report_field *field, const void *value,
  786.                    const void *sortvalue);
  787.  
  788. #endif                /* LIB_DEVICE_MAPPER_H */
  789.