[dm-crypt] shoulnt "crypt_init_by_name()" fail when the underlying device is no longer available?

Milan Broz gmazyland at gmail.com
Thu Nov 29 10:02:31 CET 2012

On 11/28/2012 07:29 PM, .. ink .. wrote:
>     http://wiki.cryptsetup.googlecode.com/git/API/libcryptsetup_8h.html#a99bc4160e7afacfba1d2c5ee6dbaf3be
>     "In case device points to active LUKS device but header load fails, context device type
>     is set to NULL and 0 is returned as if it were successful.
>     Context with NULL device type can only be deactivated by crypt_deactivate"
>     So the only think you can do here is deactivate device-mapper device
>     (which explains why it is needed).
> So,this function can be used to check if the underlying device is present or not.Good to know,it will be nice if the docs could say this.

In correctly (desktop) configured system this should not happen, because
e.g. udisks daemon will react to underlying device "remove" event and
will tear down all remaining top-level devices.
(cryptsetup here provides here just low-level support for it)

It is similar to MD raid5 device, where 2 or more devices disappeared
- md raid device is visible but not in operating state anymore.

> But why does this function behave this way though? Docs states this
> behavior but it doesnt say why and this gives inconsistent behavior.I
> always though checking for return value is sufficient to give
> indication if i should proceed or bail out,it almost became
> automatic.It looks like with this function,i should not check the
> return value but "cd".

You can initialize context 2 ways

1) from the device header on disk (LUKS, in future from other on-disk formats)
	crypt_init(&context, device)
		- no info about format yet, only initial "device ok" check
	crypt_load(context, [FORMAT])
		- either fail (no header, wrong params) or correctly initialized header

2) from already active DM device in kernel.
	crypt_init_by_name(&context, DM-active-name) or

	- if active DM device is not crypt or verity device, it will fail.
	- if active device is crypt or verity, but it uses unknown type
	(from DM-UUID) or the format requires initialization from on-disk
	header and that header is not readable (e.g. disappeared device)
	context is initialized but without type
	(=> the same situation as after crypt_init() before crypt_load())
	- otherwise you have full context initialized

On the other hand, with explicit header device
	crypt_init_by_name_and_header(&context, DM-active-name, device with header)

	it should fail if header device is not NULL and is not available anymore

It is a little bit confusing, but my intention was to allow basic initialization
even when you have no longer header available or if e.g. on-disk header
is encrypted (Truecrypt uses this for example) and you want just
read some info about active device or deactivate it (without providing password again).

> Let say i want to be lazy and only do one check,should checking if
> "cd" is NULL be sufficient to cover all invalid cases or its
> necessary to do bo checks to be 100% sure.

Which is not exactly correct. If you expect LUKS device, you should check
after crypt_init_by_name that you really get LUKS context and not e.g. PLAIN
(using crypt_get_type()). (But this check should be present in all LUKS API
functions, so you just get "not supported" error later if context is wrong.)

Hope this helps (I should probably extend API docs with above)

More information about the dm-crypt mailing list