1e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o/*
2e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * devname.c - get a dev by its device inode name
3e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o *
4e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * Copyright (C) Andries Brouwer
50f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o * Copyright (C) 1999, 2000, 2001, 2002, 2003 Theodore Ts'o
6e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * Copyright (C) 2001 Andreas Dilger
7e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o *
8e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * %Begin-Header%
9e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * This file may be redistributed under the terms of the
10e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * GNU Lesser General Public License.
11e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * %End-Header%
12e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o */
13e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
144db2f59a718c18202a7ce1d559be18bfa1087747Karel Zak#define _GNU_SOURCE 1
154db2f59a718c18202a7ce1d559be18bfa1087747Karel Zak
16e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <stdio.h>
17e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <string.h>
18e324b250593a32680309015eba7c6c5db7851227Theodore Ts'o#include <limits.h>
19e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#if HAVE_UNISTD_H
20e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <unistd.h>
21e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#endif
22e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <stdlib.h>
23e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <string.h>
24e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <ctype.h>
25e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#if HAVE_SYS_TYPES_H
26e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <sys/types.h>
27e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#endif
28e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o#include <dirent.h>
29e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#if HAVE_SYS_STAT_H
30e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <sys/stat.h>
31e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#endif
32e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#if HAVE_ERRNO_H
33e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <errno.h>
34e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#endif
35e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#if HAVE_SYS_MKDEV_H
36e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <sys/mkdev.h>
37e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#endif
38e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <time.h>
39e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
407a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o#include "blkidP.h"
41e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
42e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o/*
43e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * Find a dev struct in the cache by device name, if available.
4450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o *
4550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o * If there is no entry with the specified device name, and the create
4650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o * flag is set, then create an empty device entry.
47e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o */
4898999c399d563c248728bf217467a788cb0c1aadTheodore Ts'oblkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags)
49e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
5050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	blkid_dev dev = NULL, tmp;
51bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o	struct list_head *p, *pnext;
52e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
53e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	if (!cache || !devname)
54e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return NULL;
55e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
56e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	list_for_each(p, &cache->bic_devs) {
5750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		tmp = list_entry(p, struct blkid_struct_dev, bid_devs);
58e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		if (strcmp(tmp->bid_name, devname))
59e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			continue;
60e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
61efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		DBG(DEBUG_DEVNAME,
62f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o		    printf("found devname %s in cache\n", tmp->bid_name));
6350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		dev = tmp;
64e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		break;
65e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
66e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
6750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (!dev && (flags & BLKID_DEV_CREATE)) {
68fe144e11e961a8fb2c568f486bd5bcd49582e24fTheodore Ts'o		if (access(devname, F_OK) < 0)
69fe144e11e961a8fb2c568f486bd5bcd49582e24fTheodore Ts'o			return NULL;
7050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		dev = blkid_new_dev();
7150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		if (!dev)
7250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			return NULL;
73e324b250593a32680309015eba7c6c5db7851227Theodore Ts'o		dev->bid_time = INT_MIN;
7450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		dev->bid_name = blkid_strdup(devname);
7550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		dev->bid_cache = cache;
7650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		list_add_tail(&dev->bid_devs, &cache->bic_devs);
7750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		cache->bic_flags |= BLKID_BIC_FL_CHANGED;
7850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	}
79e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
80bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o	if (flags & BLKID_DEV_VERIFY) {
8118d12963335b04a402d097af1d714e8708805adaTheodore Ts'o		dev = blkid_verify(cache, dev);
82bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o		if (!dev || !(dev->bid_flags & BLKID_BID_FL_VERIFIED))
83bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			return dev;
84efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		/*
85bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o		 * If the device is verified, then search the blkid
86bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o		 * cache for any entries that match on the type, uuid,
87bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o		 * and label, and verify them; if a cache entry can
88bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o		 * not be verified, then it's stale and so we remove
89bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o		 * it.
90bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o		 */
91bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o		list_for_each_safe(p, pnext, &cache->bic_devs) {
92bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			blkid_dev dev2;
93bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			if (!p)
94bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o				break;
95bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			dev2 = list_entry(p, struct blkid_struct_dev, bid_devs);
96bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			if (dev2->bid_flags & BLKID_BID_FL_VERIFIED)
97bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o				continue;
98bb47c2a4aff6ec6b9be7f30cd04cf7c858a84de4Theodore Ts'o			if (!dev->bid_type || !dev2->bid_type ||
99bb47c2a4aff6ec6b9be7f30cd04cf7c858a84de4Theodore Ts'o			    strcmp(dev->bid_type, dev2->bid_type))
100bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o				continue;
101bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			if (dev->bid_label && dev2->bid_label &&
102bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			    strcmp(dev->bid_label, dev2->bid_label))
103bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o				continue;
104bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			if (dev->bid_uuid && dev2->bid_uuid &&
105bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			    strcmp(dev->bid_uuid, dev2->bid_uuid))
106bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o				continue;
107bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			if ((dev->bid_label && !dev2->bid_label) ||
108bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			    (!dev->bid_label && dev2->bid_label) ||
109bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			    (dev->bid_uuid && !dev2->bid_uuid) ||
110bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			    (!dev->bid_uuid && dev2->bid_uuid))
111bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o				continue;
112bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			dev2 = blkid_verify(cache, dev2);
113bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o			if (dev2 && !(dev2->bid_flags & BLKID_BID_FL_VERIFIED))
114bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o				blkid_free_dev(dev2);
115bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o		}
116bf58e3d1c68be63d673d232154bde5854e031afcTheodore Ts'o	}
11750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	return dev;
118e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
119e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
120f4e89bcdf2870820ff262e3aed04cbb5374d7fddTheodore Ts'o/* Directories where we will try to search for device names */
121f4e89bcdf2870820ff262e3aed04cbb5374d7fddTheodore Ts'ostatic const char *dirlist[] = { "/dev", "/devfs", "/devices", NULL };
122f4e89bcdf2870820ff262e3aed04cbb5374d7fddTheodore Ts'o
123e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'ostatic int is_dm_leaf(const char *devname)
124e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o{
125e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o	struct dirent	*de, *d_de;
126e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o	DIR		*dir, *d_dir;
127e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o	char		path[256];
128e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o	int		ret = 1;
129e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o
130e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o	if ((dir = opendir("/sys/block")) == NULL)
131e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o		return 0;
132e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o	while ((de = readdir(dir)) != NULL) {
133e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o		if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") ||
134e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o		    !strcmp(de->d_name, devname) ||
135e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o		    strncmp(de->d_name, "dm-", 3) ||
136e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o		    strlen(de->d_name) > sizeof(path)-32)
137e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o			continue;
138e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o		sprintf(path, "/sys/block/%s/slaves", de->d_name);
139e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o		if ((d_dir = opendir(path)) == NULL)
140e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o			continue;
141e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o		while ((d_de = readdir(d_dir)) != NULL) {
142e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o			if (!strcmp(d_de->d_name, devname)) {
143e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o				ret = 0;
144e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o				break;
145e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o			}
146e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o		}
147e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o		closedir(d_dir);
148e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o		if (!ret)
149e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o			break;
150e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o	}
151e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o	closedir(dir);
152e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o	return ret;
153e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o}
154e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o
155e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o/*
15646f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak * Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs
15746f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak * provides the real DM device names in /sys/block/<ptname>/dm/name
15846f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak */
15946f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zakstatic char *get_dm_name(const char *ptname)
16046f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak{
16146f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak	FILE	*f;
16246f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak	size_t	sz;
16346f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak	char	path[256], name[256], *res = NULL;
16446f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak
16546f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak	snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname);
16646f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak	if ((f = fopen(path, "r")) == NULL)
16746f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak		return NULL;
16846f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak
16946f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak	/* read "<name>\n" from sysfs */
17046f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak	if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) {
17146f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak		name[sz - 1] = '\0';
17246f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak		snprintf(path, sizeof(path), "/dev/mapper/%s", name);
17346f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak		res = blkid_strdup(path);
17446f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak	}
17546f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak	fclose(f);
17646f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak	return res;
17746f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak}
17846f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak
17946f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak/*
180e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * Probe a single block device to add to the device cache.
181e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o */
182ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'ostatic void probe_one(blkid_cache cache, const char *ptname,
183ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o		      dev_t devno, int pri, int only_if_new)
184e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
18550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	blkid_dev dev = NULL;
1865b7adf06904e6577c5d8bee7f0197a1b1032fa68Theodore Ts'o	struct list_head *p, *pnext;
187e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	const char **dir;
188e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	char *devname = NULL;
189e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
190e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	/* See if we already have this device number in the cache. */
1915b7adf06904e6577c5d8bee7f0197a1b1032fa68Theodore Ts'o	list_for_each_safe(p, pnext, &cache->bic_devs) {
19250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		blkid_dev tmp = list_entry(p, struct blkid_struct_dev,
19350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o					   bid_devs);
19450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		if (tmp->bid_devno == devno) {
19557926c8c5566f0ef5b77db326d58aa0643cf6270Theodore Ts'o			if (only_if_new && !access(tmp->bid_name, F_OK))
196ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o				return;
19718d12963335b04a402d097af1d714e8708805adaTheodore Ts'o			dev = blkid_verify(cache, tmp);
19857926c8c5566f0ef5b77db326d58aa0643cf6270Theodore Ts'o			if (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED))
19957926c8c5566f0ef5b77db326d58aa0643cf6270Theodore Ts'o				break;
20057926c8c5566f0ef5b77db326d58aa0643cf6270Theodore Ts'o			dev = 0;
20150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		}
20250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	}
20350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (dev && dev->bid_devno == devno)
204ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		goto set_pri;
205e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
2064271e23942bdc60e1fa6c0b26bc666a94a8b3e1dKarel Zak	/* Try to translate private device-mapper dm-<N> names
2074271e23942bdc60e1fa6c0b26bc666a94a8b3e1dKarel Zak	 * to standard /dev/mapper/<name>.
2084271e23942bdc60e1fa6c0b26bc666a94a8b3e1dKarel Zak	 */
2094271e23942bdc60e1fa6c0b26bc666a94a8b3e1dKarel Zak	if (!strncmp(ptname, "dm-", 3) && isdigit(ptname[3])) {
21046f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak		devname = get_dm_name(ptname);
21146f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak		if (!devname)
21246f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak			blkid__scan_dir("/dev/mapper", devno, 0, &devname);
2134271e23942bdc60e1fa6c0b26bc666a94a8b3e1dKarel Zak		if (devname)
2144271e23942bdc60e1fa6c0b26bc666a94a8b3e1dKarel Zak			goto get_dev;
2154271e23942bdc60e1fa6c0b26bc666a94a8b3e1dKarel Zak	}
2164271e23942bdc60e1fa6c0b26bc666a94a8b3e1dKarel Zak
217e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	/*
218e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	 * Take a quick look at /dev/ptname for the device number.  We check
219e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	 * all of the likely device directories.  If we don't find it, or if
220e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	 * the stat information doesn't check out, use blkid_devno_to_devname()
221e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	 * to find it via an exhaustive search for the device major/minor.
222e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	 */
223f4e89bcdf2870820ff262e3aed04cbb5374d7fddTheodore Ts'o	for (dir = dirlist; *dir; dir++) {
224e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		struct stat st;
225e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		char device[256];
226e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
227e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		sprintf(device, "%s/%s", *dir, ptname);
22898999c399d563c248728bf217467a788cb0c1aadTheodore Ts'o		if ((dev = blkid_get_dev(cache, device, BLKID_DEV_FIND)) &&
229e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		    dev->bid_devno == devno)
230ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o			goto set_pri;
231e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
232efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		if (stat(device, &st) == 0 && S_ISBLK(st.st_mode) &&
2332e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o		    st.st_rdev == devno) {
23450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			devname = blkid_strdup(device);
2354271e23942bdc60e1fa6c0b26bc666a94a8b3e1dKarel Zak			goto get_dev;
236e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		}
237e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
238f4e89bcdf2870820ff262e3aed04cbb5374d7fddTheodore Ts'o	/* Do a short-cut scan of /dev/mapper first */
239f4e89bcdf2870820ff262e3aed04cbb5374d7fddTheodore Ts'o	if (!devname)
24046f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak		devname = get_dm_name(ptname);
24146f3eeca59a1fc8233790bbed604e4634e0f3fbeKarel Zak	if (!devname)
242f4e89bcdf2870820ff262e3aed04cbb5374d7fddTheodore Ts'o		blkid__scan_dir("/dev/mapper", devno, 0, &devname);
243e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	if (!devname) {
244e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		devname = blkid_devno_to_devname(devno);
245e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		if (!devname)
246ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o			return;
247e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
2484271e23942bdc60e1fa6c0b26bc666a94a8b3e1dKarel Zakget_dev:
24998999c399d563c248728bf217467a788cb0c1aadTheodore Ts'o	dev = blkid_get_dev(cache, devname, BLKID_DEV_NORMAL);
25050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	free(devname);
251ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'oset_pri:
252f4e89bcdf2870820ff262e3aed04cbb5374d7fddTheodore Ts'o	if (dev) {
253f4e89bcdf2870820ff262e3aed04cbb5374d7fddTheodore Ts'o		if (pri)
254f4e89bcdf2870820ff262e3aed04cbb5374d7fddTheodore Ts'o			dev->bid_pri = pri;
255e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o		else if (!strncmp(dev->bid_name, "/dev/mapper/", 11)) {
256f4e89bcdf2870820ff262e3aed04cbb5374d7fddTheodore Ts'o			dev->bid_pri = BLKID_PRI_DM;
257e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o			if (is_dm_leaf(ptname))
258e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o				dev->bid_pri += 5;
259e6baebd2a9b205c2eaf8de0807e75bfba7061cadTheodore Ts'o		} else if (!strncmp(ptname, "md", 2))
260f4e89bcdf2870820ff262e3aed04cbb5374d7fddTheodore Ts'o			dev->bid_pri = BLKID_PRI_MD;
261f4e89bcdf2870820ff262e3aed04cbb5374d7fddTheodore Ts'o 	}
262ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o	return;
263e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
264e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
265e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#define PROC_PARTITIONS "/proc/partitions"
266e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#define VG_DIR		"/proc/lvm/VGs"
267e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
268e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o/*
269e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * This function initializes the UUID cache with devices from the LVM
270e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * proc hierarchy.  We currently depend on the names of the LVM
271e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * hierarchy giving us the device structure in /dev.  (XXX is this a
272e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * safe thing to do?)
273e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o */
274e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#ifdef VG_DIR
27550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'ostatic dev_t lvm_get_devno(const char *lvm_device)
276e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
277e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	FILE *lvf;
278e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	char buf[1024];
27950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	int ma, mi;
28050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	dev_t ret = 0;
281e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
282f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o	DBG(DEBUG_DEVNAME, printf("opening %s\n", lvm_device));
283e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	if ((lvf = fopen(lvm_device, "r")) == NULL) {
284f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o		DBG(DEBUG_DEVNAME, printf("%s: (%d) %s\n", lvm_device, errno,
285f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o					  strerror(errno)));
28650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		return 0;
287e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
288e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
289e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	while (fgets(buf, sizeof(buf), lvf)) {
29050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		if (sscanf(buf, "device: %d:%d", &ma, &mi) == 2) {
29150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			ret = makedev(ma, mi);
292e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			break;
293e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		}
294e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
295e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	fclose(lvf);
296e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
297e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	return ret;
298e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
299e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
300ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'ostatic void lvm_probe_all(blkid_cache cache, int only_if_new)
301e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
302e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	DIR		*vg_list;
303e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	struct dirent	*vg_iter;
304e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	int		vg_len = strlen(VG_DIR);
30550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	dev_t		dev;
306e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
307e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	if ((vg_list = opendir(VG_DIR)) == NULL)
308e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return;
309e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
310f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o	DBG(DEBUG_DEVNAME, printf("probing LVM devices under %s\n", VG_DIR));
311e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
312e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	while ((vg_iter = readdir(vg_list)) != NULL) {
313e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		DIR		*lv_list;
314e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		char		*vdirname;
315e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		char		*vg_name;
316e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		struct dirent	*lv_iter;
317e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
318e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		vg_name = vg_iter->d_name;
319e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		if (!strcmp(vg_name, ".") || !strcmp(vg_name, ".."))
320e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			continue;
321e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		vdirname = malloc(vg_len + strlen(vg_name) + 8);
322e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		if (!vdirname)
323e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			goto exit;
324e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		sprintf(vdirname, "%s/%s/LVs", VG_DIR, vg_name);
325e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
326e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		lv_list = opendir(vdirname);
327e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		free(vdirname);
328e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		if (lv_list == NULL)
329e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			continue;
330e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
331e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		while ((lv_iter = readdir(lv_list)) != NULL) {
332e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			char		*lv_name, *lvm_device;
333e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
334e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			lv_name = lv_iter->d_name;
335e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			if (!strcmp(lv_name, ".") || !strcmp(lv_name, ".."))
336e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o				continue;
337e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
338e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			lvm_device = malloc(vg_len + strlen(vg_name) +
339e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o					    strlen(lv_name) + 8);
340e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			if (!lvm_device) {
341e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o				closedir(lv_list);
342e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o				goto exit;
343e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			}
344e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			sprintf(lvm_device, "%s/%s/LVs/%s", VG_DIR, vg_name,
345e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o				lv_name);
34650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			dev = lvm_get_devno(lvm_device);
347e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			sprintf(lvm_device, "%s/%s", vg_name, lv_name);
348f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o			DBG(DEBUG_DEVNAME, printf("LVM dev %s: devno 0x%04X\n",
349f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o						  lvm_device,
350f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o						  (unsigned int) dev));
351efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			probe_one(cache, lvm_device, dev, BLKID_PRI_LVM,
352ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o				  only_if_new);
353e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			free(lvm_device);
354e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		}
355e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		closedir(lv_list);
356e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
357e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'oexit:
358e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	closedir(vg_list);
359e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
360e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#endif
361e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
3620f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o#define PROC_EVMS_VOLUMES "/proc/evms/volumes"
3630f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o
3640f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'ostatic int
365ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'oevms_probe_all(blkid_cache cache, int only_if_new)
3660f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o{
3670f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o	char line[100];
3680f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o	int ma, mi, sz, num = 0;
3690f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o	FILE *procpt;
3700f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o	char device[110];
3710f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o
3720f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o	procpt = fopen(PROC_EVMS_VOLUMES, "r");
3730f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o	if (!procpt)
3740f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o		return 0;
3750f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o	while (fgets(line, sizeof(line), procpt)) {
3760f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o		if (sscanf (line, " %d %d %d %*s %*s %[^\n ]",
3770f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o			    &ma, &mi, &sz, device) != 4)
3780f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o			continue;
3790f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o
380f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o		DBG(DEBUG_DEVNAME, printf("Checking partition %s (%d, %d)\n",
381f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o					  device, ma, mi));
3820f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o
383ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o		probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS,
384ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o			  only_if_new);
3850f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o		num++;
3860f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o	}
3870f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o	fclose(procpt);
3880f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o	return num;
3890f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o}
3900f3ac480c76d4574b9274de22784e76fd627ad6aTheodore Ts'o
391e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o/*
392e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * Read the device data for all available block devices in the system.
393e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o */
394ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'ostatic int probe_all(blkid_cache cache, int only_if_new)
395e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
396e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	FILE *proc;
397ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o	char line[1024];
398ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o	char ptname0[128], ptname1[128], *ptname = 0;
399ed78c021c3b111d8ab9a51aef5d5156e3004083fTheodore Ts'o	char *ptnames[2];
400ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o	dev_t devs[2];
401ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o	int ma, mi;
402ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o	unsigned long long sz;
403ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o	int lens[2] = { 0, 0 };
404ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o	int which = 0, last = 0;
4054e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen	struct list_head *p, *pnext;
406e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
407ed78c021c3b111d8ab9a51aef5d5156e3004083fTheodore Ts'o	ptnames[0] = ptname0;
408ed78c021c3b111d8ab9a51aef5d5156e3004083fTheodore Ts'o	ptnames[1] = ptname1;
409ed78c021c3b111d8ab9a51aef5d5156e3004083fTheodore Ts'o
410e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	if (!cache)
411e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return -BLKID_ERR_PARAM;
412e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
41350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (cache->bic_flags & BLKID_BIC_FL_PROBED &&
41450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	    time(0) - cache->bic_time < BLKID_PROBE_INTERVAL)
415e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return 0;
416e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
41779dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o	blkid_read_cache(cache);
418ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	evms_probe_all(cache, only_if_new);
419e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#ifdef VG_DIR
420ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	lvm_probe_all(cache, only_if_new);
421e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#endif
422e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
423e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	proc = fopen(PROC_PARTITIONS, "r");
424e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	if (!proc)
425e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return -BLKID_ERR_PROC;
426e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
427ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o	while (fgets(line, sizeof(line), proc)) {
428ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		last = which;
429ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		which ^= 1;
430ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		ptname = ptnames[which];
431e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
432d34588265c6fb68189090070be470725df3e8c48Matthias Andree		if (sscanf(line, " %d %d %llu %128[^\n ]",
433ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o			   &ma, &mi, &sz, ptname) != 4)
434ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o			continue;
435ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		devs[which] = makedev(ma, mi);
436ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o
437f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o		DBG(DEBUG_DEVNAME, printf("read partition name %s\n", ptname));
438ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o
43938361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen		/* Skip whole disk devs unless they have no partitions.
44038361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen		 * If base name of device has changed, also
441ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		 * check previous dev to see if it didn't have a partn.
44238361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen		 * heuristic: partition name ends in a digit, & partition
44338361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen		 * names contain whole device name as substring.
444ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		 *
445ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		 * Skip extended partitions.
446ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		 * heuristic: size is 1
447ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		 *
448ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		 * FIXME: skip /dev/{ida,cciss,rd} whole-disk devs
449ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		 */
450ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o
451ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		lens[which] = strlen(ptname);
45238361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen
45338361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen		/* ends in a digit, clearly a partition, so check */
454ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		if (isdigit(ptname[lens[which] - 1])) {
455f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o			DBG(DEBUG_DEVNAME,
456f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o			    printf("partition dev %s, devno 0x%04X\n",
457f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o				   ptname, (unsigned int) devs[which]));
458ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o
459ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o			if (sz > 1)
460efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o				probe_one(cache, ptname, devs[which], 0,
461ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o					  only_if_new);
46238361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen			lens[which] = 0;	/* mark as checked */
46338361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen		}
46438361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen
46538361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen		/*
4664e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen		 * If last was a whole disk and we just found a partition
4674e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen		 * on it, remove the whole-disk dev from the cache if
4684e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen		 * it exists.
4694e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen		 */
4704e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen		if (lens[last] && !strncmp(ptnames[last], ptname, lens[last])) {
4714e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen			list_for_each_safe(p, pnext, &cache->bic_devs) {
4724e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen				blkid_dev tmp;
4734e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen
4744e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen				/* find blkid dev for the whole-disk devno */
4754e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen				tmp = list_entry(p, struct blkid_struct_dev,
4764e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen						 bid_devs);
4774e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen				if (tmp->bid_devno == devs[last]) {
4784e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen					DBG(DEBUG_DEVNAME,
4794e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen						printf("freeing %s\n",
4804e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen						       tmp->bid_name));
4814e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen					blkid_free_dev(tmp);
4824e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen					cache->bic_flags |= BLKID_BIC_FL_CHANGED;
4834e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen					break;
4844e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen				}
4854e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen			}
4864e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen			lens[last] = 0;
4874e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen		}
4884e60e06847c781efffc8c43342b7756bbe5cff45Eric Sandeen		/*
48938361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen		 * If last was not checked because it looked like a whole-disk
49038361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen		 * dev, and the device's base name has changed,
49138361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen		 * check last as well.
49238361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen		 */
49338361bbbb55735cf0f4ed6d56079c70fb3328036Eric Sandeen		if (lens[last] && strncmp(ptnames[last], ptname, lens[last])) {
494f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o			DBG(DEBUG_DEVNAME,
495f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o			    printf("whole dev %s, devno 0x%04X\n",
496f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o				   ptnames[last], (unsigned int) devs[last]));
497ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o			probe_one(cache, ptnames[last], devs[last], 0,
498ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o				  only_if_new);
499ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o			lens[last] = 0;
500e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		}
501e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
502ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o
503ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o	/* Handle the last device if it wasn't partitioned */
504ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o	if (lens[which])
505ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o		probe_one(cache, ptname, devs[which], 0, only_if_new);
506ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o
507e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	fclose(proc);
508ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	blkid_flush_cache(cache);
509ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	return 0;
510ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o}
511e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
512ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'oint blkid_probe_all(blkid_cache cache)
513ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o{
514ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	int ret;
515ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o
516ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	DBG(DEBUG_PROBE, printf("Begin blkid_probe_all()\n"));
517ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	ret = probe_all(cache, 0);
51850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	cache->bic_time = time(0);
51950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	cache->bic_flags |= BLKID_BIC_FL_PROBED;
520ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	DBG(DEBUG_PROBE, printf("End blkid_probe_all()\n"));
521ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	return ret;
522e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
523e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
524ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'oint blkid_probe_all_new(blkid_cache cache)
525ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o{
526ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	int ret;
527ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o
528ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	DBG(DEBUG_PROBE, printf("Begin blkid_probe_all_new()\n"));
529ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	ret = probe_all(cache, 1);
530ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	DBG(DEBUG_PROBE, printf("End blkid_probe_all_new()\n"));
531ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o	return ret;
532ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o}
533ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o
534ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o
535e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#ifdef TEST_PROGRAM
536e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'oint main(int argc, char **argv)
537e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
5387a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o	blkid_cache cache = NULL;
53979dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o	int ret;
540e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
541f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o	blkid_debug_mask = DEBUG_ALL;
542e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	if (argc != 1) {
543e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		fprintf(stderr, "Usage: %s\n"
544e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			"Probe all devices and exit\n", argv[0]);
545e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		exit(1);
546e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
54779dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o	if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
54879dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o		fprintf(stderr, "%s: error creating cache (%d)\n",
54979dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o			argv[0], ret);
55050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		exit(1);
55150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	}
55250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (blkid_probe_all(cache) < 0)
553e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		printf("%s: error probing devices\n", argv[0]);
554e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
55550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	blkid_put_cache(cache);
556e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	return (0);
557e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
558e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#endif
559