summaryrefslogtreecommitdiffstats
path: root/libfdisk
diff options
context:
space:
mode:
authorMichael Marineau2015-05-03 00:52:48 +0200
committerKarel Zak2015-05-05 12:39:36 +0200
commit4a4a0927c6b761f7b8b29b00491b22b3553720e8 (patch)
tree91dc14b26e6650b10dbb94af2535354724b3736c /libfdisk
parentlibfdisk: (gpt) fix check for beginning of protective partition (diff)
downloadkernel-qcow2-util-linux-4a4a0927c6b761f7b8b29b00491b22b3553720e8.tar.gz
kernel-qcow2-util-linux-4a4a0927c6b761f7b8b29b00491b22b3553720e8.tar.xz
kernel-qcow2-util-linux-4a4a0927c6b761f7b8b29b00491b22b3553720e8.zip
libfdisk: (gpt) add API for raw partition attributes
The existing APIs can only toggle individual bits or get and set bits in a complex text representation, making it impractical to use libfdisk for manipulating the GPT partition attribute field in more complex ways such as updating a value that is multiple bits wide. For example priority based partition selection originally designed for ChromeOS includes two integer values that are 4-bits wide. http://www.chromium.org/chromium-os/chromiumos-design-docs/disk-format#TOC-Trusting-the-GPT [kzak@redhat.com: - add new symbols to .sym file and docs - remove unused variables from test program] Signed-off-by: Michael Marineau <michael.marineau@coreos.com> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libfdisk')
-rw-r--r--libfdisk/docs/libfdisk-sections.txt2
-rw-r--r--libfdisk/src/Makemodule.am6
-rw-r--r--libfdisk/src/gpt.c126
-rw-r--r--libfdisk/src/libfdisk.h.in2
-rw-r--r--libfdisk/src/libfdisk.sym2
5 files changed, 138 insertions, 0 deletions
diff --git a/libfdisk/docs/libfdisk-sections.txt b/libfdisk/docs/libfdisk-sections.txt
index acee8f855..02b775ea6 100644
--- a/libfdisk/docs/libfdisk-sections.txt
+++ b/libfdisk/docs/libfdisk-sections.txt
@@ -223,6 +223,8 @@ fdisk_sgi_set_bootfile
<SECTION>
<FILE>gpt</FILE>
fdisk_gpt_is_hybrid
+fdisk_gpt_get_partition_attrs
+fdisk_gpt_set_partition_attrs
GPT_FLAG_REQUIRED
GPT_FLAG_NOBLOCK
GPT_FLAG_LEGACYBOOT
diff --git a/libfdisk/src/Makemodule.am b/libfdisk/src/Makemodule.am
index 347ea8e11..00c3d9f0c 100644
--- a/libfdisk/src/Makemodule.am
+++ b/libfdisk/src/Makemodule.am
@@ -64,6 +64,7 @@ EXTRA_DIST += \
if BUILD_LIBFDISK_TESTS
check_PROGRAMS += \
test_fdisk_ask \
+ test_fdisk_gpt \
test_fdisk_script \
test_fdisk_utils \
test_fdisk_version
@@ -81,6 +82,11 @@ test_fdisk_ask_CFLAGS = $(libfdisk_tests_cflags)
test_fdisk_ask_LDFLAGS = $(libfdisk_tests_ldflags)
test_fdisk_ask_LDADD = $(libfdisk_tests_ldadd)
+test_fdisk_gpt_SOURCES = libfdisk/src/gpt.c
+test_fdisk_gpt_CFLAGS = $(libfdisk_tests_cflags)
+test_fdisk_gpt_LDFLAGS = $(libfdisk_tests_ldflags)
+test_fdisk_gpt_LDADD = $(libfdisk_tests_ldadd)
+
test_fdisk_utils_SOURCES = libfdisk/src/utils.c
test_fdisk_utils_CFLAGS = $(libfdisk_tests_cflags)
test_fdisk_utils_LDFLAGS = $(libfdisk_tests_ldflags)
diff --git a/libfdisk/src/gpt.c b/libfdisk/src/gpt.c
index 989fd752c..a7ec5397a 100644
--- a/libfdisk/src/gpt.c
+++ b/libfdisk/src/gpt.c
@@ -2429,6 +2429,73 @@ int fdisk_gpt_is_hybrid(struct fdisk_context *cxt)
return valid_pmbr(cxt) == GPT_MBR_HYBRID;
}
+/**
+ * fdisk_gpt_get_partition_attrs:
+ * @cxt: context
+ * @partnum: partition number
+ * @attrs: GPT partition attributes
+ *
+ * Sets @attrs for the given partition
+ *
+ * Returns: 0 on success, <0 on error.
+ */
+int fdisk_gpt_get_partition_attrs(
+ struct fdisk_context *cxt,
+ size_t partnum,
+ uint64_t *attrs)
+{
+ struct fdisk_gpt_label *gpt;
+
+ assert(cxt);
+ assert(cxt->label);
+ assert(fdisk_is_label(cxt, GPT));
+
+ gpt = self_label(cxt);
+
+ if ((uint32_t) partnum >= le32_to_cpu(gpt->pheader->npartition_entries))
+ return -EINVAL;
+
+ *attrs = le64_to_cpu(gpt->ents[partnum].attrs);
+ return 0;
+}
+
+/**
+ * fdisk_gpt_set_partition_attrs:
+ * @cxt: context
+ * @partnum: partition number
+ * @attrs: GPT partition attributes
+ *
+ * Sets the GPT partition attributes field to @attrs.
+ *
+ * Returns: 0 on success, <0 on error.
+ */
+int fdisk_gpt_set_partition_attrs(
+ struct fdisk_context *cxt,
+ size_t partnum,
+ uint64_t attrs)
+{
+ struct fdisk_gpt_label *gpt;
+
+ assert(cxt);
+ assert(cxt->label);
+ assert(fdisk_is_label(cxt, GPT));
+
+ DBG(LABEL, ul_debug("GPT entry attributes change requested partno=%zu", partnum));
+ gpt = self_label(cxt);
+
+ if ((uint32_t) partnum >= le32_to_cpu(gpt->pheader->npartition_entries))
+ return -EINVAL;
+
+ gpt->ents[partnum].attrs = cpu_to_le64(attrs);
+ fdisk_info(cxt, _("The attributes on partition %zu changed to 0x%016" PRIx64 "."),
+ partnum + 1, attrs);
+
+ gpt_recompute_crc(gpt->pheader, gpt->ents);
+ gpt_recompute_crc(gpt->bheader, gpt->ents);
+ fdisk_label_set_changed(cxt->label, 1);
+ return 0;
+}
+
static int gpt_toggle_partition_flag(
struct fdisk_context *cxt,
size_t i,
@@ -2668,3 +2735,62 @@ struct fdisk_label *fdisk_new_gpt_label(struct fdisk_context *cxt)
return lb;
}
+
+#ifdef TEST_PROGRAM
+int test_getattr(struct fdisk_test *ts, int argc, char *argv[])
+{
+ const char *disk = argv[1];
+ size_t part = strtoul(argv[2], NULL, 0) - 1;
+ struct fdisk_context *cxt;
+ uint64_t atters = 0;
+
+ cxt = fdisk_new_context();
+ fdisk_assign_device(cxt, disk, 1);
+
+ if (!fdisk_is_label(cxt, GPT))
+ return EXIT_FAILURE;
+
+ if (fdisk_gpt_get_partition_attrs(cxt, part, &atters))
+ return EXIT_FAILURE;
+
+ printf("%s: 0x%016" PRIx64 "\n", argv[2], atters);
+
+ fdisk_unref_context(cxt);
+ return 0;
+}
+
+int test_setattr(struct fdisk_test *ts, int argc, char *argv[])
+{
+ const char *disk = argv[1];
+ size_t part = strtoul(argv[2], NULL, 0) - 1;
+ uint64_t atters = strtoull(argv[3], NULL, 0);
+ struct fdisk_context *cxt;
+
+ cxt = fdisk_new_context();
+ fdisk_assign_device(cxt, disk, 0);
+
+ if (!fdisk_is_label(cxt, GPT))
+ return EXIT_FAILURE;
+
+ if (fdisk_gpt_set_partition_attrs(cxt, part, atters))
+ return EXIT_FAILURE;
+
+ if (fdisk_write_disklabel(cxt))
+ return EXIT_FAILURE;
+
+ fdisk_unref_context(cxt);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ struct fdisk_test tss[] = {
+ { "--getattr", test_getattr, "<disk> <partition> print attributes" },
+ { "--setattr", test_setattr, "<disk> <partition> <value> set attributes" },
+ { NULL }
+ };
+
+ return fdisk_run_test(tss, argc, argv);
+}
+
+#endif
diff --git a/libfdisk/src/libfdisk.h.in b/libfdisk/src/libfdisk.h.in
index 5f75ecd14..a5a465674 100644
--- a/libfdisk/src/libfdisk.h.in
+++ b/libfdisk/src/libfdisk.h.in
@@ -531,6 +531,8 @@ extern int fdisk_sgi_create_info(struct fdisk_context *cxt);
#define GPT_FLAG_GUIDSPECIFIC 4
extern int fdisk_gpt_is_hybrid(struct fdisk_context *cxt);
+extern int fdisk_gpt_get_partition_attrs(struct fdisk_context *cxt, size_t partnum, uint64_t *attrs);
+extern int fdisk_gpt_set_partition_attrs(struct fdisk_context *cxt, size_t partnum, uint64_t attrs);
/* script.c */
diff --git a/libfdisk/src/libfdisk.sym b/libfdisk/src/libfdisk.sym
index 456a52d83..1e6394465 100644
--- a/libfdisk/src/libfdisk.sym
+++ b/libfdisk/src/libfdisk.sym
@@ -247,4 +247,6 @@ FDISK_2.27 {
fdisk_enable_bootbits_protection;
fdisk_has_protected_bootbits;
fdisk_table_get_partition_by_partno;
+ fdisk_gpt_get_partition_attrs;
+ fdisk_gpt_set_partition_attrs;
} FDISK_2.26;