/*
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 * Copyright (C) 2004-2012 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "dmlib.h"
#include "libdm-targets.h"
#include "libdm-common.h"
#include "kdev_t.h"
#include "dm-ioctl.h"

#include <stdarg.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <dirent.h>

#ifdef UDEV_SYNC_SUPPORT
#  include <sys/types.h>
#  include <sys/ipc.h>
#  include <sys/sem.h>
#  include <libudev.h>
#endif

#ifdef __linux__
#  include <linux/fs.h>
#endif

#ifdef HAVE_SELINUX
#  include <selinux/selinux.h>
#endif
#ifdef HAVE_SELINUX_LABEL_H
#  include <selinux/label.h>
#endif

#define DM_DEFAULT_NAME_MANGLING_MODE_ENV_VAR_NAME "DM_DEFAULT_NAME_MANGLING_MODE"

#define DEV_DIR "/dev/"

#ifdef UDEV_SYNC_SUPPORT
#ifdef _SEM_SEMUN_UNDEFINED
union semun
{
	int val;			/* value for SETVAL */
	struct semid_ds *buf;		/* buffer for IPC_STAT & IPC_SET */
	unsigned short int *array;	/* array for GETALL & SETALL */
	struct seminfo *__buf;		/* buffer for IPC_INFO */
};
#endif
#endif

static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR;
static char _sysfs_dir[PATH_MAX] = "/sys/";
static char _path0[PATH_MAX];           /* path buffer, safe 4kB on stack */
static const char _mountinfo[] = "/proc/self/mountinfo";

#define DM_MAX_UUID_PREFIX_LEN	15
static char _default_uuid_prefix[DM_MAX_UUID_PREFIX_LEN + 1] = "LVM-";

static int _verbose = 0;
static int _suspended_dev_counter = 0;
static dm_string_mangling_t _name_mangling_mode = DEFAULT_DM_NAME_MANGLING;

#ifdef HAVE_SELINUX_LABEL_H
static struct selabel_handle *_selabel_handle = NULL;
#endif

static int _udev_disabled = 0;

#ifdef UDEV_SYNC_SUPPORT
static int _semaphore_supported = -1;
static int _udev_running = -1;
static int _sync_with_udev = 1;
static int _udev_checking = 1;
#endif

void dm_lib_init(void)
{
	const char *env;

	if (getenv("DM_DISABLE_UDEV"))
		_udev_disabled = 1;

	_name_mangling_mode = DEFAULT_DM_NAME_MANGLING;
	if ((env = getenv(DM_DEFAULT_NAME_MANGLING_MODE_ENV_VAR_NAME))) {
		if (!strcasecmp(env, "none"))
			_name_mangling_mode = DM_STRING_MANGLING_NONE;
		else if (!strcasecmp(env, "auto"))
			_name_mangling_mode = DM_STRING_MANGLING_AUTO;
		else if (!strcasecmp(env, "hex"))
			_name_mangling_mode = DM_STRING_MANGLING_HEX;
	}
}

/*
 * Library users can provide their own logging
 * function.
 */

__attribute__((format(printf, 5, 0)))
static void _default_log_line(int level,
	    const char *file __attribute__((unused)),
	    int line __attribute__((unused)), int dm_errno_or_class,
	    const char *f, va_list ap)
{
	static int _abort_on_internal_errors = -1;
	FILE *out = (level & _LOG_STDERR) ? stderr : stdout;

	level &= ~(_LOG_STDERR | _LOG_BYPASS_REPORT);

	if (level <= _LOG_WARN || _verbose) {
		if (level < _LOG_WARN)
			out = stderr;
		vfprintf(out, f, ap);
		fputc('\n', out);
	}

	if (_abort_on_internal_errors < 0)
		/* Set when env DM_ABORT_ON_INTERNAL_ERRORS is not "0" */
		_abort_on_internal_errors =
			strcmp(getenv("DM_ABORT_ON_INTERNAL_ERRORS") ? : "0", "0");

	if (_abort_on_internal_errors &&
	    !strncmp(f, INTERNAL_ERROR, sizeof(INTERNAL_ERROR) - 1))
		abort();
}

__attribute__((format(printf, 5, 6)))
static void _default_log_with_errno(int level,
	    const char *file __attribute__((unused)),
	    int line __attribute__((unused)), int dm_errno_or_class,
	    const char *f, ...)
{
	va_list ap;

	va_start(ap, f);
	_default_log_line(level, file, line, dm_errno_or_class, f, ap);
	va_end(ap);
}

__attribute__((format(printf, 4, 5)))
static void _default_log(int level, const char *file,
			 int line, const char *f, ...)
{
	va_list ap;

	va_start(ap, f);
	_default_log_line(level, file, line, 0, f, ap);
	va_end(ap);
}

dm_log_fn dm_log = _default_log;
dm_log_with_errno_fn dm_log_with_errno = _default_log_with_errno;

void dm_log_init(dm_log_fn fn)
{
	if (fn)
		dm_log = fn;
	else
		dm_log = _default_log;

	dm_log_with_errno = _default_log_with_errno;
}

int dm_log_is_non_default(void)
{
	return (dm_log == _default_log) ? 0 : 1;
}

void dm_log_with_errno_init(dm_log_with_errno_fn fn)
{
	if (fn)
		dm_log_with_errno = fn;
	else
		dm_log_with_errno = _default_log_with_errno;

	dm_log = _default_log;
}

void dm_log_init_verbose(int level)
{
	_verbose = level;
}

static int _build_dev_path(char *buffer, size_t len, const char *dev_name)
{
	int r;

	/* If there's a /, assume caller knows what they're doing */
	if (strchr(dev_name, '/'))
		r = dm_strncpy(buffer, dev_name, len);
	else
		r = (dm_snprintf(buffer, len, "%s/%s",
				 _dm_dir, dev_name) < 0) ? 0 : 1;
	if (!r)
		log_error("Failed to build dev path for \"%s\".", dev_name);

	return r;
}

int dm_get_library_version(char *version, size_t size)
{
	return dm_strncpy(version, DM_LIB_VERSION, size);
}

void inc_suspended(void)
{
	_suspended_dev_counter++;
	log_debug_activation("Suspended device counter increased to %d", _suspended_dev_counter);
}

void dec_suspended(void)
{
	if (!_suspended_dev_counter) {
		log_error("Attempted to decrement suspended device counter below zero.");
		return;
	}

	_suspended_dev_counter--;
	log_debug_activation("Suspended device counter reduced to %d", _suspended_dev_counter);
}

int dm_get_suspended_counter(void)
{
	return _suspended_dev_counter;
}

int dm_set_name_mangling_mode(dm_string_mangling_t name_mangling_mode)
{
	_name_mangling_mode = name_mangling_mode;

	return 1;
}

dm_string_mangling_t dm_get_name_mangling_mode(void)
{
	return _name_mangling_mode;
}

struct dm_task *dm_task_create(int type)
{
	struct dm_task *dmt = dm_zalloc(sizeof(*dmt));

	if (!dmt) {
		log_error("dm_task_create: malloc(%" PRIsize_t ") failed",
			  sizeof(*dmt));
		return NULL;
	}

	if (!dm_check_version()) {
		dm_free(dmt);
		return_NULL;
	}

	dmt->type = type;
	dmt->minor = -1;
	dmt->major = -1;
	dmt->allow_default_major_fallback = 1;
	dmt->uid = DM_DEVICE_UID;
	dmt->gid = DM_DEVICE_GID;
	dmt->mode = DM_DEVICE_MODE;
	dmt->no_open_count = 0;
	dmt->read_ahead = DM_READ_AHEAD_AUTO;
	dmt->read_ahead_flags = 0;
	dmt->event_nr = 0;
	dmt->cookie_set = 0;
	dmt->query_inactive_table = 0;
	dmt->new_uuid = 0;
	dmt->secure_data = 0;
	dmt->record_timestamp = 0;

	return dmt;
}

/*
 * Find the name associated with a given device number by scanning _dm_dir.
 */
static int _find_dm_name_of_device(dev_t st_rdev, char *buf, size_t buf_len)
{
	const char *name;
	char path[PATH_MAX];
	struct dirent *dirent;
	DIR *d;
	struct stat st;
	int r = 0;

	if (!(d = opendir(_dm_dir))) {
		log_sys_error("opendir", _dm_dir);
		return 0;
	}

	while ((dirent = readdir(d))) {
		name = dirent->d_name;

		if (!strcmp(name, ".") || !strcmp(name, ".."))
			continue;

		if (dm_snprintf(path, sizeof(path), "%s/%s", _dm_dir,
				name) == -1) {
			log_error("Couldn't create path for %s", name);
			continue;
		}

		if (stat(path, &st))
			continue;

		if (st.st_rdev == st_rdev) {
			strncpy(buf, name, buf_len);
			r = 1;
			break;
		}
	}

	if (closedir(d))
		log_sys_error("closedir", _dm_dir);

	return r;
}

static int _is_whitelisted_char(char c)
{
	/*
	 * Actually, DM supports any character in a device name.
	 * This whitelist is just for proper integration with udev.
	 */
        if ((c >= '0' && c <= '9') ||
            (c >= 'A' && c <= 'Z') ||
            (c >= 'a' && c <= 'z') ||
            strchr("#+-.:=@_", c) != NULL)
                return 1;

        return 0;
}

int check_multiple_mangled_string_allowed(const char *str, const char *str_name,
					 dm_string_mangling_t mode)
{
	if (mode == DM_STRING_MANGLING_AUTO && strstr(str, "\\x5cx")) {
		log_error("The %s \"%s\" seems to be mangled more than once. "
			  "This is not allowed in auto mode.", str_name, str);
		return 0;
	}

	return 1;
}

