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;
    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);

    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) {
        fprintf(stderr, "error: %s: %m\n", 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=%llu",
              udev_device_get_devnode(dev),
              noraid ? "no" : "", (unsigned long long) offset);

    err = probe_superblocks(pr);
    if (err < 0)
        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;
}
Exemplo n.º 2
0
int main(int argc, char **argv)
{
	blkid_cache cache = NULL;
	char *devices[128] = { NULL, };
	char *show[128] = { NULL, };
	char *search_type = NULL, *search_value = NULL;
	char *read = NULL;
	char *write = NULL;
	int fltr_usage = 0;
	char **fltr_type = NULL;
	int fltr_flag = BLKID_FLTR_ONLYIN;
	unsigned int numdev = 0, numtag = 0;
	int version = 0;
	int err = 4;
	unsigned int i;
	int output_format = 0;
	int lookup = 0, gc = 0, lowprobe = 0, eval = 0;
	int c;
	uintmax_t offset = 0, size = 0;

	show[0] = NULL;

	while ((c = getopt (argc, argv, "c:f:ghilL:n:o:O:ps:S:t:u:U:w:v")) != EOF)
		switch (c) {
		case 'c':
			if (optarg && !*optarg)
				read = NULL;
			else
				read = optarg;
			if (!write)
				write = read;
			break;
		case 'L':
			eval++;
			search_value = strdup(optarg);
			search_type = strdup("LABEL");
			break;
		case 'n':
			if (fltr_usage) {
				fprintf(stderr, "error: -u and -n options are mutually exclusive\n");
				exit(4);
			}
			fltr_type = list_to_types(optarg, &fltr_flag);
			break;
		case 'u':
			if (fltr_type) {
				fprintf(stderr, "error: -u and -n options are mutually exclusive\n");
				exit(4);
			}
			fltr_usage = list_to_usage(optarg, &fltr_flag);
			break;
		case 'U':
			eval++;
			search_value = strdup(optarg);
			search_type = strdup("UUID");
			break;
		case 'i':
			lowprobe |= LOWPROBE_TOPOLOGY;
			break;
		case 'l':
			lookup++;
			break;
		case 'g':
			gc = 1;
			break;
		case 'o':
			if (!strcmp(optarg, "value"))
				output_format = OUTPUT_VALUE_ONLY;
			else if (!strcmp(optarg, "device"))
				output_format = OUTPUT_DEVICE_ONLY;
			else if (!strcmp(optarg, "list"))
				output_format = OUTPUT_PRETTY_LIST;
			else if (!strcmp(optarg, "udev"))
				output_format = OUTPUT_UDEV_LIST;
			else if (!strcmp(optarg, "export"))
				output_format = OUTPUT_EXPORT_LIST;
			else if (!strcmp(optarg, "full"))
				output_format = 0;
			else {
				fprintf(stderr, "Invalid output format %s. "
					"Choose from value,\n\t"
					"device, list, udev or full\n", optarg);
				exit(4);
			}
			break;
		case 'O':
			if (strtosize(optarg, &offset))
				fprintf(stderr,
					"Invalid offset '%s' specified\n",
					optarg);
			break;
		case 'p':
			lowprobe |= LOWPROBE_SUPERBLOCKS;
			break;
		case 's':
			if (numtag + 1 >= sizeof(show) / sizeof(*show)) {
				fprintf(stderr, "Too many tags specified\n");
				usage(err);
			}
			show[numtag++] = optarg;
			show[numtag] = NULL;
			break;
		case 'S':
			if (strtosize(optarg, &size))
				fprintf(stderr,
					"Invalid size '%s' specified\n",
					optarg);
			break;
		case 't':
			if (search_type) {
				fprintf(stderr, "Can only search for "
						"one NAME=value pair\n");
				usage(err);
			}
			if (blkid_parse_tag_string(optarg,
						   &search_type,
						   &search_value)) {
				fprintf(stderr, "-t needs NAME=value pair\n");
				usage(err);
			}
			break;
		case 'v':
			version = 1;
			break;
		case 'w':
			if (optarg && !*optarg)
				write = NULL;
			else
				write = optarg;
			break;
		case 'h':
			err = 0;
		default:
			usage(err);
		}

	while (optind < argc)
		devices[numdev++] = argv[optind++];

	if (version) {
		print_version(stdout);
		goto exit;
	}

	/* convert LABEL/UUID lookup to evaluate request */
	if (lookup && output_format == OUTPUT_DEVICE_ONLY && search_type &&
	    (!strcmp(search_type, "LABEL") || !strcmp(search_type, "UUID"))) {
		eval++;
		lookup = 0;
	}

	if (!lowprobe && !eval && blkid_get_cache(&cache, read) < 0)
		goto exit;

	if (gc) {
		blkid_gc_cache(cache);
		err = 0;
		goto exit;
	}
	err = 2;

	if (eval == 0 && (output_format & OUTPUT_PRETTY_LIST)) {
		if (lowprobe) {
			fprintf(stderr, "The low-level probing mode does not "
					"support 'list' output format\n");
			exit(4);
		}
		pretty_print_dev(NULL);
	}

	if (lowprobe) {
		/*
		 * Low-level API
		 */
		blkid_probe pr;

		if (!numdev) {
			fprintf(stderr, "The low-level probing mode "
					"requires a device\n");
			exit(4);
		}

		/* automatically enable 'export' format for I/O Limits */
		if (!output_format  && (lowprobe & LOWPROBE_TOPOLOGY))
			output_format = OUTPUT_EXPORT_LIST;

		pr = blkid_new_probe();
		if (!pr)
			goto exit;

		if (lowprobe & LOWPROBE_SUPERBLOCKS) {
			blkid_probe_set_superblocks_flags(pr,
				BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
				BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
				BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION);

			if (fltr_usage && blkid_probe_filter_superblocks_usage(
						pr, fltr_flag, fltr_usage))
				goto exit;

			else if (fltr_type && blkid_probe_filter_superblocks_type(
						pr, fltr_flag, fltr_type))
				goto exit;
		}

		for (i = 0; i < numdev; i++)
			err = lowprobe_device(pr, devices[i], lowprobe, show,
					output_format,
					(blkid_loff_t) offset,
					(blkid_loff_t) size);
		blkid_free_probe(pr);
	} else if (eval) {
		/*
		 * Evaluate API
		 */
		char *res = blkid_evaluate_tag(search_type, search_value, NULL);
		if (res) {
			err = 0;
			printf("%s\n", res);
		}
	} else if (lookup) {
		/*
		 * Classic (cache based) API
		 */
		blkid_dev dev;

		if (!search_type) {
			fprintf(stderr, "The lookup option requires a "
				"search type specified using -t\n");
			exit(4);
		}
		/* Load any additional devices not in the cache */
		for (i = 0; i < numdev; i++)
			blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL);

		if ((dev = blkid_find_dev_with_tag(cache, search_type,
						   search_value))) {
			print_tags(dev, show, output_format);
			err = 0;
		}
	/* If we didn't specify a single device, show all available devices */
	} else if (!numdev) {
		blkid_dev_iterate	iter;
		blkid_dev		dev;

		blkid_probe_all(cache);

		iter = blkid_dev_iterate_begin(cache);
		blkid_dev_set_search(iter, search_type, search_value);
		while (blkid_dev_next(iter, &dev) == 0) {
			dev = blkid_verify(cache, dev);
			if (!dev)
				continue;
			print_tags(dev, show, output_format);
			err = 0;
		}
		blkid_dev_iterate_end(iter);
	/* Add all specified devices to cache (optionally display tags) */
	} else for (i = 0; i < numdev; i++) {
		blkid_dev dev = blkid_get_dev(cache, devices[i],
						  BLKID_DEV_NORMAL);

		if (dev) {
			if (search_type &&
			    !blkid_dev_has_tag(dev, search_type,
					       search_value))
				continue;
			print_tags(dev, show, output_format);
			err = 0;
		}
	}

