Index: Makefile
===================================================================
RCS file: Makefile
diff -N Makefile
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ Makefile    19 Dec 2008 00:00:15 -0000
@@ -0,0 +1,7 @@
+.include <bsd.own.mk>
+
+.if (${MKLVM} != "no")
+SUBDIR+= lvm2tools
+.endif
+
+.include <bsd.subdir.mk>
Index: ./lvm2tools/Makefile
===================================================================
RCS file: ./lvm2tools/Makefile
diff -N ./lvm2tools/Makefile
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/Makefile        19 Dec 2008 00:00:15 -0000
@@ -0,0 +1,9 @@
+#      $NetBSD$
+
+.include "lvm2tools.mk"
+
+SUBDIR+=       lib .WAIT
+
+SUBDIR+=       sbin
+
+.include <bsd.subdir.mk>
Index: ./lvm2tools/lvm2tools.mk
===================================================================
RCS file: ./lvm2tools/lvm2tools.mk
diff -N ./lvm2tools/lvm2tools.mk
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/lvm2tools.mk    19 Dec 2008 00:00:15 -0000
@@ -0,0 +1,21 @@
+#      $NetBSD$
+
+.include <bsd.own.mk>
+
+LVM2TOOLS_SRCDIR=      ${NETBSDSRCDIR}/external/gpl2/lvm2tools
+LVM2TOOLS_DISTDIR=     ${NETBSDSRCDIR}/external/gpl2/lvm2tools/dist
+
+LVM2TOOLS_PREFIX=      /
+
+LIBDM_SRCDIR=          ${NETBSDSRCDIR}/external/gpl2/lvm2tools/dist/libdm
+LIBDM_INCLUDE=         ${NETBSDSRCDIR}/external/gpl2/lvm2tools/dist/include
+
+#
+#LIBDM_OBJDIR.libdevmapper=${LIBDM_SRCDIR}/lib/libdevmapper/
+#
+#.if !defined(LVM2TOOLSOBJDIR.liblvm)
+#LVM2TOOLSOBJDIR.liblvm!=      cd ${LVM2TOOLS_SRCDIR}/lib/liblvm && ${PRINTOBJDIR}
+#.MAKEOVERRIDES+=      LVM2TOOLSOBJDIR.liblvm
+#.endif
+#
+#LVM2TOOLS.liblvm=     ${LVM2TOOLSOBJDIR.liblvm}/liblvm.a
Index: ./lvm2tools/dist/include/netbsd.h
===================================================================
RCS file: ./lvm2tools/dist/include/netbsd.h
diff -N ./lvm2tools/dist/include/netbsd.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/dist/include/netbsd.h   19 Dec 2008 00:00:15 -0000
@@ -0,0 +1,13 @@
+
+/*
+ * NetBSD specific header file.
+ */
+
+#ifndef __NETBSD_H__
+#define __NETBSD_H__
+
+
+/* lib/netbsd/netbsd.c  */
+int nbsd_check_dev(int, const char *);
+
+#endif
Index: ./lvm2tools/dist/lib/activate/fs.c
===================================================================
RCS file: /cvsroot/src/external/gpl2/lvm2tools/dist/lib/activate/fs.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 fs.c
--- ./lvm2tools/dist/lib/activate/fs.c  12 Dec 2008 11:42:24 -0000      1.1.1.2
+++ ./lvm2tools/dist/lib/activate/fs.c  19 Dec 2008 00:00:16 -0000
@@ -101,6 +101,20 @@ static void _rm_blks(const char *dir)
                       if (unlink(path) < 0)
                               log_sys_error("unlink", path);
               }
+#ifdef __NetBSD__
+               if (dm_snprintf(path, sizeof(path), "%s/r%s", dir, name) == -1) {
+                       log_error("Couldn't create path for r%s", name);
+                       continue;
+               }
+
+               if (!lstat(path, &buf)) {
+                       if (!S_ISCHR(buf.st_mode))
+                               continue;
+                       log_very_verbose("Removing %s", path);
+                       if (unlink(path) < 0)
+                               log_sys_error("unlink", path);
+               }
+#endif
       }
}

