libfdisk: add API for work with labelitems
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
e4c5250dfb
commit
40c9c3a6b7
|
@ -91,13 +91,6 @@ fdisk_get_nlabels
|
|||
fdisk_next_label
|
||||
fdisk_get_npartitions
|
||||
<SUBSECTION>
|
||||
fdisk_field
|
||||
fdisk_field_get_id
|
||||
fdisk_field_get_name
|
||||
fdisk_field_get_width
|
||||
fdisk_field_is_number
|
||||
fdisk_fieldtype
|
||||
<SUBSECTION>
|
||||
fdisk_label
|
||||
fdisk_is_label
|
||||
fdisk_label_get_field
|
||||
|
@ -347,3 +340,27 @@ fdisk_iter_get_direction
|
|||
fdisk_new_iter
|
||||
fdisk_reset_iter
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>item</FILE>
|
||||
fdisk_new_labelitem
|
||||
fdisk_ref_labelitem
|
||||
fdisk_reset_labelitem
|
||||
fdisk_unref_labelitem
|
||||
fdisk_labelitem_get_name
|
||||
fdisk_labelitem_get_id
|
||||
fdisk_labelitem_get_data_u64
|
||||
fdisk_labelitem_get_data_string
|
||||
fdisk_labelitem_is_string
|
||||
fdisk_labelitem_is_number
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>field</FILE>
|
||||
fdisk_field
|
||||
fdisk_field_get_id
|
||||
fdisk_field_get_name
|
||||
fdisk_field_get_width
|
||||
fdisk_field_is_number
|
||||
fdisk_fieldtype
|
||||
</SECTION>
|
||||
|
|
|
@ -10,6 +10,7 @@ libfdisk_la_SOURCES = \
|
|||
libfdisk/src/fdiskP.h \
|
||||
libfdisk/src/init.c \
|
||||
libfdisk/src/field.c \
|
||||
libfdisk/src/item.c \
|
||||
libfdisk/src/test.c \
|
||||
libfdisk/src/ask.c \
|
||||
libfdisk/src/alignment.c \
|
||||
|
@ -72,7 +73,8 @@ check_PROGRAMS += \
|
|||
test_fdisk_gpt \
|
||||
test_fdisk_script \
|
||||
test_fdisk_utils \
|
||||
test_fdisk_version
|
||||
test_fdisk_version \
|
||||
test_fdisk_item
|
||||
|
||||
libfdisk_tests_cflags = -DTEST_PROGRAM $(libfdisk_la_CFLAGS) $(NO_UNUSED_WARN_CFLAGS)
|
||||
libfdisk_tests_ldflags = libuuid.la -static
|
||||
|
@ -107,6 +109,11 @@ test_fdisk_version_CFLAGS = $(libfdisk_tests_cflags)
|
|||
test_fdisk_version_LDFLAGS = $(libfdisk_tests_ldflags)
|
||||
test_fdisk_version_LDADD = $(libfdisk_tests_ldadd)
|
||||
|
||||
test_fdisk_item_SOURCES = libfdisk/src/item.c
|
||||
test_fdisk_item_CFLAGS = $(libfdisk_tests_cflags)
|
||||
test_fdisk_item_LDFLAGS = $(libfdisk_tests_ldflags)
|
||||
test_fdisk_item_LDADD = $(libfdisk_tests_ldadd)
|
||||
|
||||
endif # BUILD_LIBFDISK_TESTS
|
||||
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#define LIBFDISK_DEBUG_TAB (1 << 8)
|
||||
#define LIBFDISK_DEBUG_SCRIPT (1 << 9)
|
||||
#define LIBFDISK_DEBUG_WIPE (1 << 10)
|
||||
#define LIBFDISK_DEBUG_ITEM (1 << 11)
|
||||
#define LIBFDISK_DEBUG_ALL 0xFFFF
|
||||
|
||||
UL_DEBUG_DECLARE_MASK(libfdisk);
|
||||
|
@ -420,9 +421,10 @@ extern int fdisk_probe_labels(struct fdisk_context *cxt);
|
|||
extern void fdisk_deinit_label(struct fdisk_label *lb);
|
||||
|
||||
struct fdisk_labelitem {
|
||||
int refcount; /* reference counter */
|
||||
int id; /* <label>_ITEM_* */
|
||||
char type; /* s = string, j = uint64 */
|
||||
const char *name;
|
||||
const char *name; /* human readable name */
|
||||
|
||||
union {
|
||||
char *str;
|
||||
|
|
|
@ -22,6 +22,7 @@ UL_DEBUG_DEFINE_MASKNAMES(libfdisk) =
|
|||
{ "script", LIBFDISK_DEBUG_SCRIPT, "sfdisk-like scripts" },
|
||||
{ "tab", LIBFDISK_DEBUG_TAB, "table utils"},
|
||||
{ "wipe", LIBFDISK_DEBUG_WIPE, "wipe area utils" },
|
||||
{ "item", LIBFDISK_DEBUG_WIPE, "disklabel items" },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
|
||||
#include "fdiskP.h"
|
||||
|
||||
/**
|
||||
* SECTION: labelitem
|
||||
* @title: Labelitem
|
||||
* @short_description: disk label items
|
||||
*
|
||||
* The labelitem is label specific items stored in the partition table header.
|
||||
* The information provided by labelitems are not specific to the partitions.
|
||||
*
|
||||
* For example
|
||||
*
|
||||
* <informalexample>
|
||||
* <programlisting>
|
||||
* struct fdisk_labelitem *item = fdisk_new_labelitem();
|
||||
*
|
||||
* fdisk_get_disklabel_item(cxt, GPT_LABELITEM_ALTLBA, item);
|
||||
* print("Backup header LBA: %ju\n", fdisk_labelitem_get_data_u64(item));
|
||||
*
|
||||
* fdisk_unref_labelitem(item);
|
||||
* </programlisting>
|
||||
* </informalexample>
|
||||
*
|
||||
* returns LBA of the alternative GPT header.
|
||||
*
|
||||
* See also fdisk_get_disklabel_item(). The IDs are generic (e.g.
|
||||
* FDISK_LABEL_ITEM_*) and label specific ((e.g. GPT_LABELITEM_*).
|
||||
*/
|
||||
|
||||
/**
|
||||
* fdisk_new_labelitem
|
||||
*
|
||||
* Returns: new instance.
|
||||
*
|
||||
* Since: v2.29
|
||||
*/
|
||||
struct fdisk_labelitem *fdisk_new_labelitem(void)
|
||||
{
|
||||
struct fdisk_labelitem *li = calloc(1, sizeof(*li));
|
||||
|
||||
li->refcount = 1;
|
||||
DBG(ITEM, ul_debugobj(li, "alloc"));
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_ref_labelitem:
|
||||
* @li: label item
|
||||
*
|
||||
* Incremparts reference counter.
|
||||
*
|
||||
* Since: v2.29
|
||||
*/
|
||||
void fdisk_ref_labelitem(struct fdisk_labelitem *li)
|
||||
{
|
||||
if (li)
|
||||
li->refcount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_reset_labelitem:
|
||||
* @li: label item
|
||||
*
|
||||
* Zeroize data stored in the @li (does not modify anything in disk label).
|
||||
*
|
||||
* Since: v2.29
|
||||
*/
|
||||
int fdisk_reset_labelitem(struct fdisk_labelitem *li)
|
||||
{
|
||||
int refcount;
|
||||
|
||||
if (!li)
|
||||
return -EINVAL;
|
||||
if (li->type == 's')
|
||||
free(li->data.str);
|
||||
|
||||
refcount = li->refcount;
|
||||
memset(li, 0, sizeof(*li));
|
||||
li->refcount = refcount;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_unref_labelitem:
|
||||
* @li: label item
|
||||
*
|
||||
* De-incremparts reference counter, on zero the @li is automatically
|
||||
* deallocated.
|
||||
*
|
||||
* Since: v2.29
|
||||
*/
|
||||
void fdisk_unref_labelitem(struct fdisk_labelitem *li)
|
||||
{
|
||||
if (!li)
|
||||
return;
|
||||
|
||||
li->refcount--;
|
||||
if (li->refcount <= 0) {
|
||||
DBG(ITEM, ul_debugobj(li, "free"));
|
||||
fdisk_reset_labelitem(li);
|
||||
free(li);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_labelitem_get_name:
|
||||
* @li: label item
|
||||
*
|
||||
* Returns: item name or NULL.
|
||||
* Since: v2.29
|
||||
*/
|
||||
const char *fdisk_labelitem_get_name(struct fdisk_labelitem *li)
|
||||
{
|
||||
return li ? li->name : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_labelitem_get_id:
|
||||
* @li: label item
|
||||
*
|
||||
* Returns: item Id or <0 in case of error.
|
||||
* Since: v2.29
|
||||
*/
|
||||
int fdisk_labelitem_get_id(struct fdisk_labelitem *li)
|
||||
{
|
||||
return li ? li->id : -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fdisk_labelitem_get_data_u64:
|
||||
* @li: label item
|
||||
* @data: returns data
|
||||
*
|
||||
* Returns: 0 on success, <0 on error
|
||||
* Since: v2.29
|
||||
*/
|
||||
int fdisk_labelitem_get_data_u64(struct fdisk_labelitem *li, uint64_t *data)
|
||||
{
|
||||
if (!li || li->type != 'j')
|
||||
return -EINVAL;
|
||||
|
||||
if (data)
|
||||
*data = li->data.num64;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_labelitem_get_data_string:
|
||||
* @li: label item
|
||||
* @data: returns data
|
||||
*
|
||||
* Returns: 0 on success, <0 on error.
|
||||
* Since: v2.29
|
||||
*/
|
||||
int fdisk_labelitem_get_data_string(struct fdisk_labelitem *li, const char **data)
|
||||
{
|
||||
if (!li || li->type != 's')
|
||||
return -EINVAL;
|
||||
|
||||
if (data)
|
||||
*data = li->data.str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_labelitem_is_string:
|
||||
* @li: label item
|
||||
*
|
||||
* Returns: 0 or 1
|
||||
*/
|
||||
int fdisk_labelitem_is_string(struct fdisk_labelitem *li)
|
||||
{
|
||||
return li && li->type == 's';
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_labelitem_is_number:
|
||||
* @li: label item
|
||||
*
|
||||
* Returns: 0 or 1
|
||||
*/
|
||||
int fdisk_labelitem_is_number(struct fdisk_labelitem *li)
|
||||
{
|
||||
return li && li->type == 'j';
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
static int test_listitems(struct fdisk_test *ts, int argc, char *argv[])
|
||||
{
|
||||
const char *disk = argv[1];
|
||||
struct fdisk_context *cxt;
|
||||
struct fdisk_labelitem *item;
|
||||
int i = 0, rc;
|
||||
|
||||
cxt = fdisk_new_context();
|
||||
item = fdisk_new_labelitem();
|
||||
|
||||
fdisk_assign_device(cxt, disk, 1);
|
||||
|
||||
do {
|
||||
rc = fdisk_get_disklabel_item(cxt, i++, item);
|
||||
switch (rc) {
|
||||
case 0: /* success */
|
||||
{
|
||||
const char *name = fdisk_labelitem_get_name(item);
|
||||
const char *str;
|
||||
uint64_t num;
|
||||
|
||||
if (fdisk_labelitem_is_string(item)
|
||||
&& fdisk_labelitem_get_data_string(item, &str) == 0)
|
||||
printf("%s: %s\n", name, str);
|
||||
else if (fdisk_labelitem_get_data_u64(item, &num) == 0)
|
||||
printf("%s: %ju\n", name, num);
|
||||
break;
|
||||
}
|
||||
case 1: /* item unssuported by label -- ignore */
|
||||
rc = 0;
|
||||
break;
|
||||
case 2: /* end (out of range) */
|
||||
break;
|
||||
default: /* error */
|
||||
break;
|
||||
}
|
||||
} while (rc == 0);
|
||||
|
||||
fdisk_unref_labelitem(item);
|
||||
fdisk_unref_context(cxt);
|
||||
return rc < 0 ? rc : 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct fdisk_test tss[] = {
|
||||
{ "--list-items", test_listitems, "<disk> list items" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
return fdisk_run_test(tss, argc, argv);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -321,10 +321,9 @@ int fdisk_list_disklabel(struct fdisk_context *cxt)
|
|||
case 's':
|
||||
if (item.data.str && item.name)
|
||||
fdisk_info(cxt, "%s: %s", item.name, item.data.str);
|
||||
free(item.data.str);
|
||||
item.data.str = NULL;
|
||||
break;
|
||||
}
|
||||
fdisk_reset_labelitem(&item);
|
||||
} while (rc == 0 || rc == 1);
|
||||
|
||||
return rc < 0 ? rc : 0;
|
||||
|
@ -426,8 +425,11 @@ int fdisk_get_disklabel_id(struct fdisk_context *cxt, char **id)
|
|||
DBG(CXT, ul_debugobj(cxt, "asking for disk %s ID", cxt->label->name));
|
||||
|
||||
rc = fdisk_get_disklabel_item(cxt, FDISK_LABELITEM_ID, &item);
|
||||
if (rc == 0)
|
||||
if (rc == 0) {
|
||||
*id = item.data.str;
|
||||
item.data.str = NULL;
|
||||
}
|
||||
fdisk_reset_labelitem(&item);
|
||||
if (rc > 0)
|
||||
rc = 0;
|
||||
return rc;
|
||||
|
@ -441,7 +443,7 @@ int fdisk_get_disklabel_id(struct fdisk_context *cxt, char **id)
|
|||
*
|
||||
* Note that @id is always in range 0..N. It's fine to use the function in loop
|
||||
* until it returns error or 2, the result in @item should be ignored when
|
||||
* function returns 1.
|
||||
* function returns 1. Don't forget to use fdisk_reset_labelitem() or fdisk_unref_labelitem().
|
||||
*
|
||||
* Returns: 0 on success, < 0 on error, 1 on unssupported item, 2 @id out of range
|
||||
*/
|
||||
|
@ -450,6 +452,7 @@ int fdisk_get_disklabel_item(struct fdisk_context *cxt, int id, struct fdisk_lab
|
|||
if (!cxt || !cxt->label || !item)
|
||||
return -EINVAL;
|
||||
|
||||
fdisk_reset_labelitem(item);
|
||||
item->id = id;
|
||||
DBG(CXT, ul_debugobj(cxt, "asking for disk %s item %d", cxt->label->name, item->id));
|
||||
|
||||
|
|
|
@ -148,7 +148,6 @@ enum fdisk_asktype {
|
|||
FDISK_ASKTYPE_MENU /* ask for menu item */
|
||||
};
|
||||
|
||||
|
||||
/* init.c */
|
||||
extern void fdisk_init_debug(int mask);
|
||||
|
||||
|
@ -325,7 +324,20 @@ enum fdisk_labelitem_gen {
|
|||
__FDISK_NLABELITEMS = 8 /* Specifies reserved range for generic items (0..7) */
|
||||
};
|
||||
|
||||
/* item.c */
|
||||
extern struct fdisk_labelitem *fdisk_new_labelitem(void);
|
||||
extern void fdisk_ref_labelitem(struct fdisk_labelitem *li);
|
||||
extern int fdisk_reset_labelitem(struct fdisk_labelitem *li);
|
||||
extern void fdisk_unref_labelitem(struct fdisk_labelitem *li);
|
||||
extern const char *fdisk_labelitem_get_name(struct fdisk_labelitem *li);
|
||||
extern int fdisk_labelitem_get_id(struct fdisk_labelitem *li);
|
||||
extern int fdisk_labelitem_get_data_u64(struct fdisk_labelitem *li, uint64_t *data);
|
||||
extern int fdisk_labelitem_get_data_string(struct fdisk_labelitem *li, const char **data);
|
||||
extern int fdisk_labelitem_is_string(struct fdisk_labelitem *li);
|
||||
extern int fdisk_labelitem_is_number(struct fdisk_labelitem *li);
|
||||
|
||||
extern int fdisk_get_disklabel_item(struct fdisk_context *cxt, int id, struct fdisk_labelitem *item);
|
||||
|
||||
extern int fdisk_get_disklabel_id(struct fdisk_context *cxt, char **id);
|
||||
extern int fdisk_set_disklabel_id(struct fdisk_context *cxt);
|
||||
|
||||
|
|
|
@ -262,4 +262,14 @@ FDISK_2.28 {
|
|||
|
||||
FDISK_2.29 {
|
||||
fdisk_wipe_partition;
|
||||
fdisk_new_labelitem;
|
||||
fdisk_ref_labelitem;
|
||||
fdisk_reset_labelitem;
|
||||
fdisk_unref_labelitem;
|
||||
fdisk_labelitem_get_name;
|
||||
fdisk_labelitem_get_id;
|
||||
fdisk_labelitem_get_data_u64;
|
||||
fdisk_labelitem_get_data_string;
|
||||
fdisk_labelitem_is_string;
|
||||
fdisk_labelitem_is_number;
|
||||
} FDISK_2.28;
|
||||
|
|
Loading…
Reference in New Issue