Statistics
| Branch: | Tag: | Revision:

root / image_creator / gpt.py @ 9666a511

History | View | Annotate | Download (11.1 kB)

1 331aa0ec Nikos Skalkotos
# Copyright 2012 GRNET S.A. All rights reserved.
2 331aa0ec Nikos Skalkotos
#
3 331aa0ec Nikos Skalkotos
# Redistribution and use in source and binary forms, with or
4 331aa0ec Nikos Skalkotos
# without modification, are permitted provided that the following
5 331aa0ec Nikos Skalkotos
# conditions are met:
6 331aa0ec Nikos Skalkotos
#
7 331aa0ec Nikos Skalkotos
#   1. Redistributions of source code must retain the above
8 331aa0ec Nikos Skalkotos
#      copyright notice, this list of conditions and the following
9 331aa0ec Nikos Skalkotos
#      disclaimer.
10 331aa0ec Nikos Skalkotos
#
11 331aa0ec Nikos Skalkotos
#   2. Redistributions in binary form must reproduce the above
12 331aa0ec Nikos Skalkotos
#      copyright notice, this list of conditions and the following
13 331aa0ec Nikos Skalkotos
#      disclaimer in the documentation and/or other materials
14 331aa0ec Nikos Skalkotos
#      provided with the distribution.
15 331aa0ec Nikos Skalkotos
#
16 331aa0ec Nikos Skalkotos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 331aa0ec Nikos Skalkotos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 331aa0ec Nikos Skalkotos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 331aa0ec Nikos Skalkotos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 331aa0ec Nikos Skalkotos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 331aa0ec Nikos Skalkotos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 331aa0ec Nikos Skalkotos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 331aa0ec Nikos Skalkotos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 331aa0ec Nikos Skalkotos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 331aa0ec Nikos Skalkotos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 331aa0ec Nikos Skalkotos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 331aa0ec Nikos Skalkotos
# POSSIBILITY OF SUCH DAMAGE.
28 331aa0ec Nikos Skalkotos
#
29 331aa0ec Nikos Skalkotos
# The views and conclusions contained in the software and
30 331aa0ec Nikos Skalkotos
# documentation are those of the authors and should not be
31 331aa0ec Nikos Skalkotos
# interpreted as representing official policies, either expressed
32 331aa0ec Nikos Skalkotos
# or implied, of GRNET S.A.
33 331aa0ec Nikos Skalkotos
34 331aa0ec Nikos Skalkotos
import struct
35 331aa0ec Nikos Skalkotos
import sys
36 331aa0ec Nikos Skalkotos
import uuid
37 331aa0ec Nikos Skalkotos
import binascii
38 331aa0ec Nikos Skalkotos
39 331aa0ec Nikos Skalkotos
BLOCKSIZE = 512
40 331aa0ec Nikos Skalkotos
41 331aa0ec Nikos Skalkotos
42 331aa0ec Nikos Skalkotos
class MBR(object):
43 c0240ac1 Nikos Skalkotos
    """Represents a Master Boot Record."""
44 331aa0ec Nikos Skalkotos
    class Partition(object):
45 331aa0ec Nikos Skalkotos
        format = "<B3sB3sLL"
46 331aa0ec Nikos Skalkotos
47 331aa0ec Nikos Skalkotos
        def __init__(self, raw_part):
48 c0240ac1 Nikos Skalkotos
            (
49 c0240ac1 Nikos Skalkotos
                self.status,
50 331aa0ec Nikos Skalkotos
                self.start,
51 331aa0ec Nikos Skalkotos
                self.type,
52 331aa0ec Nikos Skalkotos
                self.end,
53 331aa0ec Nikos Skalkotos
                self.first_sector,
54 331aa0ec Nikos Skalkotos
                self.sector_count
55 331aa0ec Nikos Skalkotos
            ) = struct.unpack(self.format, raw_part)
56 331aa0ec Nikos Skalkotos
57 331aa0ec Nikos Skalkotos
        def pack(self):