/*
 * Mangle all characters in the input string which are not on a whitelist
 * with '\xNN' format where NN is the hex value of the character.
 */
int mangle_string(const char *str, const char *str_name, size_t len,
		  char *buf, size_t buf_len, dm_string_mangling_t mode)
{
	int need_mangling = -1; /* -1 don't know yet, 0 no, 1 yes */
	size_t i, j;

	if (!str || !buf)
		return -1;

	/* Is there anything to do at all? */
	if (!*str || !len)
		return 0;

	if (buf_len < DM_NAME_LEN) {
		log_error(INTERNAL_ERROR "mangle_string: supplied buffer too small");
		return -1;
	}

	if (mode == DM_STRING_MANGLING_NONE)
		mode = DM_STRING_MANGLING_AUTO;

	for (i = 0, j = 0; str[i]; i++) {
		if (mode == DM_STRING_MANGLING_AUTO) {
			/*
			 * Detect already mangled part of the string and keep it.
			 * Return error on mixture of mangled/not mangled!
			 */
			if (str[i] == '\\' && str[i+1] == 'x') {
				if ((len - i < 4) || (need_mangling == 1))
					goto bad1;
				if (buf_len - j < 4)
					goto bad2;

				memcpy(&buf[j], &str[i], 4);
				i+=3; j+=4;

				need_mangling = 0;
				continue;
			}
		}

		if (_is_whitelisted_char(str[i])) {
			/* whitelisted, keep it. */
			if (buf_len - j < 1)
				goto bad2;
			buf[j] = str[i];
			j++;
		} else {
			/*
			 * Not on a whitelist, mangle it.
			 * Return error on mixture of mangled/not mangled
			 * unless a DM_STRING_MANGLING_HEX is used!.
			 */
			if ((mode != DM_STRING_MANGLING_HEX) && (need_mangling == 0))
				goto bad1;
			if (buf_len - j < 4)
				goto bad2;

			sprintf(&buf[j], "\\x%02x", (unsigned char) str[i]);
			j+=4;

			need_mangling = 1;
		}
	}

	if (buf_len - j < 1)
		goto bad2;
	buf[j] = '\0';

	/* All chars in the string whitelisted? */
	if (need_mangling == -1)
		need_mangling = 0;

	return need_mangling;

bad1:
	log_error("The %s \"%s\" contains mixed mangled and unmangled "
		  "characters or it's already mangled improperly.", str_name, str);
	return -1;
bad2:
	log_error("Mangled form of the %s too long for \"%s\".", str_name, str);
	return -1;
}

/*
 * Try to unmangle supplied string.
 * Return value: -1 on error, 0 when no unmangling needed, 1 when unmangling applied
 */
int unmangle_string(const char *str, const char *str_name, size_t len,
		    char *buf, size_t buf_len, dm_string_mangling_t mode)
{
	int strict = mode != DM_STRING_MANGLING_NONE;
	char str_rest[DM_NAME_LEN];
	size_t i, j;
	int code;
	int r = 0;

	if (!str || !buf)
		return -1;

	/* Is there anything to do at all? */
	if (!*str || !len)
		return 0;

	if (buf_len < DM_NAME_LEN) {
		log_error(INTERNAL_ERROR "unmangle_string: supplied buffer too small");
		return -1;
	}

	for (i = 0, j = 0; str[i]; i++, j++) {
		if (strict && !(_is_whitelisted_char(str[i]) || str[i]=='\\')) {
			log_error("The %s \"%s\" should be mangled but "
				  "it contains blacklisted characters.", str_name, str);
			j=0; r=-1;
			goto out;
		}

		if (str[i] == '\\' && str[i+1] == 'x') {
			if (!sscanf(&str[i+2], "%2x%s", &code, str_rest)) {
				log_debug_activation("Hex encoding mismatch detected in %s \"%s\" "
						     "while trying to unmangle it.", str_name, str);
				goto out;
			}
			buf[j] = (unsigned char) code;

			/* skip the encoded part we've just decoded! */
			i+= 3;

			/* unmangling applied */
			r = 1;
		} else
			buf[j] = str[i];
	}

out:
	buf[j] = '\0';
	return r;
}

static int _dm_task_set_name(struct dm_task *dmt, const char *name,
			     dm_string_mangling_t mangling_mode)
{
	char mangled_name[DM_NAME_LEN];
	int r = 0;

	dm_free(dmt->dev_name);
	dmt->dev_name = NULL;
	dm_free(dmt->mangled_dev_name);
	dmt->mangled_dev_name = NULL;

	if (strlen(name) >= DM_NAME_LEN) {
		log_error("Name \"%s\" too long.", name);
		return 0;
	}

	if (!check_multiple_mangled_string_allowed(name, "name", mangling_mode))
		return_0;

	if (mangling_mode != DM_STRING_MANGLING_NONE &&
	    (r = mangle_string(name, "name", strlen(name), mangled_name,
			       sizeof(mangled_name), mangling_mode)) < 0) {
		log_error("Failed to mangle device name \"%s\".", name);
		return 0;
	}

	/* Store mangled_dev_name only if it differs from dev_name! */
	if (r) {
		log_debug_activation("Device name mangled [%s]: %s --> %s",
				     mangling_mode == DM_STRING_MANGLING_AUTO ? "auto" : "hex",
				     name, mangled_name);
		if (!(dmt->mangled_dev_name = dm_strdup(mangled_name))) {
			log_error("_dm_task_set_name: dm_strdup(%s) failed", mangled_name);
			return 0;
		}
	}

	if (!(dmt->dev_name = dm_strdup(name))) {
		log_error("_dm_task_set_name: strdup(%s) failed", name);
		return 0;
	}

	return 1;
}

static int _dm_task_set_name_from_path(struct dm_task *dmt, const char *path,
				       const char *name)
{
	char buf[PATH_MAX];
	struct stat st1, st2;
	const char *final_name = NULL;
	size_t len;

	if (dmt->type == DM_DEVICE_CREATE) {
		log_error("Name \"%s\" invalid. It contains \"/\".", path);
		return 0;
	}

	if (!stat(path, &st1)) {
		/*
		 * Found directly.
		 * If supplied path points to same device as last component
		 * under /dev/mapper, use that name directly.  
		 */
		if (dm_snprintf(buf, sizeof(buf), "%s/%s", _dm_dir, name) == -1) {
			log_error("Couldn't create path for %s", name);
			return 0;
		}

		if (!stat(buf, &st2) && (st1.st_rdev == st2.st_rdev))
			final_name = name;
	} else {
		/* Not found. */
		/* If there is exactly one '/' try a prefix of /dev */
		if ((len = strlen(path)) < 3 || path[0] == '/' ||
		    dm_count_chars(path, len, '/') != 1) {
			log_error("Device %s not found", path);
			return 0;
		}
		if (dm_snprintf(buf, sizeof(buf), "%s/../%s", _dm_dir, path) == -1) {
			log_error("Couldn't create /dev path for %s", path);
			return 0;
		}
		if (stat(buf, &st1)) {
			log_error("Device %s not found", path);
			return 0;
		}
		/* Found */
	}

	/*
	 * If we don't have the dm name yet, Call _find_dm_name_of_device() to
	 * scan _dm_dir for a match.
	 */
	if (!final_name) {
		if (_find_dm_name_of_device(st1.st_rdev, buf, sizeof(buf)))
			final_name = buf;
		else {
			log_error("Device %s not found", name);
			return 0;
		}
	}

	/* This is an already existing path - do not mangle! */
	return _dm_task_set_name(dmt, final_name, DM_STRING_MANGLING_NONE);
}

int dm_task_set_name(struct dm_task *dmt, const char *name)
{
	char *pos;

	/* Path supplied for existing device? */
	if ((pos = strrchr(name, '/')))
		return _dm_task_set_name_from_path(dmt, name, pos + 1);

	return _dm_task_set_name(dmt, name, dm_get_name_mangling_mode());
}

const char *dm_task_get_name(const struct dm_task *dmt)
{
	return (dmt->dmi.v4->name);
}

static char *_task_get_string_mangled(const char *str, const char *str_name,
				      char *buf, size_t buf_size,
				      dm_string_mangling_t mode)
{
	char *rs;
	int r;

	if ((r = mangle_string(str, str_name, strlen(str), buf, buf_size, mode)) < 0)
		return NULL;

	if (!(rs = r ? dm_strdup(buf) : dm_strdup(str)))
		log_error("_task_get_string_mangled: dm_strdup failed");

	return rs;
}

static char *_task_get_string_unmangled(const char *str, const char *str_name,
					char *buf, size_t buf_size,
					dm_string_mangling_t mode)
{
	char *rs;
	int r = 0;

	/*
	 * Unless the mode used is 'none', the string
	 * is *already* unmangled on ioctl return!
	 */
	if (mode == DM_STRING_MANGLING_NONE &&
	    (r = unmangle_string(str, str_name, strlen(str), buf, buf_size, mode)) < 0)
		return NULL;

	if (!(rs = r ? dm_strdup(buf) : dm_strdup(str)))
		log_error("_task_get_string_unmangled: dm_strdup failed");

	return rs;
}

char *dm_task_get_name_mangled(const struct dm_task *dmt)
{
	const char *s = dm_task_get_name(dmt);
	char buf[DM_NAME_LEN];
	char *rs;

	if (!(rs = _task_get_string_mangled(s, "name", buf, sizeof(buf), dm_get_name_mangling_mode())))
		log_error("Failed to mangle device name \"%s\".", s);

	return rs;
}

