Simply code motion, there should be no change to the functionality.
---
filters/partition/partition.h | 48 ++++++++++
filters/partition/partition-gpt.c | 126 ++++++++++++++++++++++++++
filters/partition/partition-mbr.c | 91 +++++++++++++++++++
filters/partition/partition.c | 146 +++---------------------------
filters/partition/Makefile.am | 5 +-
5 files changed, 280 insertions(+), 136 deletions(-)
diff --git a/filters/partition/partition.h b/filters/partition/partition.h
new file mode 100644
index 0000000..f82d845
--- /dev/null
+++ b/filters/partition/partition.h
@@ -0,0 +1,48 @@
+/* nbdkit
+ * Copyright (C) 2018-2019 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Red Hat nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef NBDKIT_PARTITION_H
+#define NBDKIT_PARTITION_H
+
+#include <nbdkit-filter.h>
+
+extern int partnum;
+
+extern int find_mbr_partition (struct nbdkit_next_ops *next_ops, void *nxdata,
+ int64_t size, uint8_t *mbr,
+ int64_t *offset_r, int64_t *range_r);
+extern int find_gpt_partition (struct nbdkit_next_ops *next_ops, void *nxdata,
+ int64_t size, uint8_t *header_bytes,
+ int64_t *offset_r, int64_t *range_r);
+
+#endif /* NBDKIT_PARTITION_H */
diff --git a/filters/partition/partition-gpt.c b/filters/partition/partition-gpt.c
new file mode 100644
index 0000000..feefe7b
--- /dev/null
+++ b/filters/partition/partition-gpt.c
@@ -0,0 +1,126 @@
+/* nbdkit
+ * Copyright (C) 2018-2019 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Red Hat nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <nbdkit-filter.h>
+
+#include "byte-swapping.h"
+
+#include "partition.h"
+
+struct gpt_header {
+ uint32_t nr_partitions;
+ uint32_t partition_entry_size;
+};
+
+static void
+get_gpt_header (uint8_t *sector, struct gpt_header *header)
+{
+ memcpy (&header->nr_partitions, §or[0x50], 4);
+ header->nr_partitions = le32toh (header->nr_partitions);
+ memcpy (&header->partition_entry_size, §or[0x54], 4);
+ header->partition_entry_size = le32toh (header->partition_entry_size);
+}
+
+struct gpt_partition {
+ uint8_t partition_type_guid[16];
+ uint64_t first_lba;
+ uint64_t last_lba;
+};
+
+static void
+get_gpt_partition (uint8_t *bytes, struct gpt_partition *part)
+{
+ memcpy (&part->partition_type_guid, &bytes[0], 16);
+ memcpy (&part->first_lba, &bytes[0x20], 8);
+ part->first_lba = le64toh (part->first_lba);
+ memcpy (&part->last_lba, &bytes[0x28], 8);
+ part->last_lba = le64toh (part->last_lba);
+}
+
+int
+find_gpt_partition (struct nbdkit_next_ops *next_ops, void *nxdata,
+ int64_t size, uint8_t *header_bytes,
+ int64_t *offset_r, int64_t *range_r)
+{
+ uint8_t partition_bytes[128];
+ struct gpt_header header;
+ struct gpt_partition partition;
+ int i;
+ int err;
+
+ get_gpt_header (header_bytes, &header);
+ if (partnum > header.nr_partitions) {
+ nbdkit_error ("GPT partition number out of range");
+ return -1;
+ }
+
+ if (header.partition_entry_size < 128) {
+ nbdkit_error ("GPT partition entry size is < 128 bytes");
+ return -1;
+ }
+
+ /* Check the disk is large enough to contain the partition table
+ * array (twice) plus other GPT overheads. Otherwise it is likely
+ * that the GPT header is bogus.
+ */
+ if (size < INT64_C(3*512) +
+ INT64_C(2) * header.nr_partitions * header.partition_entry_size) {
+ nbdkit_error ("GPT partition table is too large for this disk");
+ return -1;
+ }
+
+ for (i = 0; i < header.nr_partitions; ++i) {
+ /* We already checked these are within bounds above. */
+ if (next_ops->pread (nxdata, partition_bytes, sizeof partition_bytes,
+ 2*512 + i*header.partition_entry_size, 0, &err) == -1)
+ return -1;
+ get_gpt_partition (partition_bytes, &partition);
+ if (memcmp (partition.partition_type_guid,
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) != 0 &&
+ partnum == i+1) {
+ *offset_r = partition.first_lba * 512;
+ *range_r = (1 + partition.last_lba - partition.first_lba) * 512;
+ return 0;
+ }
+ }
+
+ nbdkit_error ("GPT partition %d not found", partnum);
+ return -1;
+}
diff --git a/filters/partition/partition-mbr.c b/filters/partition/partition-mbr.c
new file mode 100644
index 0000000..f679db0
--- /dev/null
+++ b/filters/partition/partition-mbr.c
@@ -0,0 +1,91 @@
+/* nbdkit
+ * Copyright (C) 2018-2019 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Red Hat nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <nbdkit-filter.h>
+
+#include "byte-swapping.h"
+
+#include "partition.h"
+
+struct mbr_partition {
+ uint8_t part_type_byte;
+ uint32_t start_sector;
+ uint32_t nr_sectors;
+};
+
+static void
+get_mbr_partition (uint8_t *sector, int i, struct mbr_partition *part)
+{
+ int offset = 0x1BE + i*0x10;
+
+ part->part_type_byte = sector[offset+4];
+ memcpy (&part->start_sector, §or[offset+8], 4);
+ part->start_sector = le32toh (part->start_sector);
+ memcpy (&part->nr_sectors, §or[offset+0xC], 4);
+ part->nr_sectors = le32toh (part->nr_sectors);
+}
+
+int
+find_mbr_partition (struct nbdkit_next_ops *next_ops, void *nxdata,
+ int64_t size, uint8_t *mbr,
+ int64_t *offset_r, int64_t *range_r)
+{
+ int i;
+ struct mbr_partition partition;
+
+ if (partnum > 4) {
+ nbdkit_error ("MBR logical partitions are not supported");
+ return -1;
+ }
+
+ for (i = 0; i < 4; ++i) {
+ get_mbr_partition (mbr, i, &partition);
+ if (partition.nr_sectors > 0 &&
+ partition.part_type_byte != 0 &&
+ partnum == i+1) {
+ *offset_r = partition.start_sector * 512;
+ *range_r = partition.nr_sectors * 512;
+ return 0;
+ }
+ }
+
+ nbdkit_error ("MBR partition %d not found", partnum);
+ return -1;
+}
diff --git a/filters/partition/partition.c b/filters/partition/partition.c
index 4d141ef..af103a8 100644
--- a/filters/partition/partition.c
+++ b/filters/partition/partition.c
@@ -1,5 +1,5 @@
/* nbdkit
- * Copyright (C) 2018 Red Hat Inc.
+ * Copyright (C) 2018-2019 Red Hat Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,9 +43,11 @@
#include "byte-swapping.h"
+#include "partition.h"
+
#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-static int partnum = -1;
+int partnum = -1;
/* Called for each key=value passed on the command line. */
static int
@@ -111,134 +113,6 @@ partition_close (void *handle)
free (h);
}
-/* Inspect the underlying partition table. partition_prepare is
- * called before data processing.
- */
-struct mbr_partition {
- uint8_t part_type_byte;
- uint32_t start_sector;
- uint32_t nr_sectors;
-};
-
-static void
-get_mbr_partition (uint8_t *sector, int i, struct mbr_partition *part)
-{
- int offset = 0x1BE + i*0x10;
-
- part->part_type_byte = sector[offset+4];
- memcpy (&part->start_sector, §or[offset+8], 4);
- part->start_sector = le32toh (part->start_sector);
- memcpy (&part->nr_sectors, §or[offset+0xC], 4);
- part->nr_sectors = le32toh (part->nr_sectors);
-}
-
-static int
-find_mbr_partition (struct nbdkit_next_ops *next_ops, void *nxdata,
- struct handle *h, int64_t size, uint8_t *mbr)
-{
- int i;
- struct mbr_partition partition;
-
- if (partnum > 4) {
- nbdkit_error ("MBR logical partitions are not supported");
- return -1;
- }
-
- for (i = 0; i < 4; ++i) {
- get_mbr_partition (mbr, i, &partition);
- if (partition.nr_sectors > 0 &&
- partition.part_type_byte != 0 &&
- partnum == i+1) {
- h->offset = partition.start_sector * 512;
- h->range = partition.nr_sectors * 512;
- return 0;
- }
- }
-
- nbdkit_error ("MBR partition %d not found", partnum);
- return -1;
-}
-
-struct gpt_header {
- uint32_t nr_partitions;
- uint32_t partition_entry_size;
-};
-
-static void
-get_gpt_header (uint8_t *sector, struct gpt_header *header)
-{
- memcpy (&header->nr_partitions, §or[0x50], 4);
- header->nr_partitions = le32toh (header->nr_partitions);
- memcpy (&header->partition_entry_size, §or[0x54], 4);
- header->partition_entry_size = le32toh (header->partition_entry_size);
-}
-
-struct gpt_partition {
- uint8_t partition_type_guid[16];
- uint64_t first_lba;
- uint64_t last_lba;
-};
-
-static void
-get_gpt_partition (uint8_t *bytes, struct gpt_partition *part)
-{
- memcpy (&part->partition_type_guid, &bytes[0], 16);
- memcpy (&part->first_lba, &bytes[0x20], 8);
- part->first_lba = le64toh (part->first_lba);
- memcpy (&part->last_lba, &bytes[0x28], 8);
- part->last_lba = le64toh (part->last_lba);
-}
-
-static int
-find_gpt_partition (struct nbdkit_next_ops *next_ops, void *nxdata,
- struct handle *h, int64_t size, uint8_t *header_bytes)
-{
- uint8_t partition_bytes[128];
- struct gpt_header header;
- struct gpt_partition partition;
- int i;
- int err;
-
- get_gpt_header (header_bytes, &header);
- if (partnum > header.nr_partitions) {
- nbdkit_error ("GPT partition number out of range");
- return -1;
- }
-
- if (header.partition_entry_size < 128) {
- nbdkit_error ("GPT partition entry size is < 128 bytes");
- return -1;
- }
-
- /* Check the disk is large enough to contain the partition table
- * array (twice) plus other GPT overheads. Otherwise it is likely
- * that the GPT header is bogus.
- */
- if (size < INT64_C(3*512) +
- INT64_C(2) * header.nr_partitions * header.partition_entry_size) {
- nbdkit_error ("GPT partition table is too large for this disk");
- return -1;
- }
-
- for (i = 0; i < header.nr_partitions; ++i) {
- /* We already checked these are within bounds above. */
- if (next_ops->pread (nxdata, partition_bytes, sizeof partition_bytes,
- 2*512 + i*header.partition_entry_size, 0, &err) == -1)
- return -1;
- get_gpt_partition (partition_bytes, &partition);
- if (memcmp (partition.partition_type_guid,
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) != 0 &&
- partnum == i+1) {
- h->offset = partition.first_lba * 512;
- h->range = (1 + partition.last_lba - partition.first_lba) * 512;
- return 0;
- }
- }
-
- nbdkit_error ("GPT partition %d not found", partnum);
- return -1;
-}
-
static int
partition_prepare (struct nbdkit_next_ops *next_ops, void *nxdata,
void *handle)
@@ -264,10 +138,12 @@ partition_prepare (struct nbdkit_next_ops *next_ops, void *nxdata,
/* Is it GPT? */
if (size >= 2 * 34 * 512 && memcmp (&lba01[512], "EFI PART",
8) == 0)
- r = find_gpt_partition (next_ops, nxdata, h, size, &lba01[512]);
+ r = find_gpt_partition (next_ops, nxdata, size, &lba01[512],
+ &h->offset, &h->range);
/* Is it MBR? */
else if (lba01[0x1fe] == 0x55 && lba01[0x1ff] == 0xAA)
- r = find_mbr_partition (next_ops, nxdata, h, size, lba01);
+ r = find_mbr_partition (next_ops, nxdata, size, lba01,
+ &h->offset, &h->range);
else {
nbdkit_error ("disk does not contain MBR or GPT partition table
signature");
r = -1;
@@ -275,9 +151,9 @@ partition_prepare (struct nbdkit_next_ops *next_ops, void *nxdata,
if (r == -1)
return -1;
- /* The find_*_partition functions set h->offset & h->range in the
- * handle to point to the partition boundaries. However we
- * additionally check that they are inside the underlying disk.
+ /* The find_*_partition functions set h->offset & h->range to the
+ * partition boundaries. We additionally check that they are inside
+ * the underlying disk.
*/
if (h->offset < 0 || h->range < 0 || h->offset + h->range > size)
{
nbdkit_error ("partition is outside the disk");
diff --git a/filters/partition/Makefile.am b/filters/partition/Makefile.am
index 7e8430a..0932793 100644
--- a/filters/partition/Makefile.am
+++ b/filters/partition/Makefile.am
@@ -1,5 +1,5 @@
# nbdkit
-# Copyright (C) 2018 Red Hat Inc.
+# Copyright (C) 2018-2019 Red Hat Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,9 @@ filter_LTLIBRARIES = nbdkit-partition-filter.la
nbdkit_partition_filter_la_SOURCES = \
partition.c \
+ partition.h \
+ partition-gpt.c \
+ partition-mbr.c \
$(top_srcdir)/include/nbdkit-filter.h
nbdkit_partition_filter_la_CPPFLAGS = \
--
2.20.1