/* 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;
}
Beispiel #2
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 _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
}