Index: dsrc/lib/Makefile =================================================================== --- dsrc.orig/lib/Makefile 2011-01-26 09:02:09.113215003 +0100 +++ dsrc/lib/Makefile 2011-01-28 21:53:39.203333497 +0100 @@ -84,6 +84,7 @@ .endif SUBDIR+= libcurses # depends on libterminfo +SUBDIR+= libdm # depends on libprop SUBDIR+= libedit # depends on libterminfo SUBDIR+= librefuse # depends on libpuffs SUBDIR+= librumpuser # depends on libpthread Index: dsrc/lib/libdm/Makefile =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ dsrc/lib/libdm/Makefile 2011-01-29 10:09:14.330587972 +0100 @@ -0,0 +1,23 @@ +# $NetBSD$ +USE_FORT?= no # network protocol library + +LIB= dm + +SRCS= libdm_ioctl.c +MAN= dm.3 + +WARN= 4 + +CPPFLAGS+= -I${.CURDIR} +CFLAGS+= -g -O0 +INCS= libdm.h +INCSDIR= /usr/include + +#LDADD+= -lprop +#DPADD+= ${LIBPROP} + +.ifdef RUMP_ACTION +CPPFLAGS+= -DRUMP_ACTION +.endif + +.include Index: dsrc/lib/libdm/libdm.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ dsrc/lib/libdm/libdm.h 2011-02-06 14:19:07.813565209 +0100 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Adam Hamsik. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef _LIB_DM_H_ +#define _LIB_DM_H_ + +__BEGIN_DECLS + +#define DM_DEVICE_PATH "/dev/mapper/control" + +#define IOCTL_TYPE_IN 0x1 +#define IOCTL_TYPE_OUT 0x2 + +struct libdm_task; +struct libdm_cmd; +struct libdm_target; +struct libdm_table; +struct libdm_dev; +struct libdm_iter; + +typedef struct libdm_task* libdm_task_t; +typedef struct libdm_cmd* libdm_cmd_t; +typedef struct libdm_target* libdm_target_t; +typedef struct libdm_table* libdm_table_t; +typedef struct libdm_dev* libdm_dev_t; +typedef struct libdm_iter* libdm_iter_t; + +struct cmd_version { + const char *cmd; + uint32_t version[3]; +}; + +void libdm_iter_destroy(libdm_iter_t); + +libdm_task_t libdm_task_create(const char *); +void libdm_task_destroy(libdm_task_t); + +char *libdm_task_get_command(libdm_task_t); +int32_t libdm_task_get_cmd_version(libdm_task_t, uint32_t *, size_t); + +int libdm_task_set_name(const char *, libdm_task_t); +char *libdm_task_get_name(libdm_task_t); + +int libdm_task_set_uuid(const char *, libdm_task_t); +char *libdm_task_get_uuid(libdm_task_t); + +int libdm_task_set_minor(uint32_t, libdm_task_t); +uint32_t libdm_task_get_minor(libdm_task_t); + +uint32_t libdm_task_get_flags(libdm_task_t); +void libdm_task_set_flags(libdm_task_t, uint32_t); + +void libdm_task_set_suspend_flag(libdm_task_t); +void libdm_task_del_suspend_flag(libdm_task_t); + +void libdm_task_set_status_flag(libdm_task_t); +void libdm_task_del_status_flag(libdm_task_t); + +void libdm_task_set_exists_flag(libdm_task_t); +void libdm_task_del_exists_flag(libdm_task_t); + +void libdm_task_set_nocount_flag(libdm_task_t); +void libdm_task_del_nocount_flag(libdm_task_t); + +uint32_t libdm_task_get_target_num(libdm_task_t); +int32_t libdm_task_get_open_num(libdm_task_t); +uint32_t libdm_task_get_event_num(libdm_task_t); + +int libdm_task_set_cmd(libdm_cmd_t, libdm_task_t); +libdm_cmd_t libdm_task_get_cmd(libdm_task_t); + +/* cmd_data dictionary entry manipulating functions */ +libdm_cmd_t libdm_cmd_create(void); +void libdm_cmd_destroy(libdm_cmd_t); +libdm_iter_t libdm_cmd_iter_create(libdm_cmd_t); + +int libdm_cmd_set_table(libdm_table_t, libdm_cmd_t); + +/* cmd is array of table dictionaries */ +libdm_table_t libdm_cmd_get_table(libdm_iter_t); + +/* cmd is array of dev dictionaries */ +libdm_dev_t libdm_cmd_get_dev(libdm_iter_t); + +/* cmd is array of target dictonaries */ +libdm_target_t libdm_cmd_get_target(libdm_iter_t); +/* cmd is array of dev_t's */ +uint64_t libdm_cmd_get_deps(libdm_iter_t); + +/* Table functions. */ +libdm_table_t libdm_table_create(void); +void libdm_table_destroy(libdm_table_t); + +int libdm_table_set_start(uint64_t, libdm_table_t); +uint64_t libdm_table_get_start(libdm_table_t); + +int libdm_table_set_length(uint64_t, libdm_table_t); +uint64_t libdm_table_get_length(libdm_table_t); + +int libdm_table_set_target(const char *, libdm_table_t); +char * libdm_table_get_target(libdm_table_t); + +int libdm_table_set_params(const char *, libdm_table_t); +char * libdm_table_get_params(libdm_table_t); + +int32_t libdm_table_get_status(libdm_table_t); + +/* Target manipulating functions. */ +void libdm_target_destroy(libdm_target_t); + +char * libdm_target_get_name(libdm_target_t); +int32_t libdm_target_get_version(libdm_target_t, uint32_t *, size_t); + +/* Dev manipulating functions. */ +void libdm_dev_destroy(libdm_dev_t); + +char * libdm_dev_get_name(libdm_dev_t); +uint32_t libdm_dev_get_minor(libdm_dev_t); + +int libdm_dev_set_newname(const char *, libdm_cmd_t); + +/* task run routine */ +int libdm_task_run(libdm_task_t); + +__END_DECLS + +#endif /* _LIB_DM_H_ */ Index: dsrc/lib/libdm/libdm_ioctl.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ dsrc/lib/libdm/libdm_ioctl.c 2011-02-06 14:34:28.252693851 +0100 @@ -0,0 +1,869 @@ +/* + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Adam Hamsik. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "libdm.h" + +/* + * Libdm library works like interface between device-mapper driver and + * NetBSD userspace. For start it uses same set of commands like linux + * libdevmapper, but in later stage if we introduce NetBSD device-mapper + * extensions we don't need to change libdevmapper. + * + * LIBDM basically creates one proplib dictionary with everything what is + * needed to work with device-mapper devices. + * + * Basic element of libdm is libdm_task which contains version and command + * string with another dictionary cmd. + */ + +struct libdm_cmd { + prop_array_t ldm_cmd; +}; + +struct libdm_iter { + prop_object_iterator_t ldm_obji; +}; + +struct libdm_task { + prop_dictionary_t ldm_task; +}; + +struct libdm_table { + prop_dictionary_t ldm_tbl; +}; + +struct libdm_target { + prop_dictionary_t ldm_trgt; +}; + +struct libdm_dev { + prop_dictionary_t ldm_dev; +}; + +struct cmd_version cmd_ver[] = { + {"version", {4, 0, 0}}, + {"targets", {4, 0, 0}}, + {"create", {4, 0, 0}}, + {"info", {4, 0, 0}}, + {"mknodes",{4, 0, 0}}, + {"names", {4, 0, 0}}, + {"suspend",{4, 0, 0}}, + {"remove", {4, 0, 0}}, + {"rename", {4, 0, 0}}, + {"resume", {4, 0, 0}}, + {"clear", {4, 0, 0}}, + {"deps", {4, 0, 0}}, + {"reload", {4, 0, 0}}, + {"status", {4, 0, 0}}, + {"table", {4, 0, 0}}, + /* NetBSD device-mapper command extension goes here */ + {NULL, {0, 0, 0}} +}; + +/* /dev/mapper/control managing routines */ +static int libdm_control_open(const char *); +static int libdm_control_close(int); + +static int +libdm_control_open(const char *path) +{ + int fd; +#ifdef RUMP_ACTION + if ((fd = rump_sys_open(path, O_RDWR)) < 0) + return -1; +#else + if ((fd = open(path, O_RDWR)) < 0) + return -1; +#endif + return fd; +} + +static int +libdm_control_close(int fd) +{ + +#ifdef RUMP_ACTION + return rump_sys_close(fd); +#else + return close(fd); +#endif +} + +/* Destroy iterator for arrays such as version strings, cmd_data. */ +void +libdm_iter_destroy(libdm_iter_t libdm_iter) +{ + + prop_object_iterator_release(libdm_iter->ldm_obji); + free(libdm_iter); +} + +/* + * Issue ioctl call to kernel, releasing both dictionaries is + * left on callers. + */ +int +libdm_task_run(libdm_task_t libdm_task) +{ + prop_dictionary_t dict; + int libdm_control_fd = -1; + int error; +#ifdef RUMP_ACTION + struct plistref prefp; +#endif + error = 0; + + if (libdm_task == NULL) + return ENOENT; + + if ((libdm_control_fd = libdm_control_open(DM_DEVICE_PATH)) < 0) + return errno; +#ifdef RUMP_ACTION + prop_dictionary_externalize_to_pref(libdm_task->ldm_task, + &prefp); + + error = rump_sys_ioctl(libdm_control_fd, NETBSD_DM_IOCTL, &prefp); + if (error < 0) { + libdm_task_destroy(libdm_task); + libdm_task = NULL; + libdm_control_close(libdm_control_fd); + + return error; + } + dict = prop_dictionary_internalize(prefp.pref_plist); +#else + error = prop_dictionary_sendrecv_ioctl(libdm_task->ldm_task, + libdm_control_fd, NETBSD_DM_IOCTL, &dict); + if ( error != 0) { + libdm_task_destroy(libdm_task); + libdm_task = NULL; + libdm_control_close(libdm_control_fd); + return error; + } +#endif + + libdm_control_close(libdm_control_fd); + libdm_task_destroy(libdm_task); + libdm_task->ldm_task = dict; + + return EXIT_SUCCESS; +} + + +/* Create libdm General task structure */ +libdm_task_t +libdm_task_create(const char *command) +{ + libdm_task_t task; + size_t i,len,slen; + prop_array_t ver; + + task = NULL; + + task = malloc(sizeof(*task)); + if (task == NULL) + return NULL; + + if ((task->ldm_task = prop_dictionary_create()) == NULL) { + free(task); + return NULL; + } + + if ((prop_dictionary_set_cstring(task->ldm_task, DM_IOCTL_COMMAND, + command)) == false) { + prop_object_release(task->ldm_task); + free(task); + return NULL; + } + + len = strlen(command); + + for (i = 0; cmd_ver[i].cmd != NULL; i++) { + slen = strlen(cmd_ver[i].cmd); + + if (len != slen) + continue; + + if ((strncmp(command, cmd_ver[i].cmd, slen)) == 0) { + ver = prop_array_create(); + prop_array_add_uint32(ver, cmd_ver[i].version[0]); + prop_array_add_uint32(ver, cmd_ver[i].version[1]); + prop_array_add_uint32(ver, cmd_ver[i].version[2]); + + prop_dictionary_set(task->ldm_task, DM_IOCTL_VERSION, + ver); + + prop_object_release(ver); + break; + } + } + + return task; +} + +void +libdm_task_destroy(libdm_task_t libdm_task) +{ + if (libdm_task != NULL) + prop_object_release(libdm_task->ldm_task); + free(libdm_task); +} + +/* Set device name */ +int +libdm_task_set_name(const char *name, libdm_task_t libdm_task) +{ + + if ((prop_dictionary_set_cstring(libdm_task->ldm_task, + DM_IOCTL_NAME, name)) == false) + return ENOENT; + + return 0; +} + +/* Set device name */ +char * +libdm_task_get_name(libdm_task_t libdm_task) +{ + char *name; + + if (!prop_dictionary_get_cstring_nocopy(libdm_task->ldm_task, + DM_IOCTL_NAME, (const char **)&name)) + return NULL; + + return name; +} + +/* Set device uuid */ +int +libdm_task_set_uuid(const char *uuid, libdm_task_t libdm_task) +{ + + if ((prop_dictionary_set_cstring(libdm_task->ldm_task, + DM_IOCTL_NAME, uuid)) == false) + return ENOENT; + + return 0; +} + +/* Set device name */ +char * +libdm_task_get_uuid(libdm_task_t libdm_task) +{ + char *uuid; + + if (!prop_dictionary_get_cstring_nocopy(libdm_task->ldm_task, + DM_IOCTL_UUID, (const char **)&uuid)) + return NULL; + + return uuid; +} + +/* Get command name */ +char * +libdm_task_get_command(libdm_task_t libdm_task) +{ + char *command; + + if (!prop_dictionary_get_cstring_nocopy(libdm_task->ldm_task, + DM_IOCTL_COMMAND, (const char **)&command)) + return NULL; + + return command; +} + +int32_t +libdm_task_get_cmd_version(libdm_task_t libdm_task, uint32_t *ver, size_t size) +{ + prop_array_t prop_ver; + size_t i; + + prop_ver = prop_dictionary_get(libdm_task->ldm_task, + DM_IOCTL_VERSION); + + i = prop_array_count(prop_ver); + + if (i > size) + return -i; + + for (i = 0; i < size; i++) + prop_array_get_uint32(prop_ver, i, &ver[i]); + + return i; +} + +/* Select device minor number. */ +int +libdm_task_set_minor(uint32_t minor, libdm_task_t libdm_task) +{ + + if ((prop_dictionary_set_uint32(libdm_task->ldm_task, + DM_IOCTL_MINOR, minor)) == false) + return ENOENT; + + return 0; +} + +/* Select device minor number. */ +uint32_t +libdm_task_get_minor(libdm_task_t libdm_task) +{ + uint32_t minor; + + minor = 0; + + (void)prop_dictionary_get_uint32(libdm_task->ldm_task, + DM_IOCTL_MINOR, &minor); + + return minor; +} + +/* Set/Del DM_SUSPEND_FLAG for caller. */ +void +libdm_task_set_suspend_flag(libdm_task_t libdm_task) +{ + uint32_t flags; + + flags = 0; + + (void)prop_dictionary_get_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, &flags); + + flags |= DM_SUSPEND_FLAG; + + (void)prop_dictionary_set_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, flags); +} + +void +libdm_task_del_suspend_flag(libdm_task_t libdm_task) +{ + uint32_t flags; + + (void)prop_dictionary_get_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, &flags); + + flags &= ~DM_SUSPEND_FLAG; + + (void)prop_dictionary_set_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, flags); +} + +/* Set/Del DM_STATUS_FLAG for caller. */ +void +libdm_task_set_status_flag(libdm_task_t libdm_task) +{ + uint32_t flags; + + flags = 0; + + (void)prop_dictionary_get_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, &flags); + + flags |= DM_STATUS_TABLE_FLAG; + + (void)prop_dictionary_set_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, flags); +} + +void +libdm_task_del_status_flag(libdm_task_t libdm_task) +{ + uint32_t flags; + + (void)prop_dictionary_get_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, &flags); + + flags &= ~DM_STATUS_TABLE_FLAG; + + (void)prop_dictionary_set_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, flags); +} + +/* Set/Del DM_EXISTS_FLAG for caller. */ +void +libdm_task_set_exists_flag(libdm_task_t libdm_task) +{ + uint32_t flags; + + flags = 0; + + (void)prop_dictionary_get_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, &flags); + + flags |= DM_EXISTS_FLAG; + + (void)prop_dictionary_set_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, flags); +} + +void +libdm_task_del_exists_flag(libdm_task_t libdm_task) +{ + uint32_t flags; + + (void)prop_dictionary_get_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, &flags); + + flags &= ~DM_EXISTS_FLAG; + + (void)prop_dictionary_set_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, flags); +} + +/* Set flags used by LVM this is shortcut and should not be used + by anyone else. */ +void +libdm_task_set_flags(libdm_task_t libdm_task, uint32_t flags) +{ + + (void)prop_dictionary_set_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, flags); +} + +/* Get ioctl protocol status flags. */ +uint32_t +libdm_task_get_flags(libdm_task_t libdm_task) +{ + uint32_t flags; + + (void)prop_dictionary_get_uint32(libdm_task->ldm_task, + DM_IOCTL_FLAGS, &flags); + + return flags; +} + +/* Set ioctl protocol status flags. */ +uint32_t +libdm_task_get_target_num(libdm_task_t libdm_task) +{ + uint32_t count; + + (void)prop_dictionary_get_uint32(libdm_task->ldm_task, + DM_IOCTL_TARGET_COUNT, &count); + + return count; +} + +int32_t +libdm_task_get_open_num(libdm_task_t libdm_task) +{ + int32_t count; + + (void)prop_dictionary_get_int32(libdm_task->ldm_task, + DM_IOCTL_OPEN, &count); + + return count; +} + +uint32_t +libdm_task_get_event_num(libdm_task_t libdm_task) +{ + uint32_t event; + + (void)prop_dictionary_get_uint32(libdm_task->ldm_task, + DM_IOCTL_EVENT, &event); + + return event; +} + +/* Set cmd_data dictionary entry to task struct. */ +int +libdm_task_set_cmd(libdm_cmd_t libdm_cmd, libdm_task_t libdm_task) +{ + + if ((prop_dictionary_set(libdm_task->ldm_task, + DM_IOCTL_CMD_DATA, libdm_cmd->ldm_cmd)) == false) + return ENOENT; + + return 0; +} + +/* Get cmd_data dictionary entry from task struct */ +libdm_cmd_t +libdm_task_get_cmd(libdm_task_t libdm_task) +{ + libdm_cmd_t cmd; + + cmd = malloc(sizeof(*cmd)); + + cmd->ldm_cmd = prop_dictionary_get(libdm_task->ldm_task, + DM_IOCTL_CMD_DATA); + + return cmd; +} + +/* Command functions + * + * Functions for creation, destroing, set, get of command area of + * ioctl dictionary. + */ +libdm_cmd_t +libdm_cmd_create(void) +{ + libdm_cmd_t cmd; + + cmd = malloc(sizeof(*cmd)); + if (cmd == NULL) + return NULL; + + cmd->ldm_cmd = prop_array_create(); + + return cmd; +} + +void +libdm_cmd_destroy(libdm_cmd_t libdm_cmd) +{ + + prop_object_release(libdm_cmd->ldm_cmd); + free(libdm_cmd); +} + +/* Create iterator object for caller this can be used to + iterate through all members of cmd array. */ +libdm_iter_t +libdm_cmd_iter_create(libdm_cmd_t libdm_cmd) +{ + + libdm_iter_t iter; + + iter = malloc(sizeof(*iter)); + if (iter == NULL) + return NULL; + + iter->ldm_obji = prop_array_iterator(libdm_cmd->ldm_cmd); + + return iter; +} + +int +libdm_cmd_set_table(libdm_table_t libdm_table, libdm_cmd_t libdm_cmd) +{ + + return prop_array_add(libdm_cmd->ldm_cmd, + libdm_table->ldm_tbl); +} + + +libdm_target_t +libdm_cmd_get_target(libdm_iter_t iter) +{ + libdm_target_t trgt; + + trgt = malloc(sizeof(*trgt)); + if (trgt == NULL) + return NULL; + + trgt->ldm_trgt = prop_object_iterator_next(iter->ldm_obji); + + return trgt; +} + +libdm_table_t +libdm_cmd_get_table(libdm_iter_t iter) +{ + libdm_table_t tbl; + + tbl = malloc(sizeof(*tbl)); + if (tbl == NULL) + return NULL; + + tbl->ldm_tbl = prop_object_iterator_next(iter->ldm_obji); + + return tbl; +} + +libdm_dev_t +libdm_cmd_get_dev(libdm_iter_t iter) +{ + libdm_dev_t dev; + + dev = malloc(sizeof(*dev)); + if (dev == NULL) + return NULL; + + dev->ldm_dev = prop_object_iterator_next(iter->ldm_obji); + + return dev; +} + +/* + * Deps manipulation routines + */ +uint64_t +libdm_cmd_get_deps(libdm_iter_t libdm_iter) +{ + prop_object_t obj; + uint64_t deps; + + obj = prop_object_iterator_next(libdm_iter->ldm_obji); + deps = prop_number_unsigned_integer_value(obj); + + prop_object_release(obj); + return deps; +} + +/* + * Table manipulation routines + */ +libdm_table_t +libdm_table_create(void) +{ + libdm_table_t table; + + table = malloc(sizeof(*table)); + if (table == NULL) + return NULL; + + table->ldm_tbl = prop_dictionary_create(); + + return table; +} + +void +libdm_table_destroy(libdm_table_t libdm_table) +{ + + prop_object_release(libdm_table->ldm_tbl); + free(libdm_table); +} + +int +libdm_table_set_start(uint64_t start, libdm_table_t libdm_table) +{ + + if (libdm_table == NULL) + return ENOENT; + + return prop_dictionary_set_uint64(libdm_table->ldm_tbl, + DM_TABLE_START, start); +} + +uint64_t +libdm_table_get_start(libdm_table_t libdm_table) +{ + uint64_t start; + + if (libdm_table == NULL) + return ENOENT; + + (void)prop_dictionary_get_uint64(libdm_table->ldm_tbl, DM_TABLE_START, + &start); + + return start; +} + +int +libdm_table_set_length(uint64_t length, libdm_table_t libdm_table) +{ + + if (libdm_table == NULL) + return ENOENT; + + return prop_dictionary_set_uint64(libdm_table->ldm_tbl, + DM_TABLE_LENGTH, length); +} + +uint64_t +libdm_table_get_length(libdm_table_t libdm_table) +{ + uint64_t length; + + if (libdm_table == NULL) + return ENOENT; + + prop_dictionary_get_uint64(libdm_table->ldm_tbl, DM_TABLE_LENGTH, + &length); + + return length; +} + +int +libdm_table_set_target(const char *name, libdm_table_t libdm_table) +{ + + if (libdm_table == NULL) + return ENOENT; + + return prop_dictionary_set_cstring(libdm_table->ldm_tbl, DM_TABLE_TYPE, name); +} + +char * +libdm_table_get_target(libdm_table_t libdm_table) +{ + char *target; + + if (!prop_dictionary_get_cstring_nocopy(libdm_table->ldm_tbl, DM_TABLE_TYPE, + (const char **)&target)) + return NULL; + + return target; +} + +int +libdm_table_set_params(const char *params, libdm_table_t libdm_table) +{ + + if (libdm_table == NULL) + return ENOENT; + + return prop_dictionary_set_cstring(libdm_table->ldm_tbl, + DM_TABLE_PARAMS, params); +} + +/* + * Get table params string from libdm_table_t + * returned char * is dynamically allocated caller should free it. + */ +char * +libdm_table_get_params(libdm_table_t libdm_table) +{ + char *params; + + if (!prop_dictionary_get_cstring_nocopy(libdm_table->ldm_tbl, DM_TABLE_PARAMS, + (const char **)¶ms)) + return NULL; + + return params; +} + +int32_t +libdm_table_get_status(libdm_table_t libdm_table) +{ + int32_t status; + + (void)prop_dictionary_get_int32(libdm_table->ldm_tbl, DM_TABLE_STAT, + &status); + + return status; +} + +/* + * Target manipulation routines + */ +void +libdm_target_destroy(libdm_target_t libdm_target) +{ + + prop_object_release(libdm_target->ldm_trgt); + free(libdm_target); +} + +char * +libdm_target_get_name(libdm_target_t libdm_target) +{ + char *name; + + if (!prop_dictionary_get_cstring_nocopy(libdm_target->ldm_trgt, + DM_TARGETS_NAME, (const char **)&name)) + return NULL; + + return name; +} + +int32_t +libdm_target_get_version(libdm_target_t libdm_target, uint32_t *ver, size_t size) +{ + prop_array_t prop_ver; + size_t i; + + prop_ver = prop_dictionary_get(libdm_target->ldm_trgt, + DM_TARGETS_VERSION); + + i = prop_array_count(prop_ver); + + if (i > size) + return -i; + + for (i = 0; i < size; i++) + prop_array_get_uint32(prop_ver, i, &ver[i]); + + return i; +} + + +/* + * Dev manipulation routines + */ +void +libdm_dev_destroy(libdm_dev_t libdm_dev) +{ + + prop_object_release(libdm_dev->ldm_dev); + free(libdm_dev); +} + +char * +libdm_dev_get_name(libdm_dev_t libdm_dev) +{ + char *name; + + if (!prop_dictionary_get_cstring_nocopy(libdm_dev->ldm_dev, + DM_DEV_NAME, (const char **)&name)) + return NULL; + + return name; +} + +uint32_t +libdm_dev_get_minor(libdm_dev_t libdm_dev) +{ + uint32_t dev; + + (void)prop_dictionary_get_uint32(libdm_dev->ldm_dev, DM_DEV_DEV, + &dev); + + return dev; +} + +int +libdm_dev_set_newname(const char *newname, libdm_cmd_t libdm_cmd) +{ + + if (newname == NULL) + return ENOENT; + + return prop_array_set_cstring(libdm_cmd->ldm_cmd, 0, newname); +} Index: dsrc/lib/libdm/shlib_version =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ dsrc/lib/libdm/shlib_version 2011-01-28 21:53:39.211643754 +0100 @@ -0,0 +1,4 @@ +# $NetBSD: shlib_version,v 1.8 2008/09/15 18:19:25 haad Exp $ +# Remember to update distrib/sets/lists/base/shl.* when changing +major=0 +minor=0 Index: dsrc/sbin/Makefile =================================================================== --- dsrc.orig/sbin/Makefile 2011-01-26 08:55:49.500853146 +0100 +++ dsrc/sbin/Makefile 2011-01-28 21:53:39.224947637 +0100 @@ -7,7 +7,7 @@ .include SUBDIR= amrctl apmlabel atactl badsect bioctl brconfig ccdconfig \ - chown disklabel dkctl dkscan_bsdlabel dmesg \ + chown disklabel dkctl dkscan_bsdlabel dmesg dmctl \ drvctl fastboot fdisk fsck fsirand gpt ifconfig init ldconfig \ mbrlabel mknod modload modstat modunload mount newbtconf nologin \ pdisk ping pppoectl raidctl reboot rcorder rndctl route routed \ Index: dsrc/sbin/dmctl/Makefile =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ dsrc/sbin/dmctl/Makefile 2011-02-06 03:14:26.987787755 +0100 @@ -0,0 +1,27 @@ +PROG= dmctl +MAN= dmctl.8 +WARN= 4 +SRC= dmctl.c + +BINDIR= /sbin + +LIBDM_INCLUDE= ${NETBSDSRCDIR}/lib/libdm/ + +LIBDM_OBJDIR= ${NETBSDSRCDIR}/lib/libdm/ + +#CFLAGS+= -fno-inline -Wall -O0 -g + +CPPFLAGS+= -I. -I${LIBDM_INCLUDE} + +LDADD+= -L${LIBDM_OBJDIR} -ldm + +.ifdef RUMP_ACTION +CPPFLAGS+= -D RUMP_ACTION +LDADD+= -lrumpclient +.endif + +LDADD+= -lprop + +#LDSTATIC= -static + +.include Index: dsrc/sbin/dmctl/README =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ dsrc/sbin/dmctl/README 2011-01-28 21:53:39.239718520 +0100 @@ -0,0 +1,23 @@ + += RUMP howto = + +Build rump dm library, buidl libdm with RUMP_ACTION, build dmct with RUMP_ACTION. + +cd local/lib/libdm/ +RUMP_ACTION=1 USETOOLS=no make + +cd ../../sbin/dmctl +RUMP_ACTION=1 USETOOLS=no make +RUMP_ACTION=1 USETOOLS=no make -f Makefile.server + +== Server Startup == + +RUMP_SP_SERVER=unix:///tmp/dmc +env RUMP_VERBOSE=1 ./dmctl_server + +Server uses /home/haad/test.img file as disk1 device. + +== Client Startup == + +RUMP_SP_CLIENT=unix:///tmp/dmc +./dmctl version Index: dsrc/sbin/dmctl/dmctl.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ dsrc/sbin/dmctl/dmctl.c 2011-02-06 14:15:24.243673002 +0100 @@ -0,0 +1,576 @@ +/* + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Adam Hamsik. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef RUMP_ACTION +#include +#include +#include +#endif + +#include "libdm.h" + +/* dmctl command is used to communicate with device-mapper driver in NetBSD + * it uses libdm library to create and send required data to kernel. + * + * Main purpose of dmctl is to add posibility to use device-mapper driver + * from outside of LVM scope. + */ + +#define DMCTL_CMD_REQ_NODEVNAME 0 /* Command do not require device name */ +#define DMCTL_CMD_REQ_DEVNAME 1 /* Command require device name to work */ +#define DMCTL_CMD_REQ_NEWNAME 2 /* Command require device name and + newname to work */ +struct command { + const char *cmd_name; + const char *cmd_help; + const char *ioctl_cmd_name; + int min_args; + int (*cmd_func)(int, char *[], libdm_task_t); +}; + +int fd; /* file descriptor for device */ +const char *dvname; /* device name */ +const char *cmdname; /* command user issued */ + +static char * parse_stdin(char *); + +static int dmctl_get_version(int, char *[], libdm_task_t); +static int dmctl_get_targets(int, char *[], libdm_task_t); +static int dmctl_get_device_info(int, char *[], libdm_task_t); +static int dmctl_create_dev(int, char *[], libdm_task_t); +static int dmctl_dev_rename(int, char *[], libdm_task_t); +static int dmctl_dev_remove(int, char *[], libdm_task_t); +static int dmctl_dev_resume(int, char *[], libdm_task_t); +static int dmctl_dev_suspend(int, char *[], libdm_task_t); +static int dmctl_dev_deps(int, char *[], libdm_task_t); +static int dmctl_list_devices(int, char *[], libdm_task_t); +static int dmctl_table_reload(int, char *[], libdm_task_t); +static int dmctl_table_status(int, char *[], libdm_task_t); +void usage(void); + +struct command commands[] = { + { "version", + "Print driver and lib version.", + NULL, DMCTL_CMD_REQ_NODEVNAME, + dmctl_get_version }, + { "targets", + "List available kernel targets.", + NULL, DMCTL_CMD_REQ_NODEVNAME, + dmctl_get_targets }, + { "create", + "Create device with [dm device name].", + NULL, DMCTL_CMD_REQ_DEVNAME, + dmctl_create_dev }, + { "ls", + "List existing dm devices.", + "names", DMCTL_CMD_REQ_NODEVNAME, + dmctl_list_devices }, + { "info", + "Get info about device with [dm device name].", + NULL, DMCTL_CMD_REQ_DEVNAME, + dmctl_get_device_info }, + { "rename", + "Rename device with [dm device name] to [dm device new name].", + NULL, DMCTL_CMD_REQ_NEWNAME, + dmctl_dev_rename }, + { "remove", + "Remove device with [dm device name].", + NULL, DMCTL_CMD_REQ_DEVNAME, + dmctl_dev_remove }, + { "resume", + "Resume IO on dm device [dm device name].", + NULL, DMCTL_CMD_REQ_DEVNAME, + dmctl_dev_resume }, + { "suspend", + "Suspend IO on dm device [dm device name].", + NULL, DMCTL_CMD_REQ_DEVNAME, + dmctl_dev_suspend }, + { "deps", + "Print physical dependiences for dm device [dm device name].", + NULL, DMCTL_CMD_REQ_DEVNAME, + dmctl_dev_deps }, + { "reload", + "Switch active and passive tables for device with [dm device name].", + NULL, DMCTL_CMD_REQ_DEVNAME, + dmctl_table_reload }, + { "status", + "Print status for device with [dm device name].", + "table", DMCTL_CMD_REQ_DEVNAME, + dmctl_table_status }, + { "table", + "Print active table for device with [dm device name].", + NULL, DMCTL_CMD_REQ_DEVNAME, + dmctl_table_status }, + { NULL, + NULL, + NULL, 0, + NULL }, +}; + +int +main(int argc, char *argv[]) +{ + int i; + int oargc; + libdm_task_t task; + + oargc = 0; + +#ifdef RUMP_ACTION + if (rumpclient_init() == -1) + err(EXIT_FAILURE, "rump client init failed"); +#endif + + /* Must have at least: device command */ + if (argc < 2) + usage(); + + /* Skip program name, get and skip device name and command. */ + cmdname = argv[1]; + if (argc > 2) { + oargc = 1; + dvname = argv[2]; + } + + if (argc > 3) { + argv += 3; + argc -= 3; + oargc = 2; + } else { + argv = 0; + argc = 0; + } + + for (i = 0; commands[i].cmd_name != NULL; i++) + if (strcmp(cmdname, commands[i].cmd_name) == 0) + break; + + if (commands[i].cmd_name == NULL) + errx(EXIT_FAILURE, "unknown command: %s", cmdname); + + if (commands[i].ioctl_cmd_name != NULL) + cmdname = commands[i].ioctl_cmd_name; + + if (oargc != commands[i].min_args) { + (void)fprintf(stderr, "Insufficient number of arguments for " + "command: %s specified\n", commands[i].cmd_name); + usage(); + } + + /* + * Create libdm task, and pass it to command handler later. + * Don't release it here because it will be replaced by different + * dictionary received from kernel after libdm_task_run. + */ + task = libdm_task_create(cmdname); + + (*commands[i].cmd_func)(argc, argv, task); + + return 0; +} + +/* + * Print library and kernel driver versions if command can be used only when + * major, minor number of library version is <= kernel. + */ +static int +dmctl_get_version(int argc __unused, char *argv[] __unused, libdm_task_t task) +{ + uint32_t ver[3], size; + + size = libdm_task_get_cmd_version(task, ver, sizeof(ver)); + + printf("Library protocol version %d:%d:%d\n", ver[0], ver[1], ver[2]); + + if (libdm_task_run(task) != 0) + err(EXIT_FAILURE, "dmctl_get_version: libdm_task_run failed."); + + size = libdm_task_get_cmd_version(task, ver, 3); + printf("Kernel protocol version %d:%d:%d\n",ver[0], ver[1], ver[2]); + + libdm_task_destroy(task); + return 0; +} + +/* + * Get list of available targets from kernel and print them. + */ +static int +dmctl_get_targets(int argc __unused, char *argv[] __unused, libdm_task_t task) +{ + libdm_cmd_t cmd; + libdm_iter_t iter; + libdm_target_t target; + uint32_t ver[3]; + + if (libdm_task_run(task) != 0) + err(EXIT_FAILURE, "dmctl_get_targets: libdm_task_run failed."); + + if ((cmd = libdm_task_get_cmd(task)) == NULL) + return ENOENT; + + iter = libdm_cmd_iter_create(cmd); + + while((target = libdm_cmd_get_target(iter)) != NULL){ + printf("Target name: %s\n", libdm_target_get_name(target)); + + libdm_target_get_version(target, ver, sizeof(ver)); + printf("Target version %d.%d.%d\n\n", ver[0], ver[1], ver[2]); + + libdm_target_destroy(target); + } + + libdm_iter_destroy(iter); + libdm_task_destroy(task); + + return 0; +} + +/* + * Create device with name used as second parameter. + * TODO: Support for UUIDs here. + */ +static int +dmctl_create_dev(int argc __unused, char *argv[] __unused, libdm_task_t task) +{ + + libdm_task_set_name(dvname, task); + + if (libdm_task_run(task) != 0) + err(EXIT_FAILURE, "dmctl_create_dev: libdm_task_run failed."); + + libdm_task_destroy(task); + return 0; +} + +/* + * Get basic device info from device-mapper driver. + */ +static int +dmctl_get_device_info(int argc __unused, char *argv[] __unused, libdm_task_t task) +{ + + libdm_task_set_name(dvname, task); + + if (libdm_task_run(task) != 0) + err(EXIT_FAILURE, "dmctl_get_device_info: libdm_task_run failed.\n"); + + printf("Printing Device info for:\n"); + printf("Device name: \t\t%s\n", libdm_task_get_name(task)); + printf("Device uuid: \t\t%s\n", libdm_task_get_uuid(task)); + printf("Device minor: \t\t%d\n", libdm_task_get_minor(task)); + printf("Device target number: \t%d\n", libdm_task_get_target_num(task)); + printf("Device flags: \t\t%d\n", libdm_task_get_flags(task)); + + libdm_task_destroy(task); + return 0; +} + +/* + * List all device in device-mapper driver. + */ +static int +dmctl_list_devices(int argc __unused, char *argv[] __unused, libdm_task_t task) +{ + libdm_cmd_t cmd; + libdm_iter_t iter; + libdm_dev_t dev; + + if (libdm_task_run(task) != 0) + err(EXIT_FAILURE, "dmctl_list_devices: libdm_task_run failed."); + + if ((cmd = libdm_task_get_cmd(task)) == NULL) + return ENOENT; + + iter = libdm_cmd_iter_create(cmd); + + while((dev = libdm_cmd_get_dev(iter)) != NULL){ + printf("Device name: %s, device minor: %d \n", + libdm_dev_get_name(dev), libdm_dev_get_minor(dev)); + libdm_dev_destroy(dev); + } + + libdm_iter_destroy(iter); + libdm_task_destroy(task); + + return 0; +} + +/* + * Rename device to new name + */ +static int +dmctl_dev_rename(int argc __unused, char *argv[], libdm_task_t task) +{ + libdm_cmd_t cmd; + + libdm_task_set_name(dvname, task); + + cmd = libdm_cmd_create(); + libdm_dev_set_newname(argv[0], cmd); + libdm_task_set_cmd(cmd, task); + + if (libdm_task_run(task) != 0) + err(EXIT_FAILURE, "dmctl_dev_rename: libdm_task_run failed."); + + libdm_cmd_destroy(cmd); + libdm_task_destroy(task); + + return 0; +} + +/* + * Remove device from dm device list. + */ +static int +dmctl_dev_remove(int argc __unused, char *argv[] __unused, libdm_task_t task) +{ + + if (dvname == NULL) + return (ENOENT); + + libdm_task_set_name(dvname, task); + + if (libdm_task_run(task) != 0) + err(EXIT_FAILURE, "dmctl_dev_remove: libdm_task_run failed."); + + libdm_task_destroy(task); + return 0; +} + +/* + * Resume device which was suspended or created right now. + * Replace table in "active slot" witg table in "inactive slot". + */ +static int +dmctl_dev_resume(int argc __unused, char *argv[] __unused, libdm_task_t task) +{ + + libdm_task_set_name(dvname, task); + + if (libdm_task_run(task) != 0) + err(EXIT_FAILURE, "dmctl_dev_resume: libdm_task_run failed."); + + libdm_task_destroy(task); + return 0; +} + +/* + * Resume device which was suspended or created right now. + * Replace table in "active slot" with table in "inactive slot". + */ +static int +dmctl_dev_suspend(int argc __unused, char *argv[] __unused, libdm_task_t task) +{ + + libdm_task_set_name(dvname, task); + libdm_task_set_suspend_flag(task); + + if (libdm_task_run(task) != 0) + err(EXIT_FAILURE, "dmctl_dev_suspend: libdm_task_run failed."); + + libdm_task_destroy(task); + return 0; +} + +/* + * Get device dependiences from device-mapper. Device dependency is physical + * device on which dm device depends. + */ +static int +dmctl_dev_deps(int argc __unused, char *argv[] __unused, libdm_task_t task) +{ + libdm_cmd_t cmd; + libdm_iter_t iter; + dev_t dev_deps; + + libdm_task_set_name(dvname, task); + + if (libdm_task_run(task) != 0) + err(EXIT_FAILURE, "dmctl_dev_deps: libdm_task_run failed."); + + if ((cmd = libdm_task_get_cmd(task)) == NULL) + return ENOENT; + + iter = libdm_cmd_iter_create(cmd); + + printf("Device %s dependiences \n", dvname); + + while((dev_deps = libdm_cmd_get_deps(iter)) != 0) + printf("major: %d minor: %d\n", major(dev_deps), minor(dev_deps)); + + libdm_iter_destroy(iter); + libdm_task_destroy(task); + + return 0; +} + +/* + * Reload device table to get new one to use. + */ +static int +dmctl_table_reload(int argc, char *argv[], libdm_task_t task) +{ + libdm_cmd_t cmd; + libdm_table_t table; + + char *params; + char *file_path; + char target[128]; + int len; + uint64_t start, length; + + file_path = NULL; + params = NULL; + + cmd = libdm_cmd_create(); + + libdm_task_set_name(dvname, task); + + if (argc != 0) + file_path = argv[0]; + + while ((params = parse_stdin(file_path)) != NULL) { + table = libdm_table_create(); + + sscanf(params, "%llu %llu %s %n", &start, &length, target, &len); + + libdm_table_set_start(start, table); + libdm_table_set_length(length, table); + libdm_table_set_target(target, table); + libdm_table_set_params(params + len, table); + libdm_cmd_set_table(table, cmd); + + libdm_table_destroy(table); + + free(params); + } + + libdm_task_set_cmd(cmd, task); + + if (libdm_task_run(task) != 0) + err(EXIT_FAILURE, "libdm_task_run: from dmctl_table_reload failed."); + + libdm_cmd_destroy(cmd); + libdm_task_destroy(task); + free(params); + + return 0; +} + +/* + * Get table status from device. + */ +static int +dmctl_table_status(int argc __unused, char *argv[] __unused, libdm_task_t task) +{ + libdm_cmd_t cmd; + libdm_table_t table; + libdm_iter_t iter; + + libdm_task_set_name(dvname, task); + libdm_task_set_status_flag(task); + + if (libdm_task_run(task) != 0) + err(EXIT_FAILURE, "libdm_task_run"); + + if ((cmd = libdm_task_get_cmd(task)) == NULL) + return ENOENT; + + iter = libdm_cmd_iter_create(cmd); + + printf("Getting device table for device %s\n", dvname); + + while ((table = libdm_cmd_get_table(iter)) != NULL) { + printf("%10"PRIu64" %10"PRIu64" %s\n", + libdm_table_get_start(table), + libdm_table_get_length(table), + libdm_table_get_target(table)); + libdm_table_destroy(table); + } + + libdm_iter_destroy(iter); + libdm_task_destroy(task); + + return 0; +} + +void +usage(void) +{ + int i; + + (void)fprintf(stderr, "usage: %s command [dm device name]\n" + "Available commands are:\n ", getprogname()); + for (i = 0; commands[i].cmd_name != NULL; i++) + (void)fprintf(stderr, "\t%s\t%s\n", commands[i].cmd_name, commands[i].cmd_help); + exit(EXIT_FAILURE); +} + +static char * +parse_stdin(char *file_path) +{ + char *buf, *lbuf; + size_t len; + FILE *fp; + + lbuf = NULL; + + if (file_path) { + if ((fp = fopen(file_path, "r")) == NULL) + err(ENOENT, "Cannot open table file\n"); + } else + fp = stdin; + + if ((buf = fgetln(fp, &len)) == NULL) + return NULL; + + if (buf[len - 1] != '\n') + len++; + + if ((lbuf = malloc(len)) == NULL) + err(EXIT_FAILURE, "malloc"); + + memcpy(lbuf, buf, len); + lbuf[len - 1] = '\0'; + + return lbuf; +} Index: dsrc/distrib/sets/lists/base/mi =================================================================== --- dsrc.orig/distrib/sets/lists/base/mi 2011-01-26 09:01:33.577334931 +0100 +++ dsrc/distrib/sets/lists/base/mi 2011-01-28 21:53:39.301263086 +0100 @@ -217,6 +217,7 @@ ./sbin/dkctl base-sysutil-root ./sbin/dkscan_bsdlabel base-sysutil-root ./sbin/dmesg base-sysutil-root +./sbin/dmctl base-sysutil-root ./sbin/dmsetup base-lvm-root lvm ./sbin/drvctl base-sysutil-root ./sbin/dump base-sysutil-root Index: dsrc/distrib/sets/lists/comp/shl.mi =================================================================== --- dsrc.orig/distrib/sets/lists/comp/shl.mi 2011-01-26 09:01:33.767510588 +0100 +++ dsrc/distrib/sets/lists/comp/shl.mi 2011-01-28 21:53:39.324071822 +0100 @@ -25,6 +25,7 @@ ./usr/lib/libcurses_pic.a comp-c-piclib ./usr/lib/libdes_pic.a comp-c-piclib crypto ./usr/lib/libdevmapper_pic.a comp-lvm-piclib lvm +./usr/lib/libdm_pic.a comp-c-piclib ./usr/lib/libdns_pic.a comp-bind-piclib ./usr/lib/libdns_sd_pic.a comp-mdns-piclib mdns ./usr/lib/libdtrace_pic.a comp-c-piclib dtrace @@ -229,6 +230,7 @@ ./usr/libdata/debug/usr/lib/libcurses.so.7.0.debug comp-sys-debug debug ./usr/libdata/debug/usr/lib/libdes.so.8.1.debug comp-crypto-debug crypto,debug ./usr/libdata/debug/usr/lib/libdevmapper.so.1.0.debug comp-lvm-debug lvm,debug +./usr/libdata/debug/usr/lib/libdm.so.0.0.debug comp-sys-debug ./usr/libdata/debug/usr/lib/libdns.so.5.2.debug comp-bind-debug debug ./usr/libdata/debug/usr/lib/libdns_sd.so.0.0.debug comp-mdns-debug mdns,debug ./usr/libdata/debug/usr/lib/libdtrace.so.2.0.debug comp-sys-debug dtrace,debug Index: dsrc/lib/libdm/dm.3 =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ dsrc/lib/libdm/dm.3 2011-01-28 21:53:39.332841930 +0100 @@ -0,0 +1,386 @@ +.\" $NetBSD$ +.\" +.\" Copyright (c) 2004,2009 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Adam Hamsik. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.Dd Januar, 22 +.Dt DM 3 +.Os +.Sh NAME +.Nm libdm +.Nd device-mapper access manipulation library +.Sh LIBRARY +.Lb libdm +.Sh SYNOPSIS +.In libdm.h +.Ft void +.Fn libdm_iter_destroy "libdm_iter_t libdm_iter" +.Ft int +.Fn libdm_task_run "libdm_task_t *libdm_task" +.Ft libdm_task_t +.Fn libdm_task_create "const char *command" +.Ft void +.Fn libdm_task_destroy "libdm_task_t libdm_task" +.Ft int +.Fn libdm_task_set_name "const char *name" "libdm_task_t libdm_task" +.Ft char * +.Fn libdm_task_get_name "libdm_task_t libdm_task" +.Ft int +.Fn libdm_task_set_uuid "const char *uuid" "libdm_task_t libdm_task" +.Ft char * +.Fn libdm_task_get_uuid "libdm_task_t libdm_task" +.Ft char * +.Fn libdm_task_get_command "libdm_task_t libdm_task" +.Ft int32_t +.Fn libdm_task_get_cmd_version "libdm_task_t libdm_task" "uint32_t *ver" "size_t size" +.Ft int +.Fn libdm_task_set_minor "uint32_t minor" "libdm_task_t libdm_task" +.Ft uint32_t +.Fn libdm_task_get_minor "libdm_task_t libdm_task" +.Ft int +.Fn libdm_task_set_flags "uint32_t flags" "libdm_task_t libdm_task" +.Ft uint32_t +.Fn libdm_task_get_flags "libdm_task_t libdm_task" +.Ft uint32_t +.Fn libdm_task_get_target_num "libdm_task_t libdm_task" +.Ft int32_t +.Fn libdm_task_get_open_num "libdm_task_t libdm_task" +.Ft uint32_t +.Fn libdm_task_get_event_num "libdm_task_t libdm_task" +.Ft int +.Fn libdm_task_set_cmd "libdm_cmd_t libdm_cmd" "libdm_task_t libdm_task" +.Ft libdm_cmd_t +.Fn libdm_task_get_cmd "libdm_task_t libdm_task" +.Ft libdm_cmd_t +.Fn libdm_cmd_create "void" +.Ft void +.Fn libdm_cmd_destroy "libdm_cmd_t libdm_cmd" +.Ft libdm_iter_t +.Fn libdm_cmd_iter_create "libdm_cmd_t libdm_cmd" +.Ft int +.Fn libdm_cmd_set_table "libdm_table_t libdm_table" "libdm_cmd_t libdm_cmd" +.Ft libdm_table_t +.Fn libdm_cmd_get_table "libdm_iter_t iter" +.Ft libdm_target_t +.Fn libdm_cmd_get_target "libdm_iter_t iter" +.Ft libdm_dev_t +.Fn libdm_cmd_get_dev "libdm_iter_t iter" +.Ft uint64_t +.Fn libdm_cmd_get_deps "libdm_iter_t libdm_iter" +.Ft libdm_table_t +.Fn libdm_table_create "void" +.Ft void +.Fn libdm_table_destroy "libdm_table_t libdm_table" +.Ft int +.Fn libdm_table_set_start "uint64_t start" "libdm_table_t libdm_table" +.Ft uint64_t +.Fn libdm_table_get_start "libdm_table_t libdm_table" +.Ft int +.Fn libdm_table_set_length "uint64_t length" "libdm_table_t libdm_table" +.Ft uint64_t +.Fn libdm_table_get_length "libdm_table_t libdm_table" +.Ft int +.Fn libdm_table_set_target "const char *name" "libdm_table_t libdm_table" +.Ft char * +.Fn libdm_table_get_target "libdm_table_t libdm_table" +.Ft int +.Fn libdm_table_set_params "const char *params" "libdm_table_t libdm_table" +.Ft char * +.Fn libdm_table_get_params "libdm_table_t libdm_table" +.Ft int32_t +.Fn libdm_table_get_status "libdm_table_t libdm_table" +.Ft void +.Fn libdm_target_destroy "libdm_target_t libdm_target" +.Ft char * +.Fn libdm_target_get_name "libdm_target_t libdm_target" +.Ft int32_t +.Fn libdm_target_get_version "libdm_target_t libdm_target" "uint32_t *ver" "size_t size" +.Ft void +.Fn libdm_dev_destroy "libdm_dev_t libdm_dev" +.Ft char * +.Fn libdm_dev_get_name "libdm_dev_t libdm_dev" +.Ft uint32_t +.Fn libdm_dev_get_minor "libdm_dev_t libdm_dev" +.Ft int +.Fn libdm_dev_set_newname "const char *newname" "libdm_cmd_t libdm_cmd" +.Sh DESCRIPTION +Every object in libdm have it's own create and destroy routine. +.Bl -bullet -offset indent -compact +.It +libdm_task_t +.It +libdm_cmd_t +.It +libdm_table_t +.El +.Pp +Except +.Vt libdm_dev_t +which is received from kernel as list of physical devices on which +logical device depends. +.Vt libdm_target_t +which is received from kernel as list of available targets for use . +.Vt libdm_iter_t +which is used as itteration counter for array entries in task structure. +.Pp +Every object attribute in libdm can be set and get by appropriate routines, +therofore there is always set and get routine. +.Pp +.Ss LIBDM TASK +The +.Fn libdm_task_create +function creates a libdm task dictionary with command string set to +.Fa command . +If +.Fa command +is +.Dv NULL , +libdm_task_t is not created and function return +.Dv NULL . +.Pp +.Fn libdm_task_destroy +free all memory allocated to +.Fa libdm_task +by +.Fn libdm_task_create . +.Pp +.Fn libdm_task_run +Sends created +.Fa libdm_task +to kernel and receive new one as reply. +.Pp +List of attributes avaialable in +.Vt libdm_task_t : +.Bl -column -offset indent "DM_IOCTL_TARGET_COUNT" "Number of table entries" "XXX" +.It Sy Attribute Ta Sy Description Ta Sy Mode +.It Li DM_IOCTL_OPEN Ta Device open-count Ta Read-Only +.It Li DM_IOCTL_MINOR Ta Device minor number Ta Read-Write +.It Li DM_IOCTL_NAME Ta Device name Ta Read-Write +.It Li DM_IOCTL_UUID Ta Device uuid Ta Read-Write +.It Li DM_IOCTL_TARGET_COUNT Ta Number of table entries Ta Read-Only +.\".It Li DM_IOCTL_EVENT Ta Not implemented Ta not imp +.It Li DM_IOCTL_FLAGS Ta Device status flags Ta Read-Write +.El +.Pp + +.Fn libdm_task_set_name +and +.Fn libdm_task_get_name +Set name of device for commands which need to have dm device identifier. +Device-mapper later uses device name to lookup device from list of all devices. +Get routine will fetch device name from task dictionary. +.Pp +.Fn libdm_task_set_uuid +and +.Fn libdm_task_get_uuid +Set uuid of device for commands which need to have dm device identifier. +Device-mapper later uses device uuid to lookup device from list of all devices. +Get routine will fetch device uuid from task dictionary. +.Pp +.Fn libdm_task_set_minor +and +.Fn libdm_task_get_minor +Set minor device number of device for commands which need to have dm device identifier. +Device-mapper later uses device minor number to lookup device from list of all devices. +Get routine will fetch device minor number from task dictionary. +.Pp +.Fn libdm_task_set_flags +and +.Fn libdm_task_get_flags +Set/Fetch device status flags from task dictionary. +.Pp +.Fn libdm_task_get_open_num +Fetch number of opened devices from kernel and return them as +.Rt count . +.Pp +.Fn libdm_task_get_target_num +Fetch number of opened devices from kernel and return them as +.Rt count . +.Pp +.Fn libdm_task_get_cmd_version +Get dm driver in kernel version and set is as array +.Fa uint32_t *ver +with +.Fa size +size. +.Fn libdm_task_set_cmd +and +.Fn libdm_task_get_cmd +Adds and fetches cmd structure from +.Vt libdm_task_t . +.Vt libdm_cmd_t +is container used to carry information specific for particular command. +cmd is ususaly set before libdm_task_run is used and is get from task structure +after task run was called. +.Ss LIBDM TASK CMD +The +.Fn libdm_cmd_create +will allocate cmd structure which can be later put in to the task. +.Pp +.Fn libdm_cmd_destroy +will deallocate cmd strucute previously allocated. +.Pp +.Fn libdm_cmd_set_table +Will load and fetch device mapping table from dm device. Table is usually +loaded to device during initial device creation or device resizing. +.Pp +Because libdm_cmd is and array of structures all _get routines needs an +iterator to work. For every entry we can have more than one. +.Fn libdm_cmd_get_table +When user creates task with "status" command kernel sends cmd with table in it. +.Pp +.Fn libdm_cmd_get_target +Get mapping target description from cmd. Target contains target_name and +target_version. +.Pp +.Fn libdm_cmd_get_dev +When user creates task with "info" command kernel sends cmd with information +about dm device to user. +.Pp +.Fn libdm_cmd_get_deps +When user creates task with "deps" command kernel sends cmd with array of +physical devices atatched to dm device. +.Pp +Usually device has more than one table entry in device command. Therefore cmd +iterators are needed for +.Vt libdm_cmd_t +they can be created by +.Fn libdm_cmd_iter_create +routine. +.SS LIBDM CMD TABLE +Device table decribe logical mapping between dm device and physical devices. +Every table has logical block start, table length (in disk blocks), target +used by table, physical device and offset on it. Physical device and offset +on it are parameters which are target specific and are passed down to target +as param string. +.Pp +.Fn +.Pp +Example device table entry +.Dl 0 1024 linear /dev/wd1a 384 +.Bl -column -offset indent "DM_TABLE_LENGTH" "Number of table entries" +.It Sy Attribute Ta Sy Description +.It Li DM_TABLE_TYPE Ta Used device mapper target +.It Li DM_TABLE_START Ta Device Logical start block +.It Li DM_TABLE_STAT Ta Is 1 if this is current active table +.It Li DM_TABLE_LENGTH Ta Logical length described by table +.It Li DM_TABLE_PARAMS Ta Params passed down to target +.El +.Pp +.Fn libdm_table_set_start +and +.Fn libdm_table_get_start +Sets start table from +.Fa start +value to +.Fa libdm_table +argument. Get routine will get table start from kernel received in +.Vt libdm_table . +.Pp +.Fn libdm_table_set_length +and +.Fn libdm_table_get_length +Sets table length from +.Fa length +value to +.Fa libdm_table +argument. Get routine will get table length from kernel received in +.Vt libdm_table . +.Pp +.Fn libdm_table_set_target +and +.Fn libdm_table_get_target +Sets target name from +.Fa target +value to +.Fa libdm_table +argument. Target must be actually present in kernel otherwise libdm_task_run +will fail. Get routine will get table entry target from kernel received in +.Vt libdm_table . +.Pp +.Fn libdm_table_set_params +and +.Fn libdm_table_get_params +Set table target parameter string from +.Fa params +arrgument value to +.Fa libdm_table . +This is later in kernel passed to target init routine. +Get routine will get table parameter string from kernel received in +.Vt libdm_table . +.Pp +.Fn libdm_table_get_status + Get table status which can be Active/Inactive which tells if this table +is actually used or not . +.Pp +.Ss LIBDM_TARGET +.Fn libdm_target_destroy +Destroy target received from +.Vt libdm_cmd +with libdm_cmd_iter iterator. +.Pp +.Fn libdm_target_get_name +return pointer to string with available target name. +.Pp +.Fn lobdm_target_get_version +Sets argument +.Fa ver[3] +to a in kernel loaded target version. +.Pp +.Ss LIBDM_DEV +.Fn libdm_dev_destroy +Destroy device received from +.Vt libdm_cmd +with libdm_cmd_iter iterator. +.Pp +.Fn libdm_dev_get_name +Return pointer to a string with underlying device name from +.Vt libdm_dev_t +.Pp +.Fn libdm_dev_get_minor +Return underlying device minor number. +.Pp +.Ss MISC +.Fn libdm_dev_set_newname +This routine will set new dm device name attribute to +.Fa newname . +User must then called libdm_task_run on this task to +change device name. +.Pp +.Sh RETURN VALUES +Upon success all described functions return zero or non NULL pointer. +Otherwise, an error number will be returned to indicate the error. +.Pp +.Sh SEE ALSO +.Xr dm 4 +.Sh HISTORY +The +.Nm +was written and contributed to +.Nx +by Adam Hamsik and first appeared in +.Nx 6.0 . + Index: dsrc/sbin/dmctl/dmctl.8 =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ dsrc/sbin/dmctl/dmctl.8 2011-01-28 21:53:39.332990572 +0100 @@ -0,0 +1,65 @@ +.\" $NetBSD$ +.\" +.\" Copyright (c) 2004,2009 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Adam Hamsik. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.Dd Januar 23, 2011 +.Dt DMCTL 8 +.Os +.Sh NAME +.Nm dmctl +.Nd "Manipulate device-mapper driver command" +.Sh SYNOPSIS +.Nm +.Sh DESCRIPTION +.Nm +work with device-mapper kernel driver it can send/receive information and +commands from dm driver. +.Bl -column -offset indent "suspend" "Switch active and passive tables for" +.Ii Li version Ta Print driver and lib version. +.It Li targets Ta List available kernel targets. +.It Li create Ta Create device with [dm device name]. +.It Li ls Ta List existing dm devices. +.It Li info Ta Get info about device with [dm device name]. +.It Li rename Ta Rename device with [dm device name] to [dm device new name]. +.It Li remove Ta Remove device with [dm device name]. +.It Li resume Ta Resume IO on dm device [dm device name]. +.It Li suspend Ta Suspend IO on dm device [dm device name]. +.It Li deps Ta Print physical dependiences for dm device [dm device name]. +.It Li reload Ta Switch active and passive tables for [dm device name]. +.It Li status Ta Print status for device with [dm device name]. +.It Li table Ta Print active table for device with [dm device name]. +.El +.Sh SEE ALSO +.Xr dm 4 , +.Xr libdm 3 +.Sh HISTORY +The +.Nm +was written and contributed to +.Nx +by Adam Hamsik and first appeared in +.Nx 6.0 . Index: dsrc/distrib/sets/lists/comp/mi =================================================================== --- dsrc.orig/distrib/sets/lists/comp/mi 2011-01-26 09:01:33.765152740 +0100 +++ dsrc/distrib/sets/lists/comp/mi 2011-01-28 21:53:39.404128219 +0100 @@ -1391,6 +1391,7 @@ ./usr/include/ldap_schema.h comp-ldap-include ldap ./usr/include/ldap_utf8.h comp-ldap-include ldap ./usr/include/libdwarf.h comp-c-include +./usr/include/libdm.h comp-c-include ./usr/include/libelf.h comp-c-include ./usr/include/libgen.h comp-c-include ./usr/include/libintl.h comp-c-include @@ -2413,6 +2414,9 @@ ./usr/lib/libdevmapper.a comp-lvm-lib lvm ./usr/lib/libdevmapper_g.a -unknown- debuglib,lvm ./usr/lib/libdevmapper_p.a comp-lvm-proflib profile,lvm +./usr/lib/libdm.a comp-c-lib +./usr/lib/libdm_g.a -unknown- debuglib +./usr/lib/libdm_p.a comp-c-proflib profile ./usr/lib/libdns.a comp-bind-lib ./usr/lib/libdns_g.a -unknown- debuglib ./usr/lib/libdns_p.a comp-bind-proflib profile @@ -2972,6 +2976,7 @@ ./usr/libdata/debug/sbin/dkctl.debug comp-sysutil-debug debug ./usr/libdata/debug/sbin/dkscan_bsdlabel.debug comp-sysutil-debug debug ./usr/libdata/debug/sbin/dmesg.debug comp-sysutil-debug debug +./usr/libdata/debug/sbin/dmctl.debug comp-sysutil-debug debug ./usr/libdata/debug/sbin/dmsetup.debug comp-sysutil-debug lvm,debug ./usr/libdata/debug/sbin/drvctl.debug comp-sysutil-debug debug ./usr/libdata/debug/sbin/dump.debug comp-sysutil-debug debug @@ -3881,6 +3886,7 @@ ./usr/libdata/lint/llib-lcrypto_rc5.ln comp-c-lintlib lint,crypto_rc5 ./usr/libdata/lint/llib-lcurses.ln comp-c-lintlib lint ./usr/libdata/lint/llib-ldes.ln comp-c-lintlib lint,crypto +./usr/libdata/lint/llib-ldm.ln comp-c-lintlib lint ./usr/libdata/lint/llib-ldns.ln comp-bind-lintlib lint ./usr/libdata/lint/llib-ldns_sd.ln comp-mdns-lintlib lint,mdns ./usr/libdata/lint/llib-ldwarf.ln comp-c-lintlib lint @@ -5715,6 +5721,7 @@ ./usr/share/man/cat3/dlfcn.0 comp-c-catman .cat ./usr/share/man/cat3/dlopen.0 comp-c-catman .cat ./usr/share/man/cat3/dlsym.0 comp-c-catman .cat +./usr/share/man/cat3/dm.0 comp-c-catman .cat ./usr/share/man/cat3/dn_comp.0 comp-c-catman .cat ./usr/share/man/cat3/dn_expand.0 comp-c-catman .cat ./usr/share/man/cat3/dngettext.0 comp-c-catman .cat @@ -11766,6 +11773,7 @@ ./usr/share/man/html3/dlfcn.html comp-c-htmlman html ./usr/share/man/html3/dlopen.html comp-c-htmlman html ./usr/share/man/html3/dlsym.html comp-c-htmlman html +./usr/share/man/html3/dm.html comp-c-htmlman html ./usr/share/man/html3/dn_comp.html comp-c-htmlman html ./usr/share/man/html3/dn_expand.html comp-c-htmlman html ./usr/share/man/html3/dngettext.html comp-c-htmlman html @@ -17725,6 +17733,7 @@ ./usr/share/man/man3/dlfcn.3 comp-c-man .man ./usr/share/man/man3/dlopen.3 comp-c-man .man ./usr/share/man/man3/dlsym.3 comp-c-man .man +./usr/share/man/man3/dm.3 comp-c-man .man ./usr/share/man/man3/dn_comp.3 comp-c-man .man ./usr/share/man/man3/dn_expand.3 comp-c-man .man ./usr/share/man/man3/dngettext.3 comp-c-man .man Index: dsrc/distrib/sets/lists/man/mi =================================================================== --- dsrc.orig/distrib/sets/lists/man/mi 2011-01-26 09:01:33.785952592 +0100 +++ dsrc/distrib/sets/lists/man/mi 2011-01-28 21:53:39.497838839 +0100 @@ -2159,6 +2159,7 @@ ./usr/share/man/cat8/diskpart.0 man-sysutil-catman .cat ./usr/share/man/cat8/dkctl.0 man-sysutil-catman .cat ./usr/share/man/cat8/dkscan_bsdlabel.0 man-sysutil-catman .cat +./usr/share/man/cat8/dmctl.0 man-sysutil-catman .cat ./usr/share/man/cat8/dmesg.0 man-sysutil-catman .cat ./usr/share/man/cat8/dmsetup.0 man-lvm-catman lvm,.cat ./usr/share/man/cat8/dnssec-dsfromkey.0 man-bind-catman .cat @@ -4769,6 +4770,7 @@ ./usr/share/man/html8/diskpart.html man-sysutil-htmlman html ./usr/share/man/html8/dkctl.html man-sysutil-htmlman html ./usr/share/man/html8/dkscan_bsdlabel.html man-sysutil-htmlman html +./usr/share/man/html8/dmctl.html man-sysutil-htmlman html ./usr/share/man/html8/dmesg.html man-sysutil-htmlman html ./usr/share/man/html8/dmsetup.html man-lvm-htmlman lvm,html ./usr/share/man/html8/dnssec-dsfromkey.html man-bind-htmlman html @@ -7435,6 +7437,7 @@ ./usr/share/man/man8/diskpart.8 man-sysutil-man .man ./usr/share/man/man8/dkctl.8 man-sysutil-man .man ./usr/share/man/man8/dkscan_bsdlabel.8 man-sysutil-man .man +./usr/share/man/man8/dmctl.8 man-sysutil-man .man ./usr/share/man/man8/dmesg.8 man-sysutil-man .man ./usr/share/man/man8/dmsetup.8 man-lvm-man lvm,.man ./usr/share/man/man8/dnssec-dsfromkey.8 man-bind-man .man Index: dsrc/lib/libdm/libdm_private.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ dsrc/lib/libdm/libdm_private.h 2011-01-29 10:08:16.926596000 +0100 @@ -0,0 +1,37 @@ + +/* + * Libdm private definitions of structs. + */ + +#ifndef _LIBDM_PRIVATE_H_ +#define _LIBDM_PRIVATE_H_ + +__BEGIN_DECLS + +struct libdm_cmd { + prop_array_t ldm_cmd; +}; + +struct libdm_iter { + prop_object_iterator_t ldm_obji; +}; + +struct libdm_task { + prop_dictionary_t ldm_task; +}; + +struct libdm_table { + prop_dictionary_t ldm_tbl; +}; + +struct libdm_target { + prop_dictionary_t ldm_trgt; +}; + +struct libdm_dev { + prop_dictionary_t ldm_dev; +}; + +__END_DECLS + +#endif