Initial import of libdm and dmctl to tree. libdm library can be used

to access, manage and manipulate device-mapper driver. Which opens us bunch
of new possibilities like

	dm-multipath device target
	dm-crypt     device target
	dm-ccd 	     compatibility layer

With this import I'm bringing in dmctl tool for working with dm driver ,too.
I plan to replace gpl2 licensed dmsetup command with our dmctl tool in near
feature. It can also by placed to /rescue where we was not able to put
dmsetup because of licensing problems.

With libdm in tree we can now write RUMP atf test suite for dm driver to
ensure LVM subsystem stability as time goes.

Reviewed by: blymn@ and rmind@
Oked: by no objections on tech-userlevel@
This commit is contained in:
haad 2011-02-08 03:20:13 +00:00
parent af25d173e6
commit 83425a0f36
17 changed files with 2192 additions and 9 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.920 2011/02/04 19:42:12 pooka Exp $
# $NetBSD: mi,v 1.921 2011/02/08 03:20:13 haad Exp $
#
# Note: Don't delete entries from here - mark them as "obsolete" instead,
# unless otherwise stated below.
@ -218,6 +218,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

View File

@ -1,4 +1,4 @@
# $NetBSD: shl.mi,v 1.573 2011/02/06 00:44:08 christos Exp $
# $NetBSD: shl.mi,v 1.574 2011/02/08 03:20:13 haad Exp $
#
# Note: Don't delete entries from here - mark them as "obsolete" instead,
# unless otherwise stated below.
@ -25,6 +25,9 @@
./lib/libdevmapper.so base-lvm-shlib lvm,dynamicroot
./lib/libdevmapper.so.1 base-lvm-shlib lvm,dynamicroot
./lib/libdevmapper.so.1.0 base-lvm-shlib lvm,dynamicroot
./lib/libdm.so base-sys-shlib dynamicroot
./lib/libdm.so.0 base-sys-shlib dynamicroot
./lib/libdm.so.0.0 base-sys-shlib dynamicroot
./lib/libedit.so base-sys-shlib dynamicroot
./lib/libedit.so.3 base-sys-shlib dynamicroot
./lib/libedit.so.3.0 base-sys-shlib dynamicroot
@ -193,6 +196,9 @@
./usr/lib/libdevmapper.so base-lvm-shlib lvm
./usr/lib/libdevmapper.so.1 base-lvm-shlib lvm
./usr/lib/libdevmapper.so.1.0 base-lvm-shlib lvm
./usr/lib/libdm.so base-sys-shlib
./usr/lib/libdm.so.0 base-sys-shlib
./usr/lib/libdm.so.0.0 base-sys-shlib
./usr/lib/libdns.so base-bind-shlib
./usr/lib/libdns.so.5 base-bind-shlib
./usr/lib/libdns.so.5.2 base-bind-shlib

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1583 2011/02/06 01:13:42 joerg Exp $
# $NetBSD: mi,v 1.1584 2011/02/08 03:20:14 haad Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -624,6 +624,7 @@
./usr/include/dirent.h comp-c-include
./usr/include/disktab.h comp-c-include
./usr/include/dlfcn.h comp-c-include
./usr/include/dm.h comp-c-include
./usr/include/dns_sd.h comp-mdns-include mdns
./usr/include/dwarf.h comp-c-include
./usr/include/elf.h comp-c-include
@ -2417,6 +2418,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
@ -2982,6 +2986,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
@ -3892,6 +3897,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
@ -5727,6 +5733,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
@ -11782,6 +11789,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
@ -17745,6 +17753,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

View File

@ -1,4 +1,4 @@
# $NetBSD: shl.mi,v 1.158 2011/02/06 00:44:09 christos Exp $
# $NetBSD: shl.mi,v 1.159 2011/02/08 03:20:14 haad Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -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
@ -230,6 +231,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

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1284 2011/02/07 18:11:28 tsutsui Exp $
# $NetBSD: mi,v 1.1285 2011/02/08 03:20:14 haad Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -2162,6 +2162,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
@ -4776,6 +4777,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
@ -7446,6 +7448,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

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.161 2011/02/02 02:20:24 rmind Exp $
# $NetBSD: Makefile,v 1.162 2011/02/08 03:20:15 haad Exp $
# from: @(#)Makefile 5.25.1.1 (Berkeley) 5/7/91
.include <bsd.own.mk>
@ -84,6 +84,7 @@ SUBDIR+= libroken # depends on libutil, libcrypt
.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

23
lib/libdm/Makefile Normal file
View File