char *dm_task_get_name_unmangled(const struct dm_task *dmt)
{
	const char *s = dm_task_get_name(dmt);
	char buf[DM_NAME_LEN];
	char *rs;

	if (!(rs = _task_get_string_unmangled(s, "name", buf, sizeof(buf), dm_get_name_mangling_mode())))
		log_error("Failed to unmangle device name \"%s\".", s);

	return rs;
}

const char *dm_task_get_uuid(const struct dm_task *dmt)
{
	return (dmt->dmi.v4->uuid);
}

char *dm_task_get_uuid_mangled(const struct dm_task *dmt)
{
	const char *s = dm_task_get_uuid(dmt);
	char buf[DM_UUID_LEN];
	char *rs;

	if (!(rs = _task_get_string_mangled(s, "UUID", buf, sizeof(buf), dm_get_name_mangling_mode())))
		log_error("Failed to mangle device uuid \"%s\".", s);

	return rs;
}

char *dm_task_get_uuid_unmangled(const struct dm_task *dmt)
{
	const char *s = dm_task_get_uuid(dmt);
	char buf[DM_UUID_LEN];
	char *rs;

	if (!(rs = _task_get_string_unmangled(s, "UUID", buf, sizeof(buf), dm_get_name_mangling_mode())))
		log_error("Failed to unmangle device uuid \"%s\".", s);

	return rs;
}

int dm_task_set_newname(struct dm_task *dmt, const char *newname)
{
	dm_string_mangling_t mangling_mode = dm_get_name_mangling_mode();
	char mangled_name[DM_NAME_LEN];
	int r = 0;

	if (strchr(newname, '/')) {
		log_error("Name \"%s\" invalid. It contains \"/\".", newname);
		return 0;
	}

	if (strlen(newname) >= DM_NAME_LEN) {
		log_error("Name \"%s\" too long", newname);
		return 0;
	}

	if (!*newname) {
		log_error("Non empty new name is required.");
		return 0;
	}

	if (!check_multiple_mangled_string_allowed(newname, "new name", mangling_mode))
		return_0;

	if (mangling_mode != DM_STRING_MANGLING_NONE &&
	    (r = mangle_string(newname, "new name", strlen(newname), mangled_name,
			       sizeof(mangled_name), mangling_mode)) < 0) {
		log_error("Failed to mangle new device name \"%s\"", newname);
		return 0;
	}

	if (r) {
		log_debug_activation("New device name mangled [%s]: %s --> %s",
				     mangling_mode == DM_STRING_MANGLING_AUTO ? "auto" : "hex",
				     newname, mangled_name);
		newname = mangled_name;
	}

	dm_free(dmt->newname);
	if (!(dmt->newname = dm_strdup(newname))) {
		log_error("dm_task_set_newname: strdup(%s) failed", newname);
		return 0;
	}

	dmt->new_uuid = 0;

	return 1;
}

int dm_task_set_uuid(struct dm_task *dmt, const char *uuid)
{
	char mangled_uuid[DM_UUID_LEN];
	dm_string_mangling_t mangling_mode = dm_get_name_mangling_mode();
	int r = 0;

	dm_free(dmt->uuid);
	dmt->uuid = NULL;
	dm_free(dmt->mangled_uuid);
	dmt->mangled_uuid = NULL;

	if (!check_multiple_mangled_string_allowed(uuid, "UUID", mangling_mode))
		return_0;

	if (mangling_mode != DM_STRING_MANGLING_NONE &&
	    (r = mangle_string(uuid, "UUID", strlen(uuid), mangled_uuid,
			       sizeof(mangled_uuid), mangling_mode)) < 0) {
		log_error("Failed to mangle device uuid \"%s\".", uuid);
		return 0;
	}

	if (r) {
		log_debug_activation("Device uuid mangled [%s]: %s --> %s",
				     mangling_mode == DM_STRING_MANGLING_AUTO ? "auto" : "hex",
				     uuid, mangled_uuid);

		if (!(dmt->mangled_uuid = dm_strdup(mangled_uuid))) {
			log_error("dm_task_set_uuid: dm_strdup(%s) failed", mangled_uuid);
			return 0;
		}
	}

	if (!(dmt->uuid = dm_strdup(uuid))) {
		log_error("dm_task_set_uuid: strdup(%s) failed", uuid);
		return 0;
	}

	return 1;
}

int dm_task_set_major(struct dm_task *dmt, int major)
{
	dmt->major = major;
	dmt->allow_default_major_fallback = 0;

	return 1;
}

int dm_task_set_minor(struct dm_task *dmt, int minor)
{
	dmt->minor = minor;

	return 1;
}

int dm_task_set_major_minor(struct dm_task *dmt, int major, int minor,
			    int allow_default_major_fallback)
{
	dmt->major = major;
	dmt->minor = minor;
	dmt->allow_default_major_fallback = allow_default_major_fallback;

	return 1;
}

int dm_task_set_uid(struct dm_task *dmt, uid_t uid)
{
	dmt->uid = uid;

	return 1;
}

int dm_task_set_gid(struct dm_task *dmt, gid_t gid)
{
	dmt->gid = gid;

	return 1;
}

int dm_task_set_mode(struct dm_task *dmt, mode_t mode)
{
	dmt->mode = mode;

	return 1;
}

int dm_task_enable_checks(struct dm_task *dmt)
{
	dmt->enable_checks = 1;

	return 1;
}

int dm_task_add_target(struct dm_task *dmt, uint64_t start, uint64_t size,
		       const char *ttype, const char *params)
{
	struct target *t = create_target(start, size, ttype, params);
	if (!t)
		return_0;

	if (!dmt->head)
		dmt->head = dmt->tail = t;
	else {
		dmt->tail->next = t;
		dmt->tail = t;
	}

	return 1;
}

#ifdef HAVE_SELINUX
static int _selabel_lookup(const char *path, mode_t mode,
			   security_context_t *scontext)
{
#ifdef HAVE_SELINUX_LABEL_H
	if (!_selabel_handle &&
	    !(_selabel_handle = selabel_open(SELABEL_CTX_FILE, NULL, 0))) {
		log_error("selabel_open failed: %s", strerror(errno));
		return 0;
	}

	if (selabel_lookup(_selabel_handle, scontext, path, mode)) {
		log_debug_activation("selabel_lookup failed for %s: %s",
				     path, strerror(errno));
		return 0;
	}
#else
	if (matchpathcon(path, mode, scontext)) {
		log_debug_activation("matchpathcon failed for %s: %s",
				     path, strerror(errno));
		return 0;
	}
#endif
	return 1;
}
#endif

#ifdef HAVE_SELINUX
static int _is_selinux_enabled(void)
{
	static int _tested = 0;
	static int _enabled;

	if (!_tested) {
		_tested = 1;
		_enabled = is_selinux_enabled();
	}

	return _enabled;
}
#endif

int dm_prepare_selinux_context(const char *path, mode_t mode)
{
#ifdef HAVE_SELINUX
	security_context_t scontext = NULL;

	if (_is_selinux_enabled() <= 0)
		return 1;

	if (path) {
		if (!_selabel_lookup(path, mode, &scontext))
			return_0;

		log_debug_activation("Preparing SELinux context for %s to %s.", path, scontext);
	}
	else
		log_debug_activation("Resetting SELinux context to default value.");

	if (setfscreatecon(scontext) < 0) {
		log_sys_error("setfscreatecon", (path ? : "SELinux context reset"));
		freecon(scontext);
		return 0;
	}

	freecon(scontext);
#endif
	return 1;
}

int dm_set_selinux_context(const char *path, mode_t mode)
{
#ifdef HAVE_SELINUX
	security_context_t scontext = NULL;

	if (_is_selinux_enabled() <= 0)
		return 1;

	if (!_selabel_lookup(path, mode, &scontext))
		return_0;

	log_debug_activation("Setting SELinux context for %s to %s.", path, scontext);

	if ((lsetfilecon(path, scontext) < 0) && (errno != ENOTSUP)) {
		log_sys_error("lsetfilecon", path);
		freecon(scontext);
		return 0;
	}

	freecon(scontext);
#endif
	return 1;
}

void selinux_release(void)
{
#ifdef HAVE_SELINUX_LABEL_H
	if (_selabel_handle)
		selabel_close(_selabel_handle);
	_selabel_handle = NULL;
#endif
}

static int _warn_if_op_needed(int warn_if_udev_failed)
{
    return warn_if_udev_failed && dm_udev_get_sync_support() && dm_udev_get_checking();
}

static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
			 uid_t uid, gid_t gid, mode_t mode, int warn_if_udev_failed)
{
	char path[PATH_MAX];
	struct stat info;
	dev_t dev = MKDEV((dev_t)major, (dev_t)minor);
	mode_t old_mask;

	if (!_build_dev_path(path, sizeof(path), dev_name))
		return_0;

	if (stat(path, &info) >= 0) {
		if (!S_ISBLK(info.st_mode)) {
			log_error("A non-block device file at '%s' "
				  "is already present", path);
			return 0;
		}

		/* If right inode already exists we don't touch uid etc. */
		if (info.st_rdev == dev)
			return 1;

		if (unlink(path) < 0) {
			log_error("Unable to unlink device node for '%s'",
				  dev_name);
			return 0;
		}
	} else if (_warn_if_op_needed(warn_if_udev_failed))
		log_warn("%s not set up by udev: Falling back to direct "
			 "node creation.", path);

	(void) dm_prepare_selinux_context(path, S_IFBLK);
	old_mask = umask(0);

	/* The node may already have been created by udev. So ignore EEXIST. */
	if (mknod(path, S_IFBLK | mode, dev) < 0 && errno != EEXIST) {
		log_error("%s: mknod for %s failed: %s", path, dev_name, strerror(errno));
		umask(old_mask);
		(void) dm_prepare_selinux_context(NULL, 0);
		return 0;
	}
	umask(old_mask);
	(void) dm_prepare_selinux_context(NULL, 0);

	if (chown(path, uid, gid) < 0) {
		log_sys_error("chown", path);
		return 0;
	}

	log_debug_activation("Created %s", path);

	return 1;
}

