Example #1
0
static int last_lba(blkid_probe pr, uint64_t *lba)
{
	uint64_t sz = blkid_probe_get_size(pr);
	unsigned int ssz = blkid_probe_get_sectorsize(pr);

	if (sz < ssz)
		return -1;

	*lba = (sz / ssz) - 1ULL;
	return 0;
}
Example #2
0
int get_device_info(int fd, struct device_info *info)
{
    blkid_probe probe;
    struct stat stat;
    int ret;

    *info = device_info_clueless;

    ret = fstat(fd, &stat);
    if (ret < 0) {
	perror("fstat on target failed");
	return -1;
    }

    if (S_ISREG(stat.st_mode)) {
	/* there is nothing more to discover for an image file */
	info->type = TYPE_FILE;
	info->partition = 0;
	info->size = stat.st_size;
	return 0;
    }

    if (!S_ISBLK(stat.st_mode)) {
	/* neither regular file nor block device? not usable */
	info->type = TYPE_BAD;
	return 0;
    }

    probe = blkid_new_probe();
    if (!probe) {
	return -1;
    }

    if (blkid_probe_set_device(probe, fd, 0, 0)) {
	blkid_free_probe(probe);
	return -1;
    }

    get_block_device_size(info, fd);
    get_block_geometry(info, fd);
    info->sector_size = blkid_probe_get_sectorsize(probe);

    /* use udev information if available, fall back to blkid probing */
    if (udev_fill_info(info, &stat))
	blkid_fill_info(info, probe);

    blkid_free_probe(probe);
    return 0;
}
Example #3
0
static int set_disk_properties(struct sync_disk *disk)
{
	blkid_probe probe;
	blkid_topology topo;
	uint32_t sector_size, ss_logical, ss_physical;

	probe = blkid_new_probe_from_filename(disk->path);
	if (!probe) {
		log_error("cannot get blkid probe %s", disk->path);
		return -1;
	}

	topo = blkid_probe_get_topology(probe);
	if (!topo) {
		log_error("cannot get blkid topology %s", disk->path);
		blkid_free_probe(probe);
		return -1;
	}

	sector_size = blkid_probe_get_sectorsize(probe);
	ss_logical = blkid_topology_get_logical_sector_size(topo);
	ss_physical = blkid_topology_get_physical_sector_size(topo);

	blkid_free_probe(probe);

	if ((sector_size != ss_logical) ||
	    (sector_size != ss_physical) ||
	    (sector_size % 512)) {
		log_error("invalid disk sector size %u logical %u "
			  "physical %u %s", sector_size, ss_logical,
			  ss_physical, disk->path);
		return -1;
	}

	disk->sector_size = sector_size;
	return 0;
}
Example #4
0
/*
 * Reads GPT header to @hdr and returns a pointer to @hdr or NULL in case of
 * error. The function also returns GPT entries in @ents.
 *
 * Note, this function does not allocate any memory. The GPT header has fixed
 * size so we use stack, and @ents returns memory from libblkid buffer (so the
 * next blkid_probe_get_buffer() will overwrite this buffer).
 *
 * This function checks validity of header and entries array. A corrupted
 * header is not returned.
 */
