static int lowprobe_device(blkid_probe pr, const char *devname, int chain, 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; static int first = 1; fd = open(devname, O_RDONLY); if (fd < 0) { fprintf(stderr, "error: %s: %m\n", devname); return 2; } if (blkid_probe_set_device(pr, fd, offset, size)) goto done; if (chain & LOWPROBE_TOPOLOGY) rc = lowprobe_topology(pr); if (rc >= 0 && (chain & LOWPROBE_SUPERBLOCKS)) rc = lowprobe_superblocks(pr); if (rc < 0) goto done; if (!rc) nvals = blkid_probe_numof_values(pr); if (nvals && !(chain & LOWPROBE_TOPOLOGY) && !(output & OUTPUT_UDEV_LIST) && !blkid_probe_has_value(pr, "TYPE") && !blkid_probe_has_value(pr, "PTTYPE")) /* * Ignore probing result if there is not any filesystem or * partition table on the device and udev output is not * requested. * * The udev db stores information about partitions, so * PART_ENTRY_* values are alway important. */ nvals = 0; if (nvals && !first && output & (OUTPUT_UDEV_LIST | OUTPUT_EXPORT_LIST)) /* add extra line between output from devices */ fputc('\n', stdout); if (nvals && (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 (first) first = 0; if (nvals >= 1 && !(output & (OUTPUT_VALUE_ONLY | OUTPUT_UDEV_LIST | OUTPUT_EXPORT_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); if (rc == -2) return 8; /* ambivalent probing result */ if (!nvals) return 2; /* nothing detected */ return 0; /* sucess */ }
static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool test) { const char *root_partition; int64_t offset = 0; bool noraid = false; _cleanup_close_ int fd = -1; blkid_probe pr; const char *data; const char *name; const char *prtype = NULL; int nvals; int i; int err = 0; bool is_gpt = false; static const struct option options[] = { { "offset", optional_argument, NULL, 'o' }, { "noraid", no_argument, NULL, 'R' }, {} }; for (;;) { int option; option = getopt_long(argc, argv, "oR", options, NULL); if (option == -1) break; switch (option) { case 'o': offset = strtoull(optarg, NULL, 0); break; case 'R': noraid = true; break; } } pr = blkid_new_probe(); if (!pr) return EXIT_FAILURE; blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE | BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION | BLKID_SUBLKS_BADCSUM); if (noraid) blkid_probe_filter_superblocks_usage(pr, BLKID_FLTR_NOTIN, BLKID_USAGE_RAID); fd = open(udev_device_get_devnode(dev), O_RDONLY|O_CLOEXEC); if (fd < 0) { err = log_debug_errno(errno, "Failure opening block device %s: %m", udev_device_get_devnode(dev)); goto out; } err = blkid_probe_set_device(pr, fd, offset, 0); if (err < 0) goto out; log_debug("probe %s %sraid offset=%"PRIi64, udev_device_get_devnode(dev), noraid ? "no" : "", offset); err = probe_superblocks(pr); if (err < 0) goto out; if (blkid_probe_has_value(pr, "SBBADCSUM")) { if (!blkid_probe_lookup_value(pr, "TYPE", &prtype, NULL)) log_warning("incorrect %s checksum on %s", prtype, udev_device_get_devnode(dev)); else log_warning("incorrect checksum on %s", udev_device_get_devnode(dev)); goto out; } /* If we are a partition then our parent passed on the root * partition UUID to us */ root_partition = udev_device_get_property_value(dev, "ID_PART_GPT_AUTO_ROOT_UUID"); nvals = blkid_probe_numof_values(pr); for (i = 0; i < nvals; i++) { if (blkid_probe_get_value(pr, i, &name, &data, NULL)) continue; print_property(dev, test, name, data); /* Is this a disk with GPT partition table? */ if (streq(name, "PTTYPE") && streq(data, "gpt")) is_gpt = true; /* Is this a partition that matches the root partition * property we inherited from our parent? */ if (root_partition && streq(name, "PART_ENTRY_UUID") && streq(data, root_partition)) udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT", "1"); } if (is_gpt) find_gpt_root(dev, pr, test); blkid_free_probe(pr); out: if (err < 0) return EXIT_FAILURE; return EXIT_SUCCESS; }