# # old_revision [2a1aa0228658a33cec42dc65322034564ef2447d] # # add_dir "devmapper/include/netbsd" # # add_file "devmapper/include/netbsd/netbsd-dm.h" # content [67689abc00cc39c29634a64e7c48ccc967b5f240] # # add_file "devmapper/lib/ioctl/libdm-nbsd-iface.c" # content [106ceb8d3271982054f41ba820700ea0fc995d61] # # add_file "devmapper/lib/ioctl/libdm_netbsd.c" # content [5070ffe53a6414a942f00c08c048137c888bf142] # # patch "devmapper/configure" # from [de694ffba9489b87142db675bb6762d8755037e2] # to [ac591359eefe705c9f75f276a4b7a269b291f16f] # # patch "devmapper/dmeventd/Makefile.in" # from [b8bca9a39c408fc2c6258d2aa0ad74650d74c949] # to [a6e99a06db20eb54f0c37a937d35a637d0e4b2fd] # # patch "devmapper/dmeventd/dmeventd.c" # from [ca3c5b84071fabb81356ad6e9eef393b6f44ffdf] # to [1dfe03e84148a21784daff3ef36c19241593c6be] # # patch "devmapper/dmsetup/Makefile.in" # from [92c34f726175ee621da271c080f851dada7e5fb5] # to [5cb7afa601fed09f5b4d5d6559a9259d61403078] # # patch "devmapper/kernel/ioctl/dm-ioctl.h" # from [b533bf19ce749da509f5ab80eea9fa566e21f189] # to [19338478de15479c9cdfa13df7e181ce88378a9b] # # patch "devmapper/lib/Makefile.in" # from [2614baaff3d30efb9035f39a446f81d5b1d1dc18] # to [ec32a370b2dabfe85704988c10b00e8b5d641348] # # patch "devmapper/lib/ioctl/libdm-iface.c" # from [a30044d59da90986f0cea202f41ada97d870d071] # to [bcdf4c2c761e1a48869e04b6590ff9ece93ac762] # # patch "devmapper/lib/libdm-common.c" # from [0a431e3a4cc2ae33e2ec9f9bb079b597f711fa61] # to [d7123176df7d6731620675ae44a1950a97a6b8b4] # # patch "devmapper/lib/libdm-deptree.c" # from [f3241d6a88d828a26ebb62c7a19d037567208ca3] # to [79655ba2369a73e449b46c4b2191efa3e0d96140] # # patch "devmapper/lib/libdm-file.h" # from [20bd6874c83a254cfd1731a1f173f4b5c7397686] # to [286406d5603d450718cc6de27da79f62bc2337cd] # # patch "devmapper/make.tmpl.in" # from [88992e2f00cb03682b8ad196e4988d26d77d016d] # to [37a0fa5ca878d812b7d1eb37b99f8508261e65ab] # # patch "devmapper/man/Makefile.in" # from [1a2d1a896e8889ff95d90d506d03f2991fa00c80] # to [31aed3799b2de986fd45c366300c392ba39a5e79] # # patch "devmapper/po/Makefile.in" # from [37f248b822057276beee8de367e2000c1c92a23f] # to [706de6ca4ac6fa45f70992c766c447919a09bb52] # ============================================================ --- devmapper/include/netbsd/netbsd-dm.h 67689abc00cc39c29634a64e7c48ccc967b5f240 +++ devmapper/include/netbsd/netbsd-dm.h 67689abc00cc39c29634a64e7c48ccc967b5f240 @@ -0,0 +1,173 @@ +#ifndef __NETBSD_DM_H__ +#define __NETBSD_DM_H__ + +#include + +#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. + * + * + * command + * ... + * + * event_nr + * ... + * + * name + * ... + * + * uuid + * ... + * + * dev + * + * + * flags + * + * + * version + * + * ... + * ... + * ... + * + * + * cmd_data + * + * + * + * + * + * 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. + * + * + * + * name + * ... + * + * version + * + * ... + * ... + * ... + * + * + * + * + */ + +#define DM_IOCTL_COMMAND "command" +#define DM_IOCTL_VERSION "version" +#define DM_IOCTL_OPEN "open_count" +#define DM_IOCTL_DEV "dev" +#define DM_IOCTL_NAME "name" +#define DM_IOCTL_UUID "uuid" +#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 *, uint32_t *, int); /* Get dm device major/minor 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__ */ ============================================================ --- devmapper/lib/ioctl/libdm-nbsd-iface.c 106ceb8d3271982054f41ba820700ea0fc995d61 +++ devmapper/lib/ioctl/libdm-nbsd-iface.c 106ceb8d3271982054f41ba820700ea0fc995d61 @@ -0,0 +1,1044 @@ +/* + * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. 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 "lib.h" +#include "libdm-targets.h" +#include "libdm-common.h" + +#include +#include +#include +#include + +#if __NetBSD__ +#include +#endif + +#include + +/* + * 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; + +/* + * If ioctl call is added to this list + */ + +/* *INDENT-OFF* */ +static struct cmd_data _cmd_data_v4[] = { + {"create", DM_DEV_CREATE, {4, 0, 0}}, + {"reload", DM_TABLE_LOAD, {4, 0, 0}}, + {"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}}, + {"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}}, + {"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,minor,DM_CHAR_MAJOR); + +#ifdef __NETBSD_PUD__ + +#define DM_MAJOR 377; + + *major = DM_MAJOR; + *minor = 0; +#endif + + 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; +} + +/* Keep only for compatibility with linux version in NetBSD. */ +int dm_is_dm_major(uint32_t major) +{ + return 1; +} + +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; +} + +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); + +} + +/* + * Protocol Version 4 functions. + */ + +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; +} + +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; +} + +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; +} + +int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, + uint32_t dev_minor) +{ + int r; + + if (bufsize < 8) + return 0; + + r = snprintf(buf, (size_t) bufsize, "%u:%u", dev_major, dev_minor); + if (r < 0 || r > bufsize - 1) + return 0; + + return 1; +} + +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; + info->major = MAJOR(dmt->dmi.v4->dev); + 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) +{ + return 0; +} + +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 0; +} + +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; +} + +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; +} + +static int _flatten(struct dm_task *dmt, unsigned repeat_count, + 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 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); + + if (dmt->minor >= 0) { + if (dmt->major <= 0) { + log_error("Missing major number for persistent device."); + goto bad; + } + flags |= DM_PERSISTENT_DEV_FLAG; + prop_dictionary_set_uint64(dm_dict,DM_IOCTL_DEV, + MKDEV(dmt->major, dmt->minor)); + } + + /* FIXME Until resume ioctl supplies name, use dev_name for readahead */ + if (dmt->dev_name && (dmt->type != DM_DEVICE_RESUME || dmt->minor < 0 || + dmt->major < 0)) + 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); + + /* Add array for all COMMAND specific data. */ + prop_dictionary_set(dm_dict,DM_IOCTL_CMD_DATA,cmd_array); + + if (dmt->newname) + prop_array_set_cstring(cmd_array,0,dmt->newname); + + return 0; +bad: + return -1; +} + +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; +} + +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); +} + +static int _create_and_load_v4(struct dm_task *dmt) +{ + struct dm_task *task; + int r; + + /* 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; +} + +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; + } + + 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; +} + +static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command, + unsigned repeat_count) +{ + struct dm_ioctl *dmi; + prop_dictionary_t dm_dict_in, dm_dict_out; + + uint32_t flags; + + dm_dict_in = NULL; + + prop_dictionary_get_uint32(dm_dict_in,DM_IOCTL_FLAGS,&flags); + + 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 */ + _flatten(dmt, repeat_count, dm_dict_in); + + 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"); + + /* 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) + return NULL; + + 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); + + return dmi; +} + +void dm_task_update_nodes(void) +{ + update_devs(); +} + +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; + +repeat_ioctl: + if (!(dmi = _do_dm_ioctl(dmt, command, _ioctl_buffer_double_factor))) + return 0; + + if (dmi->flags & DM_BUFFER_FULL_FLAG) { + switch (dmt->type) { + case DM_DEVICE_LIST_VERSIONS: + case DM_DEVICE_LIST: + case DM_DEVICE_DEPS: + case DM_DEVICE_STATUS: + case DM_DEVICE_TABLE: + case DM_DEVICE_WAITEVENT: + _ioctl_buffer_double_factor++; + dm_free(dmi); + goto repeat_ioctl; + default: + log_error("WARNING: libdevmapper buffer too small for data"); + } + } + + 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; +} ============================================================ --- devmapper/lib/ioctl/libdm_netbsd.c 5070ffe53a6414a942f00c08c048137c888bf142 +++ devmapper/lib/ioctl/libdm_netbsd.c 5070ffe53a6414a942f00c08c048137c888bf142 @@ -0,0 +1,420 @@ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include + +#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, uint32_t *minor, 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; + + /* Minor number is predefined to 0. */ + *minor = 0; + + 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; + + nbsd_get_dm_major(&major,&minor,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_DEV,&minor); + + dmi->dev = MKDEV(major,minor); + + /* 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); + dmi->target_count = 0; + + /* 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; + } + + prop_object_release(ver); + + 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; + } + + return j; +} + +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; + + nbsd_get_dm_major(&major,&minor,DM_BLOCK_MAJOR); + + odml = NULL; + name = NULL; + j = 0; + + 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; + } + return j; +} + +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; + + size_t j,plen,rec_size,next; + + j = 0; + next = 0; + odmts = NULL; + rec_size = 0; + + 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); + + prop_dictionary_get_cstring_nocopy(target_dict, + DM_TABLE_PARAMS,(const char **)¶ms); + + 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); + + plen = strlen(params) + 1; + plen = 0; + + 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 (params) + strcpy(params_start,params); + else*/ + params_start = '\0'; + + odmts = dmts; + + dmts = (struct dm_target_spec *)((uint8_t *)dmts + rec_size); + + j++; + + } + + if (odmts != NULL) + odmts->next = 0; + } + + return j; +} + +static int +dm_dev_deps(prop_dictionary_t dm_dict, struct dm_ioctl *dmi) +{ + struct dm_target_deps *dmtd; + + prop_array_t targets; + prop_object_iterator_t iter; + + size_t j; + + j = 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,&dmtd->dev[j]); + + j++; + } + + if (j == 0) + dmtd->count = 1; + else + dmtd->count = j; + } + + return j; +} ============================================================ --- devmapper/configure de694ffba9489b87142db675bb6762d8755037e2 +++ devmapper/configure ac591359eefe705c9f75f276a4b7a269b291f16f @@ -1,4 +1,4 @@ -#! /bin/sh +#! /usr/pkg/bin/bash # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61. # @@ -6473,7 +6473,7 @@ fi fi - if [ "x$MSGFMT" == x ]; + if [ "x$MSGFMT" = x ]; then { { echo "$as_me:$LINENO: error: msgfmt not found in path $PATH " >&5 echo "$as_me: error: msgfmt not found in path $PATH ============================================================ --- devmapper/dmeventd/Makefile.in b8bca9a39c408fc2c6258d2aa0ad74650d74c949 +++ devmapper/dmeventd/Makefile.in a6e99a06db20eb54f0c37a937d35a637d0e4b2fd @@ -30,10 +30,19 @@ include ../make.tmpl include ../make.tmpl -LDFLAGS += -ldl -ldevmapper -lpthread -CLDFLAGS += -ldl -ldevmapper -lpthread +OPSYS=$(shell uname -s) -dmeventd: $(LIB_SHARED) dmeventd.o +ifeq ("${OPSYS}", "Linux") +LIBDL=-ldl +REALLIB=${LIB_SHARED} +else +REALLIB=${LIB_STATIC} +endif + +LDFLAGS += ${LIBDL} -ldevmapper -lpthread +CLDFLAGS += ${LIBDL} -ldevmapper -lpthread + +dmeventd: $(REALLIB) dmeventd.o $(CC) -o $@ dmeventd.o $(CFLAGS) $(LDFLAGS) \ -L. -ldevmapper-event $(LIBS) -rdynamic @@ -53,24 +62,24 @@ install_include: install: $(INSTALL_TYPE) install_include install_dmeventd install_include: - $(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.h \ + $(INSTALL) -m 444 libdevmapper-event.h \ $(includedir)/libdevmapper-event.h install_dynamic: libdevmapper-event.$(LIB_SUFFIX) - $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \ + $(INSTALL) -m 555 $(STRIP) $< \ $(libdir)/libdevmapper-event.$(LIB_SUFFIX).$(LIB_VERSION) $(LN_S) -f libdevmapper-event.$(LIB_SUFFIX).$(LIB_VERSION) \ $(libdir)/libdevmapper-event.$(LIB_SUFFIX) install_dmeventd: dmeventd - $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< $(sbindir)/$< + $(INSTALL) -m 555 $(STRIP) $< $(sbindir)/$< install_pkgconfig: - $(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.pc \ + $(INSTALL) -m 444 libdevmapper-event.pc \ $(usrlibdir)/pkgconfig/devmapper-event.pc install_static: libdevmapper-event.a - $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \ + $(INSTALL) -m 555 $(STRIP) $< \ $(libdir)/libdevmapper-event.a.$(LIB_VERSION) $(LN_S) -f libdevmapper-event.a.$(LIB_VERSION) $(libdir)/libdevmapper-event.a ============================================================ --- devmapper/dmeventd/dmeventd.c ca3c5b84071fabb81356ad6e9eef393b6f44ffdf +++ devmapper/dmeventd/dmeventd.c 1dfe03e84148a21784daff3ef36c19241593c6be @@ -49,6 +49,10 @@ #endif +#ifdef __NetBSD__ +#include +#endif + /* FIXME We use syslog for now, because multilog is not yet implemented */ #include ============================================================ --- devmapper/dmsetup/Makefile.in 92c34f726175ee621da271c080f851dada7e5fb5 +++ devmapper/dmsetup/Makefile.in 5cb7afa601fed09f5b4d5d6559a9259d61403078 @@ -44,8 +44,8 @@ install_dynamic: dmsetup .PHONY: install_dynamic install_static install_dynamic: dmsetup - $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< $(sbindir)/$< + $(INSTALL) -m 555 $(STRIP) $< $(sbindir)/$< install_static: dmsetup.static - $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< $(sbindir)/$< + $(INSTALL) -m 555 $(STRIP) $< $(sbindir)/$< ============================================================ --- devmapper/kernel/ioctl/dm-ioctl.h b533bf19ce749da509f5ab80eea9fa566e21f189 +++ devmapper/kernel/ioctl/dm-ioctl.h 19338478de15479c9cdfa13df7e181ce88378a9b @@ -123,9 +123,9 @@ struct dm_ioctl { * relative to start of this struct */ uint32_t target_count; /* in/out */ - int32_t open_count; /* out */ + int32_t open_count; /* out */ uint32_t flags; /* in/out */ - uint32_t event_nr; /* in/out */ + uint32_t event_nr; /* in/out */ uint32_t padding; uint64_t dev; /* in/out */ @@ -133,6 +133,7 @@ struct dm_ioctl { char name[DM_NAME_LEN]; /* device name */ char uuid[DM_UUID_LEN]; /* unique identifier for * the block device */ + char data[7]; /* padding or data */ }; ============================================================ --- devmapper/lib/Makefile.in 2614baaff3d30efb9035f39a446f81d5b1d1dc18 +++ devmapper/lib/Makefile.in ec32a370b2dabfe85704988c10b00e8b5d641348 @@ -65,7 +65,7 @@ install_include: install: $(INSTALL_TYPE) install_include install_include: - $(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper.h \ + $(INSTALL) -m 444 libdevmapper.h \ $(includedir)/libdevmapper.h install_dynamic: install_@interface@ @@ -76,15 +76,15 @@ install_ioctl: ioctl/libdevmapper.$(LIB_ $(LN_S) -f libdevmapper.a.$(LIB_VERSION) $(libdir)/libdevmapper.a install_ioctl: ioctl/libdevmapper.$(LIB_SUFFIX) - $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \ + $(INSTALL) -m 555 $(STRIP) $< \ $(libdir)/libdevmapper.$(LIB_SUFFIX).$(LIB_VERSION) install_pkgconfig: - $(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper.pc \ + $(INSTALL) -m 444 libdevmapper.pc \ $(usrlibdir)/pkgconfig/devmapper.pc install_ioctl_static: ioctl/libdevmapper.a - $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \ + $(INSTALL) -m 555 $(STRIP) $< \ $(libdir)/libdevmapper.a.$(LIB_VERSION) $(VERSIONED_SHLIB): %.$(LIB_SUFFIX).$(LIB_VERSION): $(interface)/%.$(LIB_SUFFIX) ============================================================ --- devmapper/lib/ioctl/libdm-iface.c a30044d59da90986f0cea202f41ada97d870d071 +++ devmapper/lib/ioctl/libdm-iface.c bcdf4c2c761e1a48869e04b6590ff9ece93ac762 @@ -1690,8 +1690,10 @@ repeat_ioctl: 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); + if (dmt->dev_name && *dmt->dev_name) + add_dev_node(dmt->dev_name, MAJOR(dmi->dev), + MINOR(dmi->dev), dmt->uid, dmt->gid, + dmt->mode); break; case DM_DEVICE_REMOVE: ============================================================ --- devmapper/lib/libdm-common.c 0a431e3a4cc2ae33e2ec9f9bb079b597f711fa61 +++ devmapper/lib/libdm-common.c d7123176df7d6731620675ae44a1950a97a6b8b4 @@ -17,7 +17,10 @@ #include "libdm-targets.h" #include "libdm-common.h" #include "list.h" + +#ifdef linux #include "kdev_t.h" +#endif #include #include @@ -34,6 +37,10 @@ # include #endif +#ifdef __NetBSD__ +#include +#endif + #define DEV_DIR "/dev/" static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR; @@ -268,6 +275,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,raw_minor; + dev_t rdev; + char raw_devname[DM_NAME_LEN+1]; /* r + other device name */ + + nbsd_get_dm_major(&raw_major,&raw_minor,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) { @@ -289,10 +335,12 @@ static int _add_dev_node(const char *dev } old_mask = umask(0); + if (mknod(path, S_IFBLK | mode, dev) < 0) { log_error("Unable to make device node for '%s'", dev_name); return 0; - } + } + umask(old_mask); if (chown(path, uid, gid) < 0) { @@ -316,6 +364,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 +437,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) ============================================================ --- devmapper/lib/libdm-deptree.c f3241d6a88d828a26ebb62c7a19d037567208ca3 +++ devmapper/lib/libdm-deptree.c 79655ba2369a73e449b46c4b2191efa3e0d96140 @@ -1821,10 +1821,14 @@ int dm_tree_node_add_target_area(struct return 0; } - if (!S_ISBLK(info.st_mode)) { + /* + * XXX NetBSD look here this line is bogus. + */ + + /*if (!S_ISBLK(info.st_mode)) { log_error("Device %s is not a block device.", dev_name); return 0; - } + }*/ /* FIXME Check correct macro use */ if (!(dev_node = _add_dev(node->dtree, node, MAJOR(info.st_rdev), MINOR(info.st_rdev)))) ============================================================ --- devmapper/lib/libdm-file.h 20bd6874c83a254cfd1731a1f173f4b5c7397686 +++ devmapper/lib/libdm-file.h 286406d5603d450718cc6de27da79f62bc2337cd @@ -20,6 +20,6 @@ * Create directory (recursively) if necessary. Return 1 * if directory was successfully created (or already exists), else 0. */ -int create_dir(const char *dir); +int dm_create_dir(const char *dir); #endif ============================================================ --- devmapper/make.tmpl.in 88992e2f00cb03682b8ad196e4988d26d77d016d +++ devmapper/make.tmpl.in 37a0fa5ca878d812b7d1eb37b99f8508261e65ab @@ -31,6 +31,10 @@ LIB_SUFFIX = @LIB_SUFFIX@ LDFLAGS += @LDFLAGS@ LIB_SUFFIX = @LIB_SUFFIX@ +ifeq ("$(LIB_SUFFIX)", "") +LIB_SUFFIX=a +endif + # Setup directory variables prefix = @prefix@ exec_prefix = @exec_prefix@ ============================================================ --- devmapper/man/Makefile.in 1a2d1a896e8889ff95d90d506d03f2991fa00c80 +++ devmapper/man/Makefile.in 31aed3799b2de986fd45c366300c392ba39a5e79 @@ -26,6 +26,6 @@ install: @for f in $(MANUALS); \ do \ $(RM) $(MAN8DIR)/$$f; \ - @INSTALL@ -D $(OWNER) $(GROUP) -m 444 $$f $(MAN8DIR)/$$f; \ + @INSTALL@ -m 444 $$f $(MAN8DIR)/$$f; \ done ============================================================ --- devmapper/po/Makefile.in 37f248b822057276beee8de367e2000c1c92a23f +++ devmapper/po/Makefile.in 706de6ca4ac6fa45f70992c766c447919a09bb52 @@ -28,7 +28,7 @@ install: $(TARGETS) @echo Installing translation files in $(localedir) @( \ for lang in $(LANGS); do \ - $(INSTALL) -D $(OWNER) $(GROUP) -m 444 $$lang.mo \ + $(INSTALL) -m 444 $$lang.mo \ $(localedir)/$$lang/LC_MESSAGES/@INTL_PACKAGE@.mo;\ done; \ )