static struct gpt_header *get_gpt_header(
				blkid_probe pr, struct gpt_header *hdr,
				struct gpt_entry **ents, uint64_t lba,
				uint64_t lastlba)
{
	struct gpt_header *h;
	uint32_t crc;
	uint64_t lu, fu;
	size_t esz;
	uint32_t hsz, ssz;

	ssz = blkid_probe_get_sectorsize(pr);

	/* whole sector is allocated for GPT header */
	h = (struct gpt_header *) get_lba_buffer(pr, lba, ssz);
	if (!h)
		return NULL;

	if (le64_to_cpu(h->signature) != GPT_HEADER_SIGNATURE)
		return NULL;

	hsz = le32_to_cpu(h->header_size);

	/* EFI: The HeaderSize must be greater than 92 and must be less
	 *      than or equal to the logical block size.
	 */
	if (hsz > ssz || hsz < sizeof(*h))
		return NULL;

	/* Header has to be verified when header_crc32 is zero */
	crc = count_crc32((unsigned char *) h, hsz,
			offsetof(struct gpt_header, header_crc32),
			sizeof(h->header_crc32));

	if (crc != le32_to_cpu(h->header_crc32)) {
		DBG(LOWPROBE, ul_debug("GPT header corrupted"));
		return NULL;
	}

	/* Valid header has to be at MyLBA */
	if (le64_to_cpu(h->my_lba) != lba) {
		DBG(LOWPROBE, ul_debug(
			"GPT->MyLBA mismatch with real position"));
		return NULL;
	}

	fu = le64_to_cpu(h->first_usable_lba);
	lu = le64_to_cpu(h->last_usable_lba);

	/* Check if First and Last usable LBA makes sense */
	if (lu < fu || fu > lastlba || lu > lastlba) {
		DBG(LOWPROBE, ul_debug(
			"GPT->{First,Last}UsableLBA out of range"));
		return NULL;
	}

	/* The header has to be outside usable range */
	if (fu < lba && lba < lu) {
		DBG(LOWPROBE, ul_debug("GPT header is inside usable area"));
		return NULL;
	}

	if (le32_to_cpu(h->num_partition_entries) == 0 ||
	    le32_to_cpu(h->sizeof_partition_entry) == 0 ||
	    ULONG_MAX / le32_to_cpu(h->num_partition_entries) < le32_to_cpu(h->sizeof_partition_entry)) {
		DBG(LOWPROBE, ul_debug("GPT entries undefined"));
		return NULL;
	}

	/* Size of blocks with GPT entries */
	esz = le32_to_cpu(h->num_partition_entries) *
			le32_to_cpu(h->sizeof_partition_entry);

	/* The header seems valid, save it
	 * (we don't care about zeros in hdr->reserved2 area) */
	memcpy(hdr, h, sizeof(*h));
	h = hdr;

	/* Read GPT entries */
	*ents = (struct gpt_entry *) get_lba_buffer(pr,
				le64_to_cpu(h->partition_entries_lba), esz);
	if (!*ents) {
		DBG(LOWPROBE, ul_debug("GPT entries unreadable"));
		return NULL;
	}

	/* Validate entries */
	crc = count_crc32((unsigned char *) *ents, esz, 0, 0);
	if (crc != le32_to_cpu(h->partition_entry_array_crc32)) {
		DBG(LOWPROBE, ul_debug("GPT entries corrupted"));
		return NULL;
	}

	return h;
}
Example #5
0
static inline unsigned char *get_lba_buffer(blkid_probe pr,
					uint64_t lba, size_t bytes)
{
	return blkid_probe_get_buffer(pr,
			blkid_probe_get_sectorsize(pr) * lba, bytes);
}
Example #6
0
int main(int argc, char *argv[])
{
    int i, nparts;
    char *devname;
    blkid_probe pr;
    blkid_partlist ls;
    blkid_parttable root_tab;

    if (argc < 2) {
        fprintf(stderr, "usage: %s <device|file>  "
                "-- prints partitions\n",
                program_invocation_short_name);
        return EXIT_FAILURE;
    }

    devname = argv[1];
    pr = blkid_new_probe_from_filename(devname);
    if (!pr)
        err(EXIT_FAILURE, "%s: faild to create a new libblkid probe",
            devname);
    /* Binary interface */
    ls = blkid_probe_get_partitions(pr);
    if (!ls)
        errx(EXIT_FAILURE, "%s: failed to read partitions\n", devname);

    /*
     * Print info about the primary (root) partition table
     */
    root_tab = blkid_partlist_get_table(ls);
    if (!root_tab)
        errx(EXIT_FAILURE, "%s: does not contains any "
             "known partition table\n", devname);

    printf("size: %jd, sector size: %u, PT: %s, offset: %jd\n---\n",
           blkid_probe_get_size(pr),
           blkid_probe_get_sectorsize(pr),
           blkid_parttable_get_type(root_tab),
           blkid_parttable_get_offset(root_tab));

    /*
     * List partitions
     */
    nparts = blkid_partlist_numof_partitions(ls);
    if (!nparts)
        goto done;

    for (i = 0; i < nparts; i++) {
        const char *p;
        blkid_partition par = blkid_partlist_get_partition(ls, i);
        blkid_parttable tab = blkid_partition_get_table(par);

        printf("#%d: %10llu %10llu  0x%x",
               blkid_partition_get_partno(par),
               (unsigned long long) blkid_partition_get_start(par),
               (unsigned long long) blkid_partition_get_size(par),
               blkid_partition_get_type(par));

        if (root_tab != tab)
            /* subpartition (BSD, Minix, ...) */
            printf(" (%s)", blkid_parttable_get_type(tab));

        p = blkid_partition_get_name(par);
        if (p)
            printf(" name='%s'", p);
        p = blkid_partition_get_uuid(par);
        if (p)
            printf(" uuid='%s'", p);
        p = blkid_partition_get_type_string(par);
        if (p)
            printf(" type='%s'", p);

        putc('\n', stdout);
    }

done:
    blkid_free_probe(pr);
    return EXIT_SUCCESS;
}