blob: c54119a33ddeec3501ad1bede979ab5001c2cae7 [file] [log] [blame]
David Anderson41241232018-06-13 16:50:11 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <getopt.h>
18#include <inttypes.h>
19#include <stdio.h>
20#include <sys/stat.h>
21#include <sys/types.h>
22#include <sysexits.h>
23#include <unistd.h>
24
25#include <string>
26
27#include <android-base/parseint.h>
28#include <liblp/reader.h>
29
30using namespace android;
31using namespace android::fs_mgr;
32
33static int usage(int /* argc */, char* argv[]) {
34 fprintf(stderr,
35 "%s - command-line tool for dumping Android Logical Partition images.\n"
36 "\n"
37 "Usage:\n"
38 " %s [-s,--slot] file-or-device\n"
39 "\n"
40 "Options:\n"
41 " -s, --slot=N Slot number or suffix.\n",
42 argv[0], argv[0]);
43 return EX_USAGE;
44}
45
46static std::string BuildAttributeString(uint32_t attrs) {
47 return (attrs & LP_PARTITION_ATTR_READONLY) ? "readonly" : "none";
48}
49
50static bool IsBlockDevice(const char* file) {
51 struct stat s;
52 return !stat(file, &s) && S_ISBLK(s.st_mode);
53}
54
55int main(int argc, char* argv[]) {
56 struct option options[] = {
57 { "slot", required_argument, nullptr, 's' },
58 { "help", no_argument, nullptr, 'h' },
59 { nullptr, 0, nullptr, 0 },
60 };
61
62 int rv;
63 int index;
64 uint32_t slot = 0;
65 while ((rv = getopt_long_only(argc, argv, "s:h", options, &index)) != -1) {
66 switch (rv) {
67 case 'h':
68 return usage(argc, argv);
69 case 's':
70 if (!android::base::ParseUint(optarg, &slot)) {
71 slot = SlotNumberForSlotSuffix(optarg);
72 }
73 break;
74 }
75 }
76
77 if (optind >= argc) {
78 return usage(argc, argv);
79 }
80 const char* file = argv[optind++];
81
82 std::unique_ptr<LpMetadata> pt;
83 if (IsBlockDevice(file)) {
84 pt = ReadMetadata(file, slot);
85 } else {
86 pt = ReadFromImageFile(file);
87 }
88 if (!pt) {
89 fprintf(stderr, "Failed to read metadata.\n");
90 return EX_NOINPUT;
91 }
92
93 printf("Metadata version: %u.%u\n", pt->header.major_version, pt->header.minor_version);
94 printf("Metadata size: %u bytes\n", pt->header.header_size + pt->header.tables_size);
95 printf("Metadata max size: %u bytes\n", pt->geometry.metadata_max_size);
96 printf("Metadata slot count: %u\n", pt->geometry.metadata_slot_count);
97 printf("First logical sector: %" PRIu64 "\n", pt->geometry.first_logical_sector);
98 printf("Last logical sector: %" PRIu64 "\n", pt->geometry.last_logical_sector);
99 printf("Partition table:\n");
100 printf("------------------------\n");
101
102 for (const auto& partition : pt->partitions) {
103 std::string name = GetPartitionName(partition);
104 std::string guid = GetPartitionGuid(partition);
105 printf(" Name: %s\n", name.c_str());
106 printf(" GUID: %s\n", guid.c_str());
107 printf(" Attributes: %s\n", BuildAttributeString(partition.attributes).c_str());
108 printf(" Extents:\n");
109 uint64_t first_sector = 0;
110 for (size_t i = 0; i < partition.num_extents; i++) {
111 const LpMetadataExtent& extent = pt->extents[partition.first_extent_index + i];
112 printf(" %" PRIu64 " .. %" PRIu64 " ", first_sector,
113 (first_sector + extent.num_sectors - 1));
114 first_sector += extent.num_sectors;
115 if (extent.target_type == LP_TARGET_TYPE_LINEAR) {
116 printf("linear %" PRIu64, extent.target_data);
117 } else if (extent.target_type == LP_TARGET_TYPE_ZERO) {
118 printf("zero");
119 }
120 printf("\n");
121 }
122 printf("------------------------\n");
123 }
124
125 return EX_OK;
126}