2
* partitions - partition tables parsing
4
* Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
6
* This file may be redistributed under the terms of the
7
* GNU Lesser General Public License.
16
#include <sys/types.h>
23
#include "partitions.h"
28
* @title: Partitions probing
29
* @short_description: partitions tables detection and parsing
31
* This chain supports binary and NAME=value interfaces, but complete PT
32
* description is provided by binary interface only. The libblkid prober is
33
* compatible with kernel partition tables parser. The parser does not return
34
* empty (size=0) partitions or special hidden partitions.
36
* NAME=value interface, supported tags:
38
* @PTTYPE: partition table type (dos, gpt, etc.).
40
* @PART_ENTRY_SCHEME: partition table type
42
* @PART_ENTRY_NAME: partition name (gpt and mac only)
44
* @PART_ENTRY_UUID: partition UUID (gpt only)
46
* @PART_ENTRY_TYPE: partition type, 0xNN (e.g 0x82) or type UUID (gpt only) or type string (mac)
48
* @PART_ENTRY_FLAGS: partition flags (e.g. boot_ind) or attributes (e.g. gpt attributes)
50
* @PART_ENTRY_NUMBER: partition number
52
* @PART_ENTRY_OFFSET: the begin of the partition
54
* @PART_ENTRY_SIZE: size of the partition
56
* @PART_ENTRY_DISK: whole-disk maj:min
65
* pr = blkid_new_probe_from_filename(devname);
67
* err("%s: faild to open device", devname);
69
* blkid_probe_enable_partitions(pr, TRUE);
70
* blkid_do_fullprobe(pr);
72
* blkid_probe_lookup_value(pr, "PTTYPE", &ptname, NULL);
73
* printf("%s partition type detected\n", pttype);
75
* blkid_free_probe(pr);
77
* // don't forget to check return codes in your code!
89
* pr = blkid_new_probe_from_filename(devname);
91
* err("%s: faild to open device", devname);
93
* ls = blkid_probe_get_partitions(pr);
94
* nparts = blkid_partlist_numof_partitions(ls);
96
* for (i = 0; i < nparts; i++) {
97
* blkid_partition par = blkid_partlist_get_partition(ls, i);
98
* printf("#%d: %llu %llu 0x%x",
99
* blkid_partition_get_partno(par),
100
* blkid_partition_get_start(par),
101
* blkid_partition_get_size(par),
102
* blkid_partition_get_type(par));
105
* blkid_free_probe(pr);
107
* // don't forget to check return codes in your code!
113
* Chain driver function
115
static int partitions_probe(blkid_probe pr, struct blkid_chain *chn);
116
static void partitions_free_data(blkid_probe pr, void *data);
119
* Partitions chain probing functions
121
static const struct blkid_idinfo *idinfos[] =
132
&solaris_x86_pt_idinfo,
139
const struct blkid_chaindrv partitions_drv = {
140
.id = BLKID_CHAIN_PARTS,
141
.name = "partitions",
142
.dflt_enabled = FALSE,
144
.nidinfos = ARRAY_SIZE(idinfos),
146
.probe = partitions_probe,
147
.safeprobe = partitions_probe,
148
.free_data = partitions_free_data
153
* For compatibility with the rest of libblkid API (with the old high-level
154
* API) we use completely opaque typedefs for all structs. Don't forget that
155
* the final blkid_* types are pointers! See blkid.h.
157
* [Just for the record, I hate typedef for pointers --kzak]
160
/* exported as opaque type "blkid_parttable" */
161
struct blkid_struct_parttable {
162
const char *type; /* partition table type */
163
blkid_loff_t offset; /* begin of the partition table */
164
int nparts; /* number of partitions */
165
blkid_partition parent; /* parent of nested partition table */
167
struct list_head t_tabs; /* all tables */
170
/* exported as opaque type "blkid_partition" */
171
struct blkid_struct_partition {
172
blkid_loff_t start; /* begin of the partition */
173
blkid_loff_t size; /* size of the partitions */
175
int type; /* partition type */
176
char typestr[37]; /* partition type string (GPT and Mac) */
178
unsigned long long flags; /* partition flags / attributes */
180
int partno; /* partition number */
181
char uuid[37]; /* UUID (when supported by PT), e.g GPT */
182
unsigned char name[128]; /* Partition in UTF8 name (when supporte by PT), e.g. Mac */
184
blkid_parttable tab; /* partition table */
187
/* exported as opaque type "blkid_partlist" */
188
struct blkid_struct_partlist {
189
int next_partno; /* next partition number */
190
blkid_partition next_parent; /* next parent if parsing nested PT */
192
int nparts; /* number of partitions */
193
int nparts_max; /* max.number of partitions */
194
blkid_partition parts; /* array of partitions */
196
struct list_head l_tabs; /* list of partition tables */
199
static int blkid_partitions_probe_partition(blkid_probe pr);
202
* blkid_probe_enable_partitions:
204
* @enable: TRUE/FALSE
206
* Enables/disables the partitions probing for non-binary interface.
208
* Returns: 0 on success, or -1 in case of error.
210
int blkid_probe_enable_partitions(blkid_probe pr, int enable)
214
pr->chains[BLKID_CHAIN_PARTS].enabled = enable;
219
* blkid_probe_set_partitions_flags:
221
* @flags: BLKID_PARTS_* flags
223
* Sets probing flags to the partitions prober. This function is optional.
225
* Returns: 0 on success, or -1 in case of error.
227
int blkid_probe_set_partitions_flags(blkid_probe pr, int flags)
232
pr->chains[BLKID_CHAIN_PARTS].flags = flags;
237
* blkid_probe_reset_partitions_filter:
240
* Resets partitions probing filter
242
* Returns: 0 on success, or -1 in case of error.
244
int blkid_probe_reset_partitions_filter(blkid_probe pr)
246
return __blkid_probe_reset_filter(pr, BLKID_CHAIN_PARTS);
250
* blkid_probe_invert_partitions_filter:
253
* Inverts partitions probing filter
255
* Returns: 0 on success, or -1 in case of error.
257
int blkid_probe_invert_partitions_filter(blkid_probe pr)
259
return __blkid_probe_invert_filter(pr, BLKID_CHAIN_PARTS);
263
* blkid_probe_filter_partitions_type:
265
* @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
266
* @names: NULL terminated array of probing function names (e.g. "vfat").
268
* %BLKID_FLTR_NOTIN - probe for all items which are NOT IN @names
270
* %BLKID_FLTR_ONLYIN - probe for items which are IN @names
272
* Returns: 0 on success, or -1 in case of error.
274
int blkid_probe_filter_partitions_type(blkid_probe pr, int flag, char *names[])
276
return __blkid_probe_filter_types(pr, BLKID_CHAIN_PARTS, flag, names);
280
* blkid_probe_get_partitions:
283
* This is a binary interface for partitions. See also blkid_partlist_*
286
* This function is independent on blkid_do_[safe,full]probe() and
287
* blkid_probe_enable_partitions() calls.
289
* WARNING: the returned object will be overwritten by the next
290
* blkid_probe_get_partitions() call for the same @pr. If you want to
291
* use more blkid_partlist objects in the same time you have to create
292
* more blkid_probe handlers (see blkid_new_probe()).
294
* Returns: list of partitions, or NULL in case of error.
296
blkid_partlist blkid_probe_get_partitions(blkid_probe pr)
298
return (blkid_partlist) blkid_probe_get_binary_data(pr,
299
&pr->chains[BLKID_CHAIN_PARTS]);
302
/* for internal usage only */
303
blkid_partlist blkid_probe_get_partlist(blkid_probe pr)
305
return (blkid_partlist) pr->chains[BLKID_CHAIN_PARTS].data;
308
static void blkid_probe_set_partlist(blkid_probe pr, blkid_partlist ls)
310
pr->chains[BLKID_CHAIN_PARTS].data = ls;
313
static void ref_parttable(blkid_parttable tab)
318
static void unref_parttable(blkid_parttable tab)
322
if (tab->nparts <= 0) {
323
list_del(&tab->t_tabs);
328
/* free all allocated parttables */
329
static void free_parttables(blkid_partlist ls)
331
if (!ls || !ls->l_tabs.next)
334
/* remove unassigned partition tables */
335
while (!list_empty(&ls->l_tabs)) {
336
blkid_parttable tab = list_entry(ls->l_tabs.next,
337
struct blkid_struct_parttable, t_tabs);
338
unref_parttable(tab);
342
static void reset_partlist(blkid_partlist ls)
349
if (ls->next_partno) {
350
/* already initialized - reset */
351
int tmp_nparts = ls->nparts_max;
352
blkid_partition tmp_parts = ls->parts;
354
memset(ls, 0, sizeof(struct blkid_struct_partlist));
356
ls->nparts_max = tmp_nparts;
357
ls->parts = tmp_parts;
362
INIT_LIST_HEAD(&ls->l_tabs);
364
DBG(DEBUG_LOWPROBE, printf("partlist reseted\n"));
367
static blkid_partlist partitions_init_data(struct blkid_chain *chn)
372
ls = (blkid_partlist) chn->data;
374
/* allocate the new list of partitions */
375
ls = calloc(1, sizeof(struct blkid_struct_partlist));
378
chn->data = (void *) ls;
384
printf("parts: initialized partitions list (%p, size=%d)\n",
385
ls, ls->nparts_max));
389
static void partitions_free_data(blkid_probe pr __attribute__((__unused__)),
392
blkid_partlist ls = (blkid_partlist) data;
399
/* deallocate partitions and partlist */
404
blkid_parttable blkid_partlist_new_parttable(blkid_partlist ls,
405
const char *type, blkid_loff_t offset)
409
tab = calloc(1, sizeof(struct blkid_struct_parttable));
413
tab->offset = offset;
414
tab->parent = ls->next_parent;
416
INIT_LIST_HEAD(&tab->t_tabs);
417
list_add_tail(&tab->t_tabs, &ls->l_tabs);
420
printf("parts: create a new partition table "
421
"(%p, type=%s, offset=%"PRId64")\n", tab, type, offset));
425
static blkid_partition new_partition(blkid_partlist ls, blkid_parttable tab)
429
if (ls->nparts + 1 > ls->nparts_max) {
430
/* Linux kernel has DISK_MAX_PARTS=256, but it's too much for
431
* generic Linux machine -- let start with 32 partititions.
433
ls->parts = realloc(ls->parts, (ls->nparts_max + 32) *
434
sizeof(struct blkid_struct_partition));
437
ls->nparts_max += 32;
440
par = &ls->parts[ls->nparts++];
441
memset(par, 0, sizeof(struct blkid_struct_partition));
445
par->partno = blkid_partlist_increment_partno(ls);
450
blkid_partition blkid_partlist_add_partition(blkid_partlist ls,
452
blkid_loff_t start, blkid_loff_t size)
454
blkid_partition par = new_partition(ls, tab);
463
printf("parts: add partition (%p start=%"
464
PRId64 ", size=%" PRId64 ", table=%p)\n",
465
par, par->start, par->size, tab));
469
/* allows to modify used partitions numbers (for example for logical partitions) */
470
int blkid_partlist_set_partno(blkid_partlist ls, int partno)
474
ls->next_partno = partno;
478
int blkid_partlist_increment_partno(blkid_partlist ls)
480
return ls ? ls->next_partno++ : -1;
483
/* allows to set "parent" for the next nested partition */
484
int blkid_partlist_set_parent(blkid_partlist ls, blkid_partition par)
488
ls->next_parent = par;
492
blkid_partition blkid_partlist_get_parent(blkid_partlist ls)
496
return ls->next_parent;
499
int blkid_partitions_need_typeonly(blkid_probe pr)
501
struct blkid_chain *chn = blkid_probe_get_chain(pr);
503
return chn && chn->data && chn->binary ? FALSE : TRUE;
506
/* get private chain flags */
507
int blkid_partitions_get_flags(blkid_probe pr)
509
struct blkid_chain *chn = blkid_probe_get_chain(pr);
511
return chn ? chn->flags : 0;
514
/* check if @start and @size are within @par partition */
515
int blkid_is_nested_dimension(blkid_partition par,
516
blkid_loff_t start, blkid_loff_t size)
524
pstart = blkid_partition_get_start(par);
525
psize = blkid_partition_get_size(par);
527
if (start < pstart || start + size > pstart + psize)
533
static int idinfo_probe(blkid_probe pr, const struct blkid_idinfo *id)
535
const struct blkid_idmag *mag;
536
int rc = 1; /* = nothing detected */
538
if (pr->size <= 0 || (id->minsz && id->minsz > pr->size))
539
goto nothing; /* the device is too small */
541
if (blkid_probe_get_idmag(pr, id, NULL, &mag))
544
/* final check by probing function */
546
DBG(DEBUG_LOWPROBE, printf(
547
"%s: ---> call probefunc()\n", id->name));
548
rc = id->probefunc(pr, mag);
550
/* reset after error */
551
reset_partlist(blkid_probe_get_partlist(pr));
552
DBG(DEBUG_LOWPROBE, printf(
553
"%s probefunc failed\n", id->name));
555
DBG(DEBUG_LOWPROBE, printf(
556
"%s: <--- (rc = %d)\n", id->name, rc));
564
* The blkid_do_probe() backend.
566
static int partitions_probe(blkid_probe pr, struct blkid_chain *chn)
571
if (!pr || chn->idx < -1)
573
blkid_probe_chain_reset_vals(pr, chn);
576
partitions_init_data(chn);
578
if (!pr->wipe_size && (pr->prob_flags & BLKID_PROBE_FL_IGNORE_PT))
582
printf("--> starting probing loop [PARTS idx=%d]\n",
585
i = chn->idx < 0 ? 0 : chn->idx + 1U;
587
for ( ; i < ARRAY_SIZE(idinfos); i++) {
593
if (chn->fltr && blkid_bmp_get_item(chn->fltr, i))
596
/* apply checks from idinfo */
597
if (idinfo_probe(pr, idinfos[i]) != 0)
600
name = idinfos[i]->name;
602
/* all checks passed */
604
blkid_probe_set_value(pr, "PTTYPE",
605
(unsigned char *) name,
608
printf("<-- leaving probing loop (type=%s) [PARTS idx=%d]\n",
616
printf("<-- leaving probing loop (failed) [PARTS idx=%d]\n",
622
* Gather PART_ENTRY_* values if the current device is a partition.
625
(blkid_partitions_get_flags(pr) & BLKID_PARTS_ENTRY_DETAILS)) {
627
if (!blkid_partitions_probe_partition(pr))
634
/* Probe for nested partition table within the parental partition */
635
int blkid_partitions_do_subprobe(blkid_probe pr, blkid_partition parent,
636
const struct blkid_idinfo *id)
641
blkid_loff_t sz, off;
643
DBG(DEBUG_LOWPROBE, printf(
644
"parts: ----> %s subprobe requested (parent=%p)\n",
647
if (!pr || !parent || !parent->size)
650
/* range defined by parent */
651
sz = ((blkid_loff_t) parent->size) << 9;
652
off = ((blkid_loff_t) parent->start) << 9;
654
if (off < pr->off || pr->off + pr->size < off + sz) {
655
DBG(DEBUG_LOWPROBE, printf(
656
"ERROR: parts: <---- '%s' subprobe: overflow detected.\n",
661
/* create private prober */
662
prc = blkid_clone_probe(pr);
666
blkid_probe_set_dimension(prc, off, sz);
668
/* clone is always with reseted chain, fix it */
669
prc->cur_chain = blkid_probe_get_chain(pr);
672
* Set 'parent' to the current list of the partitions and use the list
673
* in cloned prober (so the cloned prober will extend the current list
674
* of partitions rather than create a new).
676
ls = blkid_probe_get_partlist(pr);
677
blkid_partlist_set_parent(ls, parent);
679
blkid_probe_set_partlist(prc, ls);
681
rc = idinfo_probe(prc, id);
683
blkid_probe_set_partlist(prc, NULL);
684
blkid_partlist_set_parent(ls, NULL);
686
blkid_free_probe(prc); /* free cloned prober */
688
DBG(DEBUG_LOWPROBE, printf(
689
"parts: <---- %s subprobe done (parent=%p, rc=%d)\n",
690
id->name, parent, rc));
695
static int blkid_partitions_probe_partition(blkid_probe pr)
698
blkid_probe disk_pr = NULL;
703
devno = blkid_probe_get_devno(pr);
707
disk_pr = blkid_probe_get_wholedisk_probe(pr);
712
ls = blkid_probe_get_partitions(disk_pr);
716
par = blkid_partlist_devno_to_partition(ls, devno);
719
blkid_parttable tab = blkid_partition_get_table(par);
720
dev_t disk = blkid_probe_get_devno(disk_pr);
723
v = blkid_parttable_get_type(tab);
725
blkid_probe_set_value(pr, "PART_ENTRY_SCHEME",
726
(unsigned char *) v, strlen(v) + 1);
729
v = blkid_partition_get_name(par);
731
blkid_probe_set_value(pr, "PART_ENTRY_NAME",
732
(unsigned char *) v, strlen(v) + 1);
734
v = blkid_partition_get_uuid(par);
736
blkid_probe_set_value(pr, "PART_ENTRY_UUID",
737
(unsigned char *) v, strlen(v) + 1);
740
v = blkid_partition_get_type_string(par);
742
blkid_probe_set_value(pr, "PART_ENTRY_TYPE",
743
(unsigned char *) v, strlen(v) + 1);
745
blkid_probe_sprintf_value(pr, "PART_ENTRY_TYPE",
746
"0x%x", blkid_partition_get_type(par));
748
if (blkid_partition_get_flags(par))
749
blkid_probe_sprintf_value(pr, "PART_ENTRY_FLAGS",
750
"0x%llx", blkid_partition_get_flags(par));
752
blkid_probe_sprintf_value(pr, "PART_ENTRY_NUMBER",
753
"%d", blkid_partition_get_partno(par));
755
blkid_probe_sprintf_value(pr, "PART_ENTRY_OFFSET", "%jd",
756
blkid_partition_get_start(par));
757
blkid_probe_sprintf_value(pr, "PART_ENTRY_SIZE", "%jd",
758
blkid_partition_get_size(par));
760
blkid_probe_sprintf_value(pr, "PART_ENTRY_DISK", "%u:%u",
761
major(disk), minor(disk));
769
* Returns 1 if the device is whole-disk and the area specified by @offset and
770
* @size is covered by any partition.
772
int blkid_probe_is_covered_by_pt(blkid_probe pr,
773
blkid_loff_t offset, blkid_loff_t size)
776
blkid_partlist ls = NULL;
777
blkid_loff_t start, end;
778
int nparts, i, rc = 0;
780
DBG(DEBUG_LOWPROBE, printf(
781
"=> checking if off=%jd size=%jd covered by PT\n",
784
prc = blkid_clone_probe(pr);
788
ls = blkid_probe_get_partitions(prc);
792
nparts = blkid_partlist_numof_partitions(ls);
796
end = (offset + size) >> 9;
799
/* check if the partition table fits into the device */
800
for (i = 0; i < nparts; i++) {
801
blkid_partition par = &ls->parts[i];
803
if (par->start + par->size > (pr->size >> 9)) {
804
DBG(DEBUG_LOWPROBE, printf("partition #%d overflows "
805
"device (off=%" PRId64 " size=%" PRId64 ")\n",
806
par->partno, par->start, par->size));
811
/* check if the requested area is covered by PT */
812
for (i = 0; i < nparts; i++) {
813
blkid_partition par = &ls->parts[i];
815
if (start >= par->start && end <= par->start + par->size) {
821
blkid_free_probe(prc);
823
DBG(DEBUG_LOWPROBE, printf("<= %s covered by PT\n", rc ? "IS" : "NOT"));
828
* blkid_known_pttype:
829
* @pttype: partiton name
831
* Returns: 1 for known or 0 for unknown partition type.
833
int blkid_known_pttype(const char *pttype)
840
for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
841
const struct blkid_idinfo *id = idinfos[i];
842
if (strcmp(id->name, pttype) == 0)
849
* blkid_partlist_numof_partitions:
850
* @ls: partitions list
852
* Returns: number of partitions in the list or -1 in case of error.
854
int blkid_partlist_numof_partitions(blkid_partlist ls)
856
return ls ? ls->nparts : -1;
860
* blkid_partlist_get_table:
861
* @ls: partitions list
863
* Returns: top-level partition table or NULL of there is not a partition table
866
blkid_parttable blkid_partlist_get_table(blkid_partlist ls)
868
if (!ls || list_empty(&ls->l_tabs))
871
return list_entry(ls->l_tabs.next,
872
struct blkid_struct_parttable, t_tabs);
877
* blkid_partlist_get_partition:
878
* @ls: partitions list
879
* @n: partition number in range 0..N, where 'N' is blkid_partlist_numof_partitions().
881
* It's possible that the list of partitions is *empty*, but there is a valid
882
* partition table on the disk. This happen when on-disk details about
883
* partitions are unknown or the partition table is empty.
885
* See also blkid_partlist_get_table().
887
* Returns: partition object or NULL in case or error.
889
blkid_partition blkid_partlist_get_partition(blkid_partlist ls, int n)
891
if (!ls || n < 0 || n >= ls->nparts)
894
return &ls->parts[n];
898
* blkid_partlist_devno_to_partition:
899
* @ls: partitions list
900
* @devno: requested partition
902
* This function tries to get start and size for @devno from sysfs and
903
* returns a partition from @ls which matches with the values from sysfs.
905
* This funtion is necessary when you want to make a relation between an entry
906
* in the partition table (@ls) and block devices in your system.
908
* Returns: partition object or NULL in case or error.
910
blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno)
912
struct sysfs_cxt sysfs;
913
uint64_t start, size;
914
int i, rc, partno = 0;
917
printf("triyng to convert devno 0x%llx to partition\n",
920
if (sysfs_init(&sysfs, devno, NULL)) {
921
DBG(DEBUG_LOWPROBE, printf("failed t init sysfs context\n"));
924
rc = sysfs_read_u64(&sysfs, "size", &size);
926
rc = sysfs_read_u64(&sysfs, "start", &start);
928
/* try to get partition number from DM uuid.
930
char *uuid = sysfs_strdup(&sysfs, "dm/uuid");
932
char *prefix = uuid ? strsep(&tmp, "-") : NULL;
934
if (prefix && strncasecmp(prefix, "part", 4) == 0) {
937
partno = strtol(prefix + 4, &end, 10);
938
if (prefix == end || (end && *end))
941
rc = 0; /* success */
947
sysfs_deinit(&sysfs);
953
DBG(DEBUG_LOWPROBE, printf("mapped by DM, using partno %d\n", partno));
956
* Partition mapped by kpartx does not provide "start" offset
957
* in /sys, but if we know partno and size of the partition
958
* that we can probably make the releation bettween the device
959
* and an entry in partition table.
961
for (i = 0; i < ls->nparts; i++) {
962
blkid_partition par = &ls->parts[i];
964
if (partno != blkid_partition_get_partno(par))
967
if ((blkid_loff_t) size == blkid_partition_get_size(par) ||
968
(blkid_partition_is_extended(par) && size <= 1024))
975
DBG(DEBUG_LOWPROBE, printf("searching by offset/size\n"));
977
for (i = 0; i < ls->nparts; i++) {
978
blkid_partition par = &ls->parts[i];
980
if (blkid_partition_get_start(par) == (blkid_loff_t) start &&
981
blkid_partition_get_size(par) == (blkid_loff_t) size)
984
/* exception for extended dos partitions */
985
if (blkid_partition_get_start(par) == (blkid_loff_t) start &&
986
blkid_partition_is_extended(par) && size <= 1024)
991
DBG(DEBUG_LOWPROBE, printf("not found partition for device\n"));
995
int blkid_partition_set_type(blkid_partition par, int type)
1004
* blkid_parttable_get_type:
1005
* @tab: partition table
1007
* Returns: partition table type (type name, e.g. "dos", "gpt", ...)
1009
const char *blkid_parttable_get_type(blkid_parttable tab)
1011
return tab ? tab->type : NULL;
1015
* blkid_parttable_get_parent:
1016
* @tab: partition table
1018
* Returns: parent for nexted partitition tables or NULL.
1020
blkid_partition blkid_parttable_get_parent(blkid_parttable tab)
1022
return tab ? tab->parent : NULL;
1026
* blkid_parttable_get_offset:
1027
* @tab: partition table
1029
* Note the position is relative to begin of the device as defined by
1030
* blkid_probe_set_device() for primary partition table, and relative
1031
* to parental partition for nested patition tables.
1036
* blkid_partition parent = blkid_parttable_get_parent(tab);
1038
* offset = blkid_parttable_get_offset(tab);
1041
* / * 'tab' is nested partition table * /
1042
* offset += blkid_partition_get_start(parent);
1044
* </informalexample>
1046
* Returns: position (in bytes) of the partition table or -1 in case of error.
1049
blkid_loff_t blkid_parttable_get_offset(blkid_parttable tab)
1051
return tab ? tab->offset : -1;
1055
* blkid_partition_get_table:
1058
* The "parttable" describes partition table. The table is usually the same for
1059
* all partitions -- except nested partition tables.
1061
* For example bsd, solaris, etc. use a nested partition table within
1062
* standard primary dos partition:
1067
* -- dos partition table
1068
* 0: sda1 dos primary partition
1069
* 1: sda2 dos primary partition
1070
* -- bsd partition table (with in sda2)
1071
* 2: sda5 bds partition
1072
* 3: sda6 bds partition
1075
* </informalexample>
1077
* The library does not to use a separate partition table object for dos logical
1078
* partitions (partitions within extended partition). It's possible to
1079
* differentiate between logical, extended and primary partitions by
1081
* blkid_partition_is_{extended,primary,logical}().
1083
* Returns: partition table object or NULL in case of error.
1085
blkid_parttable blkid_partition_get_table(blkid_partition par)
1087
return par ? par->tab : NULL;
1090
static int partition_get_logical_type(blkid_partition par)
1092
blkid_parttable tab;
1097
tab = blkid_partition_get_table(par);
1098
if (!tab || !tab->type)
1102
return 'L'; /* report nested partitions as logical */
1104
if (!strcmp(tab->type, "dos")) {
1105
if (par->partno > 4)
1106
return 'L'; /* logical */
1108
if(par->type == BLKID_DOS_EXTENDED_PARTITION ||
1109
par->type == BLKID_W95_EXTENDED_PARTITION ||
1110
par->type == BLKID_LINUX_EXTENDED_PARTITION)
1117
* blkid_partition_is_primary:
1120
* Note, this function returns FALSE for DOS extended partitions and
1121
* all partitions in nested partition tables.
1123
* Returns: 1 if the partitions is primary partition or 0 if not.
1125
int blkid_partition_is_primary(blkid_partition par)
1127
return partition_get_logical_type(par) == 'P' ? TRUE : FALSE;
1131
* blkid_partition_is_extended:
1134
* Returns: 1 if the partitions is extended (dos, windows or linux)
1135
* partition or 0 if not.
1137
int blkid_partition_is_extended(blkid_partition par)
1139
return partition_get_logical_type(par) == 'E' ? TRUE : FALSE;
1143
* blkid_partition_is_logical:
1146
* Note that this function returns TRUE for all partitions in all
1147
* nested partition tables (e.g. BSD labels).
1149
* Returns: 1 if the partitions is logical partition or 0 if not.
1151
int blkid_partition_is_logical(blkid_partition par)
1153
return partition_get_logical_type(par) == 'L' ? TRUE : FALSE;
1156
static void set_string(unsigned char *item, size_t max,
1157
const unsigned char *data, size_t len)
1162
memcpy(item, data, len);
1165
blkid_rtrim_whitespace(item);
1168
int blkid_partition_set_name(blkid_partition par,
1169
const unsigned char *name, size_t len)
1174
set_string(par->name, sizeof(par->name), name, len);
1178
int blkid_partition_set_utf8name(blkid_partition par, const unsigned char *name,
1179
size_t len, int enc)
1184
blkid_encode_to_utf8(enc, par->name, sizeof(par->name), name, len);
1185
blkid_rtrim_whitespace(par->name);
1189
int blkid_partition_set_uuid(blkid_partition par, const unsigned char *uuid)
1194
blkid_unparse_uuid(uuid, par->uuid, sizeof(par->uuid));
1199
* blkid_partition_get_name:
1202
* Returns: partition name string if supported by PT (e.g. Mac) or NULL.
1204
const char *blkid_partition_get_name(blkid_partition par)
1206
return par && *par->name ? (char *) par->name : NULL;
1210
* blkid_partition_get_uuid:
1213
* Returns: partition UUID string if supported by PT (e.g. GPT) or NULL.
1215
const char *blkid_partition_get_uuid(blkid_partition par)
1217
return par && *par->uuid ? par->uuid : NULL;
1221
* blkid_partition_get_partno:
1224
* Returns: proposed partitin number (e.g. 'N' from sda'N') or -1 in case of
1225
* error. Note that the number is generate by library independenly on your OS.
1227
int blkid_partition_get_partno(blkid_partition par)
1229
return par ? par->partno : -1;
1233
* blkid_partition_get_start:
1236
* Be careful if you _not_ probe whole disk:
1238
* 1) the offset is usully relative to begin of the disk -- but if you probe a
1239
* fragment of the disk only -- then the offset could be still relative to
1240
* the begin of the disk rather that relative to the fragment.
1242
* 2) the offset for nested partitions could be releative to parent (e.g. Solaris)
1243
* _or_ relative to the begin of the whole disk (e.g. bsd).
1245
* You don't have to care about such details if you proble whole disk. In such
1246
* a case libblkid always returns the offset relative to the begin of the disk.
1248
* Returns: start of the partition (in 512-sectors).
1250
blkid_loff_t blkid_partition_get_start(blkid_partition par)
1252
return par ? par->start : -1;
1256
* blkid_partition_get_size:
1259
* WARNING: be very careful when you work with MS-DOS extended partitions. The
1260
* library always returns full size of the partition. If you want add
1261
* the partition to the Linux system (BLKPG_ADD_PARTITION ioctl) you
1262
* need to reduce the size of the partition to 1 or 2 blocks. The
1263
* rest of the partition has to be unaccessible for mkfs or mkswap
1264
* programs, we need a small space for boot loaders only.
1266
* For some unknown reason this (safe) practice is not to used for
1267
* nested BSD, Solaris, ..., partition tables in Linux kernel.
1269
* Returns: size of the partition (in 512-sectors).
1271
blkid_loff_t blkid_partition_get_size(blkid_partition par)
1273
return par ? par->size : -1;
1277
* blkid_partition_get_type:
1280
* Returns: partition type.
1282
int blkid_partition_get_type(blkid_partition par)
1284
return par ? par->type : 0;
1287
/* Sets partition 'type' for PT where the type is defined by string rather
1290
int blkid_partition_set_type_string(blkid_partition par,
1291
const unsigned char *type, size_t len)
1296
set_string((unsigned char *) par->typestr,
1297
sizeof(par->typestr), type, len);
1301
/* Sets partition 'type' for PT where the type is defined by UUIDrather
1304
int blkid_partition_set_type_uuid(blkid_partition par, const unsigned char *uuid)
1309
blkid_unparse_uuid(uuid, par->typestr, sizeof(par->typestr));
1314
* blkid_partition_get_type_string:
1317
* The type string is supported by a small subset of partition tables (e.g Mac
1318
* and EFI GPT). Note that GPT uses type UUID and this function returns this
1321
* Returns: partition type string or NULL.
1323
const char *blkid_partition_get_type_string(blkid_partition par)
1325
return par && *par->typestr ? par->typestr : NULL;
1329
int blkid_partition_set_flags(blkid_partition par, unsigned long long flags)
1338
* blkid_partition_get_flags
1341
* Returns: partition flags (or attributes for gpt).
1343
unsigned long long blkid_partition_get_flags(blkid_partition par)
1345
return par ? par->flags : 0;