58 331aa0ec Nikos Skalkotos
            return struct.pack(self.format,
59 331aa0ec Nikos Skalkotos
                self.status,
60 331aa0ec Nikos Skalkotos
                self.start,
61 331aa0ec Nikos Skalkotos
                self.type,
62 331aa0ec Nikos Skalkotos
                self.end,
63 331aa0ec Nikos Skalkotos
                self.first_sector,
64 331aa0ec Nikos Skalkotos
                self.sector_count
65 331aa0ec Nikos Skalkotos
            )
66 331aa0ec Nikos Skalkotos
67 c0240ac1 Nikos Skalkotos
        @staticmethod
68 c0240ac1 Nikos Skalkotos
        def size():
69 c0240ac1 Nikos Skalkotos
            """Returns the size of an MBR partition entry"""
70 c0240ac1 Nikos Skalkotos
            return struct.calcsize(MBR.Partition.format)
71 c0240ac1 Nikos Skalkotos
72 c0240ac1 Nikos Skalkotos
        def __str__(self):
73 331aa0ec Nikos Skalkotos
            start = self.unpack_chs(self.start)
74 331aa0ec Nikos Skalkotos
            end = self.unpack_chs(self.end)
75 c0240ac1 Nikos Skalkotos
            return "%d %s %d %s %d %d" % (self.status, start, self.type, end,
76 331aa0ec Nikos Skalkotos
                self.first_sector, self.sector_count)
77 331aa0ec Nikos Skalkotos
78 331aa0ec Nikos Skalkotos
        def unpack_chs(self, chs):
79 c0240ac1 Nikos Skalkotos
            """Unpacks a CHS address string to a tuple."""
80 331aa0ec Nikos Skalkotos
81 331aa0ec Nikos Skalkotos
            assert len(chs) == 3
82 331aa0ec Nikos Skalkotos
83 331aa0ec Nikos Skalkotos
            head = struct.unpack('<B', chs[0])[0]
84 331aa0ec Nikos Skalkotos
            sector = struct.unpack('<B', chs[1])[0] & 0x3f
85 331aa0ec Nikos Skalkotos
            cylinder = (struct.unpack('<B', chs[1])[0] & 0xC0) << 2 | \
86 331aa0ec Nikos Skalkotos
                struct.unpack('<B', chs[2])[0]
87 331aa0ec Nikos Skalkotos
88 331aa0ec Nikos Skalkotos
            return (cylinder, head, sector)
89 331aa0ec Nikos Skalkotos
90 331aa0ec Nikos Skalkotos
        def pack_chs(self, cylinder, head, sector):
91 c0240ac1 Nikos Skalkotos
            """Packs a CHS tuple to an address string."""
92 331aa0ec Nikos Skalkotos
93 331aa0ec Nikos Skalkotos
            assert 1 <= sector <= 63
94 331aa0ec Nikos Skalkotos
            assert 0 <= cylinder <= 1023
95 331aa0ec Nikos Skalkotos
            assert 0 <= head <= 255
96 331aa0ec Nikos Skalkotos
97 331aa0ec Nikos Skalkotos
            byte0 = head
98 331aa0ec Nikos Skalkotos
            byte1 = (cylinder >> 2) & 0xC0 | sector
99 331aa0ec Nikos Skalkotos
            byte2 = cylinder & 0xff
100 331aa0ec Nikos Skalkotos
101 331aa0ec Nikos Skalkotos
            return struct.pack('<BBB', byte0, byte1, byte2)
102 331aa0ec Nikos Skalkotos
103 331aa0ec Nikos Skalkotos
    format = "<444s2x16s16s16s16s2s"
104 331aa0ec Nikos Skalkotos
    """
105 331aa0ec Nikos Skalkotos
    Offset  Length          Contents
106 331aa0ec Nikos Skalkotos
    0       440(max. 446)   code area
107 331aa0ec Nikos Skalkotos
    440     2(optional)     disk signature
108 331aa0ec Nikos Skalkotos
    444     2               Usually nulls
109 331aa0ec Nikos Skalkotos
    446     16              Partition 0
110 331aa0ec Nikos Skalkotos
    462     16              Partition 1
111 331aa0ec Nikos Skalkotos
    478     16              Partition 2
112 331aa0ec Nikos Skalkotos
    494     16              Partition 3
113 331aa0ec Nikos Skalkotos
    510     2               MBR signature
114 331aa0ec Nikos Skalkotos
    """
