On 12/19/22 23:16, Andrey Drobyshev wrote: > Now I'm a bit confused myself as a result of our discussion: should we > really give priority to BIOS Boot partition? Because I tried to > replay the opposite scenario -- i.e. to convert a disk previously used > by BIOS machine to be used by UEFI machine, but leaving BIOS Boot > partition with its parttype unchanged. And it failed to no surprise > with this patch applied. Do you have a clearer understanding of what > to prioritize and why?
In fact I do have a preference here. I consider this partition table busted (inconsistent). If not necessarily for booting then for virt-v2v purposes certainly. As you've showed yourself, if we apply this patch, then we make things worse for the "inverse busting" of the partition table. So I think we should leave this as-is, as far as *automatic* detection is concerned. We could introduce a command line option for forcing the source firmware type, but that's something I'd like Rich to comment upon as well (especially because it is a user interface change), and Rich is on PTO. I understand this patch is motivated by a preexistent customer issue report; I figure the answer we can give, thus far, is "your source system is inconsistent enough that we can't safely/robustly judge what to do with it in an automated fashion". >>>> (5) I don't really like the runtime logic duplication that seems to >>>> be introduced by the patch. By iterating over the list of >>>> partitions twice, we make twice as many libguestfs calls. I think >>>> we should iterate only once over the list of partitions. >>> >>> Agreed, iterating just once is obviously better. I'll try to come >>> up with the code which is less obscure. For instance, List.map with >>> a custom function, taking partition as its argument and returning a >>> tuple (Some part * bool). This way we'd get a list of tuples which >>> you referred to in your other comment. >> >> Can you try out the patches I proposed below? >> >> I agree that List.map + List.fold would work, but then (a) you don't >> need a separate mapping step just so you can fold the mapped list: >> you can push the mapping down into the folder callback; (b) I >> honestly doubt in this case that the purely functional implementation >> would be easier to read. Anyway, if you prefer that, I'm certainly OK >> with it. > > Well, to my view the necessity to use ref's make it a bit clumsy, sort > of like using global variables where they could've been avoided. Would > you consider this (functional) use of List.exists, List.filter_map? I do think that (regarless of real life utility) this is a very interesting discussion. So you've now prompted me to rewrite the patches without refs, just for my own interest. I think we can do it more compactly than List.exists (for the bios boot part) *plus* List.filter_map (for the ESP part list). First patch (refactoring, purely functional style, using "Array.fold_left"): > diff --git a/convert/inspect_source.ml b/convert/inspect_source.ml > index 056d0bca62e6..9686f9fff8d8 100644 > --- a/convert/inspect_source.ml > +++ b/convert/inspect_source.ml > @@ -225,26 +225,29 @@ and list_applications g root = function > * Otherwise, [BIOS] is returned. > *) > and get_firmware_bootable_device g = > - let rec uefi_ESP_guid = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" > - and is_uefi_ESP dev part = > - let partnum = g#part_to_partnum part in > - g#part_get_gpt_type dev partnum = uefi_ESP_guid > - and parttype_is_gpt dev = > + let parttype_is_gpt dev = > try g#part_get_parttype dev = "gpt" > with G.Error msg as exn -> > (* If it's _not_ "unrecognised disk label" then re-raise it. *) > if g#last_errno () <> G.Errno.errno_EINVAL then raise exn; > debug "%s (ignored)" msg; > false > - and is_uefi_bootable_part part = > + in > + let accumulate_partition esp_parts part = > let dev = g#part_to_dev part in > - parttype_is_gpt dev && is_uefi_ESP dev part > + if parttype_is_gpt dev then > + let partnum = g#part_to_partnum part in > + let part_type_guid = g#part_get_gpt_type dev partnum in > + match part_type_guid with > + | "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" -> part :: esp_parts > + | _ -> esp_parts > + else esp_parts > in > > - let partitions = Array.to_list (g#list_partitions ()) in > - let partitions = List.filter is_uefi_bootable_part partitions in > + let esp_partitions = > + Array.fold_left accumulate_partition [] (g#list_partitions ()) in > > - match partitions with > + match esp_partitions with > | [] -> I_BIOS > | partitions -> I_UEFI partitions > Second patch (adding bios_boot): > diff --git a/convert/inspect_source.ml b/convert/inspect_source.ml > index 9686f9fff8d8..8e8f5c45f1eb 100644 > --- a/convert/inspect_source.ml > +++ b/convert/inspect_source.ml > @@ -233,23 +233,24 @@ and get_firmware_bootable_device g = > debug "%s (ignored)" msg; > false > in > - let accumulate_partition esp_parts part = > + let accumulate_partition (esp_parts, bboot) part = > let dev = g#part_to_dev part in > if parttype_is_gpt dev then > let partnum = g#part_to_partnum part in > let part_type_guid = g#part_get_gpt_type dev partnum in > match part_type_guid with > - | "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" -> part :: esp_parts > - | _ -> esp_parts > - else esp_parts > + | "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" -> part :: esp_parts, bboot > + | "21686148-6449-6E6F-744E-656564454649" -> esp_parts, true > + | _ -> esp_parts, bboot > + else esp_parts, bboot > in > > - let esp_partitions = > - Array.fold_left accumulate_partition [] (g#list_partitions ()) in > + let esp_partitions, bios_boot = > + Array.fold_left accumulate_partition ([], false) (g#list_partitions ()) > in > > - match esp_partitions with > - | [] -> I_BIOS > - | partitions -> I_UEFI partitions > + match esp_partitions, bios_boot with > + | _ :: _, false -> I_UEFI esp_partitions > + | _ -> I_BIOS > > (* If some inspection fields are "unknown", then that indicates a > * failure in inspection, and we shouldn't continue. For an example You be the judge whether this is easier to read then the reference cells version :) Laszlo _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://listman.redhat.com/mailman/listinfo/libguestfs