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>
