Support new DM_GET_TARGET_VERSION ioctl.

This way we can load kernel device-mapper target module before
table create ioctl.

Target version is available since kernel 5.4.
This commit is contained in:
Milan Broz
2019-10-08 13:48:50 +02:00
parent 21edd66892
commit 15f5126296
3 changed files with 41 additions and 0 deletions

View File

@@ -348,6 +348,7 @@ AC_CHECK_DECLS([dm_task_retry_remove], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([dm_task_deferred_remove], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([dm_device_has_mounted_fs], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([dm_device_has_holders], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([DM_GET_TARGET_VERSION], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([DM_UDEV_DISABLE_DISK_RULES_FLAG], [have_cookie=yes], [have_cookie=no], [#include <libdevmapper.h>])
if test "x$enable_udev" = xyes; then
if test "x$have_cookie" = xno; then

View File

@@ -221,6 +221,39 @@ static void _dm_set_integrity_compat(struct crypt_device *cd,
_dm_integrity_checked = true;
}
/* We use this for loading target module */
static void _dm_check_target(dm_target_type target_type)
{
#if HAVE_DECL_DM_GET_TARGET_VERSION
struct dm_task *dmt;
const char *target_name = NULL;
if (!(_dm_flags & DM_GET_TARGET_VERSION_SUPPORTED))
return;
if (target_type == DM_CRYPT)
target_name = DM_CRYPT_TARGET;
else if (target_type == DM_VERITY)
target_name = DM_VERITY_TARGET;
else if (target_type == DM_INTEGRITY)
target_name = DM_INTEGRITY_TARGET;
else
return;
if (!(dmt = dm_task_create(DM_GET_TARGET_VERSION)))
goto out;
if (!dm_task_set_name(dmt, target_name))
goto out;
if (!dm_task_run(dmt))
goto out;
out:
if (dmt)
dm_task_destroy(dmt);
#endif
}
static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_type)
{
struct dm_task *dmt;
@@ -239,6 +272,8 @@ static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_typ
/* Shut up DM while checking */
_quiet_log = 1;
_dm_check_target(target_type);
/* FIXME: add support to DM so it forces crypt target module load here */
if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
goto out;
@@ -259,6 +294,10 @@ static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_typ
#if HAVE_DECL_DM_TASK_DEFERRED_REMOVE
if (_dm_satisfies_version(4, 27, 0, dm_maj, dm_min, dm_patch))
_dm_flags |= DM_DEFERRED_SUPPORTED;
#endif
#if HAVE_DECL_DM_GET_TARGET_VERSION
if (_dm_satisfies_version(4, 41, 0, dm_maj, dm_min, dm_patch))
_dm_flags |= DM_GET_TARGET_VERSION_SUPPORTED;
#endif
}

View File

@@ -63,6 +63,7 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
#define DM_DEFERRED_SUPPORTED (1 << 15) /* deferred removal of device */
#define DM_INTEGRITY_RECALC_SUPPORTED (1 << 16) /* dm-integrity automatic recalculation supported */
#define DM_INTEGRITY_BITMAP_SUPPORTED (1 << 17) /* dm-integrity bitmap mode supported */
#define DM_GET_TARGET_VERSION_SUPPORTED (1 << 18) /* dm DM_GET_TARGET version ioctl supported */
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_UNKNOWN } dm_target_type;
enum tdirection { TARGET_SET = 1, TARGET_QUERY };