summaryrefslogtreecommitdiff
path: root/lib/device/dev-cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/device/dev-cache.c')
-rw-r--r--lib/device/dev-cache.c90
1 files changed, 86 insertions, 4 deletions
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index c3f7c49be..08ad7ef00 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -16,6 +16,7 @@
#include "base/memory/zalloc.h"
#include "lib/misc/lib.h"
#include "lib/device/dev-type.h"
+#include "lib/device/device_id.h"
#include "lib/datastruct/btree.h"
#include "lib/config/config.h"
#include "lib/commands/toolcontext.h"
@@ -72,6 +73,7 @@ static void _dev_init(struct device *dev)
dev->ext.src = DEV_EXT_NONE;
dm_list_init(&dev->aliases);
+ dm_list_init(&dev->ids);
}
void dev_destroy_file(struct device *dev)
@@ -351,7 +353,7 @@ static int _add_alias(struct device *dev, const char *path)
return 1;
}
-static int _get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value)
+int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value)
{
FILE *fp;
size_t len;
@@ -392,7 +394,7 @@ static int _get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int mi
return 0;
}
- return _get_sysfs_value(path, buf, buf_size, 0);
+ return get_sysfs_value(path, buf, buf_size, 0);
}
static struct dm_list *_get_or_add_list_by_index_key(struct dm_hash_table *idx, const char *key)
@@ -473,7 +475,7 @@ static struct device *_get_device_for_sysfs_dev_name_using_devno(const char *dev
return NULL;
}
- if (!_get_sysfs_value(path, buf, sizeof(buf), 1))
+ if (!get_sysfs_value(path, buf, sizeof(buf), 1))
return_NULL;
if (sscanf(buf, "%d:%d", &major, &minor) != 2) {
@@ -971,7 +973,7 @@ static int _dev_cache_iterate_sysfs_for_index(const char *path)
return r;
}
-int dev_cache_index_devs(void)
+static int dev_cache_index_devs(void)
{
static int sysfs_has_dev_block = -1;
char path[PATH_MAX];
@@ -1320,12 +1322,19 @@ int dev_cache_check_for_open_devices(void)
int dev_cache_exit(void)
{
+ struct device *dev;
+ struct dm_hash_node *n;
int num_open = 0;
if (_cache.names)
if ((num_open = _check_for_open_devices(1)) > 0)
log_error(INTERNAL_ERROR "%d device(s) were left open and have been closed.", num_open);
+ dm_hash_iterate(n, _cache.names) {
+ dev = (struct device *) dm_hash_get_data(_cache.names, n);
+ free_dids(&dev->ids);
+ }
+
if (_cache.mem)
dm_pool_destroy(_cache.mem);
@@ -1657,3 +1666,76 @@ bool dev_cache_has_md_with_end_superblock(struct dev_types *dt)
return false;
}
+/*
+ * Add all system devices to dev-cache, and attempt to
+ * match all devices_file entries to dev-cache entries.
+ */
+void setup_devices(struct cmd_context *cmd)
+{
+ /*
+ * Read the list of device ids that lvm can use.
+ * Adds a struct dev_id to cmd->use_device_ids for each one.
+ *
+ * (Changing enable_device_ids=0 must ensure that nothing
+ * in the command thus far has been done on the basis of
+ * enable_device_ids=1.)
+ */
+ if (!device_ids_read(cmd)) {
+ log_warn("WARNING: disabling use of devices_file, failed to read file.");
+ cmd->enable_device_ids = 0;
+ }
+
+ /*
+ * Add a 'struct device' to dev-cache for each device available on the system.
+ * This will not open or read any devices, but may look at sysfs properties.
+ * This list of devs comes from looking /dev entries, or from asking libudev.
+ * TODO: or from /proc/partitions?
+ *
+ * TODO: dev_cache_scan() optimization: start by looking only at
+ * devnames listed in the devices_file, and if the device_ids for
+ * those all match we won't need any others.
+ * Exceptions: the command wants a new device for pvcreate, or
+ * device_ids don't match the devnames.
+ */
+ dev_cache_scan();
+
+ /*
+ * Match entries from cmd->use_device_ids with device structs in dev-cache.
+ */
+ device_ids_match(cmd);
+}
+
+/*
+ * Add one system device to dev-cache, and attempt to
+ * match its dev-cache entry to a devices_file entry.
+ */
+void setup_device(struct cmd_context *cmd, const char *devname)
+{
+ struct stat buf;
+ struct device *dev;
+
+ if (!device_ids_read(cmd)) {
+ log_warn("WARNING: disabling use of devices_file, failed to read file.");
+ cmd->enable_device_ids = 0;
+ }
+
+ if (stat(devname, &buf) < 0)
+ return;
+
+ if (!S_ISBLK(buf.st_mode))
+ return;
+
+ if (!_insert_dev(devname, buf.st_rdev))
+ return;
+
+ if (!(dev = (struct device *) dm_hash_lookup(_cache.names, devname))) {
+ stack;
+ return;
+ }
+
+ /* Match this device to an entry in devices_file so it will not
+ be rejected by filter-deviceid. */
+ if (cmd->enable_device_ids)
+ device_ids_match_dev(cmd, dev);
+}
+