diff --git a/libdm/Makefile.in b/libdm/Makefile.in index 5930e16f6..eb1e7d1a4 100644 --- a/libdm/Makefile.in +++ b/libdm/Makefile.in @@ -9,7 +9,9 @@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ interface = @interface@ -SOURCES=$(interface)/libdevmapper.c +SOURCES=$(interface)/libdevmapper.c libdm-common.c + +INCLUDES=-I$(interface) TARGETS=$(interface)/libdevmapper.so diff --git a/libdm/ioctl/libdevmapper.c b/libdm/ioctl/libdevmapper.c index fd95ca87f..29b316488 100644 --- a/libdm/ioctl/libdevmapper.c +++ b/libdm/ioctl/libdevmapper.c @@ -14,74 +14,17 @@ #include #include #include -#include #include - -#include #include -#define DEV_DIR "/dev/" +#include +#include + +#include "libdm-targets.h" +#include "libdm-common.h" + #define ALIGNMENT sizeof(int) -static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR; - -/* - * Library users can provide their own logging - * function. - */ -static void _default_log(int level, const char *file, int line, - const char *f, ...) -{ - va_list ap; - - va_start(ap, f); - vfprintf(stderr, f, ap); - va_end(ap); - - fprintf(stderr, "\n"); -} - -static dm_log_fn _log = _default_log; - -void dm_log_init(dm_log_fn fn) -{ - _log = fn; -} - -#define log(msg, x...) _log(1, __FILE__, __LINE__, msg, ## x) - -struct target { - - unsigned long long start; - unsigned long long length; - char *type; - char *params; - - struct target *next; -}; - -struct dm_task { - int type; - char *dev_name; - - struct target *head, *tail; - - struct dm_ioctl *dmi; -}; - -struct dm_task *dm_task_create(int type) -{ - struct dm_task *dmt = malloc(sizeof(*dmt)); - - if (!dmt) - return NULL; - - memset(dmt, 0, sizeof(*dmt)); - - dmt->type = type; - return dmt; -} - void dm_task_destroy(struct dm_task *dmt) { struct target *t, *n; @@ -97,14 +40,6 @@ void dm_task_destroy(struct dm_task *dmt) free(dmt); } -int dm_task_set_name(struct dm_task *dmt, const char *name) -{ - if (dmt->dev_name) - free(dmt->dev_name); - - return (dmt->dev_name = strdup(name)) ? 1 : 0; -} - int dm_task_get_info(struct dm_task *dmt, struct dm_info *info) { if (!dmt->dmi) @@ -119,23 +54,26 @@ int dm_task_get_info(struct dm_task *dmt, struct dm_info *info) return 1; } -static struct target *_create_target(unsigned long long start, - unsigned long long len, +struct target *create_target(uint64_t start, + uint64_t len, const char *type, const char *params) { struct target *t = malloc(sizeof(*t)); - if (!t) + if (!t) { + log("create_target: malloc(%d) failed", sizeof(*t)); return NULL; + } + memset(t, 0, sizeof(*t)); if (!(t->params = strdup(params))) { - log("Out of memory"); + log("create_target: strdup(params) failed"); goto bad; } if (!(t->type = strdup(type))) { - log("Out of memory"); + log("create_target: strdup(type) failed"); goto bad; } @@ -150,27 +88,6 @@ static struct target *_create_target(unsigned long long start, return NULL; } -int dm_task_add_target(struct dm_task *dmt, - unsigned long long start, - unsigned long long size, - const char *ttype, - const char *params) -{ - struct target *t = _create_target(start, size, ttype, params); - - if (!t) - return 0; - - if (!dmt->head) - dmt->head = dmt->tail = t; - else { - dmt->tail->next = t; - dmt->tail = t; - } - - return 1; -} - static void *_align(void *ptr, unsigned int align) { align--; @@ -254,60 +171,6 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt) return NULL; } -static void _build_dev_path(char *buffer, size_t len, const char *dev_name) -{ - snprintf(buffer, len, "/dev/%s/%s", DM_DIR, dev_name); -} - -static int _add_dev_node(const char *dev_name, dev_t dev) -{ - char path[PATH_MAX]; - struct stat info; - - _build_dev_path(path, sizeof(path), dev_name); - - if (stat(path, &info) >= 0) { - if (!S_ISBLK(info.st_mode)) { - log("A non-block device file at '%s' " - "is already present", path); - return 0; - } - - if (info.st_rdev == dev) - return 1; - - if (unlink(path) < 0) { - log("Unable to unlink device node for '%s'", dev_name); - return 0; - } - } - - if (mknod(path, S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, dev) < 0) { - log("Unable to make device node for '%s'", dev_name); - return 0; - } - - return 1; -} - -static int _rm_dev_node(const char *dev_name) -{ - char path[PATH_MAX]; - struct stat info; - - _build_dev_path(path, sizeof(path), dev_name); - - if (stat(path, &info) < 0) - return 1; - - if (unlink(path) < 0) { - log("Unable to unlink device node for '%s'", dev_name); - return 0; - } - - return 1; -} - int dm_task_run(struct dm_task *dmt) { int fd = -1; @@ -320,7 +183,7 @@ int dm_task_run(struct dm_task *dmt) return 0; } - snprintf(control, sizeof(control), "%s/control", _dm_dir); + snprintf(control, sizeof(control), "%s/control", dm_dir()); if ((fd = open(control, O_RDWR)) < 0) { log("Couldn't open device-mapper control device"); @@ -366,11 +229,11 @@ int dm_task_run(struct dm_task *dmt) switch (dmt->type) { case DM_DEVICE_CREATE: - _add_dev_node(dmt->dev_name, MKDEV(dmi->major, dmi->minor)); + add_dev_node(dmt->dev_name, MKDEV(dmi->major, dmi->minor)); break; case DM_DEVICE_REMOVE: - _rm_dev_node(dmt->dev_name); + rm_dev_node(dmt->dev_name); break; } @@ -384,13 +247,3 @@ int dm_task_run(struct dm_task *dmt) return 0; } -int dm_set_dev_dir(const char *dir) -{ - snprintf(_dm_dir, sizeof(_dm_dir), "%s%s", dir, DM_DIR); - return 1; -} - -const char *dm_dir(void) -{ - return _dm_dir; -} diff --git a/libdm/ioctl/libdm-targets.h b/libdm/ioctl/libdm-targets.h new file mode 100644 index 000000000..884ea110c --- /dev/null +++ b/libdm/ioctl/libdm-targets.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +struct target { + uint64_t start; + uint64_t length; + char *type; + char *params; + + struct target *next; +}; + +struct dm_task { + int type; + char *dev_name; + + struct target *head, *tail; + + struct dm_ioctl *dmi; +}; + diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h index 023863fad..8a2428f88 100644 --- a/libdm/libdevmapper.h +++ b/libdm/libdevmapper.h @@ -7,6 +7,8 @@ #ifndef LIB_DEVICE_MAPPER_H #define LIB_DEVICE_MAPPER_H +#include + /* * Since it is quite laborious to build the ioctl * arguments for the device-mapper people are @@ -64,8 +66,8 @@ int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi); * Use these to prepare for a create or reload. */ int dm_task_add_target(struct dm_task *dmt, - unsigned long long start, - unsigned long long size, + uint64_t start, + uint64_t size, const char *ttype, const char *params); diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c new file mode 100644 index 000000000..70372ce3a --- /dev/null +++ b/libdm/libdm-common.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +#include "libdevmapper.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libdm-targets.h" +#include "libdm-common.h" + +#define DEV_DIR "/dev/" + +static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR; + +/* + * Library users can provide their own logging + * function. + */ +void _default_log(int level, const char *file, int line, + const char *f, ...) +{ + va_list ap; + + va_start(ap, f); + vfprintf(stderr, f, ap); + va_end(ap); + + fprintf(stderr, "\n"); +} + +dm_log_fn _log = _default_log; + +void dm_log_init(dm_log_fn fn) +{ + _log = fn; +} + +struct dm_task *dm_task_create(int type) +{ + struct dm_task *dmt = malloc(sizeof(*dmt)); + + if (!dmt) { + log("dm_task_create: malloc(%d) failed", sizeof(*dmt)); + return NULL; + } + + memset(dmt, 0, sizeof(*dmt)); + + dmt->type = type; + return dmt; +} + +int dm_task_set_name(struct dm_task *dmt, const char *name) +{ + if (dmt->dev_name) + free(dmt->dev_name); + + return (dmt->dev_name = strdup(name)) ? 1 : 0; +} + +int dm_task_add_target(struct dm_task *dmt, + uint64_t start, + uint64_t size, + const char *ttype, + const char *params) +{ + struct target *t = create_target(start, size, ttype, params); + + if (!t) + return 0; + + if (!dmt->head) + dmt->head = dmt->tail = t; + else { + dmt->tail->next = t; + dmt->tail = t; + } + + return 1; +} + +void _build_dev_path(char *buffer, size_t len, const char *dev_name) +{ + snprintf(buffer, len, "/dev/%s/%s", DM_DIR, dev_name); +} + +int add_dev_node(const char *dev_name, dev_t dev) +{ + char path[PATH_MAX]; + struct stat info; + + _build_dev_path(path, sizeof(path), dev_name); + + if (stat(path, &info) >= 0) { + if (!S_ISBLK(info.st_mode)) { + log("A non-block device file at '%s' " + "is already present", path); + return 0; + } + + if (info.st_rdev == dev) + return 1; + + if (unlink(path) < 0) { + log("Unable to unlink device node for '%s'", dev_name); + return 0; + } + } + + if (mknod(path, S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, dev) < 0) { + log("Unable to make device node for '%s'", dev_name); + return 0; + } + + return 1; +} + +int rm_dev_node(const char *dev_name) +{ + char path[PATH_MAX]; + struct stat info; + + _build_dev_path(path, sizeof(path), dev_name); + + if (stat(path, &info) < 0) + return 1; + + if (unlink(path) < 0) { + log("Unable to unlink device node for '%s'", dev_name); + return 0; + } + + return 1; +} + +int dm_set_dev_dir(const char *dir) +{ + snprintf(_dm_dir, sizeof(_dm_dir), "%s%s", dir, DM_DIR); + return 1; +} + +const char *dm_dir(void) +{ + return _dm_dir; +} + diff --git a/libdm/libdm-common.h b/libdm/libdm-common.h new file mode 100644 index 000000000..0261557ab --- /dev/null +++ b/libdm/libdm-common.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +extern dm_log_fn _log; +#define log(msg, x...) _log(1, __FILE__, __LINE__, msg, ## x) + +extern struct target *create_target(uint64_t start, + uint64_t len, + const char *type, const char *params); + +int add_dev_node(const char *dev_name, dev_t dev); +int rm_dev_node(const char *dev_name); +