115 331aa0ec Nikos Skalkotos
    def __init__(self, block):
116 331aa0ec Nikos Skalkotos
        raw_part = {}
117 331aa0ec Nikos Skalkotos
        self.code_area, \
118 331aa0ec Nikos Skalkotos
        raw_part[0], \
119 331aa0ec Nikos Skalkotos
        raw_part[1], \
120 331aa0ec Nikos Skalkotos
        raw_part[2], \
121 331aa0ec Nikos Skalkotos
        raw_part[3], \
122 331aa0ec Nikos Skalkotos
        self.signature = struct.unpack(self.format, block)
123 331aa0ec Nikos Skalkotos
124 331aa0ec Nikos Skalkotos
        self.part = {}
125 331aa0ec Nikos Skalkotos
        for i in range(4):
126 331aa0ec Nikos Skalkotos
            self.part[i] = self.Partition(raw_part[i])
127 331aa0ec Nikos Skalkotos
128 c0240ac1 Nikos Skalkotos
    @staticmethod
129 c0240ac1 Nikos Skalkotos
    def size():
130 c0240ac1 Nikos Skalkotos
        """Returns the size of a Master Boot Record."""
131 c0240ac1 Nikos Skalkotos
        return struct.calcsize(MBR.format)
132 c0240ac1 Nikos Skalkotos
133 331aa0ec Nikos Skalkotos
    def pack(self):
134 c0240ac1 Nikos Skalkotos
        """Packs an MBR to a binary string."""
135 331aa0ec Nikos Skalkotos
        return struct.pack(self.format,
136 331aa0ec Nikos Skalkotos
            self.code_area,
137 331aa0ec Nikos Skalkotos
            self.part[0].pack(),
138 331aa0ec Nikos Skalkotos
            self.part[1].pack(),
139 331aa0ec Nikos Skalkotos
            self.part[2].pack(),
140 331aa0ec Nikos Skalkotos
            self.part[3].pack(),
141 331aa0ec Nikos Skalkotos
            self.signature
142 331aa0ec Nikos Skalkotos
        )
143 331aa0ec Nikos Skalkotos
144 c0240ac1 Nikos Skalkotos
    def __str__(self):
145 c0240ac1 Nikos Skalkotos
        ret = ""
146 331aa0ec Nikos Skalkotos
        for i in range(4):
147 c0240ac1 Nikos Skalkotos
            ret += "Partition %d: %s\n" % (i, self.part[i])
148 c0240ac1 Nikos Skalkotos
        ret += "Signature: %s %s\n" % (
149 c0240ac1 Nikos Skalkotos
                    hex(ord(self.signature[0])), hex(ord(self.signature[1])))
150 c0240ac1 Nikos Skalkotos
        return ret
151 331aa0ec Nikos Skalkotos
152 331aa0ec Nikos Skalkotos
153 331aa0ec Nikos Skalkotos
class GPTPartitionTable(object):
154 c0240ac1 Nikos Skalkotos
    """Represents a GUID Partition Table."""
155 331aa0ec Nikos Skalkotos
    class GPTHeader(object):
156 c0240ac1 Nikos Skalkotos
        """Represents a GPT Header of a GUID Partition Table."""
157 331aa0ec Nikos Skalkotos
        format = "<8s4sII4xQQQQ16sQIII"
158 331aa0ec Nikos Skalkotos
        """
159 331aa0ec Nikos Skalkotos
        Offset        Length                 Contents
160 331aa0ec Nikos Skalkotos
        0       8 bytes         Signature
161 331aa0ec Nikos Skalkotos
        8       4 bytes         Revision
162 331aa0ec Nikos Skalkotos
        12      4 bytes         Header size in little endian
163 331aa0ec Nikos Skalkotos
        16         4 bytes         CRC32 of header
164 331aa0ec Nikos Skalkotos
        20         4 bytes         Reserved; must be zero
165 331aa0ec Nikos Skalkotos
        24         8 bytes         Current LBA
166 331aa0ec Nikos Skalkotos
        32         8 bytes         Backup LBA
167 331aa0ec Nikos Skalkotos
        40         8 bytes         First usable LBA for partitions
168 331aa0ec Nikos Skalkotos
        48         8 bytes         Last usable LBA
169 331aa0ec Nikos Skalkotos
        56         16 bytes         Disk GUID
170 331aa0ec Nikos Skalkotos
        72         8 bytes         Partition entries starting LBA
171 331aa0ec Nikos Skalkotos
        80         4 bytes         Number of partition entries
172 331aa0ec Nikos Skalkotos
        84         4 bytes         Size of a partition entry
173 331aa0ec Nikos Skalkotos
        88         4 bytes         CRC32 of partition array
174 331aa0ec Nikos Skalkotos
        92         *                 Reserved; must be zeroes
175 331aa0ec Nikos Skalkotos
        LBA    size            Total
176 331aa0ec Nikos Skalkotos
        """
