-1.02.00-cvs (2005-10-04)
+1.02.00-cvs (2005-10-16)
Version 1.02.00 -
=============================
Added dependency tree functions to library.
+ Added hash, bitset, pool, dbg_malloc to library.
Added ls --tree to dmsetup.
Added dmsetup --nolockfs support for suspend/reload.
printf("%s\t(%u, %u)\n", name, info.major, info.minor);
}
-static int _mknodes_single(char *name)
-{
- struct dm_task *dmt;
- int r = 0;
-
- if (!(dmt = dm_task_create(DM_DEVICE_MKNODES)))
- return 0;
-
- if (!_set_task_device(dmt, name, 1))
- goto out;
-
- if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
- goto out;
-
- if (!dm_task_run(dmt))
- goto out;
-
- r = 1;
-
- out:
- dm_task_destroy(dmt);
- return r;
-}
-
static int _mknodes(int argc, char **argv, void *data)
{
- return _mknodes_single(argc > 1 ? argv[1] : NULL);
+ return dm_mknodes(argc > 1 ? argv[1] : NULL);
}
static int _exec_command(char *name)
if (argc < 0)
return 0;
- if (!_mknodes_single(name))
+ if (!dm_mknodes(name))
return 0;
n = snprintf(path, sizeof(path), "%s/%s", dm_dir(), name);
-../lib/datastruct/bitset.h
-../lib/datastruct/hash.h
../lib/libdevmapper.h
../lib/libdm-file.h
../lib/libdm-event.h
-../lib/mm/dbg_malloc.h
-../lib/mm/pool.h
../multilog/libmultilog.h
../po/pogen.h
#include "log.h"
#include "intl.h"
-#include "dbg_malloc.h"
#include <stdio.h>
#include <stdlib.h>
dm_deptree_next_child
dm_deptree_next_parent
dm_is_dm_major
+dm_mknodes
+dm_malloc_aux
+dm_strdup
+dm_free_aux
+dm_realloc_aux
+dm_dump_memory
+dm_bounds_check
+dm_pool_create
+dm_pool_destroy
+dm_pool_alloc
+dm_pool_alloc_aligned
+dm_pool_empty
+dm_pool_free
+dm_pool_begin_object
+dm_pool_grow_object
+dm_pool_end_object
+dm_pool_abandon_object
+dm_pool_strdup
+dm_pool_strndup
+dm_pool_zalloc
+dm_bitset_create
+dm_bitset_destroy
+dm_bit_union
+dm_bit_get_first
+dm_bit_get_next
+dm_hash_create
+dm_hash_destroy
+dm_hash_wipe
+dm_hash_lookup
+dm_hash_insert
+dm_hash_remove
+dm_hash_lookup_binary
+dm_hash_insert_binary
+dm_hash_remove_binary
+dm_hash_get_num_entries
+dm_hash_iter
+dm_hash_get_key
+dm_hash_get_data
+dm_hash_get_first
+dm_hash_get_next
*/
#include "lib.h"
-#include "bitset.h"
/* FIXME: calculate this. */
#define INT_SHIFT 5
-bitset_t bitset_create(struct pool *mem, unsigned num_bits)
+dm_bitset_t dm_bitset_create(struct dm_pool *mem, unsigned num_bits)
{
- unsigned n = (num_bits / BITS_PER_INT) + 2;
+ unsigned n = (num_bits / DM_BITS_PER_INT) + 2;
size_t size = sizeof(int) * n;
- bitset_t bs;
+ dm_bitset_t bs;
if (mem)
- bs = pool_zalloc(mem, size);
+ bs = dm_pool_zalloc(mem, size);
else
- bs = dbg_malloc(size);
+ bs = dm_malloc(size);
if (!bs)
return NULL;
*bs = num_bits;
if (!mem)
- bit_clear_all(bs);
+ dm_bit_clear_all(bs);
return bs;
}
-void bitset_destroy(bitset_t bs)
+void dm_bitset_destroy(dm_bitset_t bs)
{
- dbg_free(bs);
+ dm_free(bs);
}
-void bit_union(bitset_t out, bitset_t in1, bitset_t in2)
+void dm_bit_union(dm_bitset_t out, dm_bitset_t in1, dm_bitset_t in2)
{
int i;
- for (i = (in1[0] / BITS_PER_INT) + 1; i; i--)
+ for (i = (in1[0] / DM_BITS_PER_INT) + 1; i; i--)
out[i] = in1[i] | in2[i];
}
*/
static inline int _test_word(uint32_t test, int bit)
{
- while (bit < BITS_PER_INT) {
+ while (bit < DM_BITS_PER_INT) {
if (test & (0x1 << bit))
return bit;
bit++;
return -1;
}
-int bit_get_next(bitset_t bs, int last_bit)
+int dm_bit_get_next(dm_bitset_t bs, int last_bit)
{
int bit, word;
uint32_t test;
while (last_bit < bs[0]) {
word = last_bit >> INT_SHIFT;
test = bs[word + 1];
- bit = last_bit & (BITS_PER_INT - 1);
+ bit = last_bit & (DM_BITS_PER_INT - 1);
if ((bit = _test_word(test, bit)) >= 0)
- return (word * BITS_PER_INT) + bit;
+ return (word * DM_BITS_PER_INT) + bit;
- last_bit = last_bit - (last_bit & (BITS_PER_INT - 1)) +
- BITS_PER_INT;
+ last_bit = last_bit - (last_bit & (DM_BITS_PER_INT - 1)) +
+ DM_BITS_PER_INT;
}
return -1;
}
-int bit_get_first(bitset_t bs)
+int dm_bit_get_first(dm_bitset_t bs)
{
- return bit_get_next(bs, -1);
+ return dm_bit_get_next(bs, -1);
}
*/
#include "lib.h"
-#include "hash.h"
-struct hash_node {
- struct hash_node *next;
+struct dm_hash_node {
+ struct dm_hash_node *next;
void *data;
int keylen;
char key[0];
};
-struct hash_table {
+struct dm_hash_table {
int num_nodes;
int num_slots;
- struct hash_node **slots;
+ struct dm_hash_node **slots;
};
/* Permutation of the Integers 0 through 255 */
209
};
-static struct hash_node *_create_node(const char *str, int len)
+static struct dm_hash_node *_create_node(const char *str, int len)
{
- struct hash_node *n = dbg_malloc(sizeof(*n) + len);
+ struct dm_hash_node *n = dm_malloc(sizeof(*n) + len);
if (n) {
memcpy(n->key, str, len);
return h;
}
-struct hash_table *hash_create(unsigned size_hint)
+struct dm_hash_table *dm_hash_create(unsigned size_hint)
{
size_t len;
unsigned new_size = 16u;
- struct hash_table *hc = dbg_malloc(sizeof(*hc));
+ struct dm_hash_table *hc = dm_malloc(sizeof(*hc));
if (!hc) {
stack;
hc->num_slots = new_size;
len = sizeof(*(hc->slots)) * new_size;
- if (!(hc->slots = dbg_malloc(len))) {
+ if (!(hc->slots = dm_malloc(len))) {
stack;
goto bad;
}
return hc;
bad:
- dbg_free(hc->slots);
- dbg_free(hc);
+ dm_free(hc->slots);
+ dm_free(hc);
return 0;
}
-static void _free_nodes(struct hash_table *t)
+static void _free_nodes(struct dm_hash_table *t)
{
- struct hash_node *c, *n;
+ struct dm_hash_node *c, *n;
int i;
for (i = 0; i < t->num_slots; i++)
for (c = t->slots[i]; c; c = n) {
n = c->next;
- dbg_free(c);
+ dm_free(c);
}
}
-void hash_destroy(struct hash_table *t)
+void dm_hash_destroy(struct dm_hash_table *t)
{
_free_nodes(t);
- dbg_free(t->slots);
- dbg_free(t);
+ dm_free(t->slots);
+ dm_free(t);
}
-static inline struct hash_node **_find(struct hash_table *t, const char *key,
+static inline struct dm_hash_node **_find(struct dm_hash_table *t, const char *key,
uint32_t len)
{
unsigned h = _hash(key, len) & (t->num_slots - 1);
- struct hash_node **c;
+ struct dm_hash_node **c;
for (c = &t->slots[h]; *c; c = &((*c)->next))
if (!memcmp(key, (*c)->key, len))
return c;
}
-void *hash_lookup_binary(struct hash_table *t, const char *key,
+void *dm_hash_lookup_binary(struct dm_hash_table *t, const char *key,
uint32_t len)
{
- struct hash_node **c = _find(t, key, len);
+ struct dm_hash_node **c = _find(t, key, len);
return *c ? (*c)->data : 0;
}
-int hash_insert_binary(struct hash_table *t, const char *key,
+int dm_hash_insert_binary(struct dm_hash_table *t, const char *key,
uint32_t len, void *data)
{
- struct hash_node **c = _find(t, key, len);
+ struct dm_hash_node **c = _find(t, key, len);
if (*c)
(*c)->data = data;
else {
- struct hash_node *n = _create_node(key, len);
+ struct dm_hash_node *n = _create_node(key, len);
if (!n)
return 0;
return 1;
}
-void hash_remove_binary(struct hash_table *t, const char *key,
+void dm_hash_remove_binary(struct dm_hash_table *t, const char *key,
uint32_t len)
{
- struct hash_node **c = _find(t, key, len);
+ struct dm_hash_node **c = _find(t, key, len);
if (*c) {
- struct hash_node *old = *c;
+ struct dm_hash_node *old = *c;
*c = (*c)->next;
- dbg_free(old);
+ dm_free(old);
t->num_nodes--;
}
}
-void *hash_lookup(struct hash_table *t, const char *key)
+void *dm_hash_lookup(struct dm_hash_table *t, const char *key)
{
- return hash_lookup_binary(t, key, strlen(key) + 1);
+ return dm_hash_lookup_binary(t, key, strlen(key) + 1);
}
-int hash_insert(struct hash_table *t, const char *key, void *data)
+int dm_hash_insert(struct dm_hash_table *t, const char *key, void *data)
{
- return hash_insert_binary(t, key, strlen(key) + 1, data);
+ return dm_hash_insert_binary(t, key, strlen(key) + 1, data);
}
-void hash_remove(struct hash_table *t, const char *key)
+void dm_hash_remove(struct dm_hash_table *t, const char *key)
{
- hash_remove_binary(t, key, strlen(key) + 1);
+ dm_hash_remove_binary(t, key, strlen(key) + 1);
}
-unsigned hash_get_num_entries(struct hash_table *t)
+unsigned dm_hash_get_num_entries(struct dm_hash_table *t)
{
return t->num_nodes;
}
-void hash_iter(struct hash_table *t, iterate_fn f)
+void dm_hash_iter(struct dm_hash_table *t, dm_hash_iterate_fn f)
{
- struct hash_node *c;
+ struct dm_hash_node *c;
int i;
for (i = 0; i < t->num_slots; i++)
f(c->data);
}
-void hash_wipe(struct hash_table *t)
+void dm_hash_wipe(struct dm_hash_table *t)
{
_free_nodes(t);
- memset(t->slots, 0, sizeof(struct hash_node *) * t->num_slots);
+ memset(t->slots, 0, sizeof(struct dm_hash_node *) * t->num_slots);
t->num_nodes = 0;
}
-char *hash_get_key(struct hash_table *t, struct hash_node *n)
+char *dm_hash_get_key(struct dm_hash_table *t, struct dm_hash_node *n)
{
return n->key;
}
-void *hash_get_data(struct hash_table *t, struct hash_node *n)
+void *dm_hash_get_data(struct dm_hash_table *t, struct dm_hash_node *n)
{
return n->data;
}
-static struct hash_node *_next_slot(struct hash_table *t, unsigned s)
+static struct dm_hash_node *_next_slot(struct dm_hash_table *t, unsigned s)
{
- struct hash_node *c = NULL;
+ struct dm_hash_node *c = NULL;
int i;
for (i = s; i < t->num_slots && !c; i++)
return c;
}
-struct hash_node *hash_get_first(struct hash_table *t)
+struct dm_hash_node *dm_hash_get_first(struct dm_hash_table *t)
{
return _next_slot(t, 0);
}
-struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n)
+struct dm_hash_node *dm_hash_get_next(struct dm_hash_table *t, struct dm_hash_node *n)
{
unsigned h = _hash(n->key, n->keylen) & (t->num_slots - 1);
return n->next ? n->next : _next_slot(t, h + 1);
#include "libdm-targets.h"
#include "libdm-common.h"
#include "libdm-file.h"
-#include "bitset.h"
#ifdef DM_COMPAT
# include "libdm-compat.h"
static int _dm_version = DM_VERSION_MAJOR;
static int _log_suppress = 0;
-static bitset_t _dm_bitset = NULL;
+static dm_bitset_t _dm_bitset = NULL;
static int _control_fd = -1;
static int _version_checked = 0;
static int _version_ok = 1;
fclose(fl);
return 1;
}
- bit_set(_dm_bitset, num);
+ dm_bit_set(_dm_bitset, num);
}
} else do {
c = fgetc(fl);
if (_dm_bitset)
return 1;
- if (!(_dm_bitset = bitset_create(NULL, NUMBER_OF_MAJORS)))
+ if (!(_dm_bitset = dm_bitset_create(NULL, NUMBER_OF_MAJORS)))
return 0;
if (!_get_proc_number(PROC_DEVICES, DM_NAME, NULL)) {
- bitset_destroy(_dm_bitset);
+ dm_bitset_destroy(_dm_bitset);
_dm_bitset = NULL;
return 0;
}
if (!_create_dm_bitset())
return 0;
- return bit(_dm_bitset, major) ? 1 : 0;
+ return dm_bit(_dm_bitset, major) ? 1 : 0;
}
static int _open_control(void)
for (t = dmt->head; t; t = n) {
n = t->next;
- dbg_free(t->params);
- dbg_free(t->type);
- dbg_free(t);
+ dm_free(t->params);
+ dm_free(t->type);
+ dm_free(t);
}
if (dmt->dev_name)
- dbg_free(dmt->dev_name);
+ dm_free(dmt->dev_name);
if (dmt->newname)
- dbg_free(dmt->newname);
+ dm_free(dmt->newname);
if (dmt->message)
- dbg_free(dmt->message);
+ dm_free(dmt->message);
if (dmt->dmi.v4)
- dbg_free(dmt->dmi.v4);
+ dm_free(dmt->dmi.v4);
if (dmt->uuid)
- dbg_free(dmt->uuid);
+ dm_free(dmt->uuid);
- dbg_free(dmt);
+ dm_free(dmt);
}
/*
if (len < min_size)
len = min_size;
- if (!(dmi = dbg_malloc(len)))
+ if (!(dmi = dm_malloc(len)))
return NULL;
memset(dmi, 0, len);
return dmi;
bad:
- dbg_free(dmi);
+ dm_free(dmi);
return NULL;
}
dmt->type = DM_DEVICE_INFO;
if (!dm_task_run(dmt))
goto bad;
- dbg_free(dmi); /* We'll use what info returned */
+ dm_free(dmi); /* We'll use what info returned */
return 1;
}
return 1;
bad:
- dbg_free(dmi);
+ dm_free(dmi);
return 0;
}
int dm_task_set_newname(struct dm_task *dmt, const char *newname)
{
- if (!(dmt->newname = dbg_strdup(newname))) {
+ if (!(dmt->newname = dm_strdup(newname))) {
log_error("dm_task_set_newname: strdup(%s) failed", newname);
return 0;
}
int dm_task_set_message(struct dm_task *dmt, const char *message)
{
- if (!(dmt->message = dbg_strdup(message))) {
+ if (!(dmt->message = dm_strdup(message))) {
log_error("dm_task_set_message: strdup(%s) failed", message);
return 0;
}
struct target *create_target(uint64_t start, uint64_t len, const char *type,
const char *params)
{
- struct target *t = dbg_malloc(sizeof(*t));
+ struct target *t = dm_malloc(sizeof(*t));
if (!t) {
log_error("create_target: malloc(%d) failed", sizeof(*t));
memset(t, 0, sizeof(*t));
- if (!(t->params = dbg_strdup(params))) {
+ if (!(t->params = dm_strdup(params))) {
log_error("create_target: strdup(params) failed");
goto bad;
}
- if (!(t->type = dbg_strdup(type))) {
+ if (!(t->type = dm_strdup(type))) {
log_error("create_target: strdup(type) failed");
goto bad;
}
return t;
bad:
- dbg_free(t->params);
- dbg_free(t->type);
- dbg_free(t);
+ dm_free(t->params);
+ dm_free(t->type);
+ dm_free(t);
return NULL;
}
while (repeat_count--)
len *= 2;
- if (!(dmi = dbg_malloc(len)))
+ if (!(dmi = dm_malloc(len)))
return NULL;
memset(dmi, 0, len);
return dmi;
bad:
- dbg_free(dmi);
+ dm_free(dmi);
return NULL;
}
/* Use the original structure last so the info will be correct */
dmt->type = DM_DEVICE_RESUME;
- dbg_free(dmt->uuid);
+ dm_free(dmt->uuid);
dmt->uuid = NULL;
r = dm_task_run(dmt);
log_error("device-mapper ioctl "
"cmd %d failed: %s",
_IOC_NR(command), strerror(errno));
- dbg_free(dmi);
+ dm_free(dmi);
return NULL;
}
}
case DM_DEVICE_TABLE:
case DM_DEVICE_WAITEVENT:
_ioctl_buffer_double_factor++;
- dbg_free(dmi);
+ dm_free(dmi);
goto repeat_ioctl;
default:
log_error("Warning: libdevmapper buffer too small for data");
return 1;
bad:
- dbg_free(dmi);
+ dm_free(dmi);
return 0;
}
{
dm_lib_release();
if (_dm_bitset)
- bitset_destroy(_dm_bitset);
+ dm_bitset_destroy(_dm_bitset);
_dm_bitset = NULL;
- dump_memory();
+ dm_dump_memory();
_version_ok = 1;
_version_checked = 0;
}
# include <linux/types.h>
#endif
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+
/*
* Since it is quite laborious to build the ioctl
* arguments for the device-mapper people are
void dm_lib_release(void);
void dm_lib_exit(void) __attribute((destructor));
+/***********************************************************************
+ * Wrappers
+ ***********************************************************************/
+
+/*
+ * Use NULL for all devices.
+ */
+int dm_mknodes(const char *name);
+
/*****************************
* Dependency tree functions *
*****************************/
*/
int dm_deptree_node_num_children(struct deptree_node *node, uint32_t inverted);
+/*****************************************************************************
+ * Library functions
+ *****************************************************************************/
+
+void *dm_malloc_aux(size_t s, const char *file, int line);
+#define dm_malloc(s) dm_malloc_aux((s), __FILE__, __LINE__)
+
+char *dm_strdup(const char *str);
+
+#ifdef DEBUG_MEM
+
+void dm_free_aux(void *p);
+void *dm_realloc_aux(void *p, unsigned int s, const char *file, int line);
+int dm_dump_memory(void);
+void dm_bounds_check(void);
+
+# define dm_free(p) dm_free_aux(p)
+# define dm_realloc(p, s) dm_realloc_aux(p, s, __FILE__, __LINE__)
+
+#else
+
+# define dm_free(p) free(p)
+# define dm_realloc(p, s) realloc(p, s)
+# define dm_dump_memory()
+# define dm_bounds_check()
+
+#endif
+
+/******************
+ * pool functions
+ ******************/
+
+/*
+ * 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);
+ * if (!dm_pool_grow_object(mem, buffer, strlen(buffer)))
+ * 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.
+ *
+ */
+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))
+
+/****************
+ * 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))
+
#endif /* LIB_DEVICE_MAPPER_H */
struct dm_task *dm_task_create(int type)
{
- struct dm_task *dmt = dbg_malloc(sizeof(*dmt));
+ struct dm_task *dmt = dm_malloc(sizeof(*dmt));
if (!dmt) {
log_error("dm_task_create: malloc(%d) failed", sizeof(*dmt));
struct stat st1, st2;
if (dmt->dev_name) {
- dbg_free(dmt->dev_name);
+ dm_free(dmt->dev_name);
dmt->dev_name = NULL;
}
name = pos + 1;
}
- if (!(dmt->dev_name = dbg_strdup(name))) {
+ if (!(dmt->dev_name = dm_strdup(name))) {
log_error("dm_task_set_name: strdup(%s) failed", name);
return 0;
}
int dm_task_set_uuid(struct dm_task *dmt, const char *uuid)
{
if (dmt->uuid) {
- dbg_free(dmt->uuid);
+ dm_free(dmt->uuid);
dmt->uuid = NULL;
}
- if (!(dmt->uuid = dbg_strdup(uuid))) {
+ if (!(dmt->uuid = dm_strdup(uuid))) {
log_error("dm_task_set_uuid: strdup(%s) failed", uuid);
return 0;
}
size_t len = strlen(dev_name) + strlen(old_name) + 2;
char *pos;
- if (!(nop = dbg_malloc(sizeof(*nop) + len))) {
+ if (!(nop = dm_malloc(sizeof(*nop) + len))) {
log_error("Insufficient memory to stack mknod operation");
return 0;
}
_do_node_op(nop->type, nop->dev_name, nop->major, nop->minor,
nop->uid, nop->gid, nop->mode, nop->old_name);
list_del(&nop->list);
- dbg_free(nop);
+ dm_free(nop);
}
}
{
return _dm_dir;
}
+
+int dm_mknodes(const char *name)
+{
+ struct dm_task *dmt;
+ int r = 0;
+
+ if (!(dmt = dm_task_create(DM_DEVICE_MKNODES)))
+ return 0;
+
+ if (name && !dm_task_set_name(dmt, name))
+ goto out;
+
+ if (!dm_task_no_open_count(dmt))
+ goto out;
+
+ r = dm_task_run(dmt);
+
+out:
+ dm_task_destroy(dmt);
+ return r;
+}
#include "libdm-common.h"
#include "list.h"
#include "kdev_t.h"
-#include "pool.h"
-#include "hash.h"
#include <stdarg.h>
#include <sys/param.h>
};
struct deptree {
- struct pool *mem;
- struct hash_table *devs;
+ struct dm_pool *mem;
+ struct dm_hash_table *devs;
struct deptree_node root;
};
{
struct deptree *deptree;
- if (!(deptree = dbg_malloc(sizeof(*deptree)))) {
+ if (!(deptree = dm_malloc(sizeof(*deptree)))) {
log_error("dm_deptree_create malloc failed");
return NULL;
}
list_init(&deptree->root.uses);
list_init(&deptree->root.used_by);
- if (!(deptree->mem = pool_create("deptree", 1024))) {
+ if (!(deptree->mem = dm_pool_create("deptree", 1024))) {
log_error("deptree pool creation failed");
- dbg_free(deptree);
+ dm_free(deptree);
return NULL;
}
- if (!(deptree->devs = hash_create(8))) {
+ if (!(deptree->devs = dm_hash_create(8))) {
log_error("deptree hash creation failed");
- pool_destroy(deptree->mem);
- dbg_free(deptree);
+ dm_pool_destroy(deptree->mem);
+ dm_free(deptree);
return NULL;
}
if (!deptree)
return;
- hash_destroy(deptree->devs);
- pool_destroy(deptree->mem);
- dbg_free(deptree);
+ dm_hash_destroy(deptree->devs);
+ dm_pool_destroy(deptree->mem);
+ dm_free(deptree);
}
static int _nodes_are_linked(struct deptree_node *parent,
{
struct deptree_link *dlink;
- if (!(dlink = pool_alloc(node->deptree->mem, sizeof(*dlink)))) {
+ if (!(dlink = dm_pool_alloc(node->deptree->mem, sizeof(*dlink)))) {
log_error("deptree link allocation failed");
return 0;
}
struct deptree_node *node;
uint64_t dev;
- if (!(node = pool_zalloc(deptree->mem, sizeof(*node)))) {
+ if (!(node = dm_pool_zalloc(deptree->mem, sizeof(*node)))) {
log_error("_create_deptree_node alloc failed");
return NULL;
}
dev = MKDEV(info->major, info->minor);
- if (!hash_insert_binary(deptree->devs, (const char *) &dev,
+ if (!dm_hash_insert_binary(deptree->devs, (const char *) &dev,
sizeof(dev), node)) {
log_error("deptree node hash insertion failed");
- pool_free(deptree->mem, node);
+ dm_pool_free(deptree->mem, node);
return NULL;
}
{
uint64_t dev = MKDEV(major, minor);
- return hash_lookup_binary(deptree->devs, (const char *) &dev,
+ return dm_hash_lookup_binary(deptree->devs, (const char *) &dev,
sizeof(dev));
}
-static int _deps(struct dm_task **dmt, struct pool *mem, uint32_t major, uint32_t minor,
+static int _deps(struct dm_task **dmt, struct dm_pool *mem, uint32_t major, uint32_t minor,
const char **name, const char **uuid,
struct dm_info *info, struct dm_deps **deps)
{
minor, info->minor);
goto failed;
}
- if (!(*name = pool_strdup(mem, dm_task_get_name(*dmt)))) {
+ if (!(*name = dm_pool_strdup(mem, dm_task_get_name(*dmt)))) {
log_error("name pool_strdup failed");
goto failed;
}
- if (!(*uuid = pool_strdup(mem, dm_task_get_uuid(*dmt)))) {
+ if (!(*uuid = dm_pool_strdup(mem, dm_task_get_uuid(*dmt)))) {
log_error("uuid pool_strdup failed");
goto failed;
}
*/
#include "lib.h"
-#include "dbg_malloc.h"
#include <assert.h>
#include <stdarg.h>
-char *dbg_strdup(const char *str)
+char *dm_strdup(const char *str)
{
- char *ret = dbg_malloc(strlen(str) + 1);
+ char *ret = dm_malloc(strlen(str) + 1);
if (ret)
strcpy(ret, str);
static struct memblock *_head = 0;
static struct memblock *_tail = 0;
-void *malloc_aux(size_t s, const char *file, int line)
+void *dm_malloc_aux(size_t s, const char *file, int line)
{
struct memblock *nb;
size_t tsize = s + sizeof(*nb) + sizeof(unsigned long);
nb->line = line;
#ifdef BOUNDS_CHECK
- bounds_check();
+ dm_bounds_check();
#endif
/* setup fields */
return nb + 1;
}
-void free_aux(void *p)
+void dm_free_aux(void *p)
{
char *ptr;
size_t i;
return;
#ifdef BOUNDS_CHECK
- bounds_check();
+ dm_bounds_check();
#endif
/* sanity check */
free(mb);
}
-void *realloc_aux(void *p, unsigned int s, const char *file, int line)
+void *dm_realloc_aux(void *p, unsigned int s, const char *file, int line)
{
void *r;
struct memblock *mb = ((struct memblock *) p) - 1;
- r = malloc_aux(s, file, line);
+ r = dm_malloc_aux(s, file, line);
if (p) {
memcpy(r, p, mb->length);
- free_aux(p);
+ dm_free_aux(p);
}
return r;
}
-int dump_memory(void)
+int dm_dump_memory(void)
{
unsigned long tot = 0;
struct memblock *mb;
return 1;
}
-void bounds_check(void)
+void dm_bounds_check(void)
{
struct memblock *mb = _head;
while (mb) {
#else
-void *malloc_aux(size_t s, const char *file, int line)
+void *dm_malloc_aux(size_t s, const char *file, int line)
{
if (s > 50000000) {
log_error("Huge memory allocation (size %" PRIsize_t
#include <string.h>
void *malloc_aux(size_t s, const char *file, int line);
-#define dbg_malloc(s) malloc_aux((s), __FILE__, __LINE__)
+#define dm_malloc(s) malloc_aux((s), __FILE__, __LINE__)
char *dbg_strdup(const char *str);
int dump_memory(void);
void bounds_check(void);
-# define dbg_free(p) free_aux(p)
+# define dm_free(p) free_aux(p)
# define dbg_realloc(p, s) realloc_aux(p, s, __FILE__, __LINE__)
#else
-# define dbg_free(p) free(p)
+# define dm_free(p) free(p)
# define dbg_realloc(p, s) realloc(p, s)
# define dump_memory()
# define bounds_check()
*/
#include "lib.h"
-#include "pool.h"
struct block {
struct block *next;
unsigned int bytes, maxbytes;
} pool_stats;
-struct pool {
+struct dm_pool {
const char *name;
int begun;
/* by default things come out aligned for doubles */
#define DEFAULT_ALIGNMENT __alignof__ (double)
-struct pool *pool_create(const char *name, size_t chunk_hint)
+struct pool *dm_pool_create(const char *name, size_t chunk_hint)
{
- struct pool *mem = dbg_malloc(sizeof(*mem));
+ struct dm_pool *mem = dm_malloc(sizeof(*mem));
if (!mem) {
log_error("Couldn't create memory pool %s (size %"
return mem;
}
-static void _free_blocks(struct pool *p, struct block *b)
+static void _free_blocks(struct dm_pool *p, struct block *b)
{
struct block *n;
p->stats.blocks_allocated--;
n = b->next;
- dbg_free(b->data);
- dbg_free(b);
+ dm_free(b->data);
+ dm_free(b);
b = n;
}
}
-static void _pool_stats(struct pool *p, const char *action)
+static void _pool_stats(struct dm_pool *p, const char *action)
{
#ifdef DEBUG_POOL
log_debug("%s mempool %s: %u/%u bytes, %u/%u blocks, "
#endif
}
-void pool_destroy(struct pool *p)
+void dm_pool_destroy(struct dm_pool *p)
{
_pool_stats(p, "Destroying");
_free_blocks(p, p->blocks);
- dbg_free(p);
+ dm_free(p);
}
-void *pool_alloc(struct pool *p, size_t s)
+void *dm_pool_alloc(struct dm_pool *p, size_t s)
{
- return pool_alloc_aligned(p, s, DEFAULT_ALIGNMENT);
+ return dm_pool_alloc_aligned(p, s, DEFAULT_ALIGNMENT);
}
-static void _append_block(struct pool *p, struct block *b)
+static void _append_block(struct dm_pool *p, struct block *b)
{
if (p->tail) {
p->tail->next = b;
/* FIXME: I'm currently ignoring the alignment arg. */
size_t len = sizeof(struct block) + s;
- struct block *b = dbg_malloc(len);
+ struct block *b = dm_malloc(len);
/*
* Too lazy to implement alignment for debug version, and
return NULL;
}
- if (!(b->data = dbg_malloc(s))) {
+ if (!(b->data = dm_malloc(s))) {
log_err(_oom);
- dbg_free(b);
+ dm_free(b);
return NULL;
}
return b;
}
-void *pool_alloc_aligned(struct pool *p, size_t s, unsigned alignment)
+void *dm_pool_alloc_aligned(struct dm_pool *p, size_t s, unsigned alignment)
{
struct block *b = _new_block(s, alignment);
return b->data;
}
-void pool_empty(struct pool *p)
+void dm_pool_empty(struct dm_pool *p)
{
_pool_stats(p, "Emptying");
_free_blocks(p, p->blocks);
p->blocks = p->tail = NULL;
}
-void pool_free(struct pool *p, void *ptr)
+void dm_pool_free(struct dm_pool *p, void *ptr)
{
struct block *b, *prev = NULL;
_pool_stats(p, "Freeing (after)");
}
-int pool_begin_object(struct pool *p, size_t init_size)
+int dm_pool_begin_object(struct dm_pool *p, size_t init_size)
{
assert(!p->begun);
p->begun = 1;
return 1;
}
-int pool_grow_object(struct pool *p, const void *buffer, size_t delta)
+int dm_pool_grow_object(struct dm_pool *p, const void *buffer, size_t delta)
{
struct block *new;
size_t size = delta;
if (p->object) {
memcpy(new->data, p->object->data, p->object->size);
- dbg_free(p->object->data);
- dbg_free(p->object);
+ dm_free(p->object->data);
+ dm_free(p->object);
}
p->object = new;
return 1;
}
-void *pool_end_object(struct pool *p)
+void *dm_pool_end_object(struct dm_pool *p)
{
assert(p->begun);
_append_block(p, p->object);
return p->tail->data;
}
-void pool_abandon_object(struct pool *p)
+void dm_pool_abandon_object(struct dm_pool *p)
{
assert(p->begun);
- dbg_free(p->object);
+ dm_free(p->object);
p->begun = 0;
p->object = NULL;
}
*/
#include "lib.h"
-#include "pool.h"
struct chunk {
char *begin, *end;
struct chunk *prev;
};
-struct pool {
+struct dm_pool {
struct chunk *chunk, *spare_chunk; /* spare_chunk is a one entry free
list to stop 'bobbling' */
size_t chunk_size;
};
void _align_chunk(struct chunk *c, unsigned alignment);
-struct chunk *_new_chunk(struct pool *p, size_t s);
+struct chunk *_new_chunk(struct dm_pool *p, size_t s);
/* by default things come out aligned for doubles */
#define DEFAULT_ALIGNMENT __alignof__ (double)
-struct pool *pool_create(const char *name, size_t chunk_hint)
+struct dm_pool *dm_pool_create(const char *name, size_t chunk_hint)
{
size_t new_size = 1024;
- struct pool *p = dbg_malloc(sizeof(*p));
+ struct dm_pool *p = dm_malloc(sizeof(*p));
if (!p) {
log_error("Couldn't create memory pool %s (size %"
return p;
}
-void pool_destroy(struct pool *p)
+void dm_pool_destroy(struct dm_pool *p)
{
struct chunk *c, *pr;
- dbg_free(p->spare_chunk);
+ dm_free(p->spare_chunk);
c = p->chunk;
while (c) {
pr = c->prev;
- dbg_free(c);
+ dm_free(c);
c = pr;
}
- dbg_free(p);
+ dm_free(p);
}
-void *pool_alloc(struct pool *p, size_t s)
+void *dm_pool_alloc(struct dm_pool *p, size_t s)
{
- return pool_alloc_aligned(p, s, DEFAULT_ALIGNMENT);
+ return dm_pool_alloc_aligned(p, s, DEFAULT_ALIGNMENT);
}
-void *pool_alloc_aligned(struct pool *p, size_t s, unsigned alignment)
+void *dm_pool_alloc_aligned(struct dm_pool *p, size_t s, unsigned alignment)
{
struct chunk *c = p->chunk;
void *r;
return r;
}
-void pool_empty(struct pool *p)
+void dm_pool_empty(struct dm_pool *p)
{
struct chunk *c;
;
if (c)
- pool_free(p, (char *) (c + 1));
+ dm_pool_free(p, (char *) (c + 1));
}
-void pool_free(struct pool *p, void *ptr)
+void dm_pool_free(struct dm_pool *p, void *ptr)
{
struct chunk *c = p->chunk;
}
if (p->spare_chunk)
- dbg_free(p->spare_chunk);
+ dm_free(p->spare_chunk);
p->spare_chunk = c;
c = c->prev;
}
p->chunk = c;
}
-int pool_begin_object(struct pool *p, size_t hint)
+int dm_pool_begin_object(struct dm_pool *p, size_t hint)
{
struct chunk *c = p->chunk;
const size_t align = DEFAULT_ALIGNMENT;
return 1;
}
-int pool_grow_object(struct pool *p, const void *extra, size_t n)
+int dm_pool_grow_object(struct dm_pool *p, const void *extra, size_t n)
{
struct chunk *c = p->chunk, *nc;
return 1;
}
-void *pool_end_object(struct pool *p)
+void *dm_pool_end_object(struct dm_pool *p)
{
struct chunk *c = p->chunk;
void *r = c->begin;
return r;
}
-void pool_abandon_object(struct pool *p)
+void dm_pool_abandon_object(struct dm_pool *p)
{
p->object_len = 0;
p->object_alignment = DEFAULT_ALIGNMENT;
c->begin += alignment - ((unsigned long) c->begin & (alignment - 1));
}
-struct chunk *_new_chunk(struct pool *p, size_t s)
+struct chunk *_new_chunk(struct dm_pool *p, size_t s)
{
struct chunk *c;
c = p->spare_chunk;
p->spare_chunk = 0;
} else {
- if (!(c = dbg_malloc(s))) {
+ if (!(c = dm_malloc(s))) {
log_error("Out of memory. Requested %" PRIsize_t
" bytes.", s);
return NULL;
#include "pool-fast.c"
#endif
-char *pool_strdup(struct pool *p, const char *str)
+char *dm_pool_strdup(struct dm_pool *p, const char *str)
{
- char *ret = pool_alloc(p, strlen(str) + 1);
+ char *ret = dm_pool_alloc(p, strlen(str) + 1);
if (ret)
strcpy(ret, str);
return ret;
}
-char *pool_strndup(struct pool *p, const char *str, size_t n)
+char *dm_pool_strndup(struct dm_pool *p, const char *str, size_t n)
{
- char *ret = pool_alloc(p, n + 1);
+ char *ret = dm_pool_alloc(p, n + 1);
if (ret) {
strncpy(ret, str, n);
return ret;
}
-void *pool_zalloc(struct pool *p, size_t s)
+void *dm_pool_zalloc(struct dm_pool *p, size_t s)
{
- void *ptr = pool_alloc(p, s);
+ void *ptr = dm_pool_alloc(p, s);
if (ptr)
memset(ptr, 0, s);