2 * blkid probe utilities
4 * Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "utils_blkid.h"
32 #include <blkid/blkid.h>
33 /* make bad checksums flag optional */
34 #ifndef BLKID_SUBLKS_BADCSUM
35 #define BLKID_SUBLKS_BADCSUM 0
41 #ifndef HAVE_BLKID_WIPE
42 static size_t crypt_getpagesize(void)
44 long r = sysconf(_SC_PAGESIZE);
45 return r <= 0 ? 4096 : (size_t)r;
50 void blk_set_chains_for_wipes(struct blkid_handle *h)
53 blkid_probe_enable_partitions(h->pr, 1);
54 blkid_probe_set_partitions_flags(h->pr, 0
55 #ifdef HAVE_BLKID_WIPE
60 blkid_probe_enable_superblocks(h->pr, 1);
61 blkid_probe_set_superblocks_flags(h->pr, BLKID_SUBLKS_LABEL |
65 BLKID_SUBLKS_VERSION |
67 BLKID_SUBLKS_BADCSUM);
71 void blk_set_chains_for_full_print(struct blkid_handle *h)
73 blk_set_chains_for_wipes(h);
76 void blk_set_chains_for_superblocks(struct blkid_handle *h)
79 blkid_probe_enable_superblocks(h->pr, 1);
80 blkid_probe_set_superblocks_flags(h->pr, BLKID_SUBLKS_TYPE);
84 void blk_set_chains_for_fast_detection(struct blkid_handle *h)
87 blkid_probe_enable_partitions(h->pr, 1);
88 blkid_probe_set_partitions_flags(h->pr, 0);
89 blk_set_chains_for_superblocks(h);
93 int blk_init_by_path(struct blkid_handle **h, const char *path)
97 struct blkid_handle *tmp = malloc(sizeof(*tmp));
103 tmp->pr = blkid_new_probe_from_filename(path);
116 int blk_init_by_fd(struct blkid_handle **h, int fd)
120 struct blkid_handle *tmp = malloc(sizeof(*tmp));
124 tmp->pr = blkid_new_probe();
130 if (blkid_probe_set_device(tmp->pr, fd, 0, 0)) {
131 blkid_free_probe(tmp->pr);
146 static int blk_superblocks_luks(struct blkid_handle *h, bool enable)
148 char luks[] = "crypto_LUKS";
149 char *luks_filter[] = {
153 return blkid_probe_filter_superblocks_type(h->pr,
154 enable ? BLKID_FLTR_ONLYIN : BLKID_FLTR_NOTIN,
159 int blk_superblocks_filter_luks(struct blkid_handle *h)
163 r = blk_superblocks_luks(h, false);
168 int blk_superblocks_only_luks(struct blkid_handle *h)
172 r = blk_superblocks_luks(h, true);
177 blk_probe_status blk_probe(struct blkid_handle *h)
179 blk_probe_status pr = PRB_FAIL;
181 int r = blkid_do_probe(h->pr);
191 blk_probe_status blk_safeprobe(struct blkid_handle *h)
195 r = blkid_do_safeprobe(h->pr);
199 return PRB_AMBIGUOUS;
209 int blk_is_partition(struct blkid_handle *h)
213 r = blkid_probe_has_value(h->pr, "PTTYPE");
218 int blk_is_superblock(struct blkid_handle *h)
222 r = blkid_probe_has_value(h->pr, "TYPE");
227 const char *blk_get_partition_type(struct blkid_handle *h)
229 const char *value = NULL;
231 (void) blkid_probe_lookup_value(h->pr, "PTTYPE", &value, NULL);
236 const char *blk_get_superblock_type(struct blkid_handle *h)
238 const char *value = NULL;
240 (void) blkid_probe_lookup_value(h->pr, "TYPE", &value, NULL);
245 void blk_free(struct blkid_handle *h)
252 blkid_free_probe(h->pr);
259 #ifndef HAVE_BLKID_WIPE
260 static int blk_step_back(struct blkid_handle *h)
262 #ifdef HAVE_BLKID_STEP_BACK
263 return blkid_probe_step_back(h->pr);
265 blkid_reset_probe(h->pr);
266 blkid_probe_set_device(h->pr, h->fd, 0, 0);
270 #endif /* not HAVE_BLKID_WIPE */
271 #endif /* HAVE_BLKID */
273 int blk_do_wipe(struct blkid_handle *h)
276 #ifdef HAVE_BLKID_WIPE
277 return blkid_do_wipe(h->pr, 0);
283 size_t alignment, len, bsize = blkid_probe_get_sectorsize(h->pr);
285 if (h->fd < 0 || !bsize)
288 if (blk_is_partition(h)) {
289 if (blkid_probe_lookup_value(h->pr, "PTMAGIC_OFFSET", &offset, NULL))
291 if (blkid_probe_lookup_value(h->pr, "PTMAGIC", NULL, &len))
293 } else if (blk_is_superblock(h)) {
294 if (blkid_probe_lookup_value(h->pr, "SBMAGIC_OFFSET", &offset, NULL))
296 if (blkid_probe_lookup_value(h->pr, "SBMAGIC", NULL, &len))
301 alignment = crypt_getpagesize();
303 if (posix_memalign(&buf, alignment, len))
307 offset_val = strtoll(offset, NULL, 10);
309 /* TODO: missing crypt_wipe_fd() */
310 ret = write_lseek_blockwise(h->fd, bsize, alignment, buf, len, offset_val);
315 if ((size_t)ret == len) {
322 #else /* HAVE_BLKID */
327 int blk_supported(void)
336 unsigned blk_get_block_size(struct blkid_handle *h)
338 unsigned block_size = 0;
341 if (!blk_is_superblock(h) || !blkid_probe_has_value(h->pr, "BLOCK_SIZE") ||
342 blkid_probe_lookup_value(h->pr, "BLOCK_SIZE", &data, NULL) ||
343 sscanf(data, "%u", &block_size) != 1)