177 331aa0ec Nikos Skalkotos
178 331aa0ec Nikos Skalkotos
        def __init__(self, block):
179 331aa0ec Nikos Skalkotos
            self.signature, \
180 331aa0ec Nikos Skalkotos
            self.revision, \
181 c0240ac1 Nikos Skalkotos
            self.hdr_size, \
182 331aa0ec Nikos Skalkotos
            self.header_crc32, \
183 331aa0ec Nikos Skalkotos
            self.current_lba, \
184 331aa0ec Nikos Skalkotos
            self.backup_lba, \
185 331aa0ec Nikos Skalkotos
            self.first_usable_lba, \
186 331aa0ec Nikos Skalkotos
            self.last_usable_lba, \
187 331aa0ec Nikos Skalkotos
            self.uuid, \
188 331aa0ec Nikos Skalkotos
            self.part_entry_start, \
189 331aa0ec Nikos Skalkotos
            self.part_count, \
190 331aa0ec Nikos Skalkotos
            self.part_entry_size, \
191 331aa0ec Nikos Skalkotos
            self.part_crc32 = struct.unpack(self.format, block)
192 331aa0ec Nikos Skalkotos
193 331aa0ec Nikos Skalkotos
        def pack(self):
194 c0240ac1 Nikos Skalkotos
            """Packs a GPT Header to a binary string."""
195 331aa0ec Nikos Skalkotos
            return struct.pack(self.format,
196 331aa0ec Nikos Skalkotos
                self.signature, \
197 331aa0ec Nikos Skalkotos
                self.revision, \
198 c0240ac1 Nikos Skalkotos
                self.hdr_size, \
199 331aa0ec Nikos Skalkotos
                self.header_crc32, \
200 331aa0ec Nikos Skalkotos
                self.current_lba, \
201 331aa0ec Nikos Skalkotos
                self.backup_lba, \
202 331aa0ec Nikos Skalkotos
                self.first_usable_lba, \
203 331aa0ec Nikos Skalkotos
                self.last_usable_lba, \
204 331aa0ec Nikos Skalkotos
                self.uuid, \
205 331aa0ec Nikos Skalkotos
                self.part_entry_start, \
206 331aa0ec Nikos Skalkotos
                self.part_count, \
207 331aa0ec Nikos Skalkotos
                self.part_entry_size, \
208 331aa0ec Nikos Skalkotos
                self.part_crc32
209 331aa0ec Nikos Skalkotos
            )
210 331aa0ec Nikos Skalkotos
211 c0240ac1 Nikos Skalkotos
        @staticmethod
212 c0240ac1 Nikos Skalkotos
        def size():
213 c0240ac1 Nikos Skalkotos
            """Returns the size of a GPT Header."""
214 c0240ac1 Nikos Skalkotos
            return struct.calcsize(GPTPartitionTable.GPTHeader.format)
215 c0240ac1 Nikos Skalkotos
216 c0240ac1 Nikos Skalkotos
        def __str__(self):
217 c0240ac1 Nikos Skalkotos
            return \
218 c0240ac1 Nikos Skalkotos
            "Signature: %s\n" % self.signature + \
219 c0240ac1 Nikos Skalkotos
            "Revision: %r\n" % self.revision + \
220 c0240ac1 Nikos Skalkotos
            "Header Size: %d\n" % self.hdr_size + \
221 c0240ac1 Nikos Skalkotos
            "CRC32: %d\n" % self.header_crc32 + \
222 c0240ac1 Nikos Skalkotos
            "Current LBA: %d\n" % self.current_lba + \
