libguestfs/0010-daemon-Rewrite-pvs-vgs-lvs-full-APIs-in-OCaml.patch
Richard W.M. Jones 96b6a35bd4 Rebase to libguestfs 1.55.8
resolves: RHEL-81733
Fix virt-v2v conversion of split /usr Ubuntu 22+
resolves: RHEL-87622

Remove dependencies on oUnit, flex, bison
2025-04-16 22:05:30 +01:00

661 lines
23 KiB
Diff

From a73f248369d35249a9324a0e0df9f7ccd1420d3f Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 16 Apr 2025 10:41:59 +0100
Subject: [PATCH] daemon: Rewrite {pvs,vgs,lvs}-full APIs in OCaml
These were previously written in very convoluted C which had to deal
with parsing the crazy output of the "lvm" command. In fact the
parsing was so complex that it was generated by the generator. It's
easier to do this in OCaml.
These are basically legacy APIs. They cannot be expanded and LVM
already supports many more fields. We should replace these with APIs
for getting single named fields from LVM.
---
.gitignore | 2 +-
daemon/Makefile.am | 5 +-
daemon/lvm.c | 22 ----
daemon/lvm_full.ml | 221 ++++++++++++++++++++++++++++++++++++++
docs/C_SOURCE_FILES | 1 -
generator/actions_core.ml | 3 +
generator/daemon.ml | 190 --------------------------------
generator/daemon.mli | 1 -
generator/main.ml | 2 -
generator/structs.ml | 4 +-
generator/structs.mli | 7 --
po/POTFILES | 1 -
12 files changed, 229 insertions(+), 230 deletions(-)
create mode 100644 daemon/lvm_full.ml
diff --git a/.gitignore b/.gitignore
index 9d59a80f1..81cd278cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -97,7 +97,7 @@ Makefile.in
/daemon/listfs.mli
/daemon/lvm.mli
/daemon/lvm_dm.mli
-/daemon/lvm-tokenization.c
+/daemon/lvm_full.mli
/daemon/md.mli
/daemon/mount.mli
/daemon/names.c
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index bb72c0244..90ece8461 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -22,7 +22,6 @@ BUILT_SOURCES = \
caml-stubs.c \
dispatch.c \
names.c \
- lvm-tokenization.c \
structs-cleanups.c \
structs-cleanups.h \
stubs-0.c \
@@ -52,6 +51,7 @@ generator_built = \
listfs.mli \
lvm.mli \
lvm_dm.mli \
+ lvm_full.mli \
md.mli \
mount.mli \
optgroups.ml \
@@ -152,7 +152,6 @@ guestfsd_SOURCES = \
luks.c \
lvm.c \
lvm-filter.c \
- lvm-tokenization.c \
md.c \
mkfs.c \
mknod.c \
@@ -298,6 +297,7 @@ SOURCES_MLI = \
listfs.mli \
lvm.mli \
lvm_dm.mli \
+ lvm_full.mli \
lvm_utils.mli \
md.mli \
mount.mli \
@@ -333,6 +333,7 @@ SOURCES_ML = \
ldm.ml \
link.ml \
lvm.ml \
+ lvm_full.ml \
lvm_utils.ml \
lvm_dm.ml \
findfs.ml \
diff --git a/daemon/lvm.c b/daemon/lvm.c
index 261573882..924c1ddb3 100644
--- a/daemon/lvm.c
+++ b/daemon/lvm.c
@@ -139,28 +139,6 @@ do_vgs (void)
return convert_lvm_output (out, NULL);
}
-/* These were so complex to implement that I ended up auto-generating
- * the code. That code is in stubs.c, and it is generated as usual
- * by generator.ml.
- */
-guestfs_int_lvm_pv_list *
-do_pvs_full (void)
-{
- return parse_command_line_pvs ();
-}
-
-guestfs_int_lvm_vg_list *
-do_vgs_full (void)
-{
- return parse_command_line_vgs ();
-}
-
-guestfs_int_lvm_lv_list *
-do_lvs_full (void)
-{
- return parse_command_line_lvs ();
-}
-
int
do_pvcreate (const char *device)
{
diff --git a/daemon/lvm_full.ml b/daemon/lvm_full.ml
new file mode 100644
index 000000000..d5653d2f0
--- /dev/null
+++ b/daemon/lvm_full.ml
@@ -0,0 +1,221 @@
+(* guestfs-inspection
+ * Copyright (C) 2009-2025 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+(* This file implements the complicated lvs-full, vgs-full and pvs-full APIs
+ *
+ * XXX Deprecate these APIs are replace with APIs for getting single
+ * named fields from LVM. That will be slower but far more flexible
+ * and extensible.
+ *)
+
+open Unix
+open Printf
+
+open Std_utils
+
+open Utils
+
+(* LVM UUIDs are basically 32 byte strings with '-' inserted.
+ * Remove the '-' characters and check it's the right length.
+ *)
+let parse_uuid uuid =
+ let uuid' =
+ uuid |> String.explode |> List.filter ((<>) '-') |> String.implode in
+ if String.length uuid' <> 32 then
+ failwithf "lvm-full: parse_uuid: unexpected UUID format: %S" uuid;
+ uuid'
+
+(* Parse the percent fields. These can be empty. *)
+let parse_percent pc = if pc = "" then None else Some (float_of_string pc)
+
+(* XXX These must match generator/structs.ml *)
+let lvm_pv_cols = [
+ "pv_name"; (* FString *)
+ "pv_uuid"; (* FUUID *)
+ "pv_fmt"; (* FString *)
+ "pv_size"; (* FBytes *)
+ "dev_size"; (* FBytes *)
+ "pv_free"; (* FBytes *)
+ "pv_used"; (* FBytes *)
+ "pv_attr"; (* FString (* XXX *) *)
+ "pv_pe_count"; (* FInt64 *)
+ "pv_pe_alloc_count"; (* FInt64 *)
+ "pv_tags"; (* FString *)
+ "pe_start"; (* FBytes *)
+ "pv_mda_count"; (* FInt64 *)
+ "pv_mda_free"; (* FBytes *)
+]
+
+let tokenize_pvs = function
+ | [ pv_name; pv_uuid; pv_fmt; pv_size; dev_size; pv_free;
+ pv_used; pv_attr; pv_pe_count; pv_pe_alloc_count; pv_tags;
+ pe_start; pv_mda_count; pv_mda_free ] ->
+ { Structs.pv_name = pv_name;
+ pv_uuid = parse_uuid pv_uuid;
+ pv_fmt = pv_fmt;
+ pv_size = Int64.of_string pv_size;
+ dev_size = Int64.of_string dev_size;
+ pv_free = Int64.of_string pv_free;
+ pv_used = Int64.of_string pv_used;
+ pv_attr = pv_attr;
+ pv_pe_count = Int64.of_string pv_pe_count;
+ pv_pe_alloc_count = Int64.of_string pv_pe_alloc_count;
+ pv_tags = pv_tags;
+ pe_start = Int64.of_string pe_start;
+ pv_mda_count = Int64.of_string pv_mda_count;
+ pv_mda_free = Int64.of_string pv_mda_free }
+
+ | fields ->
+ failwithf "pvs-full: tokenize_pvs: unexpected number of fields: %d"
+ (List.length fields)
+
+(* XXX These must match generator/structs.ml *)
+let lvm_vg_cols = [
+ "vg_name"; (* FString *)
+ "vg_uuid"; (* FUUID *)
+ "vg_fmt"; (* FString *)
+ "vg_attr"; (* FString (* XXX *) *)
+ "vg_size"; (* FBytes *)
+ "vg_free"; (* FBytes *)
+ "vg_sysid"; (* FString *)
+ "vg_extent_size"; (* FBytes *)
+ "vg_extent_count"; (* FInt64 *)
+ "vg_free_count"; (* FInt64 *)
+ "max_lv"; (* FInt64 *)
+ "max_pv"; (* FInt64 *)
+ "pv_count"; (* FInt64 *)
+ "lv_count"; (* FInt64 *)
+ "snap_count"; (* FInt64 *)
+ "vg_seqno"; (* FInt64 *)
+ "vg_tags"; (* FString *)
+ "vg_mda_count"; (* FInt64 *)
+ "vg_mda_free"; (* FBytes *)
+]
+
+let tokenize_vgs = function
+ | [ vg_name; vg_uuid; vg_fmt; vg_attr; vg_size; vg_free; vg_sysid;
+ vg_extent_size; vg_extent_count; vg_free_count; max_lv;
+ max_pv; pv_count; lv_count; snap_count; vg_seqno; vg_tags;
+ vg_mda_count; vg_mda_free ] ->
+ { Structs.vg_name = vg_name;
+ vg_uuid = parse_uuid vg_uuid;
+ vg_fmt = vg_fmt;
+ vg_attr = vg_attr;
+ vg_size = Int64.of_string vg_size;
+ vg_free = Int64.of_string vg_free;
+ vg_sysid = vg_sysid;
+ vg_extent_size = Int64.of_string vg_extent_size;
+ vg_extent_count = Int64.of_string vg_extent_count;
+ vg_free_count = Int64.of_string vg_free_count;
+ max_lv = Int64.of_string max_lv;
+ max_pv = Int64.of_string max_pv;
+ pv_count = Int64.of_string pv_count;
+ lv_count = Int64.of_string lv_count;
+ snap_count = Int64.of_string snap_count;
+ vg_seqno = Int64.of_string vg_seqno;
+ vg_tags = vg_tags;
+ vg_mda_count = Int64.of_string vg_mda_count;
+ vg_mda_free = Int64.of_string vg_mda_free }
+
+ | fields ->
+ failwithf "pvs-full: tokenize_vgs: unexpected number of fields: %d"
+ (List.length fields)
+
+(* XXX These must match generator/structs.ml *)
+let lvm_lv_cols = [
+ "lv_name"; (* FString *)
+ "lv_uuid"; (* FUUID *)
+ "lv_attr"; (* FString (* XXX *) *)
+ "lv_major"; (* FInt64 *)
+ "lv_minor"; (* FInt64 *)
+ "lv_kernel_major"; (* FInt64 *)
+ "lv_kernel_minor"; (* FInt64 *)
+ "lv_size"; (* FBytes *)
+ "seg_count"; (* FInt64 *)
+ "origin"; (* FString *)
+ "snap_percent"; (* FOptPercent *)
+ "copy_percent"; (* FOptPercent *)
+ "move_pv"; (* FString *)
+ "lv_tags"; (* FString *)
+ "mirror_log"; (* FString *)
+ "modules"; (* FString *)
+]
+
+let tokenize_lvs = function
+ | [ lv_name; lv_uuid; lv_attr; lv_major; lv_minor; lv_kernel_major;
+ lv_kernel_minor; lv_size; seg_count; origin; snap_percent;
+ copy_percent; move_pv; lv_tags; mirror_log; modules ] ->
+ { Structs.lv_name = lv_name;
+ lv_uuid = parse_uuid lv_uuid;
+ lv_attr = lv_attr;
+ lv_major = Int64.of_string lv_major;
+ lv_minor = Int64.of_string lv_minor;
+ lv_kernel_major = Int64.of_string lv_kernel_major;
+ lv_kernel_minor = Int64.of_string lv_kernel_minor;
+ lv_size = Int64.of_string lv_size;
+ seg_count = Int64.of_string seg_count;
+ origin = origin;
+ snap_percent = parse_percent snap_percent;
+ copy_percent = parse_percent copy_percent;
+ move_pv = move_pv;
+ lv_tags = lv_tags;
+ mirror_log = mirror_log;
+ modules = modules }
+
+ | fields ->
+ failwithf "pvs-full: tokenize_vgs: unexpected number of fields: %d"
+ (List.length fields)
+
+let rec pvs_full () =
+ let out = run_lvm_command "pvs" lvm_pv_cols in
+ let lines = trim_and_split out in
+ let pvs = List.map tokenize_pvs lines in
+ pvs
+
+and vgs_full () =
+ let out = run_lvm_command "vgs" lvm_vg_cols in
+ let lines = trim_and_split out in
+ let vgs = List.map tokenize_vgs lines in
+ vgs
+
+and lvs_full () =
+ let out = run_lvm_command "lvs" lvm_lv_cols in
+ let lines = trim_and_split out in
+ let lvs = List.map tokenize_lvs lines in
+ lvs
+
+and run_lvm_command typ cols =
+ let cols = String.concat "," cols in
+ let cmd = [ typ; "-o"; cols;
+ "--unbuffered"; "--noheadings"; "--nosuffix";
+ "--separator"; "\r"; "--units"; "b" ] in
+ command "lvm" cmd
+
+and trim_and_split out =
+ (* Split the output into lines. *)
+ let lines = String.nsplit "\n" out in
+
+ (* LVM puts leading whitespace on each line so remove that. *)
+ let lines = List.map String.triml lines in
+
+ (* Ignore any blank lines. *)
+ let lines = List.filter ((<>) "") lines in
+
+ (* Split each line into fields. *)
+ let lines = List.map (String.nsplit "\r") lines in
+ lines
diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES
index 0038f95e4..cdfb1d615 100644
--- a/docs/C_SOURCE_FILES
+++ b/docs/C_SOURCE_FILES
@@ -111,7 +111,6 @@ daemon/link.c
daemon/ls.c
daemon/luks.c
daemon/lvm-filter.c
-daemon/lvm-tokenization.c
daemon/lvm.c
daemon/md.c
daemon/mkfs.c
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index 5e8de563a..34bd15ae6 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -1795,6 +1795,7 @@ See also C<guestfs_lvs_full>, C<guestfs_list_filesystems>." };
{ defaults with
name = "pvs_full"; added = (0, 0, 4);
style = RStructList ("physvols", "lvm_pv"), [], [];
+ impl = OCaml "Lvm_full.pvs_full";
optional = Some "lvm2";
shortdesc = "list the LVM physical volumes (PVs)";
longdesc = "\
@@ -1804,6 +1805,7 @@ of the L<pvs(8)> command. The \"full\" version includes all fields." };
{ defaults with
name = "vgs_full"; added = (0, 0, 4);
style = RStructList ("volgroups", "lvm_vg"), [], [];
+ impl = OCaml "Lvm_full.vgs_full";
optional = Some "lvm2";
shortdesc = "list the LVM volume groups (VGs)";
longdesc = "\
@@ -1813,6 +1815,7 @@ of the L<vgs(8)> command. The \"full\" version includes all fields." };
{ defaults with
name = "lvs_full"; added = (0, 0, 4);
style = RStructList ("logvols", "lvm_lv"), [], [];
+ impl = OCaml "Lvm_full.lvs_full";
optional = Some "lvm2";
shortdesc = "list the LVM logical volumes (LVs)";
longdesc = "\
diff --git a/generator/daemon.ml b/generator/daemon.ml
index b23034fd7..da5593ce1 100644
--- a/generator/daemon.ml
+++ b/generator/daemon.ml
@@ -951,196 +951,6 @@ let generate_daemon_dispatch () =
pr "}\n";
pr "\n"
-let generate_daemon_lvm_tokenization () =
- generate_header CStyle GPLv2plus;
-
- pr "\
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-
-#include \"daemon.h\"
-#include \"c-ctype.h\"
-#include \"guestfs_protocol.h\"
-#include \"actions.h\"
-#include \"optgroups.h\"
-
-";
-
- (* LVM columns and tokenization functions. *)
- (* XXX This generates crap code. We should rethink how we
- * do this parsing.
- *)
- List.iter (
- function
- | typ, cols ->
- pr "static const char lvm_%s_cols[] = \"%s\";\n"
- typ (String.concat "," (List.map fst cols));
- pr "\n";
-
- pr "static int lvm_tokenize_%s (char *str, guestfs_int_lvm_%s *r)\n" typ typ;
- pr "{\n";
- pr " char *tok, *p, *next;\n";
- pr " size_t i, j;\n";
- pr "\n";
- (*
- pr " fprintf (stderr, \"%%s: <<%%s>>\\n\", __func__, str);\n";
- pr "\n";
- *)
- pr " if (!str) {\n";
- pr " fprintf (stderr, \"%%s: failed: passed a NULL string\\n\", __func__);\n";
- pr " return -1;\n";
- pr " }\n";
- pr " if (!*str || c_isspace (*str)) {\n";
- pr " fprintf (stderr, \"%%s: failed: passed a empty string or one beginning with whitespace\\n\", __func__);\n";
- pr " return -1;\n";
- pr " }\n";
- pr " tok = str;\n";
- List.iter (
- fun (name, coltype) ->
- pr " if (!tok) {\n";
- pr " fprintf (stderr, \"%%s: failed: string finished early, around token %%s\\n\", __func__, \"%s\");\n" name;
- pr " return -1;\n";
- pr " }\n";
- pr " p = strchrnul (tok, '\\r');\n";
- pr " if (*p) next = p+1; else next = NULL;\n";
- pr " *p = '\\0';\n";
- (match coltype with
- | FString | FDevice ->
- pr " r->%s = strdup (tok);\n" name;
- pr " if (r->%s == NULL) {\n" name;
- pr " perror (\"strdup\");\n";
- pr " return -1;\n";
- pr " }\n"
- | FUUID ->
- pr " for (i = j = 0; i < 32; ++j) {\n";
- pr " if (tok[j] == '\\0') {\n";
- pr " fprintf (stderr, \"%%s: failed to parse UUID from '%%s'\\n\", __func__, tok);\n";
- pr " return -1;\n";
- pr " } else if (tok[j] != '-')\n";
- pr " r->%s[i++] = tok[j];\n" name;
- pr " }\n";
- | FBytes ->
- pr " if (sscanf (tok, \"%%\" SCNi64, &r->%s) != 1) {\n" name;
- pr " fprintf (stderr, \"%%s: failed to parse size '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
- pr " return -1;\n";
- pr " }\n";
- | FInt64 ->
- pr " if (sscanf (tok, \"%%\" SCNi64, &r->%s) != 1) {\n" name;
- pr " fprintf (stderr, \"%%s: failed to parse int '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
- pr " return -1;\n";
- pr " }\n";
- | FOptPercent ->
- pr " if (tok[0] == '\\0')\n";
- pr " r->%s = -1;\n" name;
- pr " else if (sscanf (tok, \"%%f\", &r->%s) != 1) {\n" name;
- pr " fprintf (stderr, \"%%s: failed to parse float '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
- pr " return -1;\n";
- pr " }\n";
- | FBuffer | FInt32 | FUInt32 | FUInt64 | FChar ->
- assert false (* can never be an LVM column *)
- );
- pr " tok = next;\n";
- ) cols;
-
- pr " if (tok != NULL) {\n";
- pr " fprintf (stderr, \"%%s: failed: extra tokens at end of string\\n\", __func__);\n";
- pr " return -1;\n";
- pr " }\n";
- pr " return 0;\n";
- pr "}\n";
- pr "\n";
-
- pr "guestfs_int_lvm_%s_list *\n" typ;
- pr "parse_command_line_%ss (void)\n" typ;
- pr "{\n";
- pr " char *out, *err;\n";
- pr " char *p, *pend;\n";
- pr " int r, i;\n";
- pr " guestfs_int_lvm_%s_list *ret;\n" typ;
- pr " void *newp;\n";
- pr "\n";
- pr " ret = malloc (sizeof *ret);\n";
- pr " if (!ret) {\n";
- pr " reply_with_perror (\"malloc\");\n";
- pr " return NULL;\n";
- pr " }\n";
- pr "\n";
- pr " ret->guestfs_int_lvm_%s_list_len = 0;\n" typ;
- pr " ret->guestfs_int_lvm_%s_list_val = NULL;\n" typ;
- pr "\n";
- pr " r = command (&out, &err,\n";
- pr " \"lvm\", \"%ss\",\n" typ;
- pr " \"-o\", lvm_%s_cols, \"--unbuffered\", \"--noheadings\",\n" typ;
- pr " \"--nosuffix\", \"--separator\", \"\\r\", \"--units\", \"b\", NULL);\n";
- pr " if (r == -1) {\n";
- pr " reply_with_error (\"%%s\", err);\n";
- pr " free (out);\n";
- pr " free (err);\n";
- pr " free (ret);\n";
- pr " return NULL;\n";
- pr " }\n";
- pr "\n";
- pr " free (err);\n";
- pr "\n";
- pr " /* Tokenize each line of the output. */\n";
- pr " p = out;\n";
- pr " i = 0;\n";
- pr " while (p) {\n";
- pr " pend = strchr (p, '\\n'); /* Get the next line of output. */\n";
- pr " if (pend) {\n";
- pr " *pend = '\\0';\n";
- pr " pend++;\n";
- pr " }\n";
- pr "\n";
- pr " while (*p && c_isspace (*p)) /* Skip any leading whitespace. */\n";
- pr " p++;\n";
- pr "\n";
- pr " if (!*p) { /* Empty line? Skip it. */\n";
- pr " p = pend;\n";
- pr " continue;\n";
- pr " }\n";
- pr "\n";
- pr " /* Allocate some space to store this next entry. */\n";
- pr " newp = realloc (ret->guestfs_int_lvm_%s_list_val,\n" typ;
- pr " sizeof (guestfs_int_lvm_%s) * (i+1));\n" typ;
- pr " if (newp == NULL) {\n";
- pr " reply_with_perror (\"realloc\");\n";
- pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
- pr " free (ret);\n";
- pr " free (out);\n";
- pr " return NULL;\n";
- pr " }\n";
- pr " ret->guestfs_int_lvm_%s_list_val = newp;\n" typ;
- pr "\n";
- pr " /* Tokenize the next entry. */\n";
- pr " r = lvm_tokenize_%s (p, &ret->guestfs_int_lvm_%s_list_val[i]);\n" typ typ;
- pr " if (r == -1) {\n";
- pr " reply_with_error (\"failed to parse output of '%ss' command\");\n" typ;
- pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
- pr " free (ret);\n";
- pr " free (out);\n";
- pr " return NULL;\n";
- pr " }\n";
- pr "\n";
- pr " ++i;\n";
- pr " p = pend;\n";
- pr " }\n";
- pr "\n";
- pr " ret->guestfs_int_lvm_%s_list_len = i;\n" typ;
- pr "\n";
- pr " free (out);\n";
- pr " return ret;\n";
- pr "}\n"
-
- ) ["pv", lvm_pv_cols; "vg", lvm_vg_cols; "lv", lvm_lv_cols]
-
(* Generate a list of function names, for debugging in the daemon.. *)
let generate_daemon_names () =
generate_header CStyle GPLv2plus;
diff --git a/generator/daemon.mli b/generator/daemon.mli
index f65545302..849979451 100644
--- a/generator/daemon.mli
+++ b/generator/daemon.mli
@@ -23,7 +23,6 @@ val generate_daemon_caml_stubs : unit -> unit
val generate_daemon_caml_callbacks_ml : unit -> unit
val generate_daemon_caml_interface : string -> unit -> unit
val generate_daemon_dispatch : unit -> unit
-val generate_daemon_lvm_tokenization : unit -> unit
val generate_daemon_names : unit -> unit
val generate_daemon_optgroups_c : unit -> unit
val generate_daemon_optgroups_h : unit -> unit
diff --git a/generator/main.ml b/generator/main.ml
index 17bcef8b5..57285003b 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -147,8 +147,6 @@ Run it from the top source directory using the command
Daemon.generate_daemon_optgroups_ml;
output_to "daemon/optgroups.mli"
Daemon.generate_daemon_optgroups_mli;
- output_to "daemon/lvm-tokenization.c"
- Daemon.generate_daemon_lvm_tokenization;
output_to "daemon/structs-cleanups.c"
Daemon.generate_daemon_structs_cleanups_c;
output_to "daemon/structs-cleanups.h"
diff --git a/generator/structs.ml b/generator/structs.ml
index fcacade65..84db7fe84 100644
--- a/generator/structs.ml
+++ b/generator/structs.ml
@@ -31,9 +31,7 @@ type struc = {
s_unused : unit; (* Silences warning 23 when using 'defaults with ...' *)
}
-(* Because we generate extra parsing code for LVM command line tools,
- * we have to pull out the LVM columns separately here.
- *)
+(* XXX These must match daemon/lvm_full.ml *)
let lvm_pv_cols = [
"pv_name", FDevice;
"pv_uuid", FUUID;
diff --git a/generator/structs.mli b/generator/structs.mli
index 13bb0d5d3..c99086214 100644
--- a/generator/structs.mli
+++ b/generator/structs.mli
@@ -34,13 +34,6 @@ type struc = {
val structs : struc list
(** List of structures. *)
-val lvm_pv_cols : cols
-val lvm_vg_cols : cols
-val lvm_lv_cols : cols
-(** These are exported to the daemon code generator where they are
- used to generate code for parsing the output of commands like
- [lvs]. One day replace this with liblvm API calls. *)
-
val lookup_struct : string -> struc
(** Lookup a struct by name. *)
diff --git a/po/POTFILES b/po/POTFILES
index 75b040c06..d10f97106 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -90,7 +90,6 @@ daemon/link.c
daemon/ls.c
daemon/luks.c
daemon/lvm-filter.c
-daemon/lvm-tokenization.c
daemon/lvm.c
daemon/md.c
daemon/mkfs.c
--
2.47.1