exit:
	free(search_type);
	free(search_value);
	free_types_list(fltr_type);
	if (!lowprobe && !eval)
		blkid_put_cache(cache);
	return err;
}
Exemplo n.º 3
0
/**
 * blkid_probe_filter_usage
 * @pr: prober
 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
 * @usage: BLKID_USAGE_* flags
 *
 * Returns: 0 on success, or -1 in case of error.
 *
 * Deprecated: Use blkid_probe_filter_superblocks_usage().
 */
int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage)
{
	return blkid_probe_filter_superblocks_usage(pr, flag, usage);
}
Exemplo n.º 4
0
static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool test)
{
        int64_t offset = 0;
        bool noraid = false;
        int fd = -1;
        blkid_probe pr;
        const char *data;
        const char *name;
        int nvals;
        int i;
        size_t len;
        int err = 0;

        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);

        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) {
                fprintf(stderr, "error: %s: %m\n", 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=%llu\n",
                  udev_device_get_devnode(dev),
                  noraid ? "no" : "", (unsigned long long) offset);

        err = probe_superblocks(pr);
        if (err < 0)
                goto out;

        nvals = blkid_probe_numof_values(pr);
        for (i = 0; i < nvals; i++) {
                if (blkid_probe_get_value(pr, i, &name, &data, &len))
                        continue;
                len = strnlen((char *) data, len);
                print_property(dev, test, name, (char *) data);
        }

        blkid_free_probe(pr);
out:
        if (fd > 0)
                close(fd);
        if (err < 0)
                return EXIT_FAILURE;
        return EXIT_SUCCESS;
}
Exemplo n.º 5
0
int main(int argc, char **argv)
{
	blkid_cache cache = NULL;
	char **devices = NULL;
	char *show[128] = { NULL, };
	char *search_type = NULL, *search_value = NULL;
	char *read = NULL;
	int fltr_usage = 0;
	char **fltr_type = NULL;
	int fltr_flag = BLKID_FLTR_ONLYIN;
	unsigned int numdev = 0, numtag = 0;
	int version = 0;
	int err = BLKID_EXIT_OTHER;
	unsigned int i;
	int output_format = 0;
	int lookup = 0, gc = 0, lowprobe = 0, eval = 0;
	int c;
	uintmax_t offset = 0, size = 0;

	static const ul_excl_t excl[] = {       /* rows and cols in in ASCII order */
		{ 'n','u' },
		{ 0 }
	};
	int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;

	show[0] = NULL;
	atexit(close_stdout);

	while ((c = getopt (argc, argv,
			    "c:df:ghilL:n:ko:O:ps:S:t:u:U:w:Vv")) != EOF) {

		err_exclusive_options(c, NULL, excl, excl_st);

		switch (c) {
		case 'c':
			if (optarg && !*optarg)
				read = NULL;
			else
				read = optarg;
			break;
		case 'd':
			raw_chars = 1;
			break;
		case 'L':
			eval++;
			search_value = xstrdup(optarg);
			search_type = xstrdup("LABEL");
			break;
		case 'n':
			fltr_type = list_to_types(optarg, &fltr_flag);
			break;
		case 'u':
			fltr_usage = list_to_usage(optarg, &fltr_flag);
			break;
		case 'U':
			eval++;
			search_value = xstrdup(optarg);
			search_type = xstrdup("UUID");
			break;
		case 'i':
			lowprobe |= LOWPROBE_TOPOLOGY;
			break;
		case 'l':
			lookup++;
			break;
		case 'g':
			gc = 1;
			break;
		case 'k':
		{
			size_t idx = 0;
			const char *name = NULL;

			while (blkid_superblocks_get_name(idx++, &name, NULL) == 0)
				printf("%s\n", name);
			exit(EXIT_SUCCESS);
		}
		case 'o':
			if (!strcmp(optarg, "value"))
				output_format = OUTPUT_VALUE_ONLY;
			else if (!strcmp(optarg, "device"))
				output_format = OUTPUT_DEVICE_ONLY;
			else if (!strcmp(optarg, "list"))
				output_format = OUTPUT_PRETTY_LIST;	/* deprecated */
			else if (!strcmp(optarg, "udev"))
				output_format = OUTPUT_UDEV_LIST;
			else if (!strcmp(optarg, "export"))
				output_format = OUTPUT_EXPORT_LIST;
			else if (!strcmp(optarg, "full"))
				output_format = 0;
			else {
				fprintf(stderr, "Invalid output format %s. "
					"Choose from value,\n\t"
					"device, list, udev or full\n", optarg);
				exit(BLKID_EXIT_OTHER);
			}
			break;
		case 'O':
			offset = strtosize_or_err(optarg, "invalid offset argument");
			break;
		case 'p':
			lowprobe |= LOWPROBE_SUPERBLOCKS;
			break;
		case 's':
			if (numtag + 1 >= sizeof(show) / sizeof(*show)) {
				fprintf(stderr, "Too many tags specified\n");
				usage(err);
			}
			show[numtag++] = optarg;
			show[numtag] = NULL;
			break;
		case 'S':
			size = strtosize_or_err(optarg, "invalid size argument");
			break;
		case 't':
			if (search_type) {
				fprintf(stderr, "Can only search for "
						"one NAME=value pair\n");
				usage(err);
			}
			if (blkid_parse_tag_string(optarg,
						   &search_type,
						   &search_value)) {
				fprintf(stderr, "-t needs NAME=value pair\n");
				usage(err);
			}
			break;
		case 'V':
		case 'v':
			version = 1;
			break;
		case 'w':
			/* ignore - backward compatibility */
			break;
		case 'h':
			err = 0;
			/* fallthrough */
		default:
			usage(err);
		}
	}


	/* The rest of the args are device names */
	if (optind < argc) {
		devices = xcalloc(argc - optind, sizeof(char *));
		while (optind < argc)
			devices[numdev++] = argv[optind++];
	}

	if (version) {
		print_version(stdout);
		goto exit;
	}

	/* convert LABEL/UUID lookup to evaluate request */
	if (lookup && output_format == OUTPUT_DEVICE_ONLY && search_type &&
	    (!strcmp(search_type, "LABEL") || !strcmp(search_type, "UUID"))) {
		eval++;
		lookup = 0;
	}

	if (!lowprobe && !eval && blkid_get_cache(&cache, read) < 0)
		goto exit;

	if (gc) {
		blkid_gc_cache(cache);
		err = 0;
		goto exit;
	}
	err = BLKID_EXIT_NOTFOUND;

	if (eval == 0 && (output_format & OUTPUT_PRETTY_LIST)) {
		if (lowprobe) {
			fprintf(stderr, "The low-level probing mode does not "
					"support 'list' output format\n");
			exit(BLKID_EXIT_OTHER);
		}
		pretty_print_dev(NULL);
	}

	if (lowprobe) {
		/*
		 * Low-level API
		 */
		blkid_probe pr;

		if (!numdev) {
			fprintf(stderr, "The low-level probing mode "
					"requires a device\n");
			exit(BLKID_EXIT_OTHER);
		}

		/* automatically enable 'export' format for I/O Limits */
		if (!output_format  && (lowprobe & LOWPROBE_TOPOLOGY))
			output_format = OUTPUT_EXPORT_LIST;

		pr = blkid_new_probe();
		if (!pr)
			goto exit;

		if (lowprobe & LOWPROBE_SUPERBLOCKS) {
			blkid_probe_set_superblocks_flags(pr,
				BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
				BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
				BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION);

			if (fltr_usage && blkid_probe_filter_superblocks_usage(
						pr, fltr_flag, fltr_usage))
				goto exit;

			else if (fltr_type && blkid_probe_filter_superblocks_type(
						pr, fltr_flag, fltr_type))
				goto exit;
		}

		for (i = 0; i < numdev; i++) {
			err = lowprobe_device(pr, devices[i], lowprobe, show,
					output_format,
					(blkid_loff_t) offset,
					(blkid_loff_t) size);
			if (err)
				break;
		}
		blkid_free_probe(pr);
	} else if (eval) {
		/*
		 * Evaluate API
		 */
		char *res = blkid_evaluate_tag(search_type, search_value, NULL);
		if (res) {
			err = 0;
			printf("%s\n", res);
		}
	} else if (lookup) {
		/*
		 * Classic (cache based) API
		 */
		blkid_dev dev;

		if (!search_type) {
			fprintf(stderr, "The lookup option requires a "
				"search type specified using -t\n");
			exit(BLKID_EXIT_OTHER);
		}
		/* Load any additional devices not in the cache */
		for (i = 0; i < numdev; i++)
			blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL);

		if ((dev = blkid_find_dev_with_tag(cache, search_type,
						   search_value))) {
			print_tags(dev, show, output_format);
			err = 0;
		}
	/* If we didn't specify a single device, show all available devices */
	} else if (!numdev) {
		blkid_dev_iterate	iter;
		blkid_dev		dev;

		blkid_probe_all(cache);

		iter = blkid_dev_iterate_begin(cache);
		blkid_dev_set_search(iter, search_type, search_value);
		while (blkid_dev_next(iter, &dev) == 0) {
			dev = blkid_verify(cache, dev);
			if (!dev)
				continue;
			print_tags(dev, show, output_format);
			err = 0;
		}
		blkid_dev_iterate_end(iter);
	/* Add all specified devices to cache (optionally display tags) */
	} else for (i = 0; i < numdev; i++) {
		blkid_dev dev = blkid_get_dev(cache, devices[i],
						  BLKID_DEV_NORMAL);

		if (dev) {
			if (search_type &&
			    !blkid_dev_has_tag(dev, search_type,
					       search_value))
				continue;
			print_tags(dev, show, output_format);
			err = 0;
		}
	}

exit:
	free(search_type);
	free(search_value);
	free_types_list(fltr_type);
	if (!lowprobe && !eval)
		blkid_put_cache(cache);
	free(devices);
	return err;
}