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