From b147676461555c869984aa4a7fd7d9e79fc6cb1f Mon Sep 17 00:00:00 2001 From: Marius Vollmer Date: Thu, 7 Mar 2024 15:46:16 +0200 Subject: [PATCH] storage: Reopen LUKS during formatting as needed --- pkg/storaged/block/format-dialog.jsx | 38 +++++++++++++++++++++------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/pkg/storaged/block/format-dialog.jsx b/pkg/storaged/block/format-dialog.jsx index 0d12e87b803e..233a441f1292 100644 --- a/pkg/storaged/block/format-dialog.jsx +++ b/pkg/storaged/block/format-dialog.jsx @@ -176,7 +176,7 @@ function format_dialog_internal(client, path, start, size, enable_dos_extended, const content_block = block.IdUsage == "crypto" ? client.blocks_cleartext[path] : block; const offer_keep_keys = block.IdUsage == "crypto"; - const unlock_before_format = offer_keep_keys && !content_block; + const unlock_before_format = offer_keep_keys && (!content_block || content_block.ReadOnly); const create_partition = (start !== undefined); @@ -494,6 +494,8 @@ function format_dialog_internal(client, path, start, size, enable_dos_extended, if (is_encrypted(vals)) { let opts = []; if (is_filesystem(vals)) { + if (vals.mount_options?.ro) + opts.push("readonly"); if (!mount_now || vals.at_boot == "never") opts.push("noauto"); if (vals.at_boot == "nofail") @@ -572,17 +574,25 @@ function format_dialog_internal(client, path, start, size, enable_dos_extended, if (config_items.length > 0) options["config-items"] = { t: 'a(sa{sv})', v: config_items }; - function maybe_unlock() { + async function maybe_unlock() { const content_block = client.blocks_cleartext[path]; - if (content_block) + if (content_block) { + if (content_block.ReadOnly) { + console.log("REOPEN read/write"); + const block_crypto = client.blocks_crypto[path]; + await block_crypto.Lock({}); + await unlock_with_type(client, block, vals.old_passphrase, existing_passphrase_type, false); + } return content_block; + } - return (unlock_with_type(client, block, vals.old_passphrase, existing_passphrase_type) - .catch(error => { - dlg.set_values({ needs_explicit_passphrase: true }); - return Promise.reject(error); - }) - .then(() => client.blocks_cleartext[path])); + try { + await unlock_with_type(client, block, vals.old_passphrase, existing_passphrase_type, false); + return client.blocks_cleartext[path]; + } catch (error) { + dlg.set_values({ needs_explicit_passphrase: true }); + throw error; + } } function format() { @@ -644,6 +654,16 @@ function format_dialog_internal(client, path, start, size, enable_dos_extended, if (is_encrypted(vals)) remember_passphrase(new_block, vals.passphrase); + if (is_encrypted(vals) && is_filesystem(vals) && vals.mount_options?.ro) { + console.log("REOPEN readonly") + const block_crypto = await client.wait_for(() => block_crypto_for_block(path)); + await block_crypto.Lock({}); + if (vals.passphrase) + await block_crypto.Unlock(vals.passphrase, { "read-only": { t: "b", v: true } }); + else + await unlock_with_type(client, block, vals.old_passphrase, existing_passphrase_type, true); + } + if (is_filesystem(vals) && mount_now) { const block_fsys = await client.wait_for(() => block_fsys_for_block(path)); await client.mount_at(client.blocks[block_fsys.path], mount_point);