@ -0,0 +1,23 @@
# $NetBSD: Makefile,v 1.1 2011/02/08 03:20:15 haad Exp $
USE_FORT?= no # network protocol library
LIB= dm
SRCS= libdm_ioctl.c
MAN= dm.3
WARN= 4
CPPFLAGS+= -I${.CURDIR}
#CFLAGS+= -g -O0
INCS= dm.h
INCSDIR= /usr/include
#LDADD+= -lprop
#DPADD+= ${LIBPROP}
.ifdef RUMP_ACTION
CPPFLAGS+= -DRUMP_ACTION
.endif
.include <bsd.lib.mk>

386
lib/libdm/dm.3 Normal file
View File

@ -0,0 +1,386 @@
.\" $NetBSD: dm.3,v 1.1 2011/02/08 03:20:15 haad Exp $
.\"
.\" 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 .

154
lib/libdm/dm.h Normal file
View File

@ -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_ */

895
lib/libdm/libdm_ioctl.c Normal file
View File

@ -0,0 +1,895 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <prop/proplib.h>
#include <dev/dm/netbsd-dm.h>
#include "dm.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
prop_dictionary_externalize_to_file(libdm_task->ldm_task, "/tmp/libdm_in");
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;
}
prop_dictionary_externalize_to_file(dict, "/tmp/libdm_out");
#endif
libdm_control_close(libdm_control_fd);
prop_object_retain(dict);
prop_object_release(libdm_task->ldm_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);
if (cmd->ldm_cmd == NULL) {
free(cmd);
return NULL;
}
/* Get a reference prop_dictionary_get will not get it */
prop_object_retain(cmd->ldm_cmd);
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);
if (trgt->ldm_trgt == NULL) {
free(trgt);
return NULL;
}
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);
if (tbl->ldm_tbl == NULL) {
free(tbl);
return NULL;
}
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);
if (dev->ldm_dev == NULL) {
free(dev);
return NULL;
}
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);
if (obj != NULL)
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 **)&params))
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);
}

4
lib/libdm/shlib_version Normal file
View File

@ -0,0 +1,4 @@
# $NetBSD: shlib_version,v 1.1 2011/02/08 03:20:15 haad Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
major=0
minor=0

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.118 2011/01/13 22:28:36 haad Exp $
# $NetBSD: Makefile,v 1.119 2011/02/08 03:20:15 haad Exp $
# @(#)Makefile 8.5 (Berkeley) 3/31/94
# Not ported: XNSrouted enpload scsiformat startslip
@ -7,7 +7,7 @@
.include <bsd.own.mk>
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 \

24
sbin/dmctl/Makefile Normal file
View File

@ -0,0 +1,24 @@
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+= -ldm
.ifdef RUMP_ACTION
CPPFLAGS+= -D RUMP_ACTION
LDADD+= -lrumpclient
.endif
LDADD+= -lprop
#LDSTATIC= -static
.include <bsd.prog.mk>

23
sbin/dmctl/README Normal file
View File

@ -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

65
sbin/dmctl/dmctl.8 Normal file
View File

@ -0,0 +1,65 @@
.\" $NetBSD: dmctl.8,v 1.1 2011/02/08 03:20:15 haad Exp $
.\"
.\" 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 .

580
sbin/dmctl/dmctl.c Normal file
View File

@ -0,0 +1,580 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <prop/proplib.h>
#include <dm.h>
#ifdef RUMP_ACTION
#include <rump/rump.h>
#include <rump/rumpclient.h>
#include <rump/rump_syscalls.h>
#endif
/* 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_cmd_destroy(cmd);
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_cmd_destroy(cmd);
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_cmd_destroy(cmd);
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_cmd_destroy(cmd);
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;
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: intro.3,v 1.23 2010/12/09 13:51:45 njoly Exp $
.\" $NetBSD: intro.3,v 1.24 2011/02/08 03:20:16 haad Exp $
.\"
.\" Copyright (c) 1980, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@ -134,6 +134,13 @@ for two dimensional non-bitmap display terminals. See
.It Em libdes Pq Fl l Ns Ar des
The OpenSSL cryptographic library for the DES algorithms. See
.Xr des 3 .
.It Em libdm Pq Fl l Ns Ar dm
The device-mapper driver access library used for communication with
kernel driver
.Xr dm 4
and for
.Xr lvm 8
subsystem.
.It Em libedit Pq Fl l Ns Ar edit
The command-line editor or editline library. The editline library
provides generic editing and history functions. See