diff options
author | Michael Marineau | 2015-05-03 00:52:48 +0200 |
---|---|---|
committer | Karel Zak | 2015-05-05 12:39:36 +0200 |
commit | 4a4a0927c6b761f7b8b29b00491b22b3553720e8 (patch) | |
tree | 91dc14b26e6650b10dbb94af2535354724b3736c /libfdisk | |
parent | libfdisk: (gpt) fix check for beginning of protective partition (diff) | |
download | kernel-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.txt | 2 | ||||
-rw-r--r-- | libfdisk/src/Makemodule.am | 6 | ||||
-rw-r--r-- | libfdisk/src/gpt.c | 126 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.h.in | 2 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.sym | 2 |
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; |