153 lines
5.4 KiB
Diff
153 lines
5.4 KiB
Diff
|
From 1d69132b7b7209dbf231a4668b3a6531a6f9cdf3 Mon Sep 17 00:00:00 2001
|
||
|
From: Laszlo Ersek <lersek@redhat.com>
|
||
|
Date: Fri, 19 May 2023 11:34:18 +0200
|
||
|
Subject: [PATCH] update common submodule
|
||
|
|
||
|
Laszlo Ersek (2):
|
||
|
options/keys: key_store_import_key(): un-constify "key" parameter
|
||
|
options/keys: introduce unescape_device_mapper_lvm()
|
||
|
|
||
|
https://bugzilla.redhat.com/show_bug.cgi?id=2168506
|
||
|
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
||
|
(cherry picked from commit b0dbe7c7728579d6c2128c733491755eee1a91b5)
|
||
|
---
|
||
|
common | 2 +-
|
||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||
|
|
||
|
Submodule common 38e6988c..b636c3f2:
|
||
|
diff --git a/common/options/options.h b/common/options/options.h
|
||
|
index 94573ee0..94e8b9ee 100644
|
||
|
--- a/common/options/options.h
|
||
|
+++ b/common/options/options.h
|
||
|
@@ -169,7 +169,8 @@ extern struct matching_key *get_keys (struct key_store *ks, const char *device,
|
||
|
const char *uuid, size_t *nr_matches);
|
||
|
extern void free_keys (struct matching_key *keys, size_t nr_matches);
|
||
|
extern struct key_store *key_store_add_from_selector (struct key_store *ks, const char *selector);
|
||
|
-extern struct key_store *key_store_import_key (struct key_store *ks, const struct key_store_key *key);
|
||
|
+extern struct key_store *key_store_import_key (struct key_store *ks,
|
||
|
+ struct key_store_key *key);
|
||
|
extern bool key_store_requires_network (const struct key_store *ks);
|
||
|
extern void free_key_store (struct key_store *ks);
|
||
|
|
||
|
diff --git a/common/options/keys.c b/common/options/keys.c
|
||
|
index 48f1bc7c..52b27369 100644
|
||
|
--- a/common/options/keys.c
|
||
|
+++ b/common/options/keys.c
|
||
|
@@ -260,8 +260,107 @@ key_store_add_from_selector (struct key_store *ks, const char *selector)
|
||
|
return key_store_import_key (ks, &key);
|
||
|
}
|
||
|
|
||
|
+/* Turn /dev/mapper/VG-LV into /dev/VG/LV, in-place. */
|
||
|
+static void
|
||
|
+unescape_device_mapper_lvm (char *id)
|
||
|
+{
|
||
|
+ static const char dev[] = "/dev/", dev_mapper[] = "/dev/mapper/";
|
||
|
+ const char *input_start;
|
||
|
+ char *output;
|
||
|
+ enum { M_SCAN, M_FILL, M_DONE } mode;
|
||
|
+
|
||
|
+ if (!STRPREFIX (id, dev_mapper))
|
||
|
+ return;
|
||
|
+
|
||
|
+ /* Start parsing "VG-LV" from "id" after "/dev/mapper/". */
|
||
|
+ input_start = id + (sizeof dev_mapper - 1);
|
||
|
+
|
||
|
+ /* Start writing the unescaped "VG/LV" output after "/dev/". */
|
||
|
+ output = id + (sizeof dev - 1);
|
||
|
+
|
||
|
+ for (mode = M_SCAN; mode < M_DONE; ++mode) {
|
||
|
+ char c;
|
||
|
+ const char *input = input_start;
|
||
|
+ const char *hyphen_buffered = NULL;
|
||
|
+ bool single_hyphen_seen = false;
|
||
|
+
|
||
|
+ do {
|
||
|
+ c = *input;
|
||
|
+
|
||
|
+ switch (c) {
|
||
|
+ case '-':
|
||
|
+ if (hyphen_buffered == NULL)
|
||
|
+ /* This hyphen may start an escaped hyphen, or it could be the
|
||
|
+ * separator in VG-LV.
|
||
|
+ */
|
||
|
+ hyphen_buffered = input;
|
||
|
+ else {
|
||
|
+ /* This hyphen completes an escaped hyphen; unescape it. */
|
||
|
+ if (mode == M_FILL)
|
||
|
+ *output++ = '-';
|
||
|
+ hyphen_buffered = NULL;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+
|
||
|
+ case '/':
|
||
|
+ /* Slash characters are forbidden in VG-LV anywhere. If there's any,
|
||
|
+ * we'll find it in the first (i.e., scanning) phase, before we output
|
||
|
+ * anything back to "id".
|
||
|
+ */
|
||
|
+ assert (mode == M_SCAN);
|
||
|
+ return;
|
||
|
+
|
||
|
+ default:
|
||
|
+ /* Encountered a non-slash, non-hyphen character -- which also may be
|
||
|
+ * the terminating NUL.
|
||
|
+ */
|
||
|
+ if (hyphen_buffered != NULL) {
|
||
|
+ /* The non-hyphen character comes after a buffered hyphen, so the
|
||
|
+ * buffered hyphen is supposed to be the single hyphen that separates
|
||
|
+ * VG from LV in VG-LV. There are three requirements for this
|
||
|
+ * separator: (a) it must be unique (we must not have seen another
|
||
|
+ * such separator earlier), (b) it must not be at the start of VG-LV
|
||
|
+ * (because VG would be empty that way), (c) it must not be at the end
|
||
|
+ * of VG-LV (because LV would be empty that way). Should any of these
|
||
|
+ * be violated, we'll catch that during the first (i.e., scanning)
|
||
|
+ * phase, before modifying "id".
|
||
|
+ */
|
||
|
+ if (single_hyphen_seen || hyphen_buffered == input_start ||
|
||
|
+ c == '\0') {
|
||
|
+ assert (mode == M_SCAN);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Translate the separator hyphen to a slash character. */
|
||
|
+ if (mode == M_FILL)
|
||
|
+ *output++ = '/';
|
||
|
+ hyphen_buffered = NULL;
|
||
|
+ single_hyphen_seen = true;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Output the non-hyphen character (including the terminating NUL)
|
||
|
+ * regardless of whether there was a buffered hyphen separator (which,
|
||
|
+ * by now, we'll have attempted to translate and flush).
|
||
|
+ */
|
||
|
+ if (mode == M_FILL)
|
||
|
+ *output++ = c;
|
||
|
+ }
|
||
|
+
|
||
|
+ ++input;
|
||
|
+ } while (c != '\0');
|
||
|
+
|
||
|
+ /* We must have seen the VG-LV separator. If that's not the case, we'll
|
||
|
+ * catch it before modifying "id".
|
||
|
+ */
|
||
|
+ if (!single_hyphen_seen) {
|
||
|
+ assert (mode == M_SCAN);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
struct key_store *
|
||
|
-key_store_import_key (struct key_store *ks, const struct key_store_key *key)
|
||
|
+key_store_import_key (struct key_store *ks, struct key_store_key *key)
|
||
|
{
|
||
|
struct key_store_key *new_keys;
|
||
|
|
||
|
@@ -278,6 +377,7 @@ key_store_import_key (struct key_store *ks, const struct key_store_key *key)
|
||
|
error (EXIT_FAILURE, errno, "realloc");
|
||
|
|
||
|
ks->keys = new_keys;
|
||
|
+ unescape_device_mapper_lvm (key->id);
|
||
|
ks->keys[ks->nr_keys] = *key;
|
||
|
++ks->nr_keys;
|
||
|
|