static int _rm_dev_node(const char *dev_name, int warn_if_udev_failed)
{
	char path[PATH_MAX];
	struct stat info;

	if (!_build_dev_path(path, sizeof(path), dev_name))
		return_0;
	if (lstat(path, &info) < 0)
		return 1;
	else if (_warn_if_op_needed(warn_if_udev_failed))
		log_warn("Node %s was not removed by udev. "
			 "Falling back to direct node removal.", path);

	/* udev may already have deleted the node. Ignore ENOENT. */
	if (unlink(path) < 0 && errno != ENOENT) {
		log_error("Unable to unlink device node for '%s'", dev_name);
		return 0;
	}

	log_debug_activation("Removed %s", path);

	return 1;
}

static int _rename_dev_node(const char *old_name, const char *new_name,
			    int warn_if_udev_failed)
{
	char oldpath[PATH_MAX];
	char newpath[PATH_MAX];
	struct stat info, info2;
	struct stat *info_block_dev;

	if (!_build_dev_path(oldpath, sizeof(oldpath), old_name) ||
	    !_build_dev_path(newpath, sizeof(newpath), new_name))
		return_0;

	if (lstat(newpath, &info) == 0) {
		if (S_ISLNK(info.st_mode)) {
			if (stat(newpath, &info2) == 0)
				info_block_dev = &info2;
			else {
				log_sys_error("stat", newpath);
				return 0;
			}
		} else
			info_block_dev = &info;

		if (!S_ISBLK(info_block_dev->st_mode)) {
			log_error("A non-block device file at '%s' "
				  "is already present", newpath);
			return 0;
		}
		else if (_warn_if_op_needed(warn_if_udev_failed)) {
			if (lstat(oldpath, &info) < 0 &&
				 errno == ENOENT)
				/* assume udev already deleted this */
				return 1;
			else {
				log_warn("The node %s should have been renamed to %s "
					 "by udev but old node is still present. "
					 "Falling back to direct old node removal.",
					 oldpath, newpath);
				return _rm_dev_node(old_name, 0);
			}
		}

		if (unlink(newpath) < 0) {
			if (errno == EPERM) {
				/* devfs, entry has already been renamed */
				return 1;
			}
			log_error("Unable to unlink device node for '%s'",
				  new_name);
			return 0;
		}
	}
	else if (_warn_if_op_needed(warn_if_udev_failed))
		log_warn("The node %s should have been renamed to %s "
			 "by udev but new node is not present. "
			 "Falling back to direct node rename.",
			 oldpath, newpath);

	/* udev may already have renamed the node. Ignore ENOENT. */
	/* FIXME: when renaming to target mangling mode "none" with udev
	 * while there are some blacklisted characters in the node name,
	 * udev will remove the old_node, but fails to properly rename
	 * to new_node. The libdevmapper code tries to call
	 * rename(old_node,new_node), but that won't do anything
	 * since the old node is already removed by udev.
	 * For example renaming 'a\x20b' to 'a b':
	 *   - udev removes 'a\x20b'
	 *   - udev creates 'a' and 'b' (since it considers the ' ' as a delimiter
	 *   - libdevmapper checks udev has done the rename properly
	 *   - libdevmapper calls stat(new_node) and it does not see it
	 *   - libdevmapper calls rename(old_node,new_node)
	 *   - the rename is a NOP since the old_node does not exist anymore
	 *
	 * However, this situation is very rare - why would anyone need
	 * to rename to an unsupported mode??? So a fix for this would be
	 * just for completeness.
	 */
	if (rename(oldpath, newpath) < 0 && errno != ENOENT) {
		log_error("Unable to rename device node from '%s' to '%s'",
			  old_name, new_name);
		return 0;
	}

	log_debug_activation("Renamed %s to %s", oldpath, newpath);

	return 1;
}

#ifdef __linux__
static int _open_dev_node(const char *dev_name)
{
	int fd = -1;
	char path[PATH_MAX];

	if (!_build_dev_path(path, sizeof(path), dev_name))
		return fd;

	if ((fd = open(path, O_RDONLY, 0)) < 0)
		log_sys_error("open", path);

	return fd;
}

int get_dev_node_read_ahead(const char *dev_name, uint32_t major, uint32_t minor,
			    uint32_t *read_ahead)
{
	char buf[24];
	int len;
	int r = 1;
	int fd;
	long read_ahead_long;

	/*
	 * If we know the device number, use sysfs if we can.
	 * Otherwise use BLKRAGET ioctl.
	 */
	if (*_sysfs_dir && major != 0) {
		if (dm_snprintf(_path0, sizeof(_path0), "%sdev/block/%" PRIu32
				":%" PRIu32 "/bdi/read_ahead_kb", _sysfs_dir,
				major, minor) < 0) {
			log_error("Failed to build sysfs_path.");
			return 0;
		}

		if ((fd = open(_path0, O_RDONLY, 0)) != -1) {
			/* Reading from sysfs, expecting number\n */
			if ((len = read(fd, buf, sizeof(buf) - 1)) < 1) {
				log_sys_error("read", _path0);
				r = 0;
			} else {
				buf[len] = 0; /* kill \n and ensure \0 */
				*read_ahead = atoi(buf) * 2;
				log_debug_activation("%s (%d:%d): read ahead is %" PRIu32,
						     dev_name, major, minor, *read_ahead);
			}

			if (close(fd))
				log_sys_debug("close", _path0);

			return r;
		}

		log_sys_debug("open", _path0);
		/* Fall back to use dev_name */
	}

	/*
	 * Open/close dev_name may block the process
	 * (i.e. overfilled thin pool volume)
	 */
	if (!*dev_name) {
		log_error("Empty device name passed to BLKRAGET");
		return 0;
	}

	if ((fd = _open_dev_node(dev_name)) < 0)
		return_0;

	if (ioctl(fd, BLKRAGET, &read_ahead_long)) {
		log_sys_error("BLKRAGET", dev_name);
		*read_ahead = 0;
		r = 0;
	} else {
		*read_ahead = (uint32_t) read_ahead_long;
		log_debug_activation("%s: read ahead is %" PRIu32, dev_name, *read_ahead);
	}

	if (close(fd))
		log_sys_debug("close", dev_name);

	return r;
}

static int _set_read_ahead(const char *dev_name, uint32_t major, uint32_t minor,
			   uint32_t read_ahead)
{
	char buf[24];
	int len;
	int r = 1;
	int fd;
	long read_ahead_long = (long) read_ahead;

	log_debug_activation("%s (%d:%d): Setting read ahead to %" PRIu32, dev_name,
			     major, minor, read_ahead);

	/*
	 * If we know the device number, use sysfs if we can.
	 * Otherwise use BLKRASET ioctl. RA is set after resume.
	 */
	if (*_sysfs_dir && major != 0) {
		if (dm_snprintf(_path0, sizeof(_path0), "%sdev/block/%" PRIu32
				":%" PRIu32 "/bdi/read_ahead_kb",
				_sysfs_dir, major, minor) < 0) {
			log_error("Failed to build sysfs_path.");
			return 0;
		}

		/* Sysfs is kB based, round up to kB */
		if ((len = dm_snprintf(buf, sizeof(buf), FMTu32,
				       (read_ahead + 1) / 2)) < 0) {
			log_error("Failed to build size in kB.");
			return 0;
		}

		if ((fd = open(_path0, O_WRONLY, 0)) != -1) {
			if (write(fd, buf, len) < len) {
				log_sys_error("write", _path0);
				r = 0;
			}

			if (close(fd))
				log_sys_debug("close", _path0);

			return r;
		}

		log_sys_debug("open", _path0);
		/* Fall back to use dev_name */
	}

	if (!*dev_name) {
		log_error("Empty device name passed to BLKRAGET");
		return 0;
	}

	if ((fd = _open_dev_node(dev_name)) < 0)
		return_0;

	if (ioctl(fd, BLKRASET, read_ahead_long)) {
		log_sys_error("BLKRASET", dev_name);
		r = 0;
	}

	if (close(fd))
		log_sys_debug("close", dev_name);

	return r;
}

static int _set_dev_node_read_ahead(const char *dev_name,
				    uint32_t major, uint32_t minor,
				    uint32_t read_ahead, uint32_t read_ahead_flags)
{
	uint32_t current_read_ahead;

	if (read_ahead == DM_READ_AHEAD_AUTO)
		return 1;

	if (read_ahead == DM_READ_AHEAD_NONE)
		read_ahead = 0;

	if (read_ahead_flags & DM_READ_AHEAD_MINIMUM_FLAG) {
		if (!get_dev_node_read_ahead(dev_name, major, minor, &current_read_ahead))
			return_0;

		if (current_read_ahead >= read_ahead) {
			log_debug_activation("%s: retaining kernel read ahead of %" PRIu32
				  " (requested %" PRIu32 ")",           
				  dev_name, current_read_ahead, read_ahead);
			return 1;
		}
	}

	return _set_read_ahead(dev_name, major, minor, read_ahead);
}

