]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - libfdisk/src/utils.c
115409065b35026982b0e1bcea8b6713b857221e
4 #include "canonicalize.h"
11 * @short_description: misc fdisk functions
14 static int read_from_device(struct fdisk_context
*cxt
,
16 uintmax_t start
, size_t size
)
22 DBG(CXT
, ul_debugobj(cxt
, "reading: offset=%ju, size=%zu",
25 r
= lseek(cxt
->dev_fd
, start
, SEEK_SET
);
28 DBG(CXT
, ul_debugobj(cxt
, "failed to seek to offset %ju: %m", start
));
32 r
= read(cxt
->dev_fd
, buf
, size
);
33 if (r
< 0 || (size_t)r
!= size
) {
35 errno
= EINVAL
; /* probably too small file/device */
36 DBG(CXT
, ul_debugobj(cxt
, "failed to read %zu from offset %ju: %m",
46 * Zeros in-memory first sector buffer
48 int fdisk_init_firstsector_buffer(struct fdisk_context
*cxt
,
49 unsigned int protect_off
,
50 unsigned int protect_size
)
55 assert(protect_off
+ protect_size
<= cxt
->sector_size
);
57 if (!cxt
->firstsector
|| cxt
->firstsector_bufsz
!= cxt
->sector_size
) {
58 /* Let's allocate a new buffer if no allocated yet, or the
59 * current buffer has incorrect size */
60 if (!cxt
->parent
|| cxt
->parent
->firstsector
!= cxt
->firstsector
)
61 free(cxt
->firstsector
);
63 DBG(CXT
, ul_debugobj(cxt
, "initialize in-memory first sector "
64 "buffer [sector_size=%lu]", cxt
->sector_size
));
65 cxt
->firstsector
= calloc(1, cxt
->sector_size
);
66 if (!cxt
->firstsector
)
69 cxt
->firstsector_bufsz
= cxt
->sector_size
;
73 DBG(CXT
, ul_debugobj(cxt
, "zeroize in-memory first sector buffer"));
74 memset(cxt
->firstsector
, 0, cxt
->firstsector_bufsz
);
78 * It would be possible to reuse data from cxt->firstsector
79 * (call memset() for non-protected area only) and avoid one
80 * read() from the device, but it seems like a too fragile
81 * solution as we have no clue about stuff in the buffer --
82 * maybe it was already modified. Let's re-read from the device
83 * to be sure. -- kzak 13-Apr-2015
85 DBG(CXT
, ul_debugobj(cxt
, "first sector protection enabled -- re-reading"));
86 read_from_device(cxt
, cxt
->firstsector
, protect_off
, protect_size
);
91 int fdisk_read_firstsector(struct fdisk_context
*cxt
)
96 assert(cxt
->sector_size
);
98 rc
= fdisk_init_firstsector_buffer(cxt
, 0, 0);
102 assert(cxt
->sector_size
== cxt
->firstsector_bufsz
);
105 return read_from_device(cxt
, cxt
->firstsector
, 0, cxt
->sector_size
);
111 * @partno: partition name
113 * Return: allocated buffer with partition name, use free() to deallocate.
115 char *fdisk_partname(const char *dev
, size_t partno
)
119 char *dev_mapped
= NULL
;
123 if (asprintf(&res
, "%zd", partno
) > 0)
128 /* It is impossible to predict /dev/dm-N partition names. */
129 if (strncmp(dev
, "/dev/dm-", sizeof("/dev/dm-") - 1) == 0) {
130 dev_mapped
= canonicalize_dm_name (dev
+ 5);
136 if (isdigit(dev
[w
- 1]))
143 /* devfs kludge - note: fdisk partition names are not supposed
144 to equal kernel names, so there is no reason to do this */
145 if (strcmp(dev
+ w
- 4, "disc") == 0) {
150 /* udev names partitions by appending -partN
151 e.g. ata-SAMSUNG_SV8004H_0357J1FT712448-part1
152 multipath-tools kpartx.rules also append -partN */
153 if ((strncmp(dev
, _PATH_DEV_BYID
, sizeof(_PATH_DEV_BYID
) - 1) == 0) ||
154 strncmp(dev
, _PATH_DEV_BYPATH
, sizeof(_PATH_DEV_BYPATH
) - 1) == 0 ||
155 strncmp(dev
, "/dev/mapper", sizeof("/dev/mapper") - 1) == 0) {
157 /* check for <name><partno>, e.g. mpatha1 */
158 if (asprintf(&res
, "%.*s%zu", w
, dev
, partno
) <= 0)
160 if (res
&& access(res
, F_OK
) == 0)
165 /* check for partition seperator "p" */
166 if (asprintf(&res
, "%.*sp%zu", w
, dev
, partno
) <= 0)
168 if (res
&& access(res
, F_OK
) == 0)
173 /* otherwise, default to "-path" */
177 if (asprintf(&res
, "%.*s%s%zu", w
, dev
, p
, partno
) <= 0)
185 struct fdisk_label
*fdisk_new_dos_label(struct fdisk_context
*cxt
) { return NULL
; }
186 struct fdisk_label
*fdisk_new_bsd_label(struct fdisk_context
*cxt
) { return NULL
; }
188 static int test_partnames(struct fdisk_test
*ts
, int argc
, char *argv
[])
191 const char *disk
= argv
[1];
193 for (i
= 0; i
< 5; i
++) {
194 char *p
= fdisk_partname(disk
, i
+ 1);
196 printf("%zu: '%s'\n", i
+ 1, p
);
203 int main(int argc
, char *argv
[])
205 struct fdisk_test tss
[] = {
206 { "--partnames", test_partnames
, "<diskname>" },
210 return fdisk_run_test(tss
, argc
, argv
);