223 c0240ac1 Nikos Skalkotos
            "Backup LBA: %d\n" % self.backup_lba + \
224 c0240ac1 Nikos Skalkotos
            "First Usable LBA: %d\n" % self.first_usable_lba + \
225 c0240ac1 Nikos Skalkotos
            "Last Usable LBA: %d\n" % self.last_usable_lba + \
226 c0240ac1 Nikos Skalkotos
            "Disk GUID: %s\n" % uuid.UUID(bytes=self.uuid) + \
227 c0240ac1 Nikos Skalkotos
            "Partition entries starting LBA: %d\n" % self.part_entry_start + \
228 c0240ac1 Nikos Skalkotos
            "Number of Partition entries: %d\n" % self.part_count + \
229 c0240ac1 Nikos Skalkotos
            "Size of a partition entry: %d\n" % self.part_entry_size + \
230 c0240ac1 Nikos Skalkotos
            "CRC32 of partition array: %s\n" % self.part_crc32
231 331aa0ec Nikos Skalkotos
232 331aa0ec Nikos Skalkotos
    def __init__(self, disk):
233 331aa0ec Nikos Skalkotos
        self.disk = disk
234 331aa0ec Nikos Skalkotos
        with open(disk, "rb") as d:
235 5b801534 Nikos Skalkotos
            # MBR (Logical block address 0)
236 331aa0ec Nikos Skalkotos
            lba0 = d.read(BLOCKSIZE)
237 331aa0ec Nikos Skalkotos
            self.mbr = MBR(lba0)
238 c0240ac1 Nikos Skalkotos
239 331aa0ec Nikos Skalkotos
            # Primary GPT Header (LBA 1)
240 c0240ac1 Nikos Skalkotos
            raw_header = d.read(self.GPTHeader.size())
241 c0240ac1 Nikos Skalkotos
            self.primary = self.GPTHeader(raw_header)
242 c0240ac1 Nikos Skalkotos
243 331aa0ec Nikos Skalkotos
            # Partition entries (LBA 2...34)
244 331aa0ec Nikos Skalkotos
            d.seek(self.primary.part_entry_start * BLOCKSIZE)
245 331aa0ec Nikos Skalkotos
            entries_size = self.primary.part_count * \
246 331aa0ec Nikos Skalkotos
                                                self.primary.part_entry_size
247 331aa0ec Nikos Skalkotos
            self.part_entries = d.read(entries_size)
248 c0240ac1 Nikos Skalkotos
249 331aa0ec Nikos Skalkotos
            # Secondary GPT Header (LBA -1)
250 331aa0ec Nikos Skalkotos
            d.seek(self.primary.backup_lba * BLOCKSIZE)
251 c0240ac1 Nikos Skalkotos
            raw_header = d.read(self.GPTHeader.size())
252 c0240ac1 Nikos Skalkotos
            self.secondary = self.GPTHeader(raw_header)
253 331aa0ec Nikos Skalkotos
254 331aa0ec Nikos Skalkotos
    def size(self):
255 c0240ac1 Nikos Skalkotos
        """Returns the payload size of GPT partitioned device."""
256 c0240ac1 Nikos Skalkotos
        return (self.primary.backup_lba + 1) * BLOCKSIZE
257 331aa0ec Nikos Skalkotos
258 9666a511 Nikos Skalkotos
    def shrink(self, size, old_size):
259 c0240ac1 Nikos Skalkotos
        """Move the secondary GPT Header entries to the address specified by
260 c0240ac1 Nikos Skalkotos
        size parameter.
261 c0240ac1 Nikos Skalkotos
        """
262 331aa0ec Nikos Skalkotos
263 9666a511 Nikos Skalkotos
        # Most partition manipulation programs leave 2048 sector after the last
264 9666a511 Nikos Skalkotos
        # partition
265 9666a511 Nikos Skalkotos
        aligned = size + 2048 * BLOCKSIZE
266 9666a511 Nikos Skalkotos
267 9666a511 Nikos Skalkotos
        # new_size is at least: size + Partition Entries + Secondary GPT Header
268 9666a511 Nikos Skalkotos
        new_size = aligned if aligned <= old_size else \