#else

int get_dev_node_read_ahead(const char *dev_name, uint32_t *read_ahead)
{
	*read_ahead = 0;

	return 1;
}

static int _set_dev_node_read_ahead(const char *dev_name,
				    uint32_t major, uint32_t minor,
				    uint32_t read_ahead, uint32_t read_ahead_flags)
{
	return 1;
}
#endif

typedef enum {
	NODE_ADD,
	NODE_DEL,
	NODE_RENAME,
	NODE_READ_AHEAD,
	NUM_NODES
} node_op_t;

static int _do_node_op(node_op_t type, const char *dev_name, uint32_t major,
		       uint32_t minor, uid_t uid, gid_t gid, mode_t mode,
		       const char *old_name, uint32_t read_ahead,
		       uint32_t read_ahead_flags, int warn_if_udev_failed)
{
	switch (type) {
	case NODE_ADD:
		return _add_dev_node(dev_name, major, minor, uid, gid,
				     mode, warn_if_udev_failed);
	case NODE_DEL:
		return _rm_dev_node(dev_name, warn_if_udev_failed);
	case NODE_RENAME:
		return _rename_dev_node(old_name, dev_name, warn_if_udev_failed);
	case NODE_READ_AHEAD:
		return _set_dev_node_read_ahead(dev_name, major, minor,
						read_ahead, read_ahead_flags);
	default:
		; /* NOTREACHED */
	}

	return 1;
}

static DM_LIST_INIT(_node_ops);
static int _count_node_ops[NUM_NODES];

struct node_op_parms {
	struct dm_list list;
	node_op_t type;
	char *dev_name;
	uint32_t major;
	uint32_t minor;
	uid_t uid;
	gid_t gid;
	mode_t mode;
	uint32_t read_ahead;
	uint32_t read_ahead_flags;
	char *old_name;
	int warn_if_udev_failed;
	unsigned rely_on_udev;
	char names[0];
};

static void _store_str(char **pos, char **ptr, const char *str)
{
	strcpy(*pos, str);
	*ptr = *pos;
	*pos += strlen(*ptr) + 1;
}

static void _del_node_op(struct node_op_parms *nop)
{
	_count_node_ops[nop->type]--;
	dm_list_del(&nop->list);
	dm_free(nop);

}

/* Check if there is other the type of node operation stacked */
static int _other_node_ops(node_op_t type)
{
	unsigned i;

	for (i = 0; i < NUM_NODES; i++)
		if (type != i && _count_node_ops[i])
			return 1;
	return 0;
}

static void _log_node_op(const char *action_str, struct node_op_parms *nop)
{
	const char *rely = nop->rely_on_udev ? " [trust_udev]" : "" ;
	const char *verify = nop->warn_if_udev_failed ? " [verify_udev]" : "";

	switch (nop->type) {
	case NODE_ADD:
		log_debug_activation("%s: %s NODE_ADD (%" PRIu32 ",%" PRIu32 ") %u:%u 0%o%s%s",
				     nop->dev_name, action_str, nop->major, nop->minor, nop->uid, nop->gid, nop->mode,
				     rely, verify);
		break;
	case NODE_DEL:
		log_debug_activation("%s: %s NODE_DEL%s%s", nop->dev_name, action_str, rely, verify);
		break;
	case NODE_RENAME:
		log_debug_activation("%s: %s NODE_RENAME to %s%s%s", nop->old_name, action_str, nop->dev_name, rely, verify);
		break;
	case NODE_READ_AHEAD:
		log_debug_activation("%s: %s NODE_READ_AHEAD %" PRIu32 " (flags=%" PRIu32 ")%s%s",
				     nop->dev_name, action_str, nop->read_ahead, nop->read_ahead_flags, rely, verify);
		break;
	default:
		; /* NOTREACHED */
	}
}

static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major,
			  uint32_t minor, uid_t uid, gid_t gid, mode_t mode,
			  const char *old_name, uint32_t read_ahead,
			  uint32_t read_ahead_flags, int warn_if_udev_failed,
			  unsigned rely_on_udev)
{
	struct node_op_parms *nop;
	struct dm_list *noph, *nopht;
	size_t len = strlen(dev_name) + strlen(old_name) + 2;
	char *pos;

	/*
	 * Note: warn_if_udev_failed must have valid content
	 */
	if ((type == NODE_DEL) && _other_node_ops(type))
		/*
		 * Ignore any outstanding operations on the node if deleting it.
		 */
		dm_list_iterate_safe(noph, nopht, &_node_ops) {
			nop = dm_list_item(noph, struct node_op_parms);
			if (!strcmp(dev_name, nop->dev_name)) {
				_log_node_op("Unstacking", nop);
				_del_node_op(nop);
				if (!_other_node_ops(type))
					break; /* no other non DEL ops */
			}
		}
	else if ((type == NODE_ADD) && _count_node_ops[NODE_DEL])
		/*
		 * Ignore previous DEL operation on added node.
		 * (No other operations for this device then DEL could be stacked here).
		 */
		dm_list_iterate_safe(noph, nopht, &_node_ops) {
			nop = dm_list_item(noph, struct node_op_parms);
			if ((nop->type == NODE_DEL) &&
			    !strcmp(dev_name, nop->dev_name)) {
				_log_node_op("Unstacking", nop);
				_del_node_op(nop);
				break; /* no other DEL ops */
			}
		}
	else if (type == NODE_RENAME)
		/*
		 * Ignore any outstanding operations if renaming it.
		 *
		 * Currently  RENAME operation happens through 'suspend -> resume'.
		 * On 'resume' device is added with read_ahead settings, so it is
		 * safe to remove any stacked ADD, RENAME, READ_AHEAD operation
		 * There cannot be any DEL operation on the renamed device.
		 */
		dm_list_iterate_safe(noph, nopht, &_node_ops) {
			nop = dm_list_item(noph, struct node_op_parms);
			if (!strcmp(old_name, nop->dev_name)) {
				_log_node_op("Unstacking", nop);
				_del_node_op(nop);
			}
		}
	else if (type == NODE_READ_AHEAD) {
		/* udev doesn't process readahead */
		rely_on_udev = 0;
		warn_if_udev_failed = 0;
	}

	if (!(nop = dm_malloc(sizeof(*nop) + len))) {
		log_error("Insufficient memory to stack mknod operation");
		return 0;
	}

	pos = nop->names;
	nop->type = type;
	nop->major = major;
	nop->minor = minor;
	nop->uid = uid;
	nop->gid = gid;
	nop->mode = mode;
	nop->read_ahead = read_ahead;
	nop->read_ahead_flags = read_ahead_flags;
	nop->rely_on_udev = rely_on_udev;

	/*
	 * Clear warn_if_udev_failed if rely_on_udev is set.  It doesn't get
	 * checked in this case - this just removes the flag from log messages.
	 */
	nop->warn_if_udev_failed = rely_on_udev ? 0 : warn_if_udev_failed;

	_store_str(&pos, &nop->dev_name, dev_name);
	_store_str(&pos, &nop->old_name, old_name);

	_count_node_ops[type]++;
	dm_list_add(&_node_ops, &nop->list);

	_log_node_op("Stacking", nop);

	return 1;
}

static void _pop_node_ops(void)
{
	struct dm_list *noph, *nopht;
	struct node_op_parms *nop;

	dm_list_iterate_safe(noph, nopht, &_node_ops) {
		nop = dm_list_item(noph, struct node_op_parms);
		if (!nop->rely_on_udev) {
			_log_node_op("Processing", nop);
			_do_node_op(nop->type, nop->dev_name, nop->major, nop->minor,
				    nop->uid, nop->gid, nop->mode, nop->old_name,
				    nop->read_ahead, nop->read_ahead_flags,
				    nop->warn_if_udev_failed);
		} else
			_log_node_op("Skipping", nop);
		_del_node_op(nop);
	}
}

int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
		 uid_t uid, gid_t gid, mode_t mode, int check_udev, unsigned rely_on_udev)
{
	return _stack_node_op(NODE_ADD, dev_name, major, minor, uid,
			      gid, mode, "", 0, 0, check_udev, rely_on_udev);
}

int rename_dev_node(const char *old_name, const char *new_name, int check_udev, unsigned rely_on_udev)
{
	return _stack_node_op(NODE_RENAME, new_name, 0, 0, 0,
			      0, 0, old_name, 0, 0, check_udev, rely_on_udev);
}

int rm_dev_node(const char *dev_name, int check_udev, unsigned rely_on_udev)
{
	return _stack_node_op(NODE_DEL, dev_name, 0, 0, 0,
			      0, 0, "", 0, 0, check_udev, rely_on_udev);
}

int set_dev_node_read_ahead(const char *dev_name,
                            uint32_t major, uint32_t minor,
			    uint32_t read_ahead, uint32_t read_ahead_flags)
{
	if (read_ahead == DM_READ_AHEAD_AUTO)
		return 1;

	return _stack_node_op(NODE_READ_AHEAD, dev_name, major, minor, 0, 0,
                              0, "", read_ahead, read_ahead_flags, 0, 0);
}

void update_devs(void)
{
	_pop_node_ops();
}

static int _canonicalize_and_set_dir(const char *src, const char *suffix, size_t max_len, char *dir)
{
	size_t len;
	const char *slash;

	if (*src != '/') {
		log_debug_activation("Invalid directory value, %s: "
				     "not an absolute name.", src);
		return 0;
	}

	len = strlen(src);
	slash = src[len-1] == '/' ? "" : "/";

	if (dm_snprintf(dir, max_len, "%s%s%s", src, slash, suffix ? suffix : "") < 0) {
		log_debug_activation("Invalid directory value, %s: name too long.", src);
		return 0;
	}

	return 1;
}

int dm_set_dev_dir(const char *dev_dir)
{
	return _canonicalize_and_set_dir(dev_dir, DM_DIR, sizeof _dm_dir, _dm_dir);
}

const char *dm_dir(void)
{
	return _dm_dir;
}

int dm_set_sysfs_dir(const char *sysfs_dir)
{
	if (!sysfs_dir || !*sysfs_dir) {
		_sysfs_dir[0] = '\0';
		return 1;
	}

	return _canonicalize_and_set_dir(sysfs_dir, NULL, sizeof _sysfs_dir, _sysfs_dir);
}

const char *dm_sysfs_dir(void)
{
	return _sysfs_dir;
}

/*
 * Replace existing uuid_prefix provided it isn't too long.
 */
int dm_set_uuid_prefix(const char *uuid_prefix)
{
	if (!uuid_prefix)
		return_0;

	if (strlen(uuid_prefix) > DM_MAX_UUID_PREFIX_LEN) {
		log_error("New uuid prefix %s too long.", uuid_prefix);
		return 0;
	}

	strcpy(_default_uuid_prefix, uuid_prefix);

	return 1;
}

const char *dm_uuid_prefix(void)
{
	return _default_uuid_prefix;
}

static int _is_octal(int a)
{
	return (((a) & ~7) == '0');
}

/* Convert mangled mountinfo into normal ASCII string */
static void _unmangle_mountinfo_string(const char *src, char *buf)
{
	while (*src) {
		if ((*src == '\\') &&
		    _is_octal(src[1]) && _is_octal(src[2]) && _is_octal(src[3])) {
			*buf++ = 64 * (src[1] & 7) + 8 * (src[2] & 7) + (src[3] & 7);
			src += 4;
		} else
			*buf++ = *src++;
	}
	*buf = '\0';
}

/* Parse one line of mountinfo and unmangled target line */
static int _mountinfo_parse_line(const char *line, unsigned *maj, unsigned *min, char *buf)
{
	char root[PATH_MAX + 1]; /* sscanf needs extra '\0' */
	char target[PATH_MAX + 1];

	/* TODO: maybe detect availability of  %ms  glib support ? */
	if (sscanf(line, "%*u %*u %u:%u %" DM_TO_STRING(PATH_MAX)
		   "s %" DM_TO_STRING(PATH_MAX) "s",
		   maj, min, root, target) < 4) {
		log_error("Failed to parse mountinfo line.");
		return 0;
	}

	_unmangle_mountinfo_string(target, buf);

	return 1;
}

/*
 * Function to operate on individal mountinfo line,
 * minor, major and mount target are parsed and unmangled
 */
int dm_mountinfo_read(dm_mountinfo_line_callback_fn read_fn, void *cb_data)
{
	FILE *minfo;
	char buffer[2 * PATH_MAX];
	char target[PATH_MAX];
	unsigned maj, min;
	int r = 1;

	if (!(minfo = fopen(_mountinfo, "r"))) {
		if (errno != ENOENT)
			log_sys_error("fopen", _mountinfo);
		else
			log_sys_debug("fopen", _mountinfo);
		return 0;
	}

	while (!feof(minfo) && fgets(buffer, sizeof(buffer), minfo))
		if (!_mountinfo_parse_line(buffer, &maj, &min, target) ||
		    !read_fn(buffer, maj, min, target, cb_data)) {
			stack;
			r = 0;
			break;
		}

	if (fclose(minfo))
		log_sys_error("fclose", _mountinfo);

	return r;
}

static int _sysfs_get_dm_name(uint32_t major, uint32_t minor, char *buf, size_t buf_size)
{
	char *sysfs_path, *temp_buf = NULL;
	FILE *fp = NULL;
	int r = 0;
	size_t len;

	if (!(sysfs_path = dm_malloc(PATH_MAX)) ||
	    !(temp_buf = dm_malloc(PATH_MAX))) {
		log_error("_sysfs_get_dm_name: failed to allocate temporary buffers");
		goto bad;
	}

	if (dm_snprintf(sysfs_path, PATH_MAX, "%sdev/block/%" PRIu32 ":%" PRIu32
			"/dm/name", _sysfs_dir, major, minor) < 0) {
		log_error("_sysfs_get_dm_name: dm_snprintf failed");
		goto bad;
	}

	if (!(fp = fopen(sysfs_path, "r"))) {
		if (errno != ENOENT)
			log_sys_error("fopen", sysfs_path);
		else
			log_sys_debug("fopen", sysfs_path);
		goto bad;
	}

	if (!fgets(temp_buf, PATH_MAX, fp)) {
		log_sys_error("fgets", sysfs_path);
		goto bad;
	}

	len = strlen(temp_buf);

	if (len > buf_size) {
		log_error("_sysfs_get_dm_name: supplied buffer too small");
		goto bad;
	}

	temp_buf[len ? len - 1 : 0] = '\0'; /* \n */
	strcpy(buf, temp_buf);
	r = 1;
bad:
	if (fp && fclose(fp))
		log_sys_error("fclose", sysfs_path);

	dm_free(temp_buf);
	dm_free(sysfs_path);

	return r;
}

static int _sysfs_get_kernel_name(uint32_t major, uint32_t minor, char *buf, size_t buf_size)
{
	char *name, *sysfs_path, *temp_buf = NULL;
	ssize_t size;
	size_t len;
	int r = 0;

	if (!(sysfs_path = dm_malloc(PATH_MAX)) ||
	    !(temp_buf = dm_malloc(PATH_MAX))) {
		log_error("_sysfs_get_kernel_name: failed to allocate temporary buffers");
		goto bad;
	}

	if (dm_snprintf(sysfs_path, PATH_MAX, "%sdev/block/%" PRIu32 ":%" PRIu32,
			_sysfs_dir, major, minor) < 0) {
		log_error("_sysfs_get_kernel_name: dm_snprintf failed");
		goto bad;
	}

	if ((size = readlink(sysfs_path, temp_buf, PATH_MAX - 1)) < 0) {
		if (errno != ENOENT)
			log_sys_error("readlink", sysfs_path);
		else
			log_sys_debug("readlink", sysfs_path);
		goto bad;
	}
	temp_buf[size] = '\0';

	if (!(name = strrchr(temp_buf, '/'))) {
		log_error("Could not locate device kernel name in sysfs path %s", temp_buf);
		goto bad;
	}
	name += 1;
	len = size - (name - temp_buf) + 1;

	if (len > buf_size) {
		log_error("_sysfs_get_kernel_name: output buffer too small");
		goto bad;
	}

	strcpy(buf, name);
	r = 1;
bad:
	dm_free(temp_buf);
	dm_free(sysfs_path);

	return r;
}

int dm_device_get_name(uint32_t major, uint32_t minor, int prefer_kernel_name,
		       char *buf, size_t buf_size)
{
	if (!*_sysfs_dir)
		return 0;

	/*
	 * device-mapper devices and prefer_kernel_name = 0
	 * get dm name by reading /sys/dev/block/major:minor/dm/name,
	 * fallback to _sysfs_get_kernel_name if not successful
	 */
	if (dm_is_dm_major(major) && !prefer_kernel_name) {
		if (_sysfs_get_dm_name(major, minor, buf, buf_size))
			return 1;
		else
			stack;
	}

	/*
	 * non-device-mapper devices or prefer_kernel_name = 1
	 * get kernel name using readlink /sys/dev/block/major:minor -> .../dm-X
	 */
	return _sysfs_get_kernel_name(major, minor, buf, buf_size);
}

int dm_device_has_holders(uint32_t major, uint32_t minor)
{
	char sysfs_path[PATH_MAX];
	struct stat st;

	if (!*_sysfs_dir)
		return 0;

	if (dm_snprintf(sysfs_path, PATH_MAX, "%sdev/block/%" PRIu32
			":%" PRIu32 "/holders", _sysfs_dir, major, minor) < 0) {
		log_error("sysfs_path dm_snprintf failed");
		return 0;
	}

	if (stat(sysfs_path, &st)) {
		if (errno != ENOENT)
			log_sys_error("stat", sysfs_path);
		return 0;
	}

	return !dm_is_empty_dir(sysfs_path);
}

static int _mounted_fs_on_device(const char *kernel_dev_name)
{
	char sysfs_path[PATH_MAX];
	struct dirent *dirent;
	DIR *d;
	struct stat st;
	int r = 0;

	if (dm_snprintf(sysfs_path, PATH_MAX, "%sfs", _sysfs_dir) < 0) {
		log_error("sysfs_path dm_snprintf failed");
		return 0;
	}

	if (!(d = opendir(sysfs_path))) {
		if (errno != ENOENT)
			log_sys_error("opendir", sysfs_path);
		return 0;
	}

	while ((dirent = readdir(d))) {
		if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, ".."))
			continue;

		if (dm_snprintf(sysfs_path, PATH_MAX, "%sfs/%s/%s",
				_sysfs_dir, dirent->d_name, kernel_dev_name) < 0) {
			log_error("sysfs_path dm_snprintf failed");
			break;
		}

		if (!stat(sysfs_path, &st)) {
			/* found! */
			r = 1;
			break;
		}
		else if (errno != ENOENT) {
			log_sys_error("stat", sysfs_path);
			break;
		}
	}

	if (closedir(d))
		log_error("_fs_present_on_device: %s: closedir failed", kernel_dev_name);

	return r;
}

struct mountinfo_s {
	unsigned maj;
	unsigned min;
	int mounted;
};

static int _device_has_mounted_fs(char *buffer, unsigned major, unsigned minor,
				  char *target, void *cb_data)
{
	struct mountinfo_s *data = cb_data;
	char kernel_dev_name[PATH_MAX];

	if ((major == data->maj) && (minor == data->min)) {
		if (!dm_device_get_name(major, minor, 1, kernel_dev_name,
					sizeof(kernel_dev_name))) {
			stack;
			*kernel_dev_name = '\0';
		}
		log_verbose("Device %s (%u:%u) appears to be mounted on %s.",
			    kernel_dev_name, major, minor, target);
		data->mounted = 1;
	}

	return 1;
}

int dm_device_has_mounted_fs(uint32_t major, uint32_t minor)
{
	char kernel_dev_name[PATH_MAX];
	struct mountinfo_s data = {
		.maj = major,
		.min = minor,
	};

	if (!dm_mountinfo_read(_device_has_mounted_fs, &data))
		stack;

	if (data.mounted)
		return 1;
	/*
	 * TODO: Verify dm_mountinfo_read() is superset
	 * and remove sysfs check (namespaces)
	 */
	/* Get kernel device name first */
	if (!dm_device_get_name(major, minor, 1, kernel_dev_name, PATH_MAX))
		return 0;

	/* Check /sys/fs/<fs_name>/<kernel_dev_name> presence */
	return _mounted_fs_on_device(kernel_dev_name);
}

int dm_mknodes(const char *name)
{
	struct dm_task *dmt;
	int r = 0;

	if (!(dmt = dm_task_create(DM_DEVICE_MKNODES)))
		return 0;

	if (name && !dm_task_set_name(dmt, name))
		goto out;

	if (!dm_task_no_open_count(dmt))
		goto out;

	r = dm_task_run(dmt);

out:
	dm_task_destroy(dmt);
	return r;
}

int dm_driver_version(char *version, size_t size)
{
	struct dm_task *dmt;
	int r = 0;

	if (!(dmt = dm_task_create(DM_DEVICE_VERSION)))
		return 0;

	if (!dm_task_run(dmt))
		log_error("Failed to get driver version");

	if (!dm_task_get_driver_version(dmt, version, size))
		goto out;

	r = 1;

out:
	dm_task_destroy(dmt);
	return r;
}

static void _set_cookie_flags(struct dm_task *dmt, uint16_t flags)
{
	if (!dm_cookie_supported())
		return;

	if (_udev_disabled) {
		/*
		 * If udev is disabled, hardcode this functionality:
		 *   - we want libdm to create the nodes
		 *   - we don't want the /dev/mapper and any subsystem
		 *     related content to be created by udev if udev
		 *     rules are installed
		 */
		flags &= ~DM_UDEV_DISABLE_LIBRARY_FALLBACK;
		flags |= DM_UDEV_DISABLE_DM_RULES_FLAG | DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG;
	}

	dmt->event_nr = flags << DM_UDEV_FLAGS_SHIFT;
}

#ifndef UDEV_SYNC_SUPPORT
void dm_udev_set_sync_support(int sync_with_udev)
{
}

int dm_udev_get_sync_support(void)
{
	return 0;
}

void dm_udev_set_checking(int checking)
{
}

int dm_udev_get_checking(void)
{
	return 0;
}

int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags)
{
	_set_cookie_flags(dmt, flags);

	*cookie = 0;
	dmt->cookie_set = 1;

	return 1;
}

int dm_udev_complete(uint32_t cookie)
{
	return 1;
}

int dm_udev_wait(uint32_t cookie)
{
	update_devs();

	return 1;
}

int dm_udev_wait_immediate(uint32_t cookie, int *ready)
{
	update_devs();
	*ready = 1;

	return 1;
}

#else		/* UDEV_SYNC_SUPPORT */

static int _check_semaphore_is_supported(void)
{
	int maxid;
	union semun arg;
	struct seminfo seminfo;

	arg.__buf = &seminfo;
	maxid = semctl(0, 0, SEM_INFO, arg);

	if (maxid < 0) {
		log_warn("Kernel not configured for semaphores (System V IPC). "
			 "Not using udev synchronisation code.");
		return 0;
	}

	return 1;
}

static int _check_udev_is_running(void)
{
	struct udev *udev;
	struct udev_queue *udev_queue;
	int r;

	if (!(udev = udev_new()))
		goto_bad;

	if (!(udev_queue = udev_queue_new(udev))) {
		udev_unref(udev);
		goto_bad;
	}

	if (!(r = udev_queue_get_udev_is_active(udev_queue)))
		log_debug_activation("Udev is not running. "
				     "Not using udev synchronisation code.");

	udev_queue_unref(udev_queue);
	udev_unref(udev);

	return r;

bad:
	log_error("Could not get udev state. Assuming udev is not running.");
	return 0;
}

static void _check_udev_sync_requirements_once(void)
{
	if (_semaphore_supported < 0)
		_semaphore_supported = _check_semaphore_is_supported();

	if (_udev_running < 0) {
		_udev_running = _check_udev_is_running();
		if (_udev_disabled && _udev_running)
			log_warn("Udev is running and DM_DISABLE_UDEV environment variable is set. "
				 "Bypassing udev, device-mapper library will manage device "
				 "nodes in device directory.");
	}
}

void dm_udev_set_sync_support(int sync_with_udev)
{
	_check_udev_sync_requirements_once();
	_sync_with_udev = sync_with_udev;
}

int dm_udev_get_sync_support(void)
{
	_check_udev_sync_requirements_once();

	return !_udev_disabled && _semaphore_supported &&
		dm_cookie_supported() &&_udev_running && _sync_with_udev;
}

void dm_udev_set_checking(int checking)
{
	if ((_udev_checking = checking))
		log_debug_activation("DM udev checking enabled");
	else
		log_debug_activation("DM udev checking disabled");
}

int dm_udev_get_checking(void)
{
	return _udev_checking;
}

static int _get_cookie_sem(uint32_t cookie, int *semid)
{
	if (cookie >> 16 != DM_COOKIE_MAGIC) {
		log_error("Could not continue to access notification "
			  "semaphore identified by cookie value %"
			  PRIu32 " (0x%x). Incorrect cookie prefix.",
			  cookie, cookie);
		return 0;
	}

	if ((*semid = semget((key_t) cookie, 1, 0)) >= 0)
		return 1;

	switch (errno) {
		case ENOENT:
			log_error("Could not find notification "
				  "semaphore identified by cookie "
				  "value %" PRIu32 " (0x%x)",
				  cookie, cookie);
			break;
		case EACCES:
			log_error("No permission to access "
				  "notificaton semaphore identified "
				  "by cookie value %" PRIu32 " (0x%x)",
				  cookie, cookie);
			break;
		default:
			log_error("Failed to access notification "
				   "semaphore identified by cookie "
				   "value %" PRIu32 " (0x%x): %s",
				  cookie, cookie, strerror(errno));
			break;
	}

	return 0;
}

static int _udev_notify_sem_inc(uint32_t cookie, int semid)
{
	struct sembuf sb = {0, 1, 0};
	int val;

	if (semop(semid, &sb, 1) < 0) {
		log_error("semid %d: semop failed for cookie 0x%" PRIx32 ": %s",
			  semid, cookie, strerror(errno));
		return 0;
	}

 	if ((val = semctl(semid, 0, GETVAL)) < 0) {
		log_error("semid %d: sem_ctl GETVAL failed for "
			  "cookie 0x%" PRIx32 ": %s",
			  semid, cookie, strerror(errno));
		return 0;		
	}

	log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) incremented to %d",
		  cookie, semid, val);

	return 1;
}

static int _udev_notify_sem_dec(uint32_t cookie, int semid)
{
	struct sembuf sb = {0, -1, IPC_NOWAIT};
	int val;

 	if ((val = semctl(semid, 0, GETVAL)) < 0) {
		log_error("semid %d: sem_ctl GETVAL failed for "
			  "cookie 0x%" PRIx32 ": %s",
			  semid, cookie, strerror(errno));
		return 0;
	}

	if (semop(semid, &sb, 1) < 0) {
		switch (errno) {
			case EAGAIN:
				log_error("semid %d: semop failed for cookie "
					  "0x%" PRIx32 ": "
					  "incorrect semaphore state",
					  semid, cookie);
				break;
			default:
				log_error("semid %d: semop failed for cookie "
					  "0x%" PRIx32 ": %s",
					  semid, cookie, strerror(errno));
				break;
		}
		return 0;
	}

	log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) decremented to %d",
			     cookie, semid, val - 1);

	return 1;
}

static int _udev_notify_sem_destroy(uint32_t cookie, int semid)
{
	if (semctl(semid, 0, IPC_RMID, 0) < 0) {
		log_error("Could not cleanup notification semaphore "
			  "identified by cookie value %" PRIu32 " (0x%x): %s",
			  cookie, cookie, strerror(errno));
		return 0;
	}

	log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) destroyed", cookie,
			     semid);

	return 1;
}

static int _udev_notify_sem_create(uint32_t *cookie, int *semid)
{
	int fd;
	int gen_semid;
	int val;
	uint16_t base_cookie;
	uint32_t gen_cookie;
	union semun sem_arg;

	if ((fd = open("/dev/urandom", O_RDONLY)) < 0) {
		log_error("Failed to open /dev/urandom "
			  "to create random cookie value");
		*cookie = 0;
		return 0;
	}

	/* Generate random cookie value. Be sure it is unique and non-zero. */
	do {
		/* FIXME Handle non-error returns from read(). Move _io() into libdm? */
		if (read(fd, &base_cookie, sizeof(base_cookie)) != sizeof(base_cookie)) {
			log_error("Failed to initialize notification cookie");
			goto bad;
		}

		gen_cookie = DM_COOKIE_MAGIC << 16 | base_cookie;

		if (base_cookie && (gen_semid = semget((key_t) gen_cookie,
				    1, 0600 | IPC_CREAT | IPC_EXCL)) < 0) {
			switch (errno) {
				case EEXIST:
					/* if the semaphore key exists, we
					 * simply generate another random one */
					base_cookie = 0;
					break;
				case ENOMEM:
					log_error("Not enough memory to create "
						  "notification semaphore");
					goto bad;
				case ENOSPC:
					log_error("Limit for the maximum number "
						  "of semaphores reached. You can "
						  "check and set the limits in "
						  "/proc/sys/kernel/sem.");
					goto bad;
				default:
					log_error("Failed to create notification "
						  "semaphore: %s", strerror(errno));
					goto bad;
			}
		}
	} while (!base_cookie);

	log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) created",
			     gen_cookie, gen_semid);

	sem_arg.val = 1;

	if (semctl(gen_semid, 0, SETVAL, sem_arg) < 0) {
		log_error("semid %d: semctl failed: %s", gen_semid, strerror(errno));
		/* We have to destroy just created semaphore
		 * so it won't stay in the system. */
		(void) _udev_notify_sem_destroy(gen_cookie, gen_semid);
		goto bad;
	}

 	if ((val = semctl(gen_semid, 0, GETVAL)) < 0) {
		log_error("semid %d: sem_ctl GETVAL failed for "
			  "cookie 0x%" PRIx32 ": %s",
			  gen_semid, gen_cookie, strerror(errno));
		goto bad;
	}

	log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) incremented to %d",
			     gen_cookie, gen_semid, val);

	if (close(fd))
		stack;

	*semid = gen_semid;
	*cookie = gen_cookie;

	return 1;

bad:
	if (close(fd))
		stack;

	*cookie = 0;

	return 0;
}

int dm_udev_create_cookie(uint32_t *cookie)
{
	int semid;

	if (!dm_udev_get_sync_support()) {
		*cookie = 0;
		return 1;
	}

	return _udev_notify_sem_create(cookie, &semid);
}

static const char *_task_type_disp(int type)
{
	switch(type) {
	case DM_DEVICE_CREATE:
		return "CREATE";
        case DM_DEVICE_RELOAD:
		return "RELOAD";
        case DM_DEVICE_REMOVE:
		return "REMOVE";
        case DM_DEVICE_REMOVE_ALL:
		return "REMOVE_ALL";
        case DM_DEVICE_SUSPEND:
		return "SUSPEND";
        case DM_DEVICE_RESUME:
		return "RESUME";
        case DM_DEVICE_INFO:
		return "INFO";
        case DM_DEVICE_DEPS:
		return "DEPS";
        case DM_DEVICE_RENAME:
		return "RENAME";
        case DM_DEVICE_VERSION:
		return "VERSION";
        case DM_DEVICE_STATUS:
		return "STATUS";
        case DM_DEVICE_TABLE:
		return "TABLE";
        case DM_DEVICE_WAITEVENT:
		return "WAITEVENT";
        case DM_DEVICE_LIST:
		return "LIST";
        case DM_DEVICE_CLEAR:
		return "CLEAR";
        case DM_DEVICE_MKNODES:
		return "MKNODES";
        case DM_DEVICE_LIST_VERSIONS:
		return "LIST_VERSIONS";
        case DM_DEVICE_TARGET_MSG:
		return "TARGET_MSG";
        case DM_DEVICE_SET_GEOMETRY:
		return "SET_GEOMETRY";
	}
	return "unknown";
}

int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags)
{
	int semid;

	_set_cookie_flags(dmt, flags);

	if (!dm_udev_get_sync_support()) {
		*cookie = 0;
		dmt->cookie_set = 1;
		return 1;
	}

	if (*cookie) {
		if (!_get_cookie_sem(*cookie, &semid))
			goto_bad;
	} else if (!_udev_notify_sem_create(cookie, &semid))
		goto_bad;

	if (!_udev_notify_sem_inc(*cookie, semid)) {
		log_error("Could not set notification semaphore "
			  "identified by cookie value %" PRIu32 " (0x%x)",
			  *cookie, *cookie);
		goto bad;
	}

	dmt->event_nr |= ~DM_UDEV_FLAGS_MASK & *cookie;
	dmt->cookie_set = 1;

	log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) assigned to "
			     "%s task(%d) with flags%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s (0x%" PRIx16 ")",
			     *cookie, semid, _task_type_disp(dmt->type), dmt->type,
			     (flags & DM_UDEV_DISABLE_DM_RULES_FLAG) ? " DISABLE_DM_RULES" : "",
			     (flags & DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG) ? " DISABLE_SUBSYSTEM_RULES" : "",
			     (flags & DM_UDEV_DISABLE_DISK_RULES_FLAG) ? " DISABLE_DISK_RULES" : "",
			     (flags & DM_UDEV_DISABLE_OTHER_RULES_FLAG) ? " DISABLE_OTHER_RULES" : "",
			     (flags & DM_UDEV_LOW_PRIORITY_FLAG) ? " LOW_PRIORITY" : "",
			     (flags & DM_UDEV_DISABLE_LIBRARY_FALLBACK) ? " DISABLE_LIBRARY_FALLBACK" : "",
			     (flags & DM_UDEV_PRIMARY_SOURCE_FLAG) ? " PRIMARY_SOURCE" : "",
			     (flags & DM_SUBSYSTEM_UDEV_FLAG0) ? " SUBSYSTEM_0" : " ",
			     (flags & DM_SUBSYSTEM_UDEV_FLAG1) ? " SUBSYSTEM_1" : " ",
			     (flags & DM_SUBSYSTEM_UDEV_FLAG2) ? " SUBSYSTEM_2" : " ",
			     (flags & DM_SUBSYSTEM_UDEV_FLAG3) ? " SUBSYSTEM_3" : " ",
			     (flags & DM_SUBSYSTEM_UDEV_FLAG4) ? " SUBSYSTEM_4" : " ",
			     (flags & DM_SUBSYSTEM_UDEV_FLAG5) ? " SUBSYSTEM_5" : " ",
			     (flags & DM_SUBSYSTEM_UDEV_FLAG6) ? " SUBSYSTEM_6" : " ",
			     (flags & DM_SUBSYSTEM_UDEV_FLAG7) ? " SUBSYSTEM_7" : " ",
			     flags);

	return 1;

bad:
	dmt->event_nr = 0;
	return 0;
}

int dm_udev_complete(uint32_t cookie)
{
	int semid;

	if (!cookie || !dm_udev_get_sync_support())
		return 1;

	if (!_get_cookie_sem(cookie, &semid))
		return_0;

	if (!_udev_notify_sem_dec(cookie, semid)) {
		log_error("Could not signal waiting process using notification "
			  "semaphore identified by cookie value %" PRIu32 " (0x%x)",
			  cookie, cookie);
		return 0;
	}

	return 1;
}

/*
 * If *nowait is set, return immediately leaving it set if the semaphore
 * is not ready to be decremented to 0.  *nowait is cleared if the wait
 * succeeds.
 */
static int _udev_wait(uint32_t cookie, int *nowait)
{
	int semid;
	struct sembuf sb = {0, 0, 0};
	int val;

	if (!cookie || !dm_udev_get_sync_support())
		return 1;

	if (!_get_cookie_sem(cookie, &semid))
		return_0;

	/* Return immediately if the semaphore value exceeds 1? */
	if (*nowait) {
		if ((val = semctl(semid, 0, GETVAL)) < 0) {
			log_error("semid %d: sem_ctl GETVAL failed for "
				  "cookie 0x%" PRIx32 ": %s",
				  semid, cookie, strerror(errno));
			return 0;		
		}

		if (val > 1)
			return 1;

		*nowait = 0;
	}

	if (!_udev_notify_sem_dec(cookie, semid)) {
		log_error("Failed to set a proper state for notification "
			  "semaphore identified by cookie value %" PRIu32 " (0x%x) "
			  "to initialize waiting for incoming notifications.",
			  cookie, cookie);
		(void) _udev_notify_sem_destroy(cookie, semid);
		return 0;
	}

	log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) waiting for zero",
			     cookie, semid);

repeat_wait:
	if (semop(semid, &sb, 1) < 0) {
		if (errno == EINTR)
			goto repeat_wait;
		else if (errno == EIDRM)
			return 1;

		log_error("Could not set wait state for notification semaphore "
			  "identified by cookie value %" PRIu32 " (0x%x): %s",
			  cookie, cookie, strerror(errno));
		(void) _udev_notify_sem_destroy(cookie, semid);
		return 0;
	}

	return _udev_notify_sem_destroy(cookie, semid);
}

int dm_udev_wait(uint32_t cookie)
{
	int nowait = 0;
	int r = _udev_wait(cookie, &nowait);

	update_devs();

	return r;
}

int dm_udev_wait_immediate(uint32_t cookie, int *ready)
{
	int nowait = 1;
	int r = _udev_wait(cookie, &nowait);

	if (r && nowait) {
		*ready = 0;
		return 1;
	}

	update_devs();
	*ready = 1;

	return r;
}
#endif		/* UDEV_SYNC_SUPPORT */
