ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/pbcdedit/pbcdedit
(Generate patch)

Comparing pbcdedit/pbcdedit (file contents):
Revision 1.39 by root, Thu Aug 15 23:49:22 2019 UTC vs.
Revision 1.51 by root, Thu Aug 22 07:44:08 2019 UTC

19# along with this program. If not, see <https://www.gnu.org/licenses/>. 19# along with this program. If not, see <https://www.gnu.org/licenses/>.
20# 20#
21 21
22use 5.016; # numerous features need 5.14, __SUB__ needs 5.16 22use 5.016; # numerous features need 5.14, __SUB__ needs 5.16
23 23
24our $VERSION = '1.2'; 24our $VERSION = '1.3';
25our $JSON_VERSION = 2; # the version of the json objects generated by this program 25our $JSON_VERSION = 3; # the version of the json objects generated by this program
26 26
27our $CHANGELOG = <<EOF; 27our $CHANGELOG = <<EOF;
28
29 - editorial fixes to the documentation.
30
311.3 Sat Aug 17 07:04:15 CEST 2019
32 - output of pbcdedit elements --json has changed, as it didn't
33 take the reorganisation by classes fully into account.
34 - json schema bumped to 3.
35 - new "bcd-device" and "bcd-legacy-device" subcommands.
36 - implement --json option for lsblk.
37
281.2 Fri Aug 16 00:20:41 CEST 2019 381.2 Fri Aug 16 00:20:41 CEST 2019
29 - bcde element names now depend on the bcd object type they are in, 39 - bcd element names now depend on the bcd object type they are in,
30 also affects "elements" output. 40 also affects "elements" output.
31 - json schema bumped to 2. 41 - json schema bumped to 2.
32 - new version command. 42 - new version command.
33 - numerous minor bugfixes. 43 - numerous minor bugfixes.
34 44
136=item C<parse> F<path> I<instructions...> 146=item C<parse> F<path> I<instructions...>
137 147
138Same as C<edit>, above, except it doesn't save the data store again. Can 148Same as C<edit>, above, except it doesn't save the data store again. Can
139be useful to extract some data from it. 149be useful to extract some data from it.
140 150
141=item C<lsblk> 151=item C<lsblk> [C<--json>]
142 152
143On a GNU/Linux system, you can get a list of partition device descriptors 153On a GNU/Linux system, you can get a list of partition device descriptors
144using this command - the external C<lsblk> command is required, as well as 154using this command - the external C<lsblk> command is required, as well as
145a mounted C</sys> file system. 155a mounted C</sys> file system.
146 156
147The output will be a list of all partitions in the system and C<partition> 157The output will be a list of all partitions in the system and C<partition>
148descriptors for GPT and both C<legacypartition> and C<partition> 158descriptors for GPT and both C<legacypartition> and C<partition>
149descriptors for MBR partitions. 159descriptors for MBR partitions.
160
161With C<--json> it will print similar informationm as C<lsblk --json>, but
162with extra C<bcd_device> and C<bcd_legacy_device> attributes.
163
164=item C<bcd-device> F<path>
165
166Tries to find the BCD device element for the given device, which currently
167must be a a partition of some kind. Prints the C<partition=> descriptor as
168a result, or nothing. Exit status will be true on success, and false on
169failure.
170
171Like C<lsblk>, above, this likely only works on GNU/Linux systems.
172
173Example: print the partition descriptor of tghe partition with label DATA.
174
175 $ pbcdedit bcd-device /dev/disk/by-label/DATA
176 partition=<null>,harddisk,mbr,47cbc08a,213579202560
177
178=item C<bcd-legacy-device> F<path>
179
180Like above, but uses a C<legacypartition> descriptor instead.
150 181
151=item C<objects> [C<--json>] 182=item C<objects> [C<--json>]
152 183
153Outputs two tables: a table listing all type aliases with their hex BCD 184Outputs two tables: a table listing all type aliases with their hex BCD
154element ID, and all object name aliases with their GUID and default type 185element ID, and all object name aliases with their GUID and default type
352 383
353 "displaybootmenu" : 0, 384 "displaybootmenu" : 0,
354 385
355=item integer 386=item integer
356 387
357Again, very simple, this is a 64 bit integer. IT can be either specified 388Again, very simple, this is a 64 bit integer. It can be either specified
358as a decimal number, as a hex number (by prefixing it with C<0x>) or as a 389as a decimal number, as a hex number (by prefixing it with C<0x>) or as a
359binary number (prefix C<0b>). 390binary number (prefix C<0b>).
360 391
361For example, the boot C<timeout> is an integer, specifying the automatic 392For example, the boot C<timeout> is an integer, specifying the automatic
362boot delay in seconds: 393boot delay in seconds:
404hacks. Understanding this type took more time than writing all the rest of 435hacks. Understanding this type took more time than writing all the rest of
405PBCDEDIT, and because it is so complex, this type has its own subsection 436PBCDEDIT, and because it is so complex, this type has its own subsection
406below. 437below.
407=back 438=back
408 439
409=head4 The BCD "device" element type 440=head3 The BCD "device" element type
410 441
411Device elements specify, well, devices. They are used for such diverse 442Device elements specify, well, devices. They are used for such diverse
412purposes such as finding a TFTP network boot image, serial ports or VMBUS 443purposes such as finding a TFTP network boot image, serial ports or VMBUS
413devices, but most commonly they are used to specify the disk (harddisk, 444devices, but most commonly they are used to specify the disk (harddisk,
414cdrom, ramdisk, vhd...) to boot from. 445cdrom, ramdisk, vhd...) to boot from.
475the leading GUID, which it can always decode). In such cases, it will 506the leading GUID, which it can always decode). In such cases, it will
476convert the device into this type with a hexdump of the element data. 507convert the device into this type with a hexdump of the element data.
477 508
478=item C<null> 509=item C<null>
479 510
480This is another special type - sometimes, a device all zero-filled, which 511This is another special type - sometimes, a device is all zero-filled,
481is not valid. This can mark the absence of a device or something PBCDEDIT 512which is not valid. This can mark the absence of a device or something
482does not understand, so it decodes it into this special "all zero" type 513PBCDEDIT does not understand, so it decodes it into this special "all
483called C<null>. 514zero" type called C<null>.
484 515
485It's most commonly found in devices that can use an optional parent 516It's most commonly found in devices that can use an optional parent
486device, when no parent device is used. 517device, when no parent device is used.
487 518
488=item C<boot> 519=item C<boot>
599 630
600Last not least, the most complex type, C<block>, which... specifies block 631Last not least, the most complex type, C<block>, which... specifies block
601devices (which could be inside a F<vhdx> file for example). 632devices (which could be inside a F<vhdx> file for example).
602 633
603I<devicetypes> is one of C<harddisk>, C<floppy>, C<cdrom>, C<ramdisk>, 634I<devicetypes> is one of C<harddisk>, C<floppy>, C<cdrom>, C<ramdisk>,
604C<file> or C<vhd> - the same as for C<partiion=>. 635C<file> or C<vhd> - the same as for C<partition=>.
605 636
606The remaining arguments change depending on the I<devicetype>: 637The remaining arguments change depending on the I<devicetype>:
607 638
608=over 639=over
609 640
639 670
640Probably not yet implemented. Tell me of your needs... 671Probably not yet implemented. Tell me of your needs...
641 672
642=back 673=back
643 674
644=back5 Examples 675=head4 Examples
645 676
646This concludes the syntax overview for device elements, but probably 677This concludes the syntax overview for device elements, but probably
647leaves many questions open. I can't help with most of them, as I also ave 678leaves many questions open. I can't help with most of them, as I also have
648many questions, but I can walk you through some actual examples using more 679many questions, but I can walk you through some actual examples using more
649complex aspects. 680complex aspects.
650 681
651=item C<< locate=<block=vhd,<block=file,<locate=<null>,path,\disk.vhdx>,\disk.vhdx>>,element,path >> 682=item C<< locate=<block=vhd,<block=file,<locate=<null>,path,\disk.vhdx>,\disk.vhdx>>,element,path >>
652 683
2390 } 2421 }
2391 2422
2392} 2423}
2393 2424
2394############################################################################# 2425#############################################################################
2395# command line parser 2426# other utilities
2396 2427
2397# json to stdout 2428# json to stdout
2398sub prjson($) { 2429sub prjson($) {
2399 print $json_coder->encode ($_[0]); 2430 print $json_coder->encode ($_[0]);
2400} 2431}
2404 my $json; 2435 my $json;
2405 1 while read STDIN, $json, 65536, length $json; 2436 1 while read STDIN, $json, 65536, length $json;
2406 $json_coder->decode ($json) 2437 $json_coder->decode ($json)
2407} 2438}
2408 2439
2409# all subcommands 2440sub lsblk() {
2441 my $lsblk = $json_coder->decode (scalar qx<lsblk --json -o PATH,KNAME,MAJ:MIN,TYPE,PTTYPE,PTUUID,PARTUUID,LABEL,FSTYPE>);
2442
2443 for my $dev (@{ $lsblk->{blockdevices} }) {
2444 if ($dev->{type} eq "part") {
2445 if ($dev->{pttype} eq "gpt") {
2446 $dev->{bcd_device} = "partition=<null>,harddisk,gpt,$dev->{ptuuid},$dev->{partuuid}";
2447 } elsif ($dev->{pttype} eq "dos") { # why not "mbr" :(
2448 if ($dev->{partuuid} =~ /^([0-9a-f]{8})-([0-9a-f]{2})\z/i) {
2449 my ($diskid, $partno) = ($1, hex $2);
2450 $dev->{bcd_legacy_device} = "legacypartition=<null>,harddisk,mbr,$diskid,$partno";
2451 if (open my $fh, "/sys/class/block/$dev->{kname}/start") {
2452 my $start = 512 * readline $fh;
2453 $dev->{bcd_device} = "partition=<null>,harddisk,mbr,$diskid,$start";
2454 }
2455 }
2456 }
2457 }
2458 }
2459
2460 $lsblk->{blockdevices}
2461}
2462
2463sub prdev($$) {
2464 my ($path, $attribute) = @_;
2465
2466 # rather than stat'ing and guessing how devices are encoded, we use lsblk for this
2467 # unfortunately, there doesn't seem to be a way to restrict lsblk to just oned evice,
2468 # so we always assume the first one is it.
2469 my $mm = $json_coder->decode (scalar qx<lsblk -o MAJ:MIN -J \Q$path\E>)->{blockdevices}[0]{"maj:min"};
2470
2471 my $lsblk = lsblk;
2472
2473 for my $dev (@$lsblk) {
2474 if ($dev->{"maj:min"} eq $mm && $dev->{$attribute}) {
2475 say $dev->{$attribute};
2476 exit 0;
2477 }
2478 }
2479
2480 exit 1;
2481}
2482
2483#############################################################################
2484# command line parser
2485
2410our %CMD = ( 2486our %CMD = (
2411 help => sub { 2487 help => sub {
2412 require Pod::Usage; 2488 require Pod::Usage;
2413 Pod::Usage::pod2usage (-verbose => 2); 2489 Pod::Usage::pod2usage (-verbose => 2);
2414 }, 2490 },
2465 BCDE_FORMAT_INTEGER , "integer", 2541 BCDE_FORMAT_INTEGER , "integer",
2466 BCDE_FORMAT_BOOLEAN , "boolean", 2542 BCDE_FORMAT_BOOLEAN , "boolean",
2467 BCDE_FORMAT_INTEGER_LIST, "integer list", 2543 BCDE_FORMAT_INTEGER_LIST, "integer list",
2468 ); 2544 );
2469 2545
2470 my %element; 2546 my @element;
2471 2547
2472 for my $class (sort keys %rbcde_byclass) { 2548 for my $class (sort keys %rbcde_byclass) {
2473 my $rbcde = $rbcde_byclass{$class}; 2549 my $rbcde = $rbcde_byclass{$class};
2474 2550
2475 unless ($json) { 2551 unless ($json) {
2478 printf "%-9s %-12s %s\n", "Element", "Format", "Name Alias"; 2554 printf "%-9s %-12s %s\n", "Element", "Format", "Name Alias";
2479 } 2555 }
2480 for my $name (sort keys %$rbcde) { 2556 for my $name (sort keys %$rbcde) {
2481 my $id = $rbcde->{$name}; 2557 my $id = $rbcde->{$name};
2482 my $format = $format_name{$id & BCDE_FORMAT}; 2558 my $format = $format_name{$id & BCDE_FORMAT};
2483 $id = sprintf "%08x", $id;
2484 2559
2485 if ($json) { 2560 if ($json) {
2486 $element{$id} = [$class, $format, $name]; 2561 push @element, [$class, $id * 1, $format, $name];
2487 } else { 2562 } else {
2563 $id = sprintf "%08x", $id;
2488 printf "%-9s %-12s %s\n", $id, $format, $name; 2564 printf "%-9s %-12s %s\n", $id, $format, $name;
2489 } 2565 }
2490 } 2566 }
2491 } 2567 }
2492 print "\n" unless $json; 2568 print "\n" unless $json;
2493 2569
2494 prjson { 2570 prjson {
2495 version => $JSON_VERSION, 2571 version => $JSON_VERSION,
2496 element => \%element, 2572 element => \@element,
2497 class => \@bcde_typeclass, 2573 class => \@bcde_typeclass,
2498 } if $json; 2574 } if $json;
2499 2575
2500 }, 2576 },
2501 2577
2528 "import-regf" => sub { 2604 "import-regf" => sub {
2529 regf_save shift, rdjson; 2605 regf_save shift, rdjson;
2530 }, 2606 },
2531 2607
2532 lsblk => sub { 2608 lsblk => sub {
2609 my $json = $_[0] eq "--json";
2610
2611 my $lsblk = lsblk;
2612
2613 if ($json) {
2614 prjson $lsblk;
2615 } else {
2533 printf "%-10s %-8.8s %-6.6s %-3s %s\n", "DEVICE", "LABEL", "FSTYPE", "PT", "DEVICE DESCRIPTOR"; 2616 printf "%-10s %-8.8s %-6.6s %-3s %s\n", "DEVICE", "LABEL", "FSTYPE", "PT", "DEVICE DESCRIPTOR";
2534 2617 for my $dev (@$lsblk) {
2535 my $lsblk = $json_coder->decode (scalar qx<lsblk --json -o PATH,KNAME,TYPE,PTTYPE,PTUUID,PARTUUID,LABEL,FSTYPE>); 2618 for my $bcd ($dev->{bcd_device}, $dev->{bcd_legacy_device}) {
2536
2537 for my $dev (@{ $lsblk->{blockdevices} }) {
2538 my $pr = sub {
2539 printf "%-10s %-8.8s %-6.6s %-3s %s\n", 2619 printf "%-10s %-8.8s %-6.6s %-3s %s\n",
2540 $dev->{path}, $dev->{label}, $dev->{fstype}, $dev->{pttype}, $_[0]; 2620 $dev->{path}, $dev->{label}, $dev->{fstype}, $dev->{pttype}, $bcd
2541 };
2542
2543 if ($dev->{type} eq "part") {
2544 if ($dev->{pttype} eq "gpt") {
2545 $pr->("partition=<null>,harddisk,gpt,$dev->{ptuuid},$dev->{partuuid}");
2546 } elsif ($dev->{pttype} eq "dos") { # why not "mbr" :(
2547 if ($dev->{partuuid} =~ /^([0-9a-f]{8})-([0-9a-f]{2})\z/i) {
2548 my ($diskid, $partno) = ($1, hex $2);
2549 $pr->("legacypartition=<null>,harddisk,mbr,$diskid,$partno");
2550 if (open my $fh, "/sys/class/block/$dev->{kname}/start") {
2551 my $start = 512 * readline $fh;
2552 $pr->("partition=<null>,harddisk,mbr,$diskid,$start");
2553 } 2621 if $bcd;
2554 }
2555 } 2622 }
2556 } 2623 }
2557 } 2624 }
2625 },
2626
2627 "bcd-device" => sub {
2628 prdev shift, "bcd_device";
2629 },
2630
2631 "bcd-legacy-device" => sub {
2632 prdev shift, "bcd_legacy_device";
2558 }, 2633 },
2559 2634
2560 version => sub { 2635 version => sub {
2561 print "\n", 2636 print "\n",
2562 "PBCDEDIT version $VERSION, copyright 2019 Marc A. Lehmann <pbcdedit\@schmorp.de>.\n", 2637 "PBCDEDIT version $VERSION, copyright 2019 Marc A. Lehmann <pbcdedit\@schmorp.de>.\n",

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines