Exemple #1
0
static int lowprobe_superblocks(blkid_probe pr)
{
	struct stat st;
	int rc;

	if (fstat(blkid_probe_get_fd(pr), &st))
		return -1;

	blkid_probe_enable_partitions(pr, 1);
	blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);

	if (!S_ISCHR(st.st_mode) && blkid_probe_get_size(pr) <= 1024 * 1440) {
		/*
		 * check if the small disk is partitioned, if yes then
		 * don't probe for filesystems.
		 */
		blkid_probe_enable_superblocks(pr, 0);

		rc = blkid_do_fullprobe(pr);
		if (rc < 0)
			return rc;	/* -1 = error, 1 = nothing, 0 = succes */

		if (blkid_probe_lookup_value(pr, "PTTYPE", NULL, NULL) == 0)
			return 0;	/* partition table detected */

		/* small whole-disk is unpartitioned, probe for filesystems only */
		blkid_probe_enable_partitions(pr, 0);
	}

	blkid_probe_enable_superblocks(pr, 1);

	return blkid_do_safeprobe(pr);
}
Exemple #2
0
static int check_partition_table(const char *device)
{
	blkid_probe pr;
	const char *value;
	int ret;

	pr = blkid_new_probe_from_filename(device);
	if (!pr)
		return -1;

	ret = blkid_probe_enable_partitions(pr, 1);
	if (ret < 0)
		goto errout;

	ret = blkid_probe_enable_superblocks(pr, 0);
	if (ret < 0)
		goto errout;

	ret = blkid_do_fullprobe(pr);
	if (ret < 0)
		goto errout;

	ret = blkid_probe_lookup_value(pr, "PTTYPE", &value, NULL);
	if (ret == 0)
		fprintf(stderr, _("Found a %s partition table in %s\n"),
			value, device);
	else
		ret = 1;

errout:
	blkid_free_probe(pr);
	return ret;
}
Exemple #3
0
static blkid_probe
new_probe(const char *devname, int mode)
{
	blkid_probe pr;

	if (!devname)
		return NULL;

	if (mode) {
		int fd = open(devname, mode);
		if (fd < 0)
			goto error;

		pr = blkid_new_probe();
		if (pr && blkid_probe_set_device(pr, fd, 0, 0))
			goto error;
	} else
		pr = blkid_new_probe_from_filename(devname);

	if (!pr)
		goto error;

	blkid_probe_enable_superblocks(pr, 1);
	blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC |
			BLKID_SUBLKS_TYPE | BLKID_SUBLKS_USAGE |
			BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID);

	blkid_probe_enable_partitions(pr, 1);
	blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);

	return pr;
error:
	err(EXIT_FAILURE, _("error: %s: probing initialization failed"), devname);
	return NULL;
}
Exemple #4
0
gboolean type_by_device(const gchar* device, gchar** type) {
	gboolean result = false;
	const char *devtype = NULL;
	blkid_probe probe = NULL;

	*type = NULL;

	probe = blkid_new_probe_from_filename(device);
	if(!probe) {
		LOG(MOD "Probe from filename failed!\n");
		return false;
	}
	if (blkid_probe_enable_partitions(probe, true) != 0) {
		LOG(MOD "Enable partitions failed!\n");
		goto fail;
	}
	if (blkid_do_fullprobe(probe) != 0) {
		LOG(MOD "Fullprobe failed!\n");
		goto fail;
	}
	if (blkid_probe_lookup_value(probe, "TYPE", &devtype, NULL) != 0) {
		LOG(MOD "Lookup value failed!\n");
		goto fail;
	}

	*type = g_strdup(devtype);
	result = true;
fail:
	blkid_free_probe(probe);
	return result;
}
Exemple #5
0
static int _wipe_known_signatures_with_blkid(struct device *dev, const char *name,
					     uint32_t types_to_exclude,
					     uint32_t types_no_prompt,
					     int yes, force_t force, int *wiped)
{
	blkid_probe probe = NULL;
	int found = 0, left = 0, wiped_tmp;
	int r_wipe;
	int r = 0;

	if (!wiped)
		wiped = &wiped_tmp;
	*wiped = 0;

	/* TODO: Should we check for valid dev - _dev_is_valid(dev)? */

	if (!(probe = blkid_new_probe_from_filename(dev_name(dev)))) {
		log_error("Failed to create a new blkid probe for device %s.", dev_name(dev));
		goto out;
	}

	blkid_probe_enable_partitions(probe, 1);
	blkid_probe_set_partitions_flags(probe, BLKID_PARTS_MAGIC);

	blkid_probe_enable_superblocks(probe, 1);
	blkid_probe_set_superblocks_flags(probe, BLKID_SUBLKS_LABEL |
						 BLKID_SUBLKS_UUID |
						 BLKID_SUBLKS_TYPE |
						 BLKID_SUBLKS_USAGE |
						 BLKID_SUBLKS_VERSION |
						 BLKID_SUBLKS_MAGIC |
						 BLKID_SUBLKS_BADCSUM);

	while (!blkid_do_probe(probe)) {
		if ((r_wipe = _blkid_wipe(probe, dev, name, types_to_exclude, types_no_prompt, yes, force)) == 1) {
			(*wiped)++;
			if (blkid_probe_step_back(probe)) {
				log_error("Failed to step back blkid probe to check just wiped signature.");
				goto out;
			}
		}
		/* do not count excluded types */
		if (r_wipe != 2)
			found++;
	}

	if (!found)
		r = 1;

	left = found - *wiped;
	if (!left)
		r = 1;
	else
		log_warn("%d existing signature%s left on the device.",
			  left, left > 1 ? "s" : "");
out:
	if (probe)
		blkid_free_probe(probe);
	return r;
}
Exemple #6
0
int main(int argc, char *argv[])
{
	int rc;
	char *devname;
	blkid_probe pr;
	blkid_topology tp;

	if (argc < 2) {
		fprintf(stderr, "usage: %s <device>  "
			"-- checks based on libblkid for mkfs-like programs.\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);

	/*
	 * check Filesystems / Partitions overwrite
	 */

	/* enable partitions probing (superblocks are enabled by default) */
	blkid_probe_enable_partitions(pr, TRUE);

	rc = blkid_do_fullprobe(pr);
	if (rc == -1)
		errx(EXIT_FAILURE, "%s: blkid_do_fullprobe() failed", devname);
	else if (rc == 0) {
		const char *type;

		if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL))
			errx(EXIT_FAILURE, "%s: appears to contain an existing "
					"%s superblock", devname, type);

		if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL))
			errx(EXIT_FAILURE, "%s: appears to contain an partition "
					"table (%s)", devname, type);
	}

	/*
	 * get topology details
	 */
	tp = blkid_probe_get_topology(pr);
	if (!tp)
		errx(EXIT_FAILURE, "%s: failed to read topology", devname);


	/* ... your mkfs.<type> code or so ...

	off = blkid_topology_get_alignment_offset(tp);

	 */

	blkid_free_probe(pr);

	return EXIT_SUCCESS;
}
Exemple #7
0
static int lowprobe_topology(blkid_probe pr)
{
	/* enable topology probing only */
	blkid_probe_enable_topology(pr, 1);

	blkid_probe_enable_superblocks(pr, 0);
	blkid_probe_enable_partitions(pr, 0);

	return blkid_do_fullprobe(pr);
}
Exemple #8
0
static struct wipe_desc *
read_offsets(struct wipe_desc *wp, const char *fname, int zap)
{
	blkid_probe pr;
	int rc;

	if (!fname)
		return NULL;

	pr = blkid_new_probe_from_filename(fname);
	if (!pr)
		errx(EXIT_FAILURE, _("error: %s: probing initialization failed"), fname);

	blkid_probe_enable_superblocks(pr, 0);	/* enabled by default ;-( */

	blkid_probe_enable_partitions(pr, 1);
	rc = blkid_do_fullprobe(pr);
	blkid_probe_enable_partitions(pr, 0);

	if (rc == 0) {
		const char *type = NULL;
		blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL);
		warnx(_("WARNING: %s: appears to contain '%s' "
				"partition table"), fname, type);
	}

	blkid_probe_enable_superblocks(pr, 1);
	blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC |
			BLKID_SUBLKS_TYPE | BLKID_SUBLKS_USAGE |
			BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID);

	while (blkid_do_probe(pr) == 0) {
		wp = get_offset_from_probe(wp, pr, zap);
		if (!wp)
			break;
	}

	blkid_free_probe(pr);
	return wp;
}
Exemple #9
0
/*
 * This function prints a warning if the device is not wiped (e.g. wipefs(8).
 * Please don't call this function if there is already a PT.
 *
 * Returns: 0 if nothing found, < 0 on error, 1 if found a signature
 */
static int warn_wipe(struct fdisk_context *cxt)
{
#ifdef HAVE_LIBBLKID
	blkid_probe pr;
#endif
	int rc = 0;

	assert(cxt);

	if (fdisk_dev_has_disklabel(cxt) || cxt->dev_fd < 0)
		return -EINVAL;
#ifdef HAVE_LIBBLKID
	DBG(LABEL, dbgprint("wipe check: initialize libblkid prober"));

	pr = blkid_new_probe();
	if (!pr)
		return -ENOMEM;
	rc = blkid_probe_set_device(pr, cxt->dev_fd, 0, 0);
	if (rc)
		return rc;

	blkid_probe_enable_superblocks(pr, 1);
	blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_TYPE);
	blkid_probe_enable_partitions(pr, 1);

	/* we care about the first found FS/raid, so don't call blkid_do_probe()
	 * in loop or don't use blkid_do_fullprobe() ... */
	rc = blkid_do_probe(pr);
	if (rc == 0) {
		const char *name = NULL;

		if (blkid_probe_lookup_value(pr, "TYPE", &name, 0) == 0 ||
		    blkid_probe_lookup_value(pr, "PTTYPE", &name, 0) == 0) {
			fdisk_warnx(cxt, _(
				"%s: device contains a valid '%s' signature, it's "
				"strongly recommended to wipe the device by command wipefs(8) "
				"if this setup is unexpected to avoid "
				"possible collisions."), cxt->dev_path, name);
			rc = 1;
		}
	}

	blkid_free_probe(pr);
#endif
	return rc;
}
Exemple #10
0
static lgfs2_rgrps_t rgrps_init(struct gfs2_sbd *sdp)
{
	int ret;
	int error;
	uint64_t al_base = 0;
	uint64_t al_off = 0;
	struct stat st;
	blkid_probe pr = blkid_new_probe();
	if (pr == NULL || blkid_probe_set_device(pr, sdp->device_fd, 0, 0) != 0
	               || blkid_probe_enable_superblocks(pr, TRUE) != 0
	               || blkid_probe_enable_partitions(pr, TRUE) != 0) {
		fprintf(stderr, _("Failed to create probe\n"));
		return NULL;
	}

	error = fstat(sdp->device_fd, &st);
	if (error < 0) {
		fprintf(stderr, _("fstat failed\n"));
		return NULL;
	}

	if (!S_ISREG(st.st_mode) && blkid_probe_enable_topology(pr, TRUE) != 0) {
		fprintf(stderr, _("Failed to create probe\n"));
		return NULL;
	}

	ret = blkid_do_fullprobe(pr);
	if (ret == 0 && !S_ISREG(st.st_mode)) {
		blkid_topology tp = blkid_probe_get_topology(pr);
		if (tp != NULL) {
			unsigned long min_io_sz = blkid_topology_get_minimum_io_size(tp);
			unsigned long opt_io_sz = blkid_topology_get_optimal_io_size(tp);
			unsigned long phy_sector_sz = blkid_topology_get_physical_sector_size(tp);
			if ((min_io_sz > phy_sector_sz) &&
			    (opt_io_sz > phy_sector_sz)) {
					al_base = opt_io_sz / sdp->bsize;
					al_off = min_io_sz / sdp->bsize;
			}

		}
	}

	blkid_free_probe(pr);
	return lgfs2_rgrps_init(sdp, al_base, al_off);
}
Exemple #11
0
/*
 * This function prints a warning if the device is not wiped (e.g. wipefs(8).
 * Please don't call this function if there is already a PT.
 *
 * Returns: 0 if nothing found, < 0 on error, 1 if found a signature
 */
static int check_collisions(struct fdisk_context *cxt)
{
#ifdef HAVE_LIBBLKID
	int rc = 0;
	blkid_probe pr;

	assert(cxt);
	assert(cxt->dev_fd >= 0);

	DBG(CXT, ul_debugobj(cxt, "wipe check: initialize libblkid prober"));

	pr = blkid_new_probe();
	if (!pr)
		return -ENOMEM;
	rc = blkid_probe_set_device(pr, cxt->dev_fd, 0, 0);
	if (rc)
		return rc;

	blkid_probe_enable_superblocks(pr, 1);
	blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_TYPE);
	blkid_probe_enable_partitions(pr, 1);

	/* we care about the first found FS/raid, so don't call blkid_do_probe()
	 * in loop or don't use blkid_do_fullprobe() ... */
	rc = blkid_do_probe(pr);
	if (rc == 0) {
		const char *name = NULL;

		if (blkid_probe_lookup_value(pr, "TYPE", &name, 0) == 0 ||
		    blkid_probe_lookup_value(pr, "PTTYPE", &name, 0) == 0) {
			cxt->collision = strdup(name);
			if (!cxt->collision)
				rc = -ENOMEM;
		}
	}

	blkid_free_probe(pr);
	return rc;
#else
	return 0;
#endif
}
Exemple #12
0
static blkid_probe
new_probe(const char *devname, int mode)
{
	blkid_probe pr = NULL;

	if (!devname)
		return NULL;

	if (mode) {
		int fd = open(devname, mode);
		if (fd < 0)
			goto error;

		pr = blkid_new_probe();
		if (pr && blkid_probe_set_device(pr, fd, 0, 0)) {
			close(fd);
			goto error;
		}
	} else
		pr = blkid_new_probe_from_filename(devname);

	if (!pr)
		goto error;

	blkid_probe_enable_superblocks(pr, 1);
	blkid_probe_set_superblocks_flags(pr,
			BLKID_SUBLKS_MAGIC |	/* return magic string and offset */
			BLKID_SUBLKS_TYPE |	/* return superblock type */
			BLKID_SUBLKS_USAGE |	/* return USAGE= */
			BLKID_SUBLKS_LABEL |	/* return LABEL= */
			BLKID_SUBLKS_UUID |	/* return UUID= */
			BLKID_SUBLKS_BADCSUM);	/* accept bad checksums */

	blkid_probe_enable_partitions(pr, 1);
	blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);

	return pr;
error:
	blkid_free_probe(pr);
	err(EXIT_FAILURE, _("error: %s: probing initialization failed"), devname);
	return NULL;
}
Exemple #13
0
/* returns zero when the device has NAME=value (LABEL/UUID) */
static int verify_tag(const char *devname, const char *name, const char *value)
{
	blkid_probe pr;
	int fd = -1, rc = -1;
	size_t len;
	const char *data;
	int errsv = 0;

	pr = blkid_new_probe();
	if (!pr)
		return -1;

	blkid_probe_enable_superblocks(pr, TRUE);
	blkid_probe_set_superblocks_flags(pr,
			BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID);

	blkid_probe_enable_partitions(pr, TRUE);
	blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);

	fd = open(devname, O_RDONLY|O_CLOEXEC);
	if (fd < 0) {
		errsv = errno;
		goto done;
	}
	if (blkid_probe_set_device(pr, fd, 0, 0))
		goto done;
	rc = blkid_do_safeprobe(pr);
	if (rc)
		goto done;
	rc = blkid_probe_lookup_value(pr, name, &data, &len);
	if (!rc)
		rc = memcmp(value, data, len);
done:
	DBG(EVALUATE, ul_debug("%s: %s verification %s",
			devname, name, rc == 0 ? "PASS" : "FAILED"));
	if (fd >= 0)
		close(fd);
	blkid_free_probe(pr);

	/* for non-root users we use unverified udev links */
	return errsv == EACCES ? 0 : rc;
}
Exemple #14
0
static void
zap_bootbits(int fd, const char *devname, int force, int is_blkdev)
{
	char *type = NULL;
	int whole = 0;
	int zap = 1;

	if (!force) {
		if (lseek(fd, 0, SEEK_SET) != 0)
	                die(_("unable to rewind swap-device"));

		if (is_blkdev && is_whole_disk_fd(fd, devname)) {
			/* don't zap bootbits on whole disk -- we know nothing
			 * about bootloaders on the device */
			whole = 1;
			zap = 0;
		} else {
#ifdef HAVE_LIBBLKID_INTERNAL
			blkid_probe pr = blkid_new_probe();
			if (!pr)
				die(_("unable to alloc new libblkid probe"));
			if (blkid_probe_set_device(pr, fd, 0, 0))
				die(_("unable to assign device to libblkid probe"));

			blkid_probe_enable_partitions(pr, 1);
			blkid_probe_enable_superblocks(pr, 0);

			if (blkid_do_fullprobe(pr) == 0)
				blkid_probe_lookup_value(pr, "PTTYPE",
						(const char **) &type, NULL);
			if (type) {
				type = strdup(type);
				zap = 0;
			}
			blkid_free_probe(pr);
#else
			/* don't zap if compiled without libblkid */
			zap = 0;
#endif
		}
	}

	if (zap) {
		char buf[1024];

		if (lseek(fd, 0, SEEK_SET) != 0)
	                die(_("unable to rewind swap-device"));

		memset(buf, 0, sizeof(buf));
		if (write_all(fd, buf, sizeof(buf)))
			die(_("unable to erase bootbits sectors"));
		return;
	}

	fprintf(stderr, _("%s: %s: warning: don't erase bootbits sectors\n"),
		program_name, devname);
	if (type)
		fprintf(stderr, _("        (%s partition table detected). "), type);
	else if (whole)
		fprintf(stderr, _("        on whole disk. "));
	else
		fprintf(stderr, _("        (compiled without libblkid). "));
	fprintf(stderr, "Use -f to force.\n");
}
Exemple #15
0
static void
wipe_device(int fd, const char *devname, int force)
{
	char *type = NULL;
	int zap = 1;
#ifdef HAVE_LIBBLKID
	blkid_probe pr = NULL;
#endif
	if (!force) {
		if (lseek(fd, 0, SEEK_SET) != 0)
			errx(EXIT_FAILURE, _("unable to rewind swap-device"));

#ifdef HAVE_LIBBLKID
		pr = new_prober(fd);
		blkid_probe_enable_partitions(pr, 1);
		blkid_probe_enable_superblocks(pr, 0);

		if (blkid_do_fullprobe(pr) == 0 &&
		    blkid_probe_lookup_value(pr, "PTTYPE",
				(const char **) &type, NULL) == 0 && type) {
			type = xstrdup(type);
			zap = 0;
		}
#else
		/* don't zap if compiled without libblkid */
		zap = 0;
#endif
	}

	if (zap) {
		/*
		 * Wipe boodbits
		 */
		char buf[1024];
		const char *data = NULL;

		if (lseek(fd, 0, SEEK_SET) != 0)
			errx(EXIT_FAILURE, _("unable to rewind swap-device"));

		memset(buf, 0, sizeof(buf));
		if (write_all(fd, buf, sizeof(buf)))
			errx(EXIT_FAILURE, _("unable to erase bootbits sectors"));
#ifdef HAVE_LIBBLKID
		/*
		 * Wipe rest of the device
		 */
		if (!pr)
			pr = new_prober(fd);

		blkid_probe_enable_superblocks(pr, 1);
		blkid_probe_enable_partitions(pr, 0);
		blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC|BLKID_SUBLKS_TYPE);

		while (blkid_do_probe(pr) == 0) {
			if (blkid_probe_lookup_value(pr, "TYPE", &data, NULL) == 0 && data)
				warnx(_("%s: warning: wiping old %s signature."), devname, data);
			blkid_do_wipe(pr, 0);
		}
#endif
	} else {
		warnx(_("%s: warning: don't erase bootbits sectors"),
			devname);
		if (type)
			fprintf(stderr, _("        (%s partition table detected). "), type);
		else
			fprintf(stderr, _("        (compiled without libblkid). "));
		fprintf(stderr, _("Use -f to force.\n"));
	}
#ifdef HAVE_LIBBLKID
	blkid_free_probe(pr);
#endif
}
Exemple #16
0
static void write_sb(char *dev, unsigned block_size, unsigned bucket_size,
		     bool writeback, bool discard, bool wipe_bcache,
		     unsigned cache_replacement_policy,
		     uint64_t data_offset,
		     uuid_t set_uuid, bool bdev)
{
	int fd;
	char uuid_str[40], set_uuid_str[40], zeroes[SB_START] = {0};
	struct cache_sb sb;
	blkid_probe pr;

	if ((fd = open(dev, O_RDWR|O_EXCL)) == -1) {
		fprintf(stderr, "Can't open dev %s: %s\n", dev, strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb))
		exit(EXIT_FAILURE);

	if (!memcmp(sb.magic, bcache_magic, 16) && !wipe_bcache) {
		fprintf(stderr, "Already a bcache device on %s, "
			"overwrite with --wipe-bcache\n", dev);
		exit(EXIT_FAILURE);
	}

	if (!(pr = blkid_new_probe()))
		exit(EXIT_FAILURE);
	if (blkid_probe_set_device(pr, fd, 0, 0))
		exit(EXIT_FAILURE);
	/* enable ptable probing; superblock probing is enabled by default */
	if (blkid_probe_enable_partitions(pr, true))
		exit(EXIT_FAILURE);
	if (!blkid_do_probe(pr)) {
		/* XXX wipefs doesn't know how to remove partition tables */
		fprintf(stderr, "Device %s already has a non-bcache superblock, "
				"remove it using wipefs and wipefs -a\n", dev);
		exit(EXIT_FAILURE);
	}

	memset(&sb, 0, sizeof(struct cache_sb));

	sb.offset	= SB_SECTOR;
	sb.version	= bdev
		? BCACHE_SB_VERSION_BDEV
		: BCACHE_SB_VERSION_CDEV;

	memcpy(sb.magic, bcache_magic, 16);
	uuid_generate(sb.uuid);
	memcpy(sb.set_uuid, set_uuid, sizeof(sb.set_uuid));

	sb.bucket_size	= bucket_size;
	sb.block_size	= block_size;

	uuid_unparse(sb.uuid, uuid_str);
	uuid_unparse(sb.set_uuid, set_uuid_str);

	if (SB_IS_BDEV(&sb)) {
		SET_BDEV_CACHE_MODE(
			&sb, writeback ? CACHE_MODE_WRITEBACK : CACHE_MODE_WRITETHROUGH);

		if (data_offset != BDEV_DATA_START_DEFAULT) {
			sb.version = BCACHE_SB_VERSION_BDEV_WITH_OFFSET;
			sb.data_offset = data_offset;
		}

		printf("UUID:			%s\n"
		       "Set UUID:		%s\n"
		       "version:		%u\n"
		       "block_size:		%u\n"
		       "data_offset:		%ju\n",
		       uuid_str, set_uuid_str,
		       (unsigned) sb.version,
		       sb.block_size,
		       data_offset);
	} else {
		sb.nbuckets		= getblocks(fd) / sb.bucket_size;
		sb.nr_in_set		= 1;
		sb.first_bucket		= (23 / sb.bucket_size) + 1;

		if (sb.nbuckets < 1 << 7) {
			fprintf(stderr, "Not enough buckets: %ju, need %u\n",
			       sb.nbuckets, 1 << 7);
			exit(EXIT_FAILURE);
		}

		SET_CACHE_DISCARD(&sb, discard);
		SET_CACHE_REPLACEMENT(&sb, cache_replacement_policy);

		printf("UUID:			%s\n"
		       "Set UUID:		%s\n"
		       "version:		%u\n"
		       "nbuckets:		%ju\n"
		       "block_size:		%u\n"
		       "bucket_size:		%u\n"
		       "nr_in_set:		%u\n"
		       "nr_this_dev:		%u\n"
		       "first_bucket:		%u\n",
		       uuid_str, set_uuid_str,
		       (unsigned) sb.version,
		       sb.nbuckets,
		       sb.block_size,
		       sb.bucket_size,
		       sb.nr_in_set,
		       sb.nr_this_dev,
		       sb.first_bucket);
	}

	sb.csum = csum_set(&sb);

	/* Zero start of disk */
	if (pwrite(fd, zeroes, SB_START, 0) != SB_START) {
		perror("write error\n");
		exit(EXIT_FAILURE);
	}
	/* Write superblock */
	if (pwrite(fd, &sb, sizeof(sb), SB_START) != sizeof(sb)) {
		perror("write error\n");
		exit(EXIT_FAILURE);
	}

	fsync(fd);
	close(fd);
}
Exemple #17
0
int main(int argc, char **argv)
{
	bool udev = false;
	int i, o;
	extern char *optarg;
	struct cache_sb sb;
	char uuid[40];
	blkid_probe pr;

	while ((o = getopt(argc, argv, "o:")) != EOF)
		switch (o) {
		case 'o':
			if (strcmp("udev", optarg)) {
				printf("Invalid output format %s\n", optarg);
				exit(EXIT_FAILURE);
			}
			udev = true;
			break;
		}


	argv += optind;
	argc -= optind;

	for (i = 0; i < argc; i++) {
		int fd = open(argv[i], O_RDONLY);
		if (fd == -1)
			continue;

		if (!(pr = blkid_new_probe()))
			continue;
		if (blkid_probe_set_device(pr, fd, 0, 0))
			continue;
		/* probe partitions too */
		if (blkid_probe_enable_partitions(pr, true))
			continue;
		/* bail if anything was found
		 * probe-bcache isn't needed once blkid recognizes bcache */
		if (!blkid_do_probe(pr)) {
			continue;
		}

		if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb))
			continue;

		if (memcmp(sb.magic, bcache_magic, 16))
			continue;

		uuid_unparse(sb.uuid, uuid);

		if (udev)
			printf("ID_FS_UUID=%s\n"
			       "ID_FS_UUID_ENC=%s\n"
			       "ID_FS_TYPE=bcache\n",
			       uuid, uuid);
		else
			printf("%s: UUID=\"\" TYPE=\"bcache\"\n", uuid);
	}

	return 0;
}
static int enumerate_partitions(dev_t devnum) {

        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
        _cleanup_udev_unref_ struct udev *udev = NULL;
        _cleanup_free_ char *home = NULL, *srv = NULL;
        struct udev_list_entry *first, *item;
        struct udev_device *parent = NULL;
        const char *node, *pttype, *devtype;
        int home_nr = -1, srv_nr = -1;
        blkid_partlist pl;
        int r, k;
        dev_t pn;

        udev = udev_new();
        if (!udev)
                return log_oom();

        d = udev_device_new_from_devnum(udev, 'b', devnum);
        if (!d)
                return log_oom();

        parent = udev_device_get_parent(d);
        if (!parent)
                return log_oom();

        /* Does it have a devtype? */
        devtype = udev_device_get_devtype(parent);
        if (!devtype)
                return 0;

        /* Is this a disk or a partition? We only care for disks... */
        if (!streq(devtype, "disk"))
                return 0;

        /* Does it have a device node? */
        node = udev_device_get_devnode(parent);
        if (!node)
                return 0;

        log_debug("Root device %s.", node);

        pn = udev_device_get_devnum(parent);
        if (major(pn) == 0)
                return 0;

        errno = 0;
        b = blkid_new_probe_from_filename(node);
        if (!b) {
                if (errno == 0)
                        return log_oom();

                log_error("Failed allocate prober: %m");
                return -errno;
        }

        blkid_probe_enable_superblocks(b, 1);
        blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
        blkid_probe_enable_partitions(b, 1);
        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);

        errno = 0;
        r = blkid_do_safeprobe(b);
        if (r == -2 || r == 1) /* no result or uncertain */
                return 0;
        else if (r != 0) {
                if (errno == 0)
                        errno = EIO;
                log_error("Failed to probe %s: %m", node);
                return -errno;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
        if (r != 0) {
                if (errno == 0)
                        errno = EIO;
                log_error("Failed to determine partition table type of %s: %m", node);
                return -errno;
        }

        /* We only do this all for GPT... */
        if (!streq_ptr(pttype, "gpt"))
                return 0;

        errno = 0;
        pl = blkid_probe_get_partitions(b);
        if (!pl) {
                if (errno == 0)
                        return log_oom();

                log_error("Failed to list partitions of %s: %m", node);
                return -errno;
        }

        e = udev_enumerate_new(udev);
        if (!e)
                return log_oom();

        r = udev_enumerate_add_match_parent(e, parent);
        if (r < 0)
                return log_oom();

        r = udev_enumerate_add_match_subsystem(e, "block");
        if (r < 0)
                return log_oom();

        r = udev_enumerate_scan_devices(e);
        if (r < 0) {
                log_error("Failed to enumerate partitions on %s: %s", node, strerror(-r));
                return r;
        }

        first = udev_enumerate_get_list_entry(e);
        udev_list_entry_foreach(item, first) {
                _cleanup_udev_device_unref_ struct udev_device *q;
                const char *stype, *subnode;
                sd_id128_t type_id;
                blkid_partition pp;
                dev_t qn;
                int nr;

                q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
                if (!q)
                        continue;

                qn = udev_device_get_devnum(q);
                if (major(qn) == 0)
                        continue;

                if (qn == devnum)
                        continue;

                if (qn == pn)
                        continue;

                subnode = udev_device_get_devnode(q);
                if (!subnode)
                        continue;

                pp = blkid_partlist_devno_to_partition(pl, qn);
                if (!pp)
                        continue;

                nr = blkid_partition_get_partno(pp);
                if (nr < 0)
                        continue;

                stype = blkid_partition_get_type_string(pp);
                if (!stype)
                        continue;

                if (sd_id128_from_string(stype, &type_id) < 0)
                        continue;

                if (sd_id128_equal(type_id, GPT_SWAP)) {

                        k = add_swap(subnode);
                        if (k < 0)
                                r = k;

                } else if (sd_id128_equal(type_id, GPT_HOME)) {

                        /* We only care for the first /home partition */
                        if (home && nr >= home_nr)
                                continue;

                        home_nr = nr;

                        free(home);
                        home = strdup(subnode);
                        if (!home)
                                return log_oom();

                } else if (sd_id128_equal(type_id, GPT_SRV)) {

                        /* We only care for the first /srv partition */
                        if (srv && nr >= srv_nr)
                                continue;

                        srv_nr = nr;

                        free(srv);
                        srv = strdup(node);
                        if (!srv)
                                return log_oom();
                }
        }
Exemple #19
0
static int verify_esp(const char *p, uint32_t *part, uint64_t *pstart, uint64_t *psize, sd_id128_t *uuid) {
        struct statfs sfs;
        struct stat st, st2;
        _cleanup_free_ char *t = NULL;
        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
        int r;
        const char *v, *t2;

        if (statfs(p, &sfs) < 0)
                return log_error_errno(errno, "Failed to check file system type of \"%s\": %m", p);

        if (sfs.f_type != 0x4d44) {
                log_error("File system \"%s\" is not a FAT EFI System Partition (ESP) file system.", p);
                return -ENODEV;
        }

        if (stat(p, &st) < 0)
                return log_error_errno(errno, "Failed to determine block device node of \"%s\": %m", p);

        if (major(st.st_dev) == 0) {
                log_error("Block device node of %p is invalid.", p);
                return -ENODEV;
        }

        t2 = strjoina(p, "/..");
        r = stat(t2, &st2);
        if (r < 0)
                return log_error_errno(errno, "Failed to determine block device node of parent of \"%s\": %m", p);

        if (st.st_dev == st2.st_dev) {
                log_error("Directory \"%s\" is not the root of the EFI System Partition (ESP) file system.", p);
                return -ENODEV;
        }

        r = asprintf(&t, "/dev/block/%u:%u", major(st.st_dev), minor(st.st_dev));
        if (r < 0)
                return log_oom();

        errno = 0;
        b = blkid_new_probe_from_filename(t);
        if (!b) {
                if (errno == 0)
                        return log_oom();

                return log_error_errno(errno, "Failed to open file system \"%s\": %m", p);
        }

        blkid_probe_enable_superblocks(b, 1);
        blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
        blkid_probe_enable_partitions(b, 1);
        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);

        errno = 0;
        r = blkid_do_safeprobe(b);
        if (r == -2) {
                log_error("File system \"%s\" is ambiguous.", p);
                return -ENODEV;
        } else if (r == 1) {
                log_error("File system \"%s\" does not contain a label.", p);
                return -ENODEV;
        } else if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe file system \"%s\": %m", p);
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe file system type \"%s\": %m", p);
        }

        if (!streq(v, "vfat")) {
                log_error("File system \"%s\" is not FAT.", p);
                return -ENODEV;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe partition scheme \"%s\": %m", p);
        }

        if (!streq(v, "gpt")) {
                log_error("File system \"%s\" is not on a GPT partition table.", p);
                return -ENODEV;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe partition type UUID \"%s\": %m", p);
        }

        if (!streq(v, "c12a7328-f81f-11d2-ba4b-00a0c93ec93b")) {
                log_error("File system \"%s\" has wrong type for an EFI System Partition (ESP).", p);
                return -ENODEV;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe partition entry UUID \"%s\": %m", p);
        }

        r = sd_id128_from_string(v, uuid);
        if (r < 0) {
                log_error("Partition \"%s\" has invalid UUID \"%s\".", p, v);
                return -EIO;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe partition number \"%s\": m", p);
        }
        *part = strtoul(v, NULL, 10);

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_OFFSET", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe partition offset \"%s\": %m", p);
        }
        *pstart = strtoul(v, NULL, 10);

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_SIZE", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe partition size \"%s\": %m", p);
        }
        *psize = strtoul(v, NULL, 10);

        return 0;
}
Exemple #20
0
static int enumerate_partitions(dev_t devnum) {

        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
        _cleanup_udev_unref_ struct udev *udev = NULL;
        _cleanup_free_ char *boot = NULL, *home = NULL, *srv = NULL;
        struct udev_list_entry *first, *item;
        struct udev_device *parent = NULL;
        const char *name, *node, *pttype, *devtype;
        int boot_nr = -1, home_nr = -1, srv_nr = -1;
        bool home_rw = true, srv_rw = true;
        blkid_partlist pl;
        int r, k;
        dev_t pn;

        udev = udev_new();
        if (!udev)
                return log_oom();

        d = udev_device_new_from_devnum(udev, 'b', devnum);
        if (!d)
                return log_oom();

        name = udev_device_get_devnode(d);
        if (!name)
                name = udev_device_get_syspath(d);
        if (!name) {
                log_debug("Device %u:%u does not have a name, ignoring.",
                          major(devnum), minor(devnum));
                return 0;
        }

        parent = udev_device_get_parent(d);
        if (!parent) {
                log_debug("%s: not a partitioned device, ignoring.", name);
                return 0;
        }

        /* Does it have a devtype? */
        devtype = udev_device_get_devtype(parent);
        if (!devtype) {
                log_debug("%s: parent doesn't have a device type, ignoring.", name);
                return 0;
        }

        /* Is this a disk or a partition? We only care for disks... */
        if (!streq(devtype, "disk")) {
                log_debug("%s: parent isn't a raw disk, ignoring.", name);
                return 0;
        }

        /* Does it have a device node? */
        node = udev_device_get_devnode(parent);
        if (!node) {
                log_debug("%s: parent device does not have device node, ignoring.", name);
                return 0;
        }

        log_debug("%s: root device %s.", name, node);

        pn = udev_device_get_devnum(parent);
        if (major(pn) == 0)
                return 0;

        errno = 0;
        b = blkid_new_probe_from_filename(node);
        if (!b) {
                if (errno == 0)
                        return log_oom();

                return log_error_errno(errno, "%s: failed to allocate prober: %m", node);
        }

        blkid_probe_enable_partitions(b, 1);
        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);

        errno = 0;
        r = blkid_do_safeprobe(b);
        if (r == 1)
                return 0; /* no results */
        else if (r == -2) {
                log_warning("%s: probe gave ambiguous results, ignoring", node);
                return 0;
        } else if (r != 0)
                return log_error_errno(errno ?: EIO, "%s: failed to probe: %m", node);

        errno = 0;
        r = blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
        if (r != 0)
                return log_error_errno(errno ?: EIO,
                                       "%s: failed to determine partition table type: %m", node);

        /* We only do this all for GPT... */
        if (!streq_ptr(pttype, "gpt")) {
                log_debug("%s: not a GPT partition table, ignoring.", node);
                return 0;
        }

        errno = 0;
        pl = blkid_probe_get_partitions(b);
        if (!pl) {
                if (errno == 0)
                        return log_oom();

                return log_error_errno(errno, "%s: failed to list partitions: %m", node);
        }

        e = udev_enumerate_new(udev);
        if (!e)
                return log_oom();

        r = udev_enumerate_add_match_parent(e, parent);
        if (r < 0)
                return log_oom();

        r = udev_enumerate_add_match_subsystem(e, "block");
        if (r < 0)
                return log_oom();

        r = udev_enumerate_scan_devices(e);
        if (r < 0)
                return log_error_errno(r, "%s: failed to enumerate partitions: %m", node);

        first = udev_enumerate_get_list_entry(e);
        udev_list_entry_foreach(item, first) {
                _cleanup_udev_device_unref_ struct udev_device *q;
                unsigned long long flags;
                const char *stype, *subnode;
                sd_id128_t type_id;
                blkid_partition pp;
                dev_t qn;
                int nr;

                q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
                if (!q)
                        continue;

                qn = udev_device_get_devnum(q);
                if (major(qn) == 0)
                        continue;

                if (qn == devnum)
                        continue;

                if (qn == pn)
                        continue;

                subnode = udev_device_get_devnode(q);
                if (!subnode)
                        continue;

                pp = blkid_partlist_devno_to_partition(pl, qn);
                if (!pp)
                        continue;

                nr = blkid_partition_get_partno(pp);
                if (nr < 0)
                        continue;

                stype = blkid_partition_get_type_string(pp);
                if (!stype)
                        continue;

                if (sd_id128_from_string(stype, &type_id) < 0)
                        continue;

                flags = blkid_partition_get_flags(pp);

                if (sd_id128_equal(type_id, GPT_SWAP)) {

                        if (flags & GPT_FLAG_NO_AUTO)
                                continue;

                        if (flags & GPT_FLAG_READ_ONLY) {
                                log_debug("%s marked as read-only swap partition, which is bogus. Ignoring.", subnode);
                                continue;
                        }

                        k = add_swap(subnode);
                        if (k < 0)
                                r = k;

                } else if (sd_id128_equal(type_id, GPT_ESP)) {

                        /* We only care for the first /boot partition */
                        if (boot && nr >= boot_nr)
                                continue;

                        /* Note that we do not honour the "no-auto"
                         * flag for the ESP, as it is often unset, to
                         * hide it from Windows. */

                        boot_nr = nr;

                        r = free_and_strdup(&boot, subnode);
                        if (r < 0)
                                return log_oom();

                } else if (sd_id128_equal(type_id, GPT_HOME)) {

                        if (flags & GPT_FLAG_NO_AUTO)
                                continue;

                        /* We only care for the first /home partition */
                        if (home && nr >= home_nr)
                                continue;

                        home_nr = nr;
                        home_rw = !(flags & GPT_FLAG_READ_ONLY),

                        r = free_and_strdup(&home, subnode);
                        if (r < 0)
                                return log_oom();

                } else if (sd_id128_equal(type_id, GPT_SRV)) {

                        if (flags & GPT_FLAG_NO_AUTO)
                                continue;

                        /* We only care for the first /srv partition */
                        if (srv && nr >= srv_nr)
                                continue;

                        srv_nr = nr;
                        srv_rw = !(flags & GPT_FLAG_READ_ONLY),

                        r = free_and_strdup(&srv, subnode);
                        if (r < 0)
                                return log_oom();
                }
        }
Exemple #21
0
static int lowprobe_device(blkid_probe pr, const char *devname,	char *show[],
			int output, blkid_loff_t offset, blkid_loff_t size)
{
	const char *data;
	const char *name;
	int nvals = 0, n, num = 1;
	size_t len;
	int fd;
	int rc = 0;
	struct stat st;

	fd = open(devname, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "error: %s: %s\n", devname, strerror(errno));
		return 2;
	}
	if (blkid_probe_set_device(pr, fd, offset, size))
		goto done;

	if (fstat(fd, &st))
		goto done;
	/*
	 * partitions probing
	 */
	blkid_probe_enable_superblocks(pr, 0);	/* enabled by default ;-( */

	blkid_probe_enable_partitions(pr, 1);
	rc = blkid_do_fullprobe(pr);
	blkid_probe_enable_partitions(pr, 0);

	if (rc < 0)
		goto done;	/* -1 = error, 1 = nothing, 0 = succes */

	/*
	 * Don't probe for FS/RAIDs on small devices
	 */
	if (rc || S_ISCHR(st.st_mode) ||
	    blkid_probe_get_size(pr) > 1024 * 1440) {
		/*
		 * filesystems/RAIDs probing
		 */
		blkid_probe_enable_superblocks(pr, 1);

		rc = blkid_do_safeprobe(pr);
		if (rc < 0)
			goto done;
	}

	nvals = blkid_probe_numof_values(pr);

	if (output & OUTPUT_DEVICE_ONLY) {
		printf("%s\n", devname);
		goto done;
	}

	for (n = 0; n < nvals; n++) {
		if (blkid_probe_get_value(pr, n, &name, &data, &len))
			continue;
		if (show[0] && !has_item(show, name))
			continue;
		len = strnlen((char *) data, len);
		print_value(output, num++, devname, (char *) data, name, len);
	}

	if (nvals >= 1 && !(output & (OUTPUT_VALUE_ONLY | OUTPUT_UDEV_LIST)))
		printf("\n");
done:
	if (rc == -2) {
		if (output & OUTPUT_UDEV_LIST)
			print_udev_ambivalent(pr);
		else
			fprintf(stderr,
				"%s: ambivalent result (probably more "
				"filesystems on the device, use wipefs(8) "
				"to see more details)\n",
				devname);
	}
	close(fd);
	return !nvals ? 2 : 0;
}
Exemple #22
0
/*
 * Verify that the data in dev is consistent with what is on the actual
 * block device (using the devname field only).  Normally this will be
 * called when finding items in the cache, but for long running processes
 * is also desirable to revalidate an item before use.
 *
 * If we are unable to revalidate the data, we return the old data and
 * do not set the BLKID_BID_FL_VERIFIED flag on it.
 */
blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
{
    struct stat st;
    time_t diff, now;
    char *fltr[2];
    int fd;

    if (!dev)
        return NULL;

    now = time(0);
    diff = now - dev->bid_time;

    if (stat(dev->bid_name, &st) < 0) {
        DBG(DEBUG_PROBE,
            printf("blkid_verify: error %m (%d) while "
                   "trying to stat %s\n", errno,
                   dev->bid_name));
open_err:
        if ((errno == EPERM) || (errno == EACCES) || (errno == ENOENT)) {
            /* We don't have read permission, just return cache data. */
            DBG(DEBUG_PROBE, printf("returning unverified data for %s\n",
                                    dev->bid_name));
            return dev;
        }
        blkid_free_dev(dev);
        return NULL;
    }

    if (now >= dev->bid_time &&
#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
            (st.st_mtime < dev->bid_time ||
             (st.st_mtime == dev->bid_time &&
              st.st_mtim.tv_nsec / 1000 <= dev->bid_utime)) &&
#else
            st.st_mtime <= dev->bid_time &&
#endif
            (diff < BLKID_PROBE_MIN ||
             (dev->bid_flags & BLKID_BID_FL_VERIFIED &&
              diff < BLKID_PROBE_INTERVAL)))
        return dev;

#ifndef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
    DBG(DEBUG_PROBE,
        printf("need to revalidate %s (cache time %lu, stat time %lu,\n\t"
               "time since last check %lu)\n",
               dev->bid_name, (unsigned long)dev->bid_time,
               (unsigned long)st.st_mtime, (unsigned long)diff));
#else
    DBG(DEBUG_PROBE,
        printf("need to revalidate %s (cache time %lu.%lu, stat time %lu.%lu,\n\t"
               "time since last check %lu)\n",
               dev->bid_name,
               (unsigned long)dev->bid_time, (unsigned long)dev->bid_utime,
               (unsigned long)st.st_mtime, (unsigned long)st.st_mtim.tv_nsec / 1000,
               (unsigned long)diff));
#endif

    if (!cache->probe) {
        cache->probe = blkid_new_probe();
        if (!cache->probe) {
            blkid_free_dev(dev);
            return NULL;
        }
    }

    fd = open(dev->bid_name, O_RDONLY|O_CLOEXEC);
    if (fd < 0) {
        DBG(DEBUG_PROBE, printf("blkid_verify: error %m (%d) while "
                                "opening %s\n", errno,
                                dev->bid_name));
        goto open_err;
    }

    if (blkid_probe_set_device(cache->probe, fd, 0, 0)) {
        /* failed to read the device */
        close(fd);
        blkid_free_dev(dev);
        return NULL;
    }

    blkid_probe_enable_superblocks(cache->probe, TRUE);

    blkid_probe_set_superblocks_flags(cache->probe,
                                      BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
                                      BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE);

    blkid_probe_enable_partitions(cache->probe, TRUE);
    blkid_probe_set_partitions_flags(cache->probe, BLKID_PARTS_ENTRY_DETAILS);

    /*
     * If we already know the type, then try that first.
     */
    if (dev->bid_type) {
        blkid_tag_iterate iter;
        const char *type, *value;

        fltr[0] = dev->bid_type;
        fltr[1] = NULL;

        blkid_probe_filter_superblocks_type(cache->probe,
                                            BLKID_FLTR_ONLYIN, fltr);

        if (!blkid_do_probe(cache->probe))
            goto found_type;
        blkid_probe_invert_superblocks_filter(cache->probe);

        /*
         * Zap the device filesystem information and try again
         */
        DBG(DEBUG_PROBE,
            printf("previous fs type %s not valid, "
                   "trying full probe\n", dev->bid_type));
        iter = blkid_tag_iterate_begin(dev);
        while (blkid_tag_next(iter, &type, &value) == 0)
            blkid_set_tag(dev, type, 0, 0);
        blkid_tag_iterate_end(iter);
    }

    /*
     * Probe for all types.
     */
    if (blkid_do_safeprobe(cache->probe)) {
        /* found nothing or error */
        blkid_free_dev(dev);
        dev = NULL;
    }

found_type:
    if (dev) {
#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
        struct timeval tv;
        if (!gettimeofday(&tv, NULL)) {
            dev->bid_time = tv.tv_sec;
            dev->bid_utime = tv.tv_usec;
        } else
#endif
            dev->bid_time = time(0);

        dev->bid_devno = st.st_rdev;
        dev->bid_flags |= BLKID_BID_FL_VERIFIED;
        cache->bic_flags |= BLKID_BIC_FL_CHANGED;

        blkid_probe_to_tags(cache->probe, dev);

        DBG(DEBUG_PROBE, printf("%s: devno 0x%04llx, type %s\n",
                                dev->bid_name, (long long)st.st_rdev, dev->bid_type));
    }

    blkid_reset_probe(cache->probe);
    blkid_probe_reset_superblocks_filter(cache->probe);
    close(fd);
    return dev;
}
Exemple #23
0
static int verify_esp(const char *p, uint32_t *part, uint64_t *pstart, uint64_t *psize, sd_id128_t *uuid) {
        struct statfs sfs;
        struct stat st, st2;
        char *t;
        blkid_probe b = NULL;
        int r;
        const char *v;

        if (statfs(p, &sfs) < 0) {
                fprintf(stderr, "Failed to check file system type of %s: %m\n", p);
                return -errno;
        }

        if (sfs.f_type != 0x4d44) {
                fprintf(stderr, "File system %s is not a FAT EFI System Partition (ESP) file system.\n", p);
                return -ENODEV;
        }

        if (stat(p, &st) < 0) {
                fprintf(stderr, "Failed to determine block device node of %s: %m\n", p);
                return -errno;
        }

        if (major(st.st_dev) == 0) {
                fprintf(stderr, "Block device node of %p is invalid.\n", p);
                return -ENODEV;
        }

        r = asprintf(&t, "%s/..", p);
        if (r < 0) {
                fprintf(stderr, "Out of memory.\n");
                return -ENOMEM;
        }

        r = stat(t, &st2);
        free(t);
        if (r < 0) {
                fprintf(stderr, "Failed to determine block device node of parent of %s: %m\n", p);
                return -errno;
        }

        if (st.st_dev == st2.st_dev) {
                fprintf(stderr, "Directory %s is not the root of the EFI System Partition (ESP) file system.\n", p);
                return -ENODEV;
        }

        r = asprintf(&t, "/dev/block/%u:%u", major(st.st_dev), minor(st.st_dev));
        if (r < 0) {
                fprintf(stderr, "Out of memory.\n");
                return -ENOMEM;
        }

        errno = 0;
        b = blkid_new_probe_from_filename(t);
        free(t);
        if (!b) {
                if (errno != 0) {
                        fprintf(stderr, "Failed to open file system %s: %m\n", p);
                        return -errno;
                }

                fprintf(stderr, "Out of memory.\n");
                return -ENOMEM;
        }

        blkid_probe_enable_superblocks(b, 1);
        blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
        blkid_probe_enable_partitions(b, 1);
        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);

        errno = 0;
        r = blkid_do_safeprobe(b);
        if (r == -2) {
                fprintf(stderr, "File system %s is ambigious.\n", p);
                r = -ENODEV;
                goto fail;
        } else if (r == 1) {
                fprintf(stderr, "File system %s does not contain a label.\n", p);
                r = -ENODEV;
                goto fail;
        } else if (r != 0) {
                r = errno ? -errno : -EIO;
                fprintf(stderr, "Failed to probe file system %s: %s\n", p, strerror(-r));
                goto fail;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                fprintf(stderr, "Failed to probe file system type %s: %s\n", p, strerror(-r));
                goto fail;
        }

        if (strcmp(v, "vfat") != 0) {
                fprintf(stderr, "File system %s is not a FAT EFI System Partition (ESP) file system after all.\n", p);
                r = -ENODEV;
                goto fail;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                fprintf(stderr, "Failed to probe partition scheme %s: %s\n", p, strerror(-r));
                goto fail;
        }

        if (strcmp(v, "gpt") != 0) {
                fprintf(stderr, "File system %s is not on a GPT partition table.\n", p);
                r = -ENODEV;
                goto fail;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                fprintf(stderr, "Failed to probe partition type UUID %s: %s\n", p, strerror(-r));
                goto fail;
        }

        if (strcmp(v, "c12a7328-f81f-11d2-ba4b-00a0c93ec93b") != 0) {
                r = -ENODEV;
                fprintf(stderr, "File system %s is not an EFI System Partition (ESP).\n", p);
                goto fail;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                fprintf(stderr, "Failed to probe partition entry UUID %s: %s\n", p, strerror(-r));
                goto fail;
        }

        r = sd_id128_from_string(v, uuid);
        if (r < 0) {
                fprintf(stderr, "Partition %s has invalid UUID: %s\n", p, v);
                r = -EIO;
                goto fail;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                fprintf(stderr, "Failed to probe partition number %s: %s\n", p, strerror(-r));
                goto fail;
        }
        *part = strtoul(v, NULL, 10);

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_OFFSET", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                fprintf(stderr, "Failed to probe partition offset %s: %s\n", p, strerror(-r));
                goto fail;
        }
        *pstart = strtoul(v, NULL, 10);

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_SIZE", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                fprintf(stderr, "Failed to probe partition size %s: %s\n", p, strerror(-r));
                goto fail;
        }
        *psize = strtoul(v, NULL, 10);

        blkid_free_probe(b);
        return 0;
fail:
        if (b)
                blkid_free_probe(b);
        return r;
}
Exemple #24
0
int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectedImage **ret) {

#ifdef HAVE_BLKID
        sd_id128_t root_uuid = SD_ID128_NULL, verity_uuid = SD_ID128_NULL;
        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
        bool is_gpt, is_mbr, generic_rw, multiple_generic = false;
        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
        _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
        _cleanup_udev_unref_ struct udev *udev = NULL;
        _cleanup_free_ char *generic_node = NULL;
        const char *pttype = NULL, *usage = NULL;
        struct udev_list_entry *first, *item;
        blkid_partlist pl;
        int r, generic_nr;
        struct stat st;
        unsigned i;

        assert(fd >= 0);
        assert(ret);
        assert(root_hash || root_hash_size == 0);

        /* Probes a disk image, and returns information about what it found in *ret.
         *
         * Returns -ENOPKG if no suitable partition table or file system could be found.
         * Returns -EADDRNOTAVAIL if a root hash was specified but no matching root/verity partitions found. */

        if (root_hash) {
                /* If a root hash is supplied, then we use the root partition that has a UUID that match the first
                 * 128bit of the root hash. And we use the verity partition that has a UUID that match the final
                 * 128bit. */

                if (root_hash_size < sizeof(sd_id128_t))
                        return -EINVAL;

                memcpy(&root_uuid, root_hash, sizeof(sd_id128_t));
                memcpy(&verity_uuid, (const uint8_t*) root_hash + root_hash_size - sizeof(sd_id128_t), sizeof(sd_id128_t));

                if (sd_id128_is_null(root_uuid))
                        return -EINVAL;
                if (sd_id128_is_null(verity_uuid))
                        return -EINVAL;
        }

        if (fstat(fd, &st) < 0)
                return -errno;

        if (!S_ISBLK(st.st_mode))
                return -ENOTBLK;

        b = blkid_new_probe();
        if (!b)
                return -ENOMEM;

        errno = 0;
        r = blkid_probe_set_device(b, fd, 0, 0);
        if (r != 0) {
                if (errno == 0)
                        return -ENOMEM;

                return -errno;
        }

        blkid_probe_enable_superblocks(b, 1);
        blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE|BLKID_SUBLKS_USAGE);
        blkid_probe_enable_partitions(b, 1);
        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);

        errno = 0;
        r = blkid_do_safeprobe(b);
        if (r == -2 || r == 1) {
                log_debug("Failed to identify any partition table.");
                return -ENOPKG;
        }
        if (r != 0) {
                if (errno == 0)
                        return -EIO;

                return -errno;
        }

        m = new0(DissectedImage, 1);
        if (!m)
                return -ENOMEM;

        (void) blkid_probe_lookup_value(b, "USAGE", &usage, NULL);
        if (STRPTR_IN_SET(usage, "filesystem", "crypto")) {
                _cleanup_free_ char *t = NULL, *n = NULL;
                const char *fstype = NULL;

                /* OK, we have found a file system, that's our root partition then. */
                (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);

                if (fstype) {
                        t = strdup(fstype);
                        if (!t)
                                return -ENOMEM;
                }

                if (asprintf(&n, "/dev/block/%u:%u", major(st.st_rdev), minor(st.st_rdev)) < 0)
                        return -ENOMEM;

                m->partitions[PARTITION_ROOT] = (DissectedPartition) {
                        .found = true,
                        .rw = true,
                        .partno = -1,
                        .architecture = _ARCHITECTURE_INVALID,
                        .fstype = t,
                        .node = n,
                };

                t = n = NULL;

                m->encrypted = streq(fstype, "crypto_LUKS");

                *ret = m;
                m = NULL;

                return 0;
        }

        (void) blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
        if (!pttype)
                return -ENOPKG;

        is_gpt = streq_ptr(pttype, "gpt");
        is_mbr = streq_ptr(pttype, "dos");

        if (!is_gpt && !is_mbr)
                return -ENOPKG;

        errno = 0;
        pl = blkid_probe_get_partitions(b);
        if (!pl) {
                if (errno == 0)
                        return -ENOMEM;

                return -errno;
        }

        udev = udev_new();
        if (!udev)
                return -errno;

        d = udev_device_new_from_devnum(udev, 'b', st.st_rdev);
        if (!d)
                return -ENOMEM;

        for (i = 0;; i++) {
                int n, z;

                if (i >= 10) {
                        log_debug("Kernel partitions never appeared.");
                        return -ENXIO;
                }

                e = udev_enumerate_new(udev);
                if (!e)
                        return -errno;

                r = udev_enumerate_add_match_parent(e, d);
                if (r < 0)
                        return r;

                r = udev_enumerate_scan_devices(e);
                if (r < 0)
                        return r;

                /* Count the partitions enumerated by the kernel */
                n = 0;
                first = udev_enumerate_get_list_entry(e);
                udev_list_entry_foreach(item, first)
                        n++;

                /* Count the partitions enumerated by blkid */
                z = blkid_partlist_numof_partitions(pl);
                if (n == z + 1)
                        break;
                if (n > z + 1) {
                        log_debug("blkid and kernel partition list do not match.");
                        return -EIO;
                }
                if (n < z + 1) {
                        unsigned j;

                        /* The kernel has probed fewer partitions than blkid? Maybe the kernel prober is still running
                         * or it got EBUSY because udev already opened the device. Let's reprobe the device, which is a
                         * synchronous call that waits until probing is complete. */

                        for (j = 0; j < 20; j++) {

                                r = ioctl(fd, BLKRRPART, 0);
                                if (r < 0)
                                        r = -errno;
                                if (r >= 0 || r != -EBUSY)
                                        break;

                                /* If something else has the device open, such as an udev rule, the ioctl will return
                                 * EBUSY. Since there's no way to wait until it isn't busy anymore, let's just wait a
                                 * bit, and try again.
                                 *
                                 * This is really something they should fix in the kernel! */

                                usleep(50 * USEC_PER_MSEC);
                        }

                        if (r < 0)
                                return r;
                }

                e = udev_enumerate_unref(e);
        }

        first = udev_enumerate_get_list_entry(e);
        udev_list_entry_foreach(item, first) {
                _cleanup_udev_device_unref_ struct udev_device *q;
                unsigned long long flags;
                blkid_partition pp;
                const char *node;
                dev_t qn;
                int nr;

                q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
                if (!q)
                        return -errno;

                qn = udev_device_get_devnum(q);
                if (major(qn) == 0)
                        continue;

                if (st.st_rdev == qn)
                        continue;

                node = udev_device_get_devnode(q);
                if (!node)
                        continue;

                pp = blkid_partlist_devno_to_partition(pl, qn);
                if (!pp)
                        continue;

                flags = blkid_partition_get_flags(pp);

                nr = blkid_partition_get_partno(pp);
                if (nr < 0)
                        continue;

                if (is_gpt) {
                        int designator = _PARTITION_DESIGNATOR_INVALID, architecture = _ARCHITECTURE_INVALID;
                        const char *stype, *sid, *fstype = NULL;
                        sd_id128_t type_id, id;
                        bool rw = true;

                        if (flags & GPT_FLAG_NO_AUTO)
                                continue;

                        sid = blkid_partition_get_uuid(pp);
                        if (!sid)
                                continue;
                        if (sd_id128_from_string(sid, &id) < 0)
                                continue;

                        stype = blkid_partition_get_type_string(pp);
                        if (!stype)
                                continue;
                        if (sd_id128_from_string(stype, &type_id) < 0)
                                continue;

                        if (sd_id128_equal(type_id, GPT_HOME)) {
                                designator = PARTITION_HOME;
                                rw = !(flags & GPT_FLAG_READ_ONLY);
                        } else if (sd_id128_equal(type_id, GPT_SRV)) {
                                designator = PARTITION_SRV;
                                rw = !(flags & GPT_FLAG_READ_ONLY);
                        } else if (sd_id128_equal(type_id, GPT_ESP)) {
                                designator = PARTITION_ESP;
                                fstype = "vfat";
                        }
#ifdef GPT_ROOT_NATIVE
                        else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE)) {

                                /* If a root ID is specified, ignore everything but the root id */
                                if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id))
                                        continue;

                                designator = PARTITION_ROOT;
                                architecture = native_architecture();
                                rw = !(flags & GPT_FLAG_READ_ONLY);
                        } else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE_VERITY)) {

                                m->can_verity = true;

                                /* Ignore verity unless a root hash is specified */
                                if (sd_id128_is_null(verity_uuid) || !sd_id128_equal(verity_uuid, id))
                                        continue;

                                designator = PARTITION_ROOT_VERITY;
                                fstype = "DM_verity_hash";
                                architecture = native_architecture();
                                rw = false;
                        }
#endif
#ifdef GPT_ROOT_SECONDARY
                        else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY)) {

                                /* If a root ID is specified, ignore everything but the root id */
                                if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id))
                                        continue;

                                designator = PARTITION_ROOT_SECONDARY;
                                architecture = SECONDARY_ARCHITECTURE;
                                rw = !(flags & GPT_FLAG_READ_ONLY);
                        } else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY_VERITY)) {

                                m->can_verity = true;

                                /* Ignore verity unless root has is specified */
                                if (sd_id128_is_null(verity_uuid) || !sd_id128_equal(verity_uuid, id))
                                        continue;

                                designator = PARTITION_ROOT_SECONDARY_VERITY;
                                fstype = "DM_verity_hash";
                                architecture = SECONDARY_ARCHITECTURE;
                                rw = false;
                        }
#endif
                        else if (sd_id128_equal(type_id, GPT_SWAP)) {
                                designator = PARTITION_SWAP;
                                fstype = "swap";
                        } else if (sd_id128_equal(type_id, GPT_LINUX_GENERIC)) {

                                if (generic_node)
                                        multiple_generic = true;
                                else {
                                        generic_nr = nr;
                                        generic_rw = !(flags & GPT_FLAG_READ_ONLY);
                                        generic_node = strdup(node);
                                        if (!generic_node)
                                                return -ENOMEM;
                                }
                        }

                        if (designator != _PARTITION_DESIGNATOR_INVALID) {
                                _cleanup_free_ char *t = NULL, *n = NULL;

                                /* First one wins */
                                if (m->partitions[designator].found)
                                        continue;

                                if (fstype) {
                                        t = strdup(fstype);
                                        if (!t)
                                                return -ENOMEM;
                                }

                                n = strdup(node);
                                if (!n)
                                        return -ENOMEM;

                                m->partitions[designator] = (DissectedPartition) {
                                        .found = true,
                                        .partno = nr,
                                        .rw = rw,
                                        .architecture = architecture,
                                        .node = n,
                                        .fstype = t,
                                };

                                n = t = NULL;
                        }

                } else if (is_mbr) {
Exemple #25
0
/**
 * mnt_cache_read_tags
 * @cache: pointer to struct libmnt_cache instance
 * @devname: path device
 *
 * Reads @devname LABEL and UUID to the @cache.
 *
 * Returns: 0 if at least one tag was added, 1 if no tag was added or
 *          negative number in case of error.
 */
int mnt_cache_read_tags(struct libmnt_cache *cache, const char *devname)
{
	blkid_probe pr;
	size_t i, ntags = 0;
	int rc;
	const char *tags[] = { "LABEL", "UUID", "TYPE", "PARTUUID", "PARTLABEL" };
	const char *blktags[] = { "LABEL", "UUID", "TYPE", "PART_ENTRY_UUID", "PART_ENTRY_NAME" };

	if (!cache || !devname)
		return -EINVAL;

	DBG(CACHE, ul_debugobj(cache, "tags for %s requested", devname));

	/* check if device is already cached */
	for (i = 0; i < cache->nents; i++) {
		struct mnt_cache_entry *e = &cache->ents[i];
		if (!(e->flag & MNT_CACHE_TAGREAD))
			continue;
		if (strcmp(e->value, devname) == 0)
			/* tags have already been read */
			return 0;
	}

	pr =  blkid_new_probe_from_filename(devname);
	if (!pr)
		return -1;

	blkid_probe_enable_superblocks(pr, 1);
	blkid_probe_set_superblocks_flags(pr,
			BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
			BLKID_SUBLKS_TYPE);

	blkid_probe_enable_partitions(pr, 1);
	blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);

	rc = blkid_do_safeprobe(pr);
	if (rc)
		goto error;

	DBG(CACHE, ul_debugobj(cache, "reading tags for: %s", devname));

	for (i = 0; i < ARRAY_SIZE(tags); i++) {
		const char *data;
		char *dev;

		if (cache_find_tag_value(cache, devname, tags[i])) {
			DBG(CACHE, ul_debugobj(cache,
					"\ntag %s already cached", tags[i]));
			continue;
		}
		if (blkid_probe_lookup_value(pr, blktags[i], &data, NULL))
			continue;
		dev = strdup(devname);
		if (!dev)
			goto error;
		if (cache_add_tag(cache, tags[i], data, dev,
					MNT_CACHE_TAGREAD)) {
			free(dev);
			goto error;
		}
		ntags++;
	}

	DBG(CACHE, ul_debugobj(cache, "\tread %zd tags", ntags));
	blkid_free_probe(pr);
	return ntags ? 0 : 1;
error:
	blkid_free_probe(pr);
	return rc < 0 ? rc : -1;
}
Exemple #26
0
static int add_boot(const char *what) {
        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
        const char *fstype = NULL, *uuid = NULL;
        sd_id128_t id, type_id;
        int r;

        assert(what);

        if (!is_efi_boot()) {
                log_debug("Not an EFI boot, ignoring /boot.");
                return 0;
        }

        if (in_initrd()) {
                log_debug("In initrd, ignoring /boot.");
                return 0;
        }

        if (detect_container() > 0) {
                log_debug("In a container, ignoring /boot.");
                return 0;
        }

        /* We create an .automount which is not overridden by the .mount from the fstab generator. */
        if (fstab_is_mount_point("/boot")) {
                log_debug("/boot specified in fstab, ignoring.");
                return 0;
        }

        if (path_is_busy("/boot")) {
                log_debug("/boot already populated, ignoring.");
                return 0;
        }

        r = efi_loader_get_device_part_uuid(&id);
        if (r == -ENOENT) {
                log_debug("EFI loader partition unknown.");
                return 0;
        }

        if (r < 0) {
                log_error_errno(r, "Failed to read ESP partition UUID: %m");
                return r;
        }

        errno = 0;
        b = blkid_new_probe_from_filename(what);
        if (!b) {
                if (errno == 0)
                        return log_oom();
                return log_error_errno(errno, "Failed to allocate prober: %m");
        }

        blkid_probe_enable_partitions(b, 1);
        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);

        errno = 0;
        r = blkid_do_safeprobe(b);
        if (r == -2 || r == 1) /* no result or uncertain */
                return 0;
        else if (r != 0)
                return log_error_errno(errno ?: EIO, "Failed to probe %s: %m", what);

        (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
        if (!streq(fstype, "vfat")) {
                log_debug("Partition for /boot is not a FAT filesystem, ignoring.");
                return 0;
        }

        r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &uuid, NULL);
        if (r != 0) {
                log_debug_errno(r, "Partition for /boot does not have a UUID, ignoring. %m");
                return 0;
        }

        if (sd_id128_from_string(uuid, &type_id) < 0) {
                log_debug("Partition for /boot does not have a valid UUID, ignoring.");
                return 0;
        }

        if (!sd_id128_equal(type_id, id)) {
                log_debug("Partition for /boot does not appear to be the partition we are booted from.");
                return 0;
        }

        r = add_automount("boot",
                       what,
                       "/boot",
                       "vfat",
                       true,
                       "umask=0077",
                       "EFI System Partition Automount",
                       120 * USEC_PER_SEC);

        return r;
}