269 9666a511 Nikos Skalkotos
                   size + len(self.part_entries) + BLOCKSIZE
270 9666a511 Nikos Skalkotos
271 9666a511 Nikos Skalkotos
        assert new_size <= old_size, "The secodary GPT fits in the device"
272 9666a511 Nikos Skalkotos
273 9666a511 Nikos Skalkotos
        if new_size == self.size():
274 9666a511 Nikos Skalkotos
            return new_size
275 331aa0ec Nikos Skalkotos
276 331aa0ec Nikos Skalkotos
        lba_count = new_size // BLOCKSIZE
277 331aa0ec Nikos Skalkotos
278 331aa0ec Nikos Skalkotos
        # Correct MBR
279 c0240ac1 Nikos Skalkotos
        #TODO: Check if the partition tables is hybrid
280 331aa0ec Nikos Skalkotos
        self.mbr.part[0].sector_count = (new_size // BLOCKSIZE) - 1
281 331aa0ec Nikos Skalkotos
282 c0240ac1 Nikos Skalkotos
        # Fix Primary header
283 331aa0ec Nikos Skalkotos
        self.primary.header_crc32 = 0
284 331aa0ec Nikos Skalkotos
        self.primary.backup_lba = lba_count - 1  # LBA-1
285 331aa0ec Nikos Skalkotos
        self.primary.last_usable_lba = lba_count - 34  # LBA-34
286 331aa0ec Nikos Skalkotos
        self.primary.header_crc32 = \
287 331aa0ec Nikos Skalkotos
                            binascii.crc32(self.primary.pack()) & 0xffffffff
288 331aa0ec Nikos Skalkotos
289 c0240ac1 Nikos Skalkotos
        # Fix Secondary header
290 331aa0ec Nikos Skalkotos
        self.secondary.header_crc32 = 0
291 331aa0ec Nikos Skalkotos
        self.secondary.current_lba = self.primary.backup_lba
292 331aa0ec Nikos Skalkotos
        self.secondary.last_usable_lba = lba_count - 34  # LBA-34
293 331aa0ec Nikos Skalkotos
        self.secondary.part_entry_start = lba_count - 33  # LBA-33
294 331aa0ec Nikos Skalkotos
        self.secondary.header_crc32 = \
295 331aa0ec Nikos Skalkotos
                            binascii.crc32(self.secondary.pack()) & 0xffffffff
296 331aa0ec Nikos Skalkotos
297 331aa0ec Nikos Skalkotos
        # Copy the new partition table back to the device
298 331aa0ec Nikos Skalkotos
        with open(self.disk, "wb") as d:
299 331aa0ec Nikos Skalkotos
            d.write(self.mbr.pack())
300 331aa0ec Nikos Skalkotos
            d.write(self.primary.pack())
301 c0240ac1 Nikos Skalkotos
            d.write('\x00' * (BLOCKSIZE - self.primary.size()))
302 331aa0ec Nikos Skalkotos
            d.seek(self.secondary.part_entry_start * BLOCKSIZE)
303 331aa0ec Nikos Skalkotos
            d.write(self.part_entries)
304 331aa0ec Nikos Skalkotos
            d.seek(self.primary.backup_lba * BLOCKSIZE)
305 331aa0ec Nikos Skalkotos
            d.write(self.secondary.pack())
306 c0240ac1 Nikos Skalkotos
            d.write('\x00' * (BLOCKSIZE - self.secondary.size()))
307 331aa0ec Nikos Skalkotos
308 331aa0ec Nikos Skalkotos
        return new_size
309 331aa0ec Nikos Skalkotos
310 331aa0ec Nikos Skalkotos
if __name__ == '__main__':
311 331aa0ec Nikos Skalkotos
    ptable = GPTPartitionTable(sys.argv[1])
312 331aa0ec Nikos Skalkotos
313 c0240ac1 Nikos Skalkotos
    print "MBR:\n%s" % ptable.mbr
314 c0240ac1 Nikos Skalkotos
    print "Primary partition table:\n%s" % ptable.primary
315 c0240ac1 Nikos Skalkotos
    print "Secondary partition table:\n%s" % ptable.secondary
316 331aa0ec Nikos Skalkotos
317 331aa0ec Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :