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(DM_DEV_DIR_UMASK);
	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;
	}

#ifdef HAVE_SELINUX
	if (!dm_set_selinux_context(control, S_IFCHR)) {
		stack;
		return 0;
	}
#endif

	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;
}
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;
}
/* Open control device if doesn't exist create it. */
static int _open_control(void)
{
	char control[PATH_MAX];
	uint32_t major = 0, minor = 0;

	if (_control_fd != -1)
		return 1;

#ifdef RUMP_ACTION
	rump_init();
#endif
	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;
}
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(DM_DEV_DIR_UMASK);
	ret = dm_create_dir(dm_dir());
	umask(old_umask);

	if (!ret)
		return 0;

	log_verbose("Creating device %s (%u, %u)", control, major, minor);

	old_umask = umask(0);
	if (mknod(control, S_IFCHR | DM_CONTROL_DEVICE_MODE,
		  MKDEV(major, minor)) < 0)  {
		umask(old_umask);
		log_sys_error("mknod", control);
		return 0;
	}
	umask(old_umask);
	if (chown(control, DM_DEVICE_UID, DM_DEVICE_GID) == -1) {
		log_sys_error("chown", control);
		return 0;
	}


	return 1;
}
Exemple #6
0
static char *lookup_dev(const char *dev_id)
{
	uint32_t major, minor;
	dev_t dev;
	char *result = NULL, buf[PATH_MAX + 1];

	if (sscanf(dev_id, "%" PRIu32 ":%" PRIu32, &major, &minor) != 2)
		return NULL;

	dev = makedev(major, minor);
	strncpy(buf, DEVICE_DIR, PATH_MAX);
	buf[PATH_MAX] = '\0';

	/* First try low level device */
	if ((result = __lookup_dev(buf, dev, 0, 0)))
		return result;

	/* If it is dm, try DM dir  */
	if (dm_is_dm_major(major)) {
		strncpy(buf, dm_dir(), PATH_MAX);
		if ((result = __lookup_dev(buf, dev, 0, 0)))
			return result;
	}

	strncpy(buf, DEVICE_DIR, PATH_MAX);
	result = __lookup_dev(buf, dev, 0, 4);

	/* If not found, return NULL */
	return result;
}
Exemple #7
0
/* Make up a dm path. */
char *
mkdm_path(struct lib_context *lc, const char *name)
{
	char *ret;
	const char *dir = dm_dir();

	if ((ret = dbg_malloc(strlen(dir) + strlen(name) + 2)))
		sprintf(ret, "%s/%s", dir, name);
	else
		log_alloc_err(lc, __func__);

	return ret;
}
Exemple #8
0
static int _open_control(void)
{
#ifdef DM_IOCTLS
	char control[PATH_MAX];
	uint32_t major = 0, minor;

	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;
	}

	if (!_create_dm_bitset()) {
		log_error("Failed to set up list of device-mapper major numbers");
		return 0;
	}

	return 1;

error:
	log_error("Failure to communicate with kernel device-mapper driver.");
	return 0;
#else
	return 1;
#endif
}
static int _dm_names_v1(struct dm_ioctl_v1 *dmi)
{
	const char *dev_dir = dm_dir();
	int r = 1, len;
	const char *name;
	struct dirent *dirent;
	DIR *d;
	struct dm_names *names, *old_names = NULL;
	void *end = (void *) dmi + dmi->data_size;
	struct stat buf;
	char path[PATH_MAX];

	log_warn("WARNING: Device list may be incomplete with interface "
		  "version 1.");
	log_warn("Please upgrade your kernel device-mapper driver.");

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

	names = (struct dm_names *) ((void *) dmi + dmi->data_start);

	names->dev = 0;		/* Flags no data */

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

		if (name[0] == '.' || !strcmp(name, "control"))
			continue;

		if (old_names)
			old_names->next = (uint32_t) ((void *) names -
						      (void *) old_names);
		snprintf(path, sizeof(path), "%s/%s", dev_dir, name);
		if (stat(path, &buf)) {
			log_sys_error("stat", path);
			continue;
		}
		if (!S_ISBLK(buf.st_mode))
			continue;
		names->dev = (uint64_t) buf.st_rdev;
		names->next = 0;
		len = strlen(name);
		if (((void *) (names + 1) + len + 1) >= end) {
			log_error("Insufficient buffer space for device list");
			r = 0;
			break;
		}

		strcpy(names->name, name);

		old_names = names;
		names = _align((void *) ++names + len + 1, ALIGNMENT);
	}

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

	return r;
}
static int _open_control(void)
{
#ifdef DM_IOCTLS
	char control[PATH_MAX];
	uint32_t major = 0, minor;
	int dm_mod_autoload_support, needs_open;

	if (_control_fd != -1)
		return 1;

	if (!_uname())
		return 0;

	snprintf(control, sizeof(control), "%s/%s", dm_dir(), DM_CONTROL_NODE);

	/*
	 * dm-mod autoloading is supported since kernel 2.6.36.
	 * Udev daemon will try to read modules.devname file extracted
	 * by depmod and create any static nodes needed.
	 * The /dev/mapper/control node can be created and prepared this way.
	 * First access to such node should load dm-mod module automatically.
	 */
	dm_mod_autoload_support = KERNEL_VERSION(_kernel_major, _kernel_minor,
				  _kernel_release) >= KERNEL_VERSION(2, 6, 36);

	/*
	 *  If dm-mod autoloading is supported and the control node exists
	 *  already try to open it now. This should autoload dm-mod module.
	 */
	if (dm_mod_autoload_support) {
		if (!_get_proc_number(PROC_DEVICES, MISC_NAME, &major))
			/* If major not found, just fallback to hardcoded value. */
			major = MISC_MAJOR;

		/* Recreate the node with correct major and minor if needed. */
		if (!_control_exists(control, major, MAPPER_CTRL_MINOR) &&
		    !_create_control(control, major, MAPPER_CTRL_MINOR))
			goto error;

		_open_and_assign_control_fd(control, 1);
	}

	/*
	 * Get major and minor number assigned for the control node.
	 * In case we make use of the module autoload support, this
	 * information should be accessible now as well.
	 */
	if (!_control_device_number(&major, &minor))
		log_error("Is device-mapper driver missing from kernel?");

	/*
	 * Check the control node and its major and minor number.
	 * If there's anything wrong, remove the old node and create
	 * a correct one.
	 */
	if ((needs_open = !_control_exists(control, major, minor)) &&
	    !_create_control(control, major, minor)) {
		_close_control_fd();
		goto error;
	}

	/*
	 * For older kernels without dm-mod autoloading support, we always
	 * need to open the control node here - we still haven't done that!
	 * For newer kernels with dm-mod autoloading, we open it only if the
	 * node was recreated and corrected in previous step.
	 */
	if ((!dm_mod_autoload_support || needs_open) &&
	     !_open_and_assign_control_fd(control, 0))
		goto error;

	if (!_create_dm_bitset()) {
		log_error("Failed to set up list of device-mapper major numbers");
		return 0;
	}

	return 1;

error:
	log_error("Failure to communicate with kernel device-mapper driver.");
	return 0;
#else
	return 1;
#endif
}
Exemple #11
0
const char *dm_get_dir(void)
{
	return dm_dir();
}