static int _reload_device(struct crypt_device *cd, const char *name,
			  struct crypt_dm_active_device *sdmd)
{
	int r;
	struct crypt_dm_active_device tdmd;
	struct dm_target *src, *tgt = &tdmd.segment;

	if (!cd || !cd->type || !name || !(sdmd->flags & CRYPT_ACTIVATE_REFRESH))
		return -EINVAL;

	r = dm_query_device(cd, name, DM_ACTIVE_DEVICE | DM_ACTIVE_CRYPT_CIPHER |
				  DM_ACTIVE_UUID | DM_ACTIVE_CRYPT_KEYSIZE |
				  DM_ACTIVE_CRYPT_KEY, &tdmd);
	if (r < 0) {
		log_err(cd, _("Device %s is not active."), name);
		return -EINVAL;
	}

	if (!single_segment(&tdmd) || tgt->type != DM_CRYPT || tgt->u.crypt.tag_size) {
		r = -ENOTSUP;
		log_err(cd, _("Unsupported parameters on device %s."), name);
		goto out;
	}

	r = crypt_compare_dm_devices(cd, sdmd, &tdmd);
	if (r) {
		log_err(cd, _("Mismatching parameters on device %s."), name);
		goto out;
	}

	src = &sdmd->segment;

	/* Changing read only flag for active device makes no sense */
	if (tdmd.flags & CRYPT_ACTIVATE_READONLY)
		sdmd->flags |= CRYPT_ACTIVATE_READONLY;
	else
		sdmd->flags &= ~CRYPT_ACTIVATE_READONLY;

	if (sdmd->flags & CRYPT_ACTIVATE_KEYRING_KEY) {
		r = crypt_volume_key_set_description(tgt->u.crypt.vk, src->u.crypt.vk->key_description);
		if (r)
			goto out;
	} else {
		crypt_free_volume_key(tgt->u.crypt.vk);
		tgt->u.crypt.vk = crypt_alloc_volume_key(src->u.crypt.vk->keylength, src->u.crypt.vk->key);
		if (!tgt->u.crypt.vk) {
			r = -ENOMEM;
			goto out;
		}
	}

	r = device_block_adjust(cd, src->data_device, DEV_OK,
				src->u.crypt.offset, &sdmd->size, NULL);
	if (r)
		goto out;

	tdmd.flags = sdmd->flags;
	tgt->size = tdmd.size = sdmd->size;

	r = dm_reload_device(cd, name, &tdmd, 0, 1);
out:
	dm_targets_free(cd, &tdmd);
	free(CONST_CAST(void*)tdmd.uuid);

	return r;
}
static int _reload_device(struct crypt_device *cd, const char *name,
			  struct crypt_dm_active_device *sdmd)
{
	int r;
	struct crypt_dm_active_device tdmd;
	struct dm_target *src, *tgt = &tdmd.segment;

	if (!cd || !cd->type || !name || !(sdmd->flags & CRYPT_ACTIVATE_REFRESH))
		return -EINVAL;

	r = dm_query_device(cd, name, DM_ACTIVE_DEVICE | DM_ACTIVE_CRYPT_CIPHER |
				  DM_ACTIVE_UUID | DM_ACTIVE_CRYPT_KEYSIZE |
				  DM_ACTIVE_CRYPT_KEY, &tdmd);
	if (r < 0) {
		log_err(cd, _("Device %s is not active."), name);
		return -EINVAL;
	}

	if (!single_segment(&tdmd) || tgt->type != DM_CRYPT || tgt->u.crypt.tag_size) {
		r = -ENOTSUP;
		log_err(cd, _("Unsupported parameters on device %s."), name);
		goto out;
	}

	r = crypt_compare_dm_devices(cd, sdmd, &tdmd);
	if (r) {
		log_err(cd, _("Mismatching parameters on device %s."), name);
		goto out;
	}

	src = &sdmd->segment;

	 
	if (tdmd.flags & CRYPT_ACTIVATE_READONLY)
		sdmd->flags |= CRYPT_ACTIVATE_READONLY;
	else
		sdmd->flags &= ~CRYPT_ACTIVATE_READONLY;

	if (sdmd->flags & CRYPT_ACTIVATE_KEYRING_KEY) {
		r = crypt_volume_key_set_description(tgt->u.crypt.vk, src->u.crypt.vk->key_description);
		if (r)
			goto out;
	} else {
		crypt_free_volume_key(tgt->u.crypt.vk);
		tgt->u.crypt.vk = crypt_alloc_volume_key(src->u.crypt.vk->keylength, src->u.crypt.vk->key);
		if (!tgt->u.crypt.vk) {
			r = -ENOMEM;
			goto out;
		}
	}

	r = device_block_adjust(cd, src->data_device, DEV_OK,
				src->u.crypt.offset, &sdmd->size, NULL);
	if (r)
		goto out;

	tdmd.flags = sdmd->flags;
	tgt->size = tdmd.size = sdmd->size;

	r = dm_reload_device(cd, name, &tdmd, 0, 1);
out:
	dm_targets_free(cd, &tdmd);
	free(CONST_CAST(void*)tdmd.uuid);

	return r;
}