@@ -111,6 +125,11 @@ static int _mk_link(const char *dev_dir,
       char vg_path[PATH_MAX];
       struct stat buf;

+#ifdef __NetBSD__
+       /* Add support for creating links to BSD raw devices */
+       char raw_lv_path[PATH_MAX], raw_link_path[PATH_MAX];
+#endif
+
       if (dm_snprintf(vg_path, sizeof(vg_path), "%s%s",
                        dev_dir, vg_name) == -1) {
               log_error("Couldn't create path for volume group dir %s",
@@ -118,6 +137,42 @@ static int _mk_link(const char *dev_dir,
               return 0;
       }

+#ifdef __NetBSD__
+       if (dm_snprintf(raw_lv_path, sizeof(raw_lv_path), "%s/r%s", vg_path,
+               lv_name) == -1) {
+               log_error("Couldn't create source pathname for "
+                   "logical volume link r%s", lv_name);
+               return 0;
+       }
+
+       if (dm_snprintf(raw_link_path, sizeof(raw_link_path), "%s/r%s",
+               dm_dir(), dev) == -1) {
+               log_error("Couldn't create destination pathname for "
+                   "logical volume link for %s", lv_name);
+               return 0;
+       }
+
+       if (!lstat(raw_lv_path, &buf)) {
+               if (!S_ISLNK(buf.st_mode) && !S_ISCHR(buf.st_mode)) {
+                       log_error("Symbolic link %s not created: file exists",
+                                 raw_link_path);
+                       return 0;
+               }
+
+               log_very_verbose("Removing %s", raw_lv_path);
+               if (unlink(raw_lv_path) < 0) {
+                       log_sys_error("unlink", raw_lv_path);
+                       return 0;
+               }
+       }
+
+       log_very_verbose("Linking %s -> %s", raw_lv_path, raw_link_path);
+       if (symlink(raw_link_path, raw_lv_path) < 0) {
+               log_sys_error("symlink", raw_lv_path);
+               return 0;
+       }
+
+#endif
       if (dm_snprintf(lv_path, sizeof(lv_path), "%s/%s", vg_path,
                        lv_name) == -1) {
               log_error("Couldn't create source pathname for "
@@ -190,6 +245,29 @@ static int _rm_link(const char *dev_dir,
       struct stat buf;
       char lv_path[PATH_MAX];

+#ifdef __NetBSD__
+       /* Add support for removing links to BSD raw devices */
+       char raw_lv_path[PATH_MAX];
+
+       if (dm_snprintf(raw_lv_path, sizeof(raw_lv_path), "%s%s/r%s",
+                        dev_dir, vg_name, lv_name) == -1) {
+               log_error("Couldn't determine link pathname.");
+               return 0;
+       }
+
+       if (lstat(raw_lv_path, &buf) || !S_ISLNK(buf.st_mode)) {
+               if (errno == ENOENT)
+                       return 1;
+               log_error("%s not symbolic link - not removing", raw_lv_path);
+               return 0;
+       }
+
+       log_very_verbose("Removing link %s", raw_lv_path);
+       if (unlink(raw_lv_path) < 0) {
+               log_sys_error("unlink", raw_lv_path);
+               return 0;
+       }
+#endif
       if (dm_snprintf(lv_path, sizeof(lv_path), "%s%s/%s",
                        dev_dir, vg_name, lv_name) == -1) {
               log_error("Couldn't determine link pathname.");
Index: ./lvm2tools/dist/lib/commands/toolcontext.c
===================================================================
RCS file: /cvsroot/src/external/gpl2/lvm2tools/dist/lib/commands/toolcontext.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 toolcontext.c
--- ./lvm2tools/dist/lib/commands/toolcontext.c 12 Dec 2008 11:42:15 -0000      1.1.1.2
+++ ./lvm2tools/dist/lib/commands/toolcontext.c 19 Dec 2008 00:00:16 -0000
@@ -220,6 +220,8 @@ static int _process_config(struct cmd_co
#ifdef DEVMAPPER_SUPPORT
       dm_set_dev_dir(cmd->dev_dir);
#endif
+#ifndef __NetBSD__
+

       /* proc dir */
       if (dm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
@@ -228,11 +230,11 @@ static int _process_config(struct cmd_co
               log_error("Device directory given in config file too long");
               return 0;
       }
-
+#endif
       if (*cmd->proc_dir && !dir_exists(cmd->proc_dir)) {
               log_error("WARNING: proc dir %s not found - some checks will be bypassed",
                         cmd->proc_dir);
-               cmd->proc_dir[0] = '\0';
+               *cmd->proc_dir = '\0';
       }

       _get_sysfs_dir(cmd);
Index: ./lvm2tools/dist/lib/device/dev-cache.c
===================================================================
RCS file: /cvsroot/src/external/gpl2/lvm2tools/dist/lib/device/dev-cache.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 dev-cache.c
--- ./lvm2tools/dist/lib/device/dev-cache.c     12 Dec 2008 11:42:18 -0000      1.1.1.2
+++ ./lvm2tools/dist/lib/device/dev-cache.c     19 Dec 2008 00:00:17 -0000
@@ -27,6 +27,10 @@
#include <sys/param.h>
#include <dirent.h>

+#ifdef __NetBSD__
+#include "netbsd.h"
+#endif
+
struct dev_iter {
       struct btree_iter *current;
       struct dev_filter *filter;
@@ -423,14 +427,26 @@ static int _insert(const char *path, int
               if (rec)
                       r = _insert_dir(path);

-       } else {                /* add a device */
-               if (!S_ISBLK(info.st_mode)) {
-                       log_debug("%s: Not a block device", path);
-                       return 0;
+       } else {
+               /* add a device */
+#ifdef __NetBSD__
+               /*
+                * In NetBSD we have two different types of devices
+                * raw and block. I can insert only  existing
+                * raw and block device.
+                */
+               if (nbsd_check_dev(MAJOR(info.st_rdev),path) < 0) {
+                       log_debug("%s: Not a block device.", path);
+                       return_0;
               }

-               if (!_insert_dev(path, info.st_rdev))
+#else
+               if (!S_ISBLK(info.st_mode))
+                       log_debug("%s: Not a block device", path);
+#endif
+               if (!_insert_dev(path, info.st_rdev)) {
                       return_0;
+               }

               r = 1;
       }
Index: ./lvm2tools/dist/lib/device/dev-io.c
===================================================================
RCS file: /cvsroot/src/external/gpl2/lvm2tools/dist/lib/device/dev-io.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 dev-io.c
--- ./lvm2tools/dist/lib/device/dev-io.c        12 Dec 2008 11:42:19 -0000      1.1.1.2
+++ ./lvm2tools/dist/lib/device/dev-io.c        19 Dec 2008 00:00:17 -0000
@@ -38,6 +38,10 @@
#  ifndef BLKGETSIZE64         /* fs.h out-of-date */
#    define BLKGETSIZE64 _IOR(0x12, 114, size_t)
#  endif /* BLKGETSIZE64 */
+#elif __NetBSD__
+#  include <sys/disk.h>
+#  include <sys/disklabel.h>
+#  include <sys/param.h>
#else
#  include <sys/disk.h>
#  define BLKBSZGET DKIOCGETBLOCKSIZE
@@ -127,12 +131,22 @@ static int _io(struct device_area *where
static int _get_block_size(struct device *dev, unsigned int *size)
{
       const char *name = dev_name(dev);
+#ifdef __NetBSD__
+       struct disklabel        lab;
+#endif

       if ((dev->block_size == -1)) {
+#ifdef __NetBSD__
+               if (ioctl(dev_fd(dev), DIOCGDINFO, &lab) < 0) {
+                       dev->block_size = DEV_BSIZE;
+               } else
+                       dev->block_size = lab.d_secsize;
+#else
               if (ioctl(dev_fd(dev), BLKBSZGET, &dev->block_size) < 0) {
                       log_sys_error("ioctl BLKBSZGET", name);
                       return 0;
               }
+#endif
               log_debug("%s: block size is %u bytes", name, dev->block_size);
       }

@@ -242,12 +256,35 @@ static int _dev_get_size_dev(const struc
{
       int fd;
       const char *name = dev_name(dev);
+#ifdef __NetBSD__
+       struct disklabel        lab;
+       struct dkwedge_info     dkw;
+#endif

       if ((fd = open(name, O_RDONLY)) < 0) {
               log_sys_error("open", name);
               return 0;
+               }
+
+#ifdef __NetBSD__
+       if ((*size = lseek (fd, 0, SEEK_END)) < 0) {
+               log_sys_error("lseek SEEK_END", name);
+               close(fd);
+               return 0;
       }

+       if (ioctl(fd, DIOCGDINFO, &lab) < 0) {
+               if (ioctl(fd, DIOCGWEDGEINFO, &dkw) < 0) {
+                       log_sys_error("ioctl DIOCGWEDGEINFO", name);
+                       close(fd);
+                       return 0;
+               } else
+                       if (dkw.dkw_size)
+                               *size = dkw.dkw_size;
+       } else
+               if (lab.d_secsize)
+                       *size /= lab.d_secsize;
+#else
       if (ioctl(fd, BLKGETSIZE64, size) < 0) {
               log_sys_error("ioctl BLKGETSIZE64", name);
               if (close(fd))
@@ -256,6 +293,7 @@ static int _dev_get_size_dev(const struc
       }

       *size >>= BLKSIZE_SHIFT;        /* Convert to sectors */
+#endif
       if (close(fd))
               log_sys_error("close", name);

@@ -308,8 +346,10 @@ int dev_get_sectsize(struct device *dev,

void dev_flush(struct device *dev)
{
+#ifdef __linux__
       if (!(dev->flags & DEV_REGULAR) && ioctl(dev->fd, BLKFLSBUF, 0) >= 0)
               return;
+#endif

       if (fsync(dev->fd) >= 0)
               return;
Index: ./lvm2tools/dist/lib/filters/filter_netbsd.c
===================================================================
RCS file: ./lvm2tools/dist/lib/filters/filter_netbsd.c
diff -N ./lvm2tools/dist/lib/filters/filter_netbsd.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/dist/lib/filters/filter_netbsd.c        19 Dec 2008 00:00:17 -0000
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2008 Adam Hamsik. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "lib.h"
+#include "dev-cache.h"
+#include "filter.h"
+#include "lvm-string.h"
+#include "config.h"
+#include "metadata.h"
+#include "activate.h"
+
+#include <sys/sysctl.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
+
+#define NUMBER_OF_MAJORS 4096
+
+#define LVM_SUCCESS 1
+#define LVM_FAILURE 0
+
+/* -1 means LVM won't use this major number. */
+static int _char_device_major[NUMBER_OF_MAJORS];
+static int _block_device_major[NUMBER_OF_MAJORS];
+
+typedef struct {
+       const char *name;
+       const int max_partitions;
+} device_info_t;
+
+static int _md_major = -1;
+static int _device_mapper_major = -1;
+
+int md_major(void)
+{
+       return _md_major;
+}
+
+/*
+ * Devices are only checked for partition tables if their minor number
+ * is a multiple of the number corresponding to their type below
+ * i.e. this gives the granularity of whole-device minor numbers.
+ * Use 1 if the device is not partitionable.
+ *
+ * The list can be supplemented with devices/types in the config file.
+ */
+static const device_info_t device_info[] = {
+       {"wd", 64},
+       {"sd", 64},
+       {"dk", 1},
+       {"wd", 64},
+       {"vnd", 1},
+       {"raid", 64},
+       {"cgd", 1},
+       {"ccd", 1},
+       {NULL, -1}
+};
+
+/*
+ * Test if device passes filter tests and can be inserted in to cache.
+ */
+static int _passes_lvm_type_device_filter(struct dev_filter *f __attribute((unused)),
+                                         struct device *dev)
+{
+       const char *name = dev_name(dev);
+       int ret = 0;
+       uint64_t size;
+
+       /* Is this a recognised device type? */
+       if (_char_device_major[MAJOR(dev->dev)] == -1 ){
+               log_debug("%s: Skipping: Unrecognised LVM device type %"
+                                 PRIu64, name, (uint64_t) MAJOR(dev->dev));
+               return LVM_FAILURE;
+       }
+
+       /* Skip suspended devices */
+       if (MAJOR(dev->dev) == _device_mapper_major &&
+           ignore_suspended_devices() && !device_is_usable(dev->dev)) {
+               log_debug("%s: Skipping: Suspended dm device", name);
+               return LVM_FAILURE;
+       }
+
+       /* Check it's accessible */
+       if (!dev_open_flags(dev, O_RDONLY, 0, 1)) {
+               log_debug("%s: Skipping: open failed", name);
+               return LVM_FAILURE;
+       }
+
+       /* Check it's not too small */
+       if (!dev_get_size(dev, &size)) {
+               log_debug("%s: Skipping: dev_get_size failed", name);
+               goto out;
+       }
+
+       if (size < PV_MIN_SIZE) {
+               log_debug("%s: Skipping: Too small to hold a PV", name);
+               goto out;
+       }
+
+       if (is_partitioned_dev(dev)) {
+               log_debug("%s: Skipping: Partition table signature found",
+                         name);
+               goto out;
+       }
+
+       ret = LVM_SUCCESS;
+
+      out:
+       dev_close(dev);
+
+       return ret;
+}
+
+static int _scan_dev(const struct config_node *cn)
+{
+       size_t val_len,i,j;
+       char *name;
+
+       struct kinfo_drivers *kd;
+       struct config_value *cv;
+
+       /* All types unrecognised initially */
+       memset(_char_device_major, -1, sizeof(int) * NUMBER_OF_MAJORS);
+       memset(_block_device_major, -1, sizeof(int) * NUMBER_OF_MAJORS);
+
+       /* get size kernel drivers array from kernel*/
+       if (sysctlbyname("kern.drivers", NULL, &val_len, NULL, 0) < 0) {
+               printf("sysctlbyname failed");
+               return LVM_FAILURE;
+       }
+
+       if ((kd = malloc(val_len)) == NULL){
+               printf("malloc kd info error\n");
+               return LVM_FAILURE;
+       }
+
+       /* get array from kernel */
+       if (sysctlbyname("kern.drivers", kd, &val_len, NULL, 0) < 0) {
+               printf("sysctlbyname failed kd");
+               return LVM_FAILURE;
+       }
+
+       for (i = 0, val_len /= sizeof(*kd); i < val_len; i++) {
+
+               if (!strncmp("device-mapper", kd[i].d_name, 13) ||
+                   !strncmp("dm", kd[i].d_name, 2))
+                       _device_mapper_major = kd[i].d_bmajor;
+
+               /* We select only devices with correct char/block major number. */
+               if (kd[i].d_cmajor != -1 && kd[i].d_bmajor != -1) {
+                       /* Go through the valid device names and if there is a
+                          match store max number of partitions */
+                       for (j = 0; device_info[j].name != NULL; j++){
+                               if (!strcmp(device_info[j].name, kd[i].d_name)){
+                                       _char_device_major[kd[i].d_cmajor] =
+                                           device_info[j].max_partitions;
+                                       _block_device_major[kd[i].d_bmajor] =
+                                           device_info[j].max_partitions;
+                                       break;
+                               }
+                       }
+               }
+
+               if (!cn)
+                       continue;
+
+               /* Check devices/types for local variations */
+               for (cv = cn->v; cv; cv = cv->next) {
+                       if (cv->type != CFG_STRING) {
+                               log_error("Expecting string in devices/types "
+                                         "in config file");
+                               free(kd);
+                               return LVM_FAILURE;
+                       }
+
+                       name = cv->v.str;
+                       cv = cv->next;
+                       if (!cv || cv->type != CFG_INT) {
+                               log_error("Max partition count missing for %s "
+                                         "in devices/types in config file",
+                                         name);
+                               free(kd);
+                               return LVM_FAILURE;
+                       }
+                       if (!cv->v.i) {
+                               log_error("Zero partition count invalid for "
+                                         "%s in devices/types in config file",
+                                         name);
+                               free(kd);
+                               return LVM_FAILURE;
+                       }
+
+                       if (!strncmp(name, kd[i].d_name, strlen(name))){
+                                       _char_device_major[kd[i].d_cmajor] =
+                                           device_info[j].max_partitions;
+                                       _block_device_major[kd[i].d_bmajor] =
+                                           device_info[j].max_partitions;
+                                       break;
+                       }
+               }
+       }
+
+       free(kd);
+
+       return LVM_SUCCESS;
+}
+
+int max_partitions(int major)
+{
+       return _char_device_major[major];
+}
+
+struct dev_filter *lvm_type_filter_create(const char *proc,
+                                         const struct config_node *cn)
+{
+       struct dev_filter *f;
+
+       if (!(f = dm_malloc(sizeof(struct dev_filter)))) {
+               log_error("LVM type filter allocation failed");
+               return NULL;
+       }
+
+       f->passes_filter = _passes_lvm_type_device_filter;
+       f->destroy = lvm_type_filter_destroy;
+       f->private = NULL;
+
+       if (!_scan_dev(cn)) {
+               dm_free(f);
+               return_NULL;
+       }
+
+       return f;
+}
+
+void lvm_type_filter_destroy(struct dev_filter *f)
+{
+       dm_free(f);
+       return;
+}
Index: ./lvm2tools/dist/lib/metadata/lv_manip.c
===================================================================
RCS file: /cvsroot/src/external/gpl2/lvm2tools/dist/lib/metadata/lv_manip.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 lv_manip.c
--- ./lvm2tools/dist/lib/metadata/lv_manip.c    12 Dec 2008 11:42:32 -0000      1.1.1.2
+++ ./lvm2tools/dist/lib/metadata/lv_manip.c    19 Dec 2008 00:00:18 -0000
@@ -2656,13 +2656,19 @@ int set_lv(struct cmd_context *cmd, stru
               log_error("Name allocation failed - device not cleared");
               return 0;
       }
-
+#ifdef __NetBSD__
+       if (dm_snprintf(name, PATH_MAX, "%s%s/r%s", cmd->dev_dir,
+                       lv->vg->name, lv->name) < 0) {
+               log_error("Name too long - device not cleared (%s)", lv->name);
+               return 0;
+       }
+#else
       if (dm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
                       lv->vg->name, lv->name) < 0) {
               log_error("Name too long - device not cleared (%s)", lv->name);
               return 0;
       }
-
+#endif
       log_verbose("Clearing start of logical volume \"%s\"", lv->name);

       if (!(dev = dev_cache_get(name, NULL))) {
Index: ./lvm2tools/dist/lib/netbsd/dev.c
===================================================================
RCS file: ./lvm2tools/dist/lib/netbsd/dev.c
diff -N ./lvm2tools/dist/lib/netbsd/dev.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/dist/lib/netbsd/dev.c   19 Dec 2008 00:00:21 -0000
@@ -0,0 +1,70 @@
+/*
+ * NetBSD specific device routines are added to this file.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <sys/sysctl.h>
+
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <limits.h>
+
+#include "netbsd.h"
+
+#define LVM_FAILURE -1
+
+/*
+ * Find major numbers for char/block parts of all block devices.
+ * In NetBSD every block device has it's char counter part.
+ * Return success only for device drivers with defined char/block
+ * major numbers.
+ */
+int
+nbsd_check_dev(int major, const char *path)
+{
+
+       size_t val_len,i;
+
+       struct kinfo_drivers *kd;
+
+       /* XXX HACK */
+       if (strcmp(path,"/dev/console") == 0)
+               return LVM_FAILURE;
+
+       /* get size kernel drivers array from kernel*/
+       if (sysctlbyname("kern.drivers",NULL,&val_len,NULL,0) < 0) {
+               printf("sysctlbyname failed");
+               return LVM_FAILURE;
+       }
+
+       if ((kd = malloc (val_len)) == NULL){
+               printf("malloc kd info error\n");
+               return LVM_FAILURE;
+       }
+
+       /* get array from kernel */
+       if (sysctlbyname("kern.drivers", kd, &val_len, NULL, 0) < 0) {
+               printf("sysctlbyname failed kd");
+               return LVM_FAILURE;
+       }
+
+       for (i = 0, val_len /= sizeof(*kd); i < val_len; i++)
+               /* We select only devices with correct char/block major number. */
+               if (kd[i].d_cmajor != -1 && kd[i].d_bmajor != -1) {
+
+                       if (kd[i].d_cmajor == major)
+                               return kd[i].d_bmajor;
+
+                       if (kd[i].d_bmajor == major)
+                               return kd[i].d_cmajor;
+
+               }
+
+       return LVM_FAILURE;
+}
Index: ./lvm2tools/dist/lib/netbsd/netbsd.h
===================================================================
RCS file: ./lvm2tools/dist/lib/netbsd/netbsd.h
diff -N ./lvm2tools/dist/lib/netbsd/netbsd.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/dist/lib/netbsd/netbsd.h        19 Dec 2008 00:00:21 -0000
@@ -0,0 +1,13 @@
+
+/*
+ * NetBSD specific header file.
+ */
+
+#ifndef __NETBSD_H__
+#define __NETBSD_H__
+
+
+/* lib/netbsd/netbsd.c  */
+int nbsd_check_dev(int, const char *);
+
+#endif
Index: ./lvm2tools/dist/libdm/libdm-common.c
===================================================================
RCS file: /cvsroot/src/external/gpl2/lvm2tools/dist/libdm/libdm-common.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 libdm-common.c
--- ./lvm2tools/dist/libdm/libdm-common.c       12 Dec 2008 11:42:48 -0000      1.1.1.1
+++ ./lvm2tools/dist/libdm/libdm-common.c       19 Dec 2008 00:00:21 -0000
@@ -18,7 +18,9 @@
#include "dmlib.h"
#include "libdm-targets.h"
#include "libdm-common.h"
+#ifdef linux
#include "kdev_t.h"
+#endif
#include "dm-ioctl.h"

#include <stdarg.h>
@@ -34,6 +36,10 @@
#  include <selinux/selinux.h>
#endif

+#ifdef __NetBSD__
+#include <netbsd-dm.h>
+#endif
+
#define DEV_DIR "/dev/"

static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR;
@@ -268,6 +274,45 @@ static int _add_dev_node(const char *dev
       dev_t dev = MKDEV(major, minor);
       mode_t old_mask;

+       #ifdef __NetBSD__
+       char rpath[PATH_MAX];
+       uint32_t raw_major;
+       dev_t rdev;
+       char raw_devname[DM_NAME_LEN+1]; /* r + other device name */
+
+       nbsd_get_dm_major(&raw_major,DM_CHAR_MAJOR);
+       rdev = MKDEV(raw_major,minor);
+
+       snprintf(raw_devname,sizeof(raw_devname),"r%s",dev_name);
+
+       _build_dev_path(rpath, sizeof(rpath), raw_devname);
+
+       if (stat(rpath, &info) >= 0) {
+               if (!S_ISCHR(info.st_mode)) {
+                       log_error("A non-raw device file at '%s' "
+                           "is already present", rpath);
+                       return 0;
+               }
+
+               /* If right inode already exists we don't touch uid etc. */
+               if (info.st_rdev == rdev)
+                       return 1;
+
+               if (unlink(rpath) < 0) {
+                       log_error("Unable to unlink device node for '%s'",
+                           raw_devname);
+                       return 0;
+               }
+       }
+
+       old_mask = umask(0);
+
+       if (mknod(rpath, S_IFCHR | mode, rdev) < 0) {
+               log_error("Unable to make device node for '%s'", raw_devname);
+               return 0;
+       }
+#endif
+
       _build_dev_path(path, sizeof(path), dev_name);

       if (stat(path, &info) >= 0) {
@@ -316,6 +361,42 @@ static int _rename_dev_node(const char *
       char newpath[PATH_MAX];
       struct stat info;

+#ifdef __NetBSD__
+       char rpath[PATH_MAX];
+       char nrpath[PATH_MAX];
+       char raw_devname[DM_NAME_LEN+1]; /* r + other device name */
+       char nraw_devname[DM_NAME_LEN+1]; /* r + other device name */
+
+       snprintf(nraw_devname,sizeof(raw_devname),"r%s",new_name);
+       snprintf(raw_devname,sizeof(raw_devname),"r%s",old_name);
+
+       _build_dev_path(nrpath, sizeof(nrpath), nraw_devname);
+       _build_dev_path(rpath, sizeof(rpath), raw_devname);
+
+       if (stat(nrpath, &info) == 0) {
+               if (S_ISBLK(info.st_mode)) {
+                       log_error("A block device file at '%s' "
+                           "is present where raw device should be.", newpath);
+                       return 0;
+               }
+
+               if (unlink(nrpath) < 0) {
+                       log_error("Unable to unlink device node for '%s'",
+                           nraw_devname);
+                       return 0;
+               }
+       }
+
+       if (rename(rpath, nrpath) < 0) {
+               log_error("Unable to rename device node from '%s' to '%s'",
+                   raw_devname, nraw_devname);
+               return 0;
+       }
+
+       log_debug("Renamed %s to %s", rpath, nrpath);
+
+#endif
+
       _build_dev_path(oldpath, sizeof(oldpath), old_name);
       _build_dev_path(newpath, sizeof(newpath), new_name);

@@ -353,6 +434,25 @@ static int _rm_dev_node(const char *dev_
       char path[PATH_MAX];
       struct stat info;

+#ifdef __NetBSD__
+       char rpath[PATH_MAX];
+       char raw_devname[DM_NAME_LEN+1]; /* r + other device name */
+
+       snprintf(raw_devname,sizeof(raw_devname),"r%s",dev_name);
+
+       _build_dev_path(rpath, sizeof(rpath), raw_devname);
+
+       if (stat(rpath, &info) < 0)
+               return 1;
+
+       if (unlink(rpath) < 0) {
+               log_error("Unable to unlink device node for '%s'", raw_devname);
+               return 0;
+       }
+
+       log_debug("Removed %s", rpath);
+#endif
+
       _build_dev_path(path, sizeof(path), dev_name);

       if (stat(path, &info) < 0)
Index: ./lvm2tools/dist/libdm/libdm-deptree.c
===================================================================
RCS file: /cvsroot/src/external/gpl2/lvm2tools/dist/libdm/libdm-deptree.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 libdm-deptree.c
--- ./lvm2tools/dist/libdm/libdm-deptree.c      12 Dec 2008 11:42:50 -0000      1.1.1.1
+++ ./lvm2tools/dist/libdm/libdm-deptree.c      19 Dec 2008 00:00:22 -0000
@@ -1830,12 +1830,17 @@ int dm_tree_node_add_target_area(struct
                       log_error("Device %s not found.", dev_name);
                       return 0;
               }
-
+#ifndef __NetBSD__
               if (!S_ISBLK(info.st_mode)) {
                       log_error("Device %s is not a block device.", dev_name);
                       return 0;
               }
-
+#else
+               if (S_ISBLK(info.st_mode)) {
+                       log_error("Device %s is a block device. Use raw devices on NetBSD.", dev_name);
+                       return 0;
+               }
+#endif
               /* FIXME Check correct macro use */
               if (!(dev_node = _add_dev(node->dtree, node, MAJOR(info.st_rdev), MINOR(info.st_rdev))))
                       return_0;
Index: ./lvm2tools/dist/libdm/ioctl/libdm-nbsd-iface.c
===================================================================
RCS file: ./lvm2tools/dist/libdm/ioctl/libdm-nbsd-iface.c
diff -N ./lvm2tools/dist/libdm/ioctl/libdm-nbsd-iface.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/dist/libdm/ioctl/libdm-nbsd-iface.c     19 Dec 2008 00:00:23 -0000
@@ -0,0 +1,1153 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2008 Adam Hamsik. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "dmlib.h"
+#include "libdm-targets.h"
+#include "libdm-common.h"
+
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+
+#include <fcntl.h>
+#include <dirent.h>
+#include <limits.h>
+
+#include <netbsd-dm.h>
+
+#include <dm-ioctl.h>
+
+/*
+ * Ensure build compatibility.
+ * The hard-coded versions here are the highest present
+ * in the _cmd_data arrays.
+ */
+
+#if !((DM_VERSION_MAJOR == 1 && DM_VERSION_MINOR >= 0) || \
+      (DM_VERSION_MAJOR == 4 && DM_VERSION_MINOR >= 0))
+#error The version of dm-ioctl.h included is incompatible.
+#endif
+
+/* dm major version no for running kernel */
+static unsigned _dm_version_minor = 0;
+static unsigned _dm_version_patchlevel = 0;
+
+static int _control_fd = -1;
+static int _version_checked = 0;
+static int _version_ok = 1;
+static unsigned _ioctl_buffer_double_factor = 0;
+
+/* *INDENT-OFF* */
+
+/*
+ * XXX Remove this structure and write another own one
+ * I don't understand why ioctl calls has different
+ * names then dm task type
+ */
+static struct cmd_data _cmd_data_v4[] = {
+       {"create",      DM_DEV_CREATE,          {4, 0, 0}},
+       {"reload",      DM_TABLE_LOAD,          {4, 0, 0}}, /* DM_DEVICE_RELOAD */
+       {"remove",      DM_DEV_REMOVE,          {4, 0, 0}},
+       {"remove_all",  DM_REMOVE_ALL,          {4, 0, 0}},
+       {"suspend",     DM_DEV_SUSPEND,         {4, 0, 0}},
+       {"resume",      DM_DEV_SUSPEND,         {4, 0, 0}},
+       {"info",        DM_DEV_STATUS,          {4, 0, 0}},
+       {"deps",        DM_TABLE_DEPS,          {4, 0, 0}}, /* DM_DEVICE_DEPS */
+       {"rename",      DM_DEV_RENAME,          {4, 0, 0}},
+       {"version",     DM_VERSION,             {4, 0, 0}},
+       {"status",      DM_TABLE_STATUS,        {4, 0, 0}},
+       {"table",       DM_TABLE_STATUS,        {4, 0, 0}}, /* DM_DEVICE_TABLE */
+       {"waitevent",   DM_DEV_WAIT,            {4, 0, 0}},
+       {"names",       DM_LIST_DEVICES,        {4, 0, 0}},
+       {"clear",       DM_TABLE_CLEAR,         {4, 0, 0}},
+       {"mknodes",     DM_DEV_STATUS,          {4, 0, 0}},
+#ifdef DM_LIST_VERSIONS
+       {"targets",     DM_LIST_VERSIONS,       {4, 1, 0}},
+#endif
+#ifdef DM_TARGET_MSG
+       {"message",     DM_TARGET_MSG,          {4, 2, 0}},
+#endif
+#ifdef DM_DEV_SET_GEOMETRY
+       {"setgeometry", DM_DEV_SET_GEOMETRY,    {4, 6, 0}},
+#endif
+};
+/* *INDENT-ON* */
+
+/*
+ * In NetBSD we use sysctl to get kernel drivers info. control device
+ * has predefined minor number 0 and major number = char major number
+ * of dm driver. First slot is therefore ocupied with control device
+ * and minor device starts from 1;
+ */
+
+static int _control_device_number(uint32_t *major, uint32_t *minor)
+{
+
+       nbsd_get_dm_major(major, DM_CHAR_MAJOR);
+
+       *minor = 0;
+
+       return 1;
+}
+
+/*
+ * Returns 1 if exists; 0 if it doesn't; -1 if it's wrong
+ */
+static int _control_exists(const char *control, uint32_t major, uint32_t minor)
+{
+       struct stat buf;
+
+       if (stat(control, &buf) < 0) {
+               if (errno != ENOENT)
+                       log_sys_error("stat", control);
+               return 0;
+       }
+
+       if (!S_ISCHR(buf.st_mode)) {
+               log_verbose("%s: Wrong inode type", control);
+               if (!unlink(control))
+                       return 0;
+               log_sys_error("unlink", control);
+               return -1;
+       }
+
+       if (major && buf.st_rdev != MKDEV(major, minor)) {
+               log_verbose("%s: Wrong device number: (%u, %u) instead of "
+                           "(%u, %u)", control,
+                           MAJOR(buf.st_mode), MINOR(buf.st_mode),
+                           major, minor);
+               if (!unlink(control))
+                       return 0;
+               log_sys_error("unlink", control);
+               return -1;
+       }
+
+       return 1;
+}
+
+static int _create_control(const char *control, uint32_t major, uint32_t minor)
+{
+       int ret;
+       mode_t old_umask;
+
+       if (!major)
+               return 0;
+
+       old_umask = umask(0022);
+       ret = dm_create_dir(dm_dir());
+       umask(old_umask);
+
+       if (!ret)
+               return 0;
+
+       log_verbose("Creating device %s (%u, %u)", control, major, minor);
+
+       if (mknod(control, S_IFCHR | S_IRUSR | S_IWUSR,
+                 MKDEV(major, minor)) < 0)  {
+               log_sys_error("mknod", control);
+               return 0;
+       }
+
+
+       return 1;
+}
+
+/* Check if major is device-mapper block device major number */
+int dm_is_dm_major(uint32_t major)
+{
+       uint32_t dm_major;
+
+       nbsd_get_dm_major(&dm_major, DM_BLOCK_MAJOR);
+
+       if (major == dm_major)
+               return 1;
+
+       return 0;
+}
+
+/* Open control device if doesn't exist create it. */
+static int _open_control(void)
+{
+       char control[PATH_MAX];
+       uint32_t major = 0, minor = 0;
+
+       if (_control_fd != -1)
+               return 1;
+
+       snprintf(control, sizeof(control), "%s/control", dm_dir());
+
+       if (!_control_device_number(&major, &minor))
+               log_error("Is device-mapper driver missing from kernel?");
+
+       if (!_control_exists(control, major, minor) &&
+           !_create_control(control, major, minor))
+               goto error;
+
+       if ((_control_fd = open(control, O_RDWR)) < 0) {
+               log_sys_error("open", control);
+               goto error;
+       }
+
+       return 1;
+
+error:
+       log_error("Failure to communicate with kernel device-mapper driver.");
+       return 0;
+}
+
+/*
+ * Destroy dm task structure there are some dynamically alocated values there.
+ * name, uuid, head, tail list.
+ */
+void dm_task_destroy(struct dm_task *dmt)
+{
+       struct target *t, *n;
+
+       for (t = dmt->head; t; t = n) {
+               n = t->next;
+               dm_free(t->params);
+               dm_free(t->type);
+               dm_free(t);
+       }
+
+       if (dmt->dev_name)
+               dm_free(dmt->dev_name);
+
+       if (dmt->newname)
+               dm_free(dmt->newname);
+
+       if (dmt->message)
+               dm_free(dmt->message);
+
+       if (dmt->dmi.v4)
+               dm_free(dmt->dmi.v4);
+
+       if (dmt->uuid)
+               dm_free(dmt->uuid);
+
+       dm_free(dmt);
+
+}
+
+/* Get kernel driver version from dm_ioctl structure. */
+int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size)
+{
+       unsigned *v;
+
+       if (!dmt->dmi.v4) {
+               version[0] = '\0';
+               return 0;
+       }
+
+       v = dmt->dmi.v4->version;
+       snprintf(version, size, "%u.%u.%u", v[0], v[1], v[2]);
+       _dm_version_minor = v[1];
+       _dm_version_patchlevel = v[2];
+
+       return 1;
+}
+
+/* Get kernel driver protocol version and comapre it with library version. */
+static int _check_version(char *version, size_t size)
+{
+       struct dm_task *task;
+       int r;
+
+       if (!(task = dm_task_create(DM_DEVICE_VERSION))) {
+               log_error("Failed to get device-mapper version");
+               version[0] = '\0';
+               return 0;
+       }
+
+       r = dm_task_run(task);
+       dm_task_get_driver_version(task, version, size);
+       dm_task_destroy(task);
+
+       return r;
+}
+
+/*
+ * Find out device-mapper's major version number the first time
+ * this is called and whether or not we support it.
+ */
+int dm_check_version(void)
+{
+       char dmversion[64];
+
+       if (_version_checked)
+               return _version_ok;
+
+       _version_checked = 1;
+
+       if (_check_version(dmversion, sizeof(dmversion)))
+               return 1;
+
+
+       return 0;
+}
+
+/* Get next target(table description) from list pointed by dmt->head. */
+void *dm_get_next_target(struct dm_task *dmt, void *next,
+                        uint64_t *start, uint64_t *length,
+                        char **target_type, char **params)
+{
+       struct target *t = (struct target *) next;
+
+       if (!t)
+               t = dmt->head;
+
+       if (!t)
+               return NULL;
+
+       *start = t->start;
+       *length = t->length;
+       *target_type = t->type;
+       *params = t->params;
+
+       return t->next;
+}
+
+/* Unmarshall the target info returned from a status call */
+static int _unmarshal_status(struct dm_task *dmt, struct dm_ioctl *dmi)
+{
+       char *outbuf = (char *) dmi + dmi->data_start;
+       char *outptr = outbuf;
+       uint32_t i;
+       struct dm_target_spec *spec;
+
+       for (i = 0; i < dmi->target_count; i++) {
+               spec = (struct dm_target_spec *) outptr;
+               if (!dm_task_add_target(dmt, spec->sector_start,
+                                       spec->length,
+                                       spec->target_type,
+                                       outptr + sizeof(*spec))) {
+                       return 0;
+               }
+
+               outptr = outbuf + spec->next;
+       }
+
+       return 1;
+}
+
+/*
+ * @dev_major is major number of char device
+ *
+ * I have to find it's block device number and lookup dev in
+ * device database to find device path.
+ *
+ */
+
+int dm_format_dev(char *buf, int bufsize, uint32_t dev_major,
+                 uint32_t dev_minor)
+{
+       int r;
+       uint32_t major, dm_major;
+       char *name;
+       mode_t mode;
+       dev_t dev;
+       size_t val_len,i;
+       struct kinfo_drivers *kd;
+
+       mode = 0;
+
+       nbsd_get_dm_major(&dm_major, DM_BLOCK_MAJOR);
+
+       log_error("format_dev %d--%d %d", dev_major, dev_minor, bufsize);
+
+       if (bufsize < 8)
+               return 0;
+
+       if (sysctlbyname("kern.drivers",NULL,&val_len,NULL,0) < 0) {
+               printf("sysctlbyname failed");
+               return 0;
+       }
+
+       if ((kd = malloc (val_len)) == NULL){
+               printf("malloc kd info error\n");
+               return 0;
+       }
+
+       if (sysctlbyname("kern.drivers", kd, &val_len, NULL, 0) < 0) {
+               printf("sysctlbyname failed kd");
+               return 0;
+       }
+
+       for (i = 0, val_len /= sizeof(*kd); i < val_len; i++){
+               if (kd[i].d_cmajor == dev_major) {
+                       major = kd[i].d_bmajor;
+                       break;
+               }
+       }
+
+       dev = MKDEV(major,dev_minor);
+
+       mode |= S_IFBLK;
+
+       name = devname(dev,mode);
+
+       r = snprintf(buf, (size_t) bufsize, "/dev/%s",name);
+
+       free(kd);
+
+       if (r < 0 || r > bufsize - 1 || name == NULL)
+               return 0;
+
+       return 1;
+}
+
+/* Fill info from dm_ioctl structure. Look at DM_EXISTS_FLAG*/
+int dm_task_get_info(struct dm_task *dmt, struct dm_info *info)
+{
+       if (!dmt->dmi.v4)
+               return 0;
+
+       memset(info, 0, sizeof(*info));
+
+       info->exists = dmt->dmi.v4->flags & DM_EXISTS_FLAG ? 1 : 0;
+       if (!info->exists)
+               return 1;
+
+       info->suspended = dmt->dmi.v4->flags & DM_SUSPEND_FLAG ? 1 : 0;
+       info->read_only = dmt->dmi.v4->flags & DM_READONLY_FLAG ? 1 : 0;
+       info->live_table = dmt->dmi.v4->flags & DM_ACTIVE_PRESENT_FLAG ? 1 : 0;
+       info->inactive_table = dmt->dmi.v4->flags & DM_INACTIVE_PRESENT_FLAG ?
+           1 : 0;
+       info->target_count = dmt->dmi.v4->target_count;
+       info->open_count = dmt->dmi.v4->open_count;
+       info->event_nr = dmt->dmi.v4->event_nr;
+
+       nbsd_get_dm_major(&info->major, DM_BLOCK_MAJOR); /* get netbsd dm device major number */
+       info->minor = MINOR(dmt->dmi.v4->dev);
+
+       return 1;
+}
+
+/* Unsupported on NetBSD */
+uint32_t dm_task_get_read_ahead(const struct dm_task *dmt, uint32_t *read_ahead)
+{
+       *read_ahead = DM_READ_AHEAD_NONE;
+       return 1;
+}
+
+const char *dm_task_get_name(const struct dm_task *dmt)
+{
+
+       return (dmt->dmi.v4->name);
+}
+
+const char *dm_task_get_uuid(const struct dm_task *dmt)
+{
+
+       return (dmt->dmi.v4->uuid);
+}
+
+struct dm_deps *dm_task_get_deps(struct dm_task *dmt)
+{
+       return (struct dm_deps *) (((void *) dmt->dmi.v4) +
+                                  dmt->dmi.v4->data_start);
+}
+
+struct dm_names *dm_task_get_names(struct dm_task *dmt)
+{
+       return (struct dm_names *) (((void *) dmt->dmi.v4) +
+                                   dmt->dmi.v4->data_start);
+}
+
+struct dm_versions *dm_task_get_versions(struct dm_task *dmt)
+{
+       return (struct dm_versions *) (((void *) dmt->dmi.v4) +
+                                      dmt->dmi.v4->data_start);
+}
+
+int dm_task_set_ro(struct dm_task *dmt)
+{
+       dmt->read_only = 1;
+       return 1;
+}
+
+/* Unsupported on NetBSD */
+int dm_task_set_read_ahead(struct dm_task *dmt, uint32_t read_ahead,
+                          uint32_t read_ahead_flags)
+{
+       return 1;
+}
+
+int dm_task_suppress_identical_reload(struct dm_task *dmt)
+{
+       dmt->suppress_identical_reload = 1;
+       return 1;
+}
+
+int dm_task_set_newname(struct dm_task *dmt, const char *newname)
+{
+       if (!(dmt->newname = dm_strdup(newname))) {
+               log_error("dm_task_set_newname: strdup(%s) failed", newname);
+               return 0;
+       }
+
+       return 1;
+}
+
+int dm_task_set_message(struct dm_task *dmt, const char *message)
+{
+       if (!(dmt->message = dm_strdup(message))) {
+               log_error("dm_task_set_message: strdup(%s) failed", message);
+               return 0;
+       }
+
+       return 1;
+}
+
+int dm_task_set_sector(struct dm_task *dmt, uint64_t sector)
+{
+       dmt->sector = sector;
+
+       return 1;
+}
+
+/* Unsupported in NetBSD */
+int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders,
+    const char *heads, const char *sectors, const char *start)
+{
+       return 0;
+}
+
+int dm_task_no_flush(struct dm_task *dmt)
+{
+       dmt->no_flush = 1;
+
+       return 1;
+}
+
+int dm_task_no_open_count(struct dm_task *dmt)
+{
+       dmt->no_open_count = 1;
+
+       return 1;
+}
+
+int dm_task_skip_lockfs(struct dm_task *dmt)
+{
+       dmt->skip_lockfs = 1;
+
+       return 1;
+}
+
+int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr)
+{
+       dmt->event_nr = event_nr;
+
+       return 1;
+}
+
+/* Allocate one target(table description) entry. */
+struct target *create_target(uint64_t start, uint64_t len, const char *type,
+                            const char *params)
+{
+       struct target *t = dm_malloc(sizeof(*t));
+
+       if (!t) {
+               log_error("create_target: malloc(%" PRIsize_t ") failed",
+                         sizeof(*t));
+               return NULL;
+       }
+
+       memset(t, 0, sizeof(*t));
+
+       if (!(t->params = dm_strdup(params))) {
+               log_error("create_target: strdup(params) failed");
+               goto bad;
+       }
+
+       if (!(t->type = dm_strdup(type))) {
+               log_error("create_target: strdup(type) failed");
+               goto bad;
+       }
+
+       t->start = start;
+       t->length = len;
+       return t;
+
+      bad:
+       dm_free(t->params);
+       dm_free(t->type);
+       dm_free(t);
+       return NULL;
+}
+
+/* Parse given dm task structure to proplib dictionary.  */
+static int _flatten(struct dm_task *dmt, prop_dictionary_t dm_dict)
+{
+       prop_array_t cmd_array;
+       prop_dictionary_t target_spec;
+
+       struct target *t;
+
+       size_t len;
+       char type[DM_MAX_TYPE_NAME];
+
+       uint32_t major, flags;
+       int count = 0;
+       const int (*version)[3];
+
+       flags = 0;
+       version = &_cmd_data_v4[dmt->type].version;
+
+       cmd_array = prop_array_create();
+
+       for (t = dmt->head; t; t = t->next) {
+               target_spec = prop_dictionary_create();
+
+               prop_dictionary_set_uint64(target_spec,DM_TABLE_START,t->start);
+               prop_dictionary_set_uint64(target_spec,DM_TABLE_LENGTH,t->length);
+
+               strlcpy(type,t->type,DM_MAX_TYPE_NAME);
+
+               prop_dictionary_set_cstring(target_spec,DM_TABLE_TYPE,type);
+               prop_dictionary_set_cstring(target_spec,DM_TABLE_PARAMS,t->params);
+
+               prop_array_set(cmd_array,count,target_spec);
+
+               prop_object_release(target_spec);
+
+               count++;
+       }
+
+
+       if (count && (dmt->sector || dmt->message)) {
+               log_error("targets and message are incompatible");
+               return -1;
+       }
+
+       if (count && dmt->newname) {
+               log_error("targets and newname are incompatible");
+               return -1;
+       }
+
+       if (count && dmt->geometry) {
+               log_error("targets and geometry are incompatible");
+               return -1;
+       }
+
+       if (dmt->newname && (dmt->sector || dmt->message)) {
+               log_error("message and newname are incompatible");
+               return -1;
+       }
+
+       if (dmt->newname && dmt->geometry) {
+               log_error("geometry and newname are incompatible");
+               return -1;
+       }
+
+       if (dmt->geometry && (dmt->sector || dmt->message)) {
+               log_error("geometry and message are incompatible");
+               return -1;
+       }
+
+       if (dmt->sector && !dmt->message) {
+               log_error("message is required with sector");
+               return -1;
+       }
+
+       if (dmt->newname)
+               len += strlen(dmt->newname) + 1;
+
+       if (dmt->message)
+               len += sizeof(struct dm_target_msg) + strlen(dmt->message) + 1;
+
+       if (dmt->geometry)
+               len += strlen(dmt->geometry) + 1;
+
+       nbsd_dmi_add_version((*version), dm_dict);
+
+       nbsd_get_dm_major(&major, DM_BLOCK_MAJOR);
+       /*
+        * Only devices with major which is equal to netbsd dm major
+        * dm devices in NetBSD can't have more majors then one assigned to dm.
+        */
+       if (dmt->major != major && dmt->major != -1)
+               return -1;
+
+       if (dmt->minor >= 0) {
+               flags |= DM_PERSISTENT_DEV_FLAG;
+
+               prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmt->minor);
+       }
+
+       /* Set values to dictionary. */
+       if (dmt->dev_name)
+               prop_dictionary_set_cstring(dm_dict, DM_IOCTL_NAME, dmt->dev_name);
+
+       if (dmt->uuid)
+               prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmt->uuid);
+
+       if (dmt->type == DM_DEVICE_SUSPEND)
+               flags |= DM_SUSPEND_FLAG;
+       if (dmt->no_flush)
+               flags |= DM_NOFLUSH_FLAG;
+       if (dmt->read_only)
+               flags |= DM_READONLY_FLAG;
+       if (dmt->skip_lockfs)
+               flags |= DM_SKIP_LOCKFS_FLAG;
+
+       prop_dictionary_set_uint32(dm_dict, DM_IOCTL_FLAGS, flags);
+
+       prop_dictionary_set_uint32(dm_dict, DM_IOCTL_EVENT, dmt->event_nr);
+
+       if (dmt->newname)
+               prop_array_set_cstring(cmd_array, 0, dmt->newname);
+
+       /* Add array for all COMMAND specific data. */
+       prop_dictionary_set(dm_dict, DM_IOCTL_CMD_DATA, cmd_array);
+       prop_object_release(cmd_array);
+
+       return 0;
+}
+
+static int _process_mapper_dir(struct dm_task *dmt)
+{
+       struct dirent *dirent;
+       DIR *d;
+       const char *dir;
+       int r = 1;
+
+       dir = dm_dir();
+       if (!(d = opendir(dir))) {
+               log_sys_error("opendir", dir);
+               return 0;
+       }
+
+       while ((dirent = readdir(d))) {
+               if (!strcmp(dirent->d_name, ".") ||
+                   !strcmp(dirent->d_name, "..") ||
+                   !strcmp(dirent->d_name, "control"))
+                       continue;
+               dm_task_set_name(dmt, dirent->d_name);
+               dm_task_run(dmt);
+       }
+
+       if (closedir(d))
+               log_sys_error("closedir", dir);
+
+       return r;
+}
+
+/* Get list of all devices. */
+static int _process_all_v4(struct dm_task *dmt)
+{
+       struct dm_task *task;
+       struct dm_names *names;
+       unsigned next = 0;
+       int r = 1;
+
+       if (!(task = dm_task_create(DM_DEVICE_LIST)))
+               return 0;
+
+       if (!dm_task_run(task)) {
+               r = 0;
+               goto out;
+       }
+
+       if (!(names = dm_task_get_names(task))) {
+               r = 0;
+               goto out;
+       }
+
+       if (!names->dev)
+               goto out;
+
+       do {
+               names = (void *) names + next;
+               if (!dm_task_set_name(dmt, names->name)) {
+                       r = 0;
+                       goto out;
+               }
+               if (!dm_task_run(dmt))
+                       r = 0;
+               next = names->next;
+       } while (next);
+
+      out:
+       dm_task_destroy(task);
+       return r;
+}
+
+static int _mknodes_v4(struct dm_task *dmt)
+{
+       (void) _process_mapper_dir(dmt);
+
+       return _process_all_v4(dmt);
+}
+
+/* Create new device and load table to it. */
+static int _create_and_load_v4(struct dm_task *dmt)
+{
+       struct dm_task *task;
+       int r;
+
+       printf("create and load called \n");
+
+       /* Use new task struct to create the device */
+       if (!(task = dm_task_create(DM_DEVICE_CREATE))) {
+               log_error("Failed to create device-mapper task struct");
+               return 0;
+       }
+
+       /* Copy across relevant fields */
+       if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) {
+               dm_task_destroy(task);
+               return 0;
+       }
+
+       if (dmt->uuid && !dm_task_set_uuid(task, dmt->uuid)) {
+               dm_task_destroy(task);
+               return 0;
+       }
+
+       task->major = dmt->major;
+       task->minor = dmt->minor;
+       task->uid = dmt->uid;
+       task->gid = dmt->gid;
+       task->mode = dmt->mode;
+
+       r = dm_task_run(task);
+       dm_task_destroy(task);
+       if (!r)
+               return r;
+
+       /* Next load the table */
+       if (!(task = dm_task_create(DM_DEVICE_RELOAD))) {
+               log_error("Failed to create device-mapper task struct");
+               return 0;
+       }
+
+       /* Copy across relevant fields */
+       if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) {
+               dm_task_destroy(task);
+               return 0;
+       }
+
+       task->read_only = dmt->read_only;
+       task->head = dmt->head;
+       task->tail = dmt->tail;
+
+       r = dm_task_run(task);
+
+       task->head = NULL;
+       task->tail = NULL;
+       dm_task_destroy(task);
+       if (!r)
+               goto revert;
+
+       /* Use the original structure last so the info will be correct */
+       dmt->type = DM_DEVICE_RESUME;
+       dm_free(dmt->uuid);
+       dmt->uuid = NULL;
+
+       r = dm_task_run(dmt);
+
+       if (r)
+               return r;
+
+      revert:
+       dmt->type = DM_DEVICE_REMOVE;
+       dm_free(dmt->uuid);
+       dmt->uuid = NULL;
+
+       if (!dm_task_run(dmt))
+               log_error("Failed to revert device creation.");
+
+       return r;
+}
+
+uint64_t dm_task_get_existing_table_size(struct dm_task *dmt)
+{
+       return dmt->existing_table_size;
+}
+
+static int _reload_with_suppression_v4(struct dm_task *dmt)
+{
+       struct dm_task *task;
+       struct target *t1, *t2;
+       int r;
+
+       /* New task to get existing table information */
+       if (!(task = dm_task_create(DM_DEVICE_TABLE))) {
+               log_error("Failed to create device-mapper task struct");
+               return 0;
+       }
+
+       /* Copy across relevant fields */
+       if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) {
+               dm_task_destroy(task);
+               return 0;
+       }
+
+       if (dmt->uuid && !dm_task_set_uuid(task, dmt->uuid)) {
+               dm_task_destroy(task);
+               return 0;
+       }
+
+       task->major = dmt->major;
+       task->minor = dmt->minor;
+
+       r = dm_task_run(task);
+
+       if (!r) {
+               dm_task_destroy(task);
+               return r;
+       }
+
+       /* Store existing table size */
+       t2 = task->head;
+       while (t2 && t2->next)
+               t2 = t2->next;
+       dmt->existing_table_size = t2 ? t2->start + t2->length : 0;
+
+       if ((task->dmi.v4->flags & DM_READONLY_FLAG) ? 1 : 0 != dmt->read_only)
+               goto no_match;
+
+       t1 = dmt->head;
+       t2 = task->head;
+
+       while (t1 && t2) {
+               while (t2->params[strlen(t2->params) - 1] == ' ')
+                       t2->params[strlen(t2->params) - 1] = '\0';
+               if ((t1->start != t2->start) ||
+                   (t1->length != t2->length) ||
+                   (strcmp(t1->type, t2->type)) ||
+                   (strcmp(t1->params, t2->params)))
+                       goto no_match;
+               t1 = t1->next;
+               t2 = t2->next;
+       }
+
+       if (!t1 && !t2) {
+               dmt->dmi.v4 = task->dmi.v4;
+               task->dmi.v4 = NULL;
+               dm_task_destroy(task);
+               return 1;
+       }
+
+no_match:
+       dm_task_destroy(task);
+
+       /* Now do the original reload */
+       dmt->suppress_identical_reload = 0;
+       r = dm_task_run(dmt);
+
+       return r;
+}
+
+/*
+ * This function is heart of NetBSD libdevmapper-> device-mapper kernel protocol
+ * It creates proplib_dictionary from dm task structure and sends it to NetBSD
+ * kernel driver. After succesfull ioctl it create dmi structure from returned
+ * proplib dictionary. This way I keep number of changes in NetBSD version of
+ * libdevmapper as small as posible.
+ */
+static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command)
+{
+       struct dm_ioctl *dmi;
+       prop_dictionary_t dm_dict_in, dm_dict_out;
+
+       uint32_t flags;
+
+       dm_dict_in = NULL;
+
+       dm_dict_in = prop_dictionary_create(); /* Dictionary send to kernel */
+       dm_dict_out = prop_dictionary_create(); /* Dictionary received from kernel */
+
+       /* Set command name to dictionary */
+       prop_dictionary_set_cstring(dm_dict_in, DM_IOCTL_COMMAND,
+           _cmd_data_v4[dmt->type].name);
+
+       /* Parse dmi from libdevmapper to dictionary */
+       if (_flatten(dmt, dm_dict_in) < 0)
+               goto bad;
+
+       prop_dictionary_get_uint32(dm_dict_in, DM_IOCTL_FLAGS, &flags);
+
+       if (dmt->type == DM_DEVICE_TABLE)
+               flags |= DM_STATUS_TABLE_FLAG;
+
+       if (dmt->no_open_count)
+               flags |= DM_SKIP_BDGET_FLAG;
+
+       flags |= DM_EXISTS_FLAG;
+
+       /* Set flags to dictionary. */
+       prop_dictionary_set_uint32(dm_dict_in,DM_IOCTL_FLAGS,flags);
+
+       prop_dictionary_externalize_to_file(dm_dict_in,"/tmp/test_in");
+
+       log_very_verbose("Ioctl type  %s --- flags %d",_cmd_data_v4[dmt->type].name,flags);
+       //printf("name %s, major %d minor %d\n uuid %s\n",
+        //dm_task_get_name(dmt), dmt->minor, dmt->major, dm_task_get_uuid(dmt));
+       /* Send dictionary to kernel and wait for reply. */
+       if (prop_dictionary_sendrecv_ioctl(dm_dict_in,_control_fd,
+               NETBSD_DM_IOCTL,&dm_dict_out) != 0) {
+
+               if (errno == ENOENT &&
+                   ((dmt->type == DM_DEVICE_INFO) ||
+                       (dmt->type == DM_DEVICE_MKNODES) ||
+                       (dmt->type == DM_DEVICE_STATUS))) {
+
+                       /*
+                        * Linux version doesn't fail when ENOENT is returned
+                        * for nonexisting device after info, deps, mknodes call.
+                        * It returns dmi sent to kernel with DM_EXISTS_FLAG = 0;
+                        */
+
+                       dmi = nbsd_dm_dict_to_dmi(dm_dict_in,_cmd_data_v4[dmt->type].cmd);
+
+                       dmi->flags &= ~DM_EXISTS_FLAG;
+
+                       prop_object_release(dm_dict_in);
+                       prop_object_release(dm_dict_out);
+
+                       goto out;
+               } else {
+                       log_error("ioctl %s call failed with errno %d\n",
+                                         _cmd_data_v4[dmt->type].name, errno);
+
+                       prop_object_release(dm_dict_in);
+                       prop_object_release(dm_dict_out);
+
+                       goto bad;
+               }
+       }
+
+       prop_dictionary_externalize_to_file(dm_dict_out,"/tmp/test_out");
+
+       /* Parse kernel dictionary to dmi structure and return it to libdevmapper. */
+       dmi = nbsd_dm_dict_to_dmi(dm_dict_out,_cmd_data_v4[dmt->type].cmd);
+
+       prop_object_release(dm_dict_in);
+       prop_object_release(dm_dict_out);
+out:
+       return dmi;
+bad:
+       return NULL;
+}
+
+/* Create new edvice nodes in mapper/ dir. */
+void dm_task_update_nodes(void)
+{
+       update_devs();
+}
+
+/* Run dm command which is descirbed in dm_task structure. */
+int dm_task_run(struct dm_task *dmt)
+{
+       struct dm_ioctl *dmi;
+       unsigned command;
+
+       if ((unsigned) dmt->type >=
+           (sizeof(_cmd_data_v4) / sizeof(*_cmd_data_v4))) {
+               log_error("Internal error: unknown device-mapper task %d",
+                         dmt->type);
+               return 0;
+       }
+
+       command = _cmd_data_v4[dmt->type].cmd;
+
+       /* Old-style creation had a table supplied */
+       if (dmt->type == DM_DEVICE_CREATE && dmt->head)
+               return _create_and_load_v4(dmt);
+
+       if (dmt->type == DM_DEVICE_MKNODES && !dmt->dev_name &&
+           !dmt->uuid && dmt->major <= 0)
+               return _mknodes_v4(dmt);
+
+       if ((dmt->type == DM_DEVICE_RELOAD) && dmt->suppress_identical_reload)
+               return _reload_with_suppression_v4(dmt);
+
+       if (!_open_control())
+               return 0;
+
+       if (!(dmi = _do_dm_ioctl(dmt, command)))
+               return 0;
+
+       switch (dmt->type) {
+       case DM_DEVICE_CREATE:
+               add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev),
+                            dmt->uid, dmt->gid, dmt->mode);
+               break;
+
+       case DM_DEVICE_REMOVE:
+               /* FIXME Kernel needs to fill in dmi->name */
+               if (dmt->dev_name)
+                       rm_dev_node(dmt->dev_name);
+               break;
+
+       case DM_DEVICE_RENAME:
+               /* FIXME Kernel needs to fill in dmi->name */
+               if (dmt->dev_name)
+                       rename_dev_node(dmt->dev_name, dmt->newname);
+               break;
+
+       case DM_DEVICE_RESUME:
+               /* FIXME Kernel needs to fill in dmi->name */
+               set_dev_node_read_ahead(dmt->dev_name, dmt->read_ahead,
+                                       dmt->read_ahead_flags);
+               break;
+
+       case DM_DEVICE_MKNODES:
+               if (dmi->flags & DM_EXISTS_FLAG)
+                       add_dev_node(dmi->name, MAJOR(dmi->dev),
+                                    MINOR(dmi->dev),
+                                    dmt->uid, dmt->gid, dmt->mode);
+               else if (dmt->dev_name)
+                       rm_dev_node(dmt->dev_name);
+               break;
+
+       case DM_DEVICE_STATUS:
+       case DM_DEVICE_TABLE:
+       case DM_DEVICE_WAITEVENT:
+               if (!_unmarshal_status(dmt, dmi))
+                       goto bad;
+               break;
+       }
+
+       /* Was structure reused? */
+       if (dmt->dmi.v4)
+               dm_free(dmt->dmi.v4);
+
+       dmt->dmi.v4 = dmi;
+       return 1;
+
+      bad:
+       dm_free(dmi);
+       return 0;
+}
+
+void dm_lib_release(void)
+{
+       if (_control_fd != -1) {
+               close(_control_fd);
+               _control_fd = -1;
+       }
+       update_devs();
+}
+
+void dm_lib_exit(void)
+{
+       dm_lib_release();
+       dm_dump_memory();
+       _version_ok = 1;
+       _version_checked = 0;
+}
Index: ./lvm2tools/dist/libdm/ioctl/libdm_netbsd.c
===================================================================
RCS file: ./lvm2tools/dist/libdm/ioctl/libdm_netbsd.c
diff -N ./lvm2tools/dist/libdm/ioctl/libdm_netbsd.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/dist/libdm/ioctl/libdm_netbsd.c 19 Dec 2008 00:00:23 -0000
@@ -0,0 +1,502 @@
+/*
+ * Copyright (c) 1996, 1997, 1998, 1999, 2002 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/ioctl.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include <err.h>
+#include <errno.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <netbsd-dm.h>
+
+#include <dm-ioctl.h>
+
+#include "lib.h"
+
+#define DMI_SIZE 16 * 1024
+
+static int dm_list_versions(prop_dictionary_t, struct dm_ioctl *);
+static int dm_list_devices(prop_dictionary_t, struct dm_ioctl *);
+static int dm_dev_deps(prop_dictionary_t, struct dm_ioctl *);
+static int dm_table_status(prop_dictionary_t, struct dm_ioctl *);
+
+int
+nbsd_get_dm_major(uint32_t *major,  int type)
+{
+       size_t val_len,i;
+       struct kinfo_drivers *kd;
+
+       if (sysctlbyname("kern.drivers",NULL,&val_len,NULL,0) < 0) {
+               printf("sysctlbyname failed");
+               return 0;
+       }
+
+       if ((kd = malloc (val_len)) == NULL){
+               printf("malloc kd info error\n");
+               return 0;
+       }
+
+       if (sysctlbyname("kern.drivers", kd, &val_len, NULL, 0) < 0) {
+               printf("sysctlbyname failed kd");
+               return 0;
+       }
+
+       for (i = 0, val_len /= sizeof(*kd); i < val_len; i++) {
+
+               if (strncmp(kd[i].d_name,DM_NAME,strlen(kd[i].d_name)) == 0){
+
+                       if (type == DM_CHAR_MAJOR)
+                               /* Set major to dm-driver char major number. */
+                               *major = kd[i].d_cmajor;
+                       else
+                               if (type == DM_BLOCK_MAJOR)
+                                       *major = kd[i].d_bmajor;
+
+                       free(kd);
+
+                       return 1;
+               }
+       }
+
+       free(kd);
+
+       return 0;
+}
+
+int
+nbsd_dmi_add_version(const int *version, prop_dictionary_t dm_dict)
+{
+       prop_array_t ver;
+       size_t i;
+
+       if ((ver = prop_array_create()) == NULL)
+               return -1;
+
+               for (i=0;i<3;i++)
+               prop_array_set_uint32(ver,i,version[i]);
+
+       if ((prop_dictionary_set(dm_dict,"version",ver)) == false)
+               return -1;
+
+       prop_object_release(ver);
+
+       return 0;
+}
+
+struct dm_ioctl*
+nbsd_dm_dict_to_dmi(prop_dictionary_t dm_dict,const int cmd)
+{
+       struct dm_ioctl *dmi;
+       prop_array_t ver;
+
+       size_t i;
+       int r;
+       char *name, *uuid;
+       uint32_t major,minor;
+
+       name = NULL;
+       uuid = NULL;
+       minor = 0;
+
+       nbsd_get_dm_major(&major, DM_BLOCK_MAJOR);
+
+       if (!(dmi = dm_malloc(DMI_SIZE)))
+               return NULL;
+
+       memset(dmi,0,DMI_SIZE);
+
+       prop_dictionary_get_int32(dm_dict, DM_IOCTL_OPEN, &dmi->open_count);
+       prop_dictionary_get_uint32(dm_dict, DM_IOCTL_EVENT, &dmi->event_nr);
+       prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &dmi->flags);
+       prop_dictionary_get_uint32(dm_dict, DM_IOCTL_TARGET_COUNT,
+               &dmi->target_count);
+
+       if (prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor))
+               dmi->dev = MKDEV(major, minor);
+       else
+               dmi->dev = 0;
+
+       /* Copy name and uuid to dm_ioctl. */
+       if (prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME,
+               (const char **)&name)){
+               strlcpy(dmi->name, name, DM_NAME_LEN);
+       } else
+               dmi->name[0] = '\0';
+
+       if (prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID,
+               (const char **)&uuid)){
+               strlcpy(dmi->uuid, uuid, DM_UUID_LEN);
+       }  else
+               dmi->uuid[0] = '\0';
+
+       /* dmi parsing values, size of dmi block and offset to data. */
+       dmi->data_size  = DMI_SIZE;
+       dmi->data_start = sizeof(struct dm_ioctl);
+
+       /* Get kernel version from dm_dict. */
+       ver = prop_dictionary_get(dm_dict,DM_IOCTL_VERSION);
+
+       for(i=0; i<3; i++)
+               prop_array_get_uint32(ver,i,&dmi->version[i]);
+
+       switch (cmd){
+
+       case DM_LIST_VERSIONS:
+               r = dm_list_versions(dm_dict,dmi);
+               if (r >= 0)
+                       dmi->target_count = r;
+               break;
+
+       case DM_LIST_DEVICES:
+               r = dm_list_devices(dm_dict,dmi);
+               if (r >= 0)
+                       dmi->target_count = r;
+               break;
+
+       case DM_TABLE_STATUS:
+               r = dm_table_status(dm_dict,dmi);
+               if (r >= 0)
+                       dmi->target_count = r;
+               break;
+
+       case DM_TABLE_DEPS:
+               r = dm_dev_deps(dm_dict,dmi);
+               if (r >= 0)
+                       dmi->target_count = r;
+               break;
+       }
+
+       return dmi;
+}
+
+/*
+ * Parse dm_dict when targets command was called and fill dm_ioctl buffer with it.
+ *
+ * Return number of targets or if failed <0 error.
+ */
+
+static int
+dm_list_versions(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
+{
+       struct dm_target_versions *dmtv,*odmtv;
+
+       prop_array_t targets,ver;
+       prop_dictionary_t target_dict;
+       prop_object_iterator_t iter;
+
+       char *name;
+       size_t j,i,slen,rec_size;
+
+       odmtv = NULL;
+       name = NULL;
+       j = 0;
+
+       dmtv = (struct dm_target_versions *)((uint8_t *)dmi + dmi->data_start);
+
+/*     printf("dmi: vers: %d.%d.%d data_size: %d data_start: %d name: %s t_count: %d\n",
+           dmi->version[0],dmi->version[1],dmi->version[2],dmi->data_size,dmi->data_start,
+           dmi->name,dmi->target_count);
+
+       printf("dmi: size: %d -- %p --- %p \n",sizeof(struct dm_ioctl),dmi,dmi+dmi->data_start);
+       printf("dmtv: size: %p --- %p\n",dmtv,(struct dm_target_versions *)(dmi+312));*/
+
+       /* get prop_array of target_version dictionaries */
+       if ((targets = prop_dictionary_get(dm_dict,DM_IOCTL_CMD_DATA))){
+
+               iter = prop_array_iterator(targets);
+               if (!iter)
+                       err(EXIT_FAILURE,"dm_list_versions %s",__func__);
+
+               while((target_dict = prop_object_iterator_next(iter)) != NULL){
+                       j++;
+
+                       prop_dictionary_get_cstring_nocopy(target_dict,
+                           DM_TARGETS_NAME,(const char **)&name);
+
+                       slen = strlen(name) + 1;
+                       rec_size = sizeof(struct dm_target_versions) + slen + 1;
+
+                       if (rec_size > dmi->data_size)
+                               return -ENOMEM;
+
+                       ver = prop_dictionary_get(target_dict,DM_TARGETS_VERSION);
+
+                       for (i=0; i<3; i++)
+                               prop_array_get_uint32(ver,i,&dmtv->version[i]);
+
+                       dmtv->next = rec_size;
+
+                       strlcpy(dmtv->name,name,slen);
+
+                       odmtv = dmtv;
+
+                       dmtv =(struct dm_target_versions *)((uint8_t *)dmtv + rec_size);
+               }
+
+               if (odmtv != NULL)
+                       odmtv->next = 0;
+       }
+
+       prop_object_iterator_release(iter);
+       return j;
+}
+
+/*
+ * List all available dm devices in system.
+ */
+static int
+dm_list_devices(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
+{
+       struct dm_name_list *dml,*odml;
+
+       prop_array_t targets;
+       prop_dictionary_t target_dict;
+       prop_object_iterator_t iter;
+
+       uint32_t minor;
+       uint32_t major;
+
+       char *name;
+       size_t j,slen,rec_size;
+
+       odml = NULL;
+       name = NULL;
+       minor = 0;
+       j = 0;
+
+       nbsd_get_dm_major(&major,DM_BLOCK_MAJOR);
+
+       dml = (struct dm_name_list *)((uint8_t *)dmi + dmi->data_start);
+
+       if ((targets = prop_dictionary_get(dm_dict,DM_IOCTL_CMD_DATA))){
+
+               iter = prop_array_iterator(targets);
+               if (!iter)
+                       err(EXIT_FAILURE,"dm_list_devices %s",__func__);
+
+               while((target_dict = prop_object_iterator_next(iter)) != NULL){
+
+                       prop_dictionary_get_cstring_nocopy(target_dict,
+                           DM_DEV_NAME,(const char **)&name);
+
+                       prop_dictionary_get_uint32(target_dict,DM_DEV_DEV,&minor);
+
+                       dml->dev = MKDEV(major,minor);
+
+                       slen = strlen(name) + 1;
+                       rec_size = sizeof(struct dm_name_list) + slen + 1;
+
+                       if (rec_size > dmi->data_size)
+                               return -ENOMEM;
+
+                       dml->next = rec_size;
+
+                       strlcpy(dml->name,name,slen);
+
+                       odml = dml;
+
+                       dml =(struct dm_name_list *)((uint8_t *)dml + rec_size);
+
+                       j++;
+               }
+
+               if (odml != NULL)
+                       odml->next = 0;
+       }
+       prop_object_iterator_release(iter);
+       return j;
+}
+
+/*
+ * Print status of each table, target arguments, start sector,
+ * size and target name.
+ */
+static int
+dm_table_status(prop_dictionary_t dm_dict,struct dm_ioctl *dmi)
+{
+       struct dm_target_spec *dmts, *odmts;
+
+       prop_array_t targets;
+       prop_dictionary_t target_dict;
+       prop_object_iterator_t iter;
+
+       char *type,*params,*params_start;
+
+       bool prm;
+       size_t j,plen,rec_size,next;
+
+       j = 0;
+       next = 0;
+       params = NULL;
+       odmts = NULL;
+       rec_size = 0;
+       plen = -1;
+       prm = false;
+
+       dmts = (struct dm_target_spec *)((uint8_t *)dmi + dmi->data_start);
+
+       if ((targets = prop_dictionary_get(dm_dict,DM_IOCTL_CMD_DATA))){
+
+               iter = prop_array_iterator(targets);
+               if (!iter)
+                       err(EXIT_FAILURE,"dm_table_status %s",__func__);
+
+               while((target_dict = prop_object_iterator_next(iter)) != NULL){
+
+                       prop_dictionary_get_cstring_nocopy(target_dict,
+                           DM_TABLE_TYPE,(const char **)&type);
+
+                       prm = prop_dictionary_get_cstring_nocopy(target_dict,
+                           DM_TABLE_PARAMS,(const char **)&params);
+
+                       prop_dictionary_get_uint64(target_dict,DM_TABLE_START,&dmts->sector_start);
+                       prop_dictionary_get_uint64(target_dict,DM_TABLE_LENGTH,&dmts->length);
+                       prop_dictionary_get_int32(target_dict,DM_TABLE_STAT,&dmts->status);
+
+                       if (prm)
+                               plen = strlen(params) + 1;
+
+                       rec_size = sizeof(struct dm_target_spec) + plen;
+
+                       /*
+                        * In linux when copying table status from kernel next is
+                        * number of bytes from the start of the first dm_target_spec
+                        * structure. I don't know why but, it has to be done this way.
+                        */
+                       next += rec_size;
+
+                       if (rec_size > dmi->data_size)
+                               return -ENOMEM;
+
+                       dmts->next = next;
+
+                       strlcpy(dmts->target_type, type, DM_MAX_TYPE_NAME);
+
+                       params_start = (char *)dmts + sizeof(struct dm_target_spec);
+
+                       if (prm)
+                               strlcpy(params_start, params, plen);
+                       else
+                               params_start = "\0";
+
+
+                       odmts = dmts;
+
+                       dmts = (struct dm_target_spec *)((uint8_t *)dmts + rec_size);
+
+                       j++;
+
+               }
+
+               if (odmts != NULL)
+                       odmts->next = 0;
+       }
+       prop_object_iterator_release(iter);
+
+       return j;
+}
+
+/*
+ * Print dm device dependiences, get minor/major number for
+ * devices. From kernel I will receive major:minor number of
+ * block device used with target. I have to translate it to
+ * raw device numbers and use them, because all other parts of lvm2tools
+ * uses raw devices internaly.
+ */
+static int
+dm_dev_deps(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
+{
+       struct dm_target_deps *dmtd;
+       struct kinfo_drivers *kd;
+
+       prop_array_t targets;
+       prop_object_iterator_t iter;
+
+       uint32_t major;
+
+       size_t val_len, i, j;
+
+       uint64_t dev_tmp;
+
+       dev_tmp = 0;
+       j = 0;
+       i = 0;
+
+       if (sysctlbyname("kern.drivers",NULL,&val_len,NULL,0) < 0) {
+               printf("sysctlbyname failed");
+               return 0;
+       }
+
+       if ((kd = malloc (val_len)) == NULL){
+               printf("malloc kd info error\n");
+               return 0;
+       }
+
+       if (sysctlbyname("kern.drivers", kd, &val_len, NULL, 0) < 0) {
+               printf("sysctlbyname failed kd");
+               return 0;
+       }
+
+       dmtd = (struct dm_target_deps *)((uint8_t *)dmi + dmi->data_start);
+
+       if ((targets = prop_dictionary_get(dm_dict, DM_IOCTL_CMD_DATA))){
+
+               iter = prop_array_iterator(targets);
+               if (!iter)
+                       err(EXIT_FAILURE,"dm_target_deps %s", __func__);
+
+               while((prop_object_iterator_next(iter)) != NULL){
+
+                       prop_array_get_uint64(targets, j, &dev_tmp);
+
+                       for (i = 0, val_len /= sizeof(*kd); i < val_len; i++){
+                               if (kd[i].d_bmajor == MAJOR(dev_tmp)) {
+                                       major = kd[i].d_cmajor;
+                                       break;
+                               }
+                       }
+
+                       dmtd->dev[j] = MKDEV(major,MINOR(dev_tmp));
+
+                       j++;
+               }
+       }
+
+       dmtd->count = j;
+
+       prop_object_iterator_release(iter);
+
+       return j;
+}
Index: ./lvm2tools/lib/Makefile
===================================================================
RCS file: ./lvm2tools/lib/Makefile
diff -N ./lvm2tools/lib/Makefile
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/lib/Makefile    19 Dec 2008 00:00:24 -0000
@@ -0,0 +1,5 @@
+#      $NetBSD$
+
+SUBDIR=        libdevmapper liblvm
+
+.include <bsd.subdir.mk>
Index: ./lvm2tools/lib/libdevmapper/Makefile
===================================================================
RCS file: ./lvm2tools/lib/libdevmapper/Makefile
diff -N ./lvm2tools/lib/libdevmapper/Makefile
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/lib/libdevmapper/Makefile       19 Dec 2008 00:00:24 -0000
@@ -0,0 +1,34 @@
+#      $NetBSD$
+
+USE_SHLIBDIR=  yes
+USE_FORT?=     no
+NOLINT=                #defined
+
+.include "../../lvm2tools.mk"
+
+LIB=           devmapper
+
+CFLAGS+= -fno-inline
+
+CPPFLAGS+=     -I${LIBDM_SRCDIR} -I${LIBDM_SRCDIR}/misc -I${LIBDM_SRCDIR}/mm \
+               -I${LIBDM_SRCDIR}/datastruct -I${LIBDM_SRCDIR}/ioctl \
+               -I${LVM2TOOLS_DISTDIR}/include -I. -D__NetBSD__
+
+
+CPPFLAGS+=     -D__LIB_DEVMAPPER__ -DDM_DEVICE_UID=0 \
+               -DDM_DEVICE_GID=0 -DDM_DEVICE_MODE=0600
+
+LDADD+=                -lprop
+
+SRCS+=         bitset.c hash.c list.c libdm-common.c libdm-file.c \
+               libdm-deptree.c libdm-string.c libdm-report.c \
+               dbg_malloc.c pool.c matcher.c parse_rx.c ttree.c \
+               libdm-nbsd-iface.c libdm_netbsd.c
+
+.PATH: ${LIBDM_SRCDIR}/
+.PATH: ${LIBDM_SRCDIR}/datastruct
+.PATH: ${LIBDM_SRCDIR}/mm
+.PATH: ${LIBDM_SRCDIR}/regex
+.PATH: ${LIBDM_SRCDIR}/ioctl
+
+.include <bsd.lib.mk>
Index: ./lvm2tools/lib/libdevmapper/netbsd-dm.h
===================================================================
RCS file: ./lvm2tools/lib/libdevmapper/netbsd-dm.h
diff -N ./lvm2tools/lib/libdevmapper/netbsd-dm.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/lib/libdevmapper/netbsd-dm.h    19 Dec 2008 00:00:24 -0000
@@ -0,0 +1,174 @@
+#ifndef __NETBSD_DM_H__
+#define __NETBSD_DM_H__
+
+#include <prop/proplib.h>
+
+#define DM_CMD_LEN 16
+
+#define DM_IOCTL 0xfd
+
+#define DM_IOCTL_CMD 0
+
+#define NETBSD_DM_IOCTL       _IOWR(DM_IOCTL, DM_IOCTL_CMD, struct plistref)
+
+
+/*
+ * DM-ioctl dictionary.
+ *
+ * This contains general information about dm device.
+ *
+ * <dict>
+ *     <key>command</key>
+ *     <string>...</string>
+ *
+ *     <key>event_nr</key>
+ *     <integer>...</integer>
+ *
+ *     <key>name</key>
+ *     <string>...</string>
+ *
+ *     <key>uuid</key>
+ *     <string>...</string>
+ *
+ *     <key>dev</key>
+ *     <integer></integer>
+ *
+ *     <key>flags</key>
+ *     <integer></integer>
+ *
+ *     <key>version</key>
+ *      <array>
+ *       <integer>...</integer>
+ *       <integer>...</integer>
+ *       <integer>...</integer>
+ *      </array>
+ *
+ *      <key>cmd_data</key>
+ *       <array>
+ *        <!-- See below for command
+ *             specific dictionaries -->
+ *       </array>
+ * </dict>
+ *
+ * Available commands from _cmd_data_v4.
+ *
+ * create, reload, remove, remove_all, suspend,
+ * resume, info, deps, rename, version, status,
+ * table, waitevent, names, clear, mknodes,
+ * targets, message, setgeometry
+ *
+ */
+
+/*
+ * DM_LIST_VERSIONS command dictionary entry.
+ * Lists all available targets with their version.
+ *
+ * <array>
+ *   <dict>
+ *    <key>name<key>
+ *    <string>...</string>
+ *
+ *    <key>version</key>
+ *      <array>
+ *       <integer>...</integer>
+ *       <integer>...</integer>
+ *       <integer>...</integer>
+ *      </array>
+ *   </dict>
+ * </array>
+ *
+ */
+
+#define DM_IOCTL_COMMAND      "command"
+#define DM_IOCTL_VERSION      "version"
+#define DM_IOCTL_OPEN         "open_count"
+#define DM_IOCTL_MINOR        "minor"
+#define DM_IOCTL_NAME         "name"
+#define DM_IOCTL_UUID         "uuid"
+#define DM_IOCTL_TARGET_COUNT "target_count"
+#define DM_IOCTL_EVENT        "event_nr"
+#define DM_IOCTL_FLAGS        "flags"
+#define DM_IOCTL_CMD_DATA     "cmd_data"
+
+#define DM_TARGETS_NAME       "name"
+#define DM_TARGETS_VERSION    "ver"
+
+#define DM_DEV_NEWNAME        "newname"
+#define DM_DEV_NAME           "name"
+#define DM_DEV_DEV            "dev"
+
+#define DM_TABLE_TYPE         "type"
+#define DM_TABLE_START        "start"
+#define DM_TABLE_STAT         "status"
+#define DM_TABLE_LENGTH       "length"
+#define DM_TABLE_PARAMS       "params"
+
+
+/* Status bits */
+#define DM_READONLY_FLAG       (1 << 0) /* In/Out */
+#define DM_SUSPEND_FLAG                (1 << 1) /* In/Out */
+#define DM_EXISTS_FLAG          (1 << 2) /* In/Out */ /* XXX. This flag is undocumented. */
+#define DM_PERSISTENT_DEV_FLAG (1 << 3) /* In */
+
+/*
+ * Flag passed into ioctl STATUS command to get table information
+ * rather than current status.
+ */
+#define DM_STATUS_TABLE_FLAG   (1 << 4) /* In */
+
+/*
+ * Flags that indicate whether a table is present in either of
+ * the two table slots that a device has.
+ */
+#define DM_ACTIVE_PRESENT_FLAG   (1 << 5) /* Out */
+#define DM_INACTIVE_PRESENT_FLAG (1 << 6) /* Out */
+
+/*
+ * Indicates that the buffer passed in wasn't big enough for the
+ * results.
+ */
+#define DM_BUFFER_FULL_FLAG    (1 << 8) /* Out */
+
+/*
+ * This flag is now ignored.
+ */
+#define DM_SKIP_BDGET_FLAG     (1 << 9) /* In */
+
+/*
+ * Set this to avoid attempting to freeze any filesystem when suspending.
+ */
+#define DM_SKIP_LOCKFS_FLAG    (1 << 10) /* In */
+
+/*
+ * Set this to suspend without flushing queued ios.
+ */
+#define DM_NOFLUSH_FLAG                (1 << 11) /* In */
+
+
+#ifdef __LIB_DEVMAPPER__
+
+#  define MAJOR(x) major((x))
+#  define MINOR(x) minor((x))
+#  define MKDEV(x,y) makedev((x),(y))
+
+/* Name of device-mapper driver in kernel */
+#define DM_NAME "dm"
+
+/* Types for nbsd_get_dm_major */
+#define DM_CHAR_MAJOR 1
+#define DM_BLOCK_MAJOR 2
+
+/* libdm_netbsd.c */
+
+int nbsd_get_dm_major(uint32_t *, int); /* Get dm device major numbers */
+
+int nbsd_dmi_add_cmd(const char *, prop_dictionary_t);
+int nbsd_dmi_add_version(const int [3], prop_dictionary_t);
+int nbsd_dm_add_uint(const char *, uint64_t, prop_dictionary_t);
+int nbsd_dm_add_str(const char *, char *, prop_dictionary_t );
+
+struct dm_ioctl* nbsd_dm_dict_to_dmi(prop_dictionary_t, const int);
+
+#endif /* __LIB_DEVMAPPER__ */
+
+#endif /* __NETBSD_DM_H__ */
Index: ./lvm2tools/lib/libdevmapper/shlib_version
===================================================================
RCS file: ./lvm2tools/lib/libdevmapper/shlib_version
diff -N ./lvm2tools/lib/libdevmapper/shlib_version
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/lib/libdevmapper/shlib_version  19 Dec 2008 00:00:24 -0000
@@ -0,0 +1,2 @@
+major=0
+minor=0
Index: ./lvm2tools/lib/liblvm/Makefile
===================================================================
RCS file: ./lvm2tools/lib/liblvm/Makefile
diff -N ./lvm2tools/lib/liblvm/Makefile
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/lib/liblvm/Makefile     19 Dec 2008 00:00:24 -0000
@@ -0,0 +1,63 @@
+#      $NetBSD$
+
+LIBISPRIVATE=  yes
+
+USE_FORT?=     no
+NOLINT=                #defined
+
+.include "../../lvm2tools.mk"
+
+LIB=           lvm
+
+CPPFLAGS+=     -I${LVM2TOOLS_DISTDIR}/lib -I${LVM2TOOLS_DISTDIR}/include \
+               -I.
+
+SRCS+=         activate.c lvmcache.c toolcontext.c config.c btree.c \
+               str_list.c dev-cache.c dev-io.c dev-md.c device.c \
+               display.c errseg.c filter-composite.c \
+               filter-persistent.c \
+               filter-regex.c filter-sysfs.c filter-md.c archive.c \
+               archiver.c export.c flags.c format-text.c import.c \
+               import_vsn1.c tags.c text_label.c freeseg.c label.c \
+               file_locking.c locking.c no_locking.c log.c lv_manip.c \
+               merge.c metadata.c mirror.c pv_manip.c pv_map.c segtype.c \
+               snapshot_manip.c crc.c lvm-exec.c lvm-file.c lvm-string.c \
+               lvm-wrappers.c timestamp.c util.c memlock.c report.c \
+               striped.c uuid.c zero.c disk-rep.c format1.c import-export.c \
+               import-extents.c layout.c lvm1-label.c vg_number.c \
+               disk_rep.c format_pool.c import_export.c pool_label.c \
+               filter_netbsd.c snapshot.c mirrored.c dev_manager.c fs.c dev.c \
+               lvm-globals.c
+
+LDADD+=                -lprop
+
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/activate
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/cache
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/commands
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/config
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/datastruct
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/device
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/display
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/error
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/filters
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/format1
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/format_pool
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/format_text
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/freeseg
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/label
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/locking
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/log
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/metadata
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/mirror
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/misc
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/mm
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/report
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/snapshot
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/striped
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/uuid
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/zero
+.PATH: ${LVM2TOOLS_DISTDIR}/lib/netbsd
+
+.include <bsd.lib.mk>
+.include <bsd.subdir.mk>
Index: ./lvm2tools/sbin/Makefile
===================================================================
RCS file: ./lvm2tools/sbin/Makefile
diff -N ./lvm2tools/sbin/Makefile
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/sbin/Makefile   19 Dec 2008 00:00:24 -0000
@@ -0,0 +1,5 @@
+#      $NetBSD$
+
+SUBDIR= dmsetup        lvm
+
+.include <bsd.subdir.mk>
Index: ./lvm2tools/sbin/dmsetup/Makefile
===================================================================
RCS file: ./lvm2tools/sbin/dmsetup/Makefile
diff -N ./lvm2tools/sbin/dmsetup/Makefile
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/sbin/dmsetup/Makefile   19 Dec 2008 00:00:24 -0000
@@ -0,0 +1,31 @@
+#      $NetBSD$
+
+USE_FORT?=     no
+NOLINT=                #defined
+
+.include "../../lvm2tools.mk"
+
+.PATH:  ${LVM2TOOLS_DISTDIR}/man
+
+PROG=          dmsetup
+
+MAN=           dmsetup.8
+MLINKS=                dmsetup.8 dmsetup.1
+
+BINDIR=                /sbin
+
+CPPFLAGS+=      -I${LIBDM_SRCDIR}/ -I${LIBDM_SRCDIR}/misc \
+               -I. -I${LIBDM_SRCDIR}/ioctl -I${LVM2TOOLS_DISTDIR}/include
+
+CPPFLAGS+=     -D__LIB_DEVMAPPER__ -DDM_DEVICE_UID=0 \
+               -DDM_DEVICE_GID=0 -DDM_DEVICE_MODE=0600
+
+LIBDM_OBJDIR!= cd ${LVM2TOOLS_SRCDIR}/lib/libdevmapper && ${PRINTOBJDIR}
+LDADD+=                -L${LIBDM_OBJDIR} -ldevmapper
+DPADD+=                ${LIBDM_OBJDIR}/libdevmapper.a
+
+LDADD+=                -lprop
+
+.PATH: ${LVM2TOOLS_DISTDIR}/tools
+
+.include <bsd.prog.mk>
Index: ./lvm2tools/sbin/lvm/Makefile
===================================================================
RCS file: ./lvm2tools/sbin/lvm/Makefile
diff -N ./lvm2tools/sbin/lvm/Makefile
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ./lvm2tools/sbin/lvm/Makefile       19 Dec 2008 00:00:24 -0000
@@ -0,0 +1,102 @@
+
+
+USE_FORT?=     no
+NOLINT=                #defined
+
+.include "../../lvm2tools.mk"
+
+.PATH: ${LVM2TOOLS_DISTDIR}/man
+
+PROG=          lvm
+
+BINDIR=                /sbin
+
+SRCS=          dumpconfig.c formats.c lvchange.c lvconvert.c lvcreate.c \
+               lvdisplay.c lvextend.c lvmchange.c lvmcmdline.c \
+               lvmdiskscan.c lvreduce.c lvremove.c lvrename.c lvresize.c \
+               lvscan.c polldaemon.c pvchange.c pvck.c pvcreate.c \
+               pvdisplay.c pvmove.c pvremove.c pvresize.c pvscan.c \
+               reporter.c segtypes.c toollib.c vgcfgbackup.c \
+               vgcfgrestore.c vgchange.c vgck.c vgconvert.c vgcreate.c \
+               vgdisplay.c vgexport.c vgextend.c vgimport.c vgmerge.c \
+               vgmknodes.c vgreduce.c vgremove.c vgrename.c vgscan.c \
+               vgsplit.c lvm.c
+
+CFLAGS+=       -fno-inline
+
+CPPFLAGS+=     -I${LVM2TOOLS_DISTDIR}/lib -I${LVM2TOOLS_DISTDIR}/include \
+               -I. -I${LIBDM_INCLUDE} -I${LVM2TOOLS_DISTDIR}/tools -I${LVM2TOOLS_DISTDIR}/libdm
+
+CPPFLAGS+=     -DLVM_SHARED_PATH=\"$(BINDIR)/lvm\"
+
+
+MAN=           lvchange.8 lvconvert.8 lvcreate.8 lvdisplay.8 lvextend.8 \
+               lvm.8 lvm.conf.5 lvmchange.8 lvmdiskscan.8 lvmdump.8 \
+               lvreduce.8 lvremove.8 lvrename.8 lvresize.8 lvs.8 \
+               lvscan.8 pvchange.8 pvck.8 pvcreate.8 pvdisplay.8 \
+               pvmove.8 pvremove.8 pvresize.8 pvs.8 pvscan.8 \
+               vgcfgbackup.8 vgcfgrestore.8 vgchange.8 vgck.8 vgconvert.8 \
+               vgcreate.8 vgdisplay.8 vgexport.8 vgextend.8 vgimport.8 \
+               vgmerge.8 vgmknodes.8 vgreduce.8 vgremove.8 vgrename.8 \
+               vgs.8 vgscan.8 vgsplit.8
+
+
+MKLINKS+=      lvchange.8 lvchange.1 \
+                lvconvert.8 lvconvert.1 \
+                lvcreate.8 lvcreate.1 \
+                lvdisplay.8 lvdisplay.1 \
+                lvextend.8 lvextend.1 \
+                lvm.8 lvm.1 \
+                lvm.conf lvm.1 \
+                lvmchange.8 lvmchange.1 \
+                lvmdiskscan.8 lvmdiskscan.1 \
+                lvmdump.8 lvmdump.1 \
+                lvreduce.8 lvreduce.1 \
+                lvremove.8 lvremove.1 \
+                lvrename.8 lvrename.1 \
+                lvresize.8 lvresize.1 \
+                lvs.8 lvs.1 \
+                lvscan.8 lvscan.1 \
+                pvchange.8 pvchange.1 \
+                pvck.8 pvck.1 \
+                pvcreate.8 pvcreate.1 \
+                pvdisplay.8 pvdisplay.1 \
+                pvmove.8 pvmove.1 \
+                pvremove.8 pvremove.1 \
+                pvresize.8 pvresize.1 \
+                pvs.8 pvs.1 \
+                pvscan.8 pvscan.1 \
+                vgcfgbackup.8 vgcfgbackup.1 \
+                vgcfgrestore.8 vgcfgrestore.1 \
+                vgchange.8 vgchange.1 \
+                vgck.8 vgck.1 \
+                vgconvert.8 vgconvert.1 \
+                vgcreate.8 vgcreate.1 \
+                vgdisplay.8 vgdisplay.1 \
+                vgexport.8 vgexport.1 \
+                vgextend.8 vgextend.1 \
+                vgimport.8 vgimport.1 \
+                vgmerge.8 vgmerge.1 \
+                vgmknodes.8 vgmknodes.1 \
+                vgreduce.8 vgreduce.1 \
+                vgremove.8 vgremove.1 \
+                vgrename.8 vgrename.1 \
+                vgs.8 vgs.1 \
+                vgscan.8 vgscan.1 \
+                vgsplit.8 vgsplit.1
+
+LIBLVM_OBJDIR!= cd ${LVM2TOOLS_SRCDIR}/lib/liblvm && ${PRINTOBJDIR}
+LDADD+=         -L${LIBLVM_OBJDIR} -llvm
+DPADD+=         ${LIBLVM_OBJDIR}/liblvm.a
+
+LIBDM_OBJDIR!=  cd ${LVM2TOOLS_SRCDIR}/lib/libdevmapper && ${PRINTOBJDIR}
+LDADD+=         -L${LIBDM_OBJDIR} -ldevmapper
+DPADD+=         ${LIBDM_OBJDIR}/libdevmapper.a
+
+LDADD+=                -lprop
+
+
+.PATH: ${LVM2TOOLS_DISTDIR}/tools
+
+
+.include <bsd.prog.mk>