summaryrefslogtreecommitdiff
path: root/tools/lvmdevices.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lvmdevices.c')
-rw-r--r--tools/lvmdevices.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c
index 3f104f7de..dc96e9570 100644
--- a/tools/lvmdevices.c
+++ b/tools/lvmdevices.c
@@ -19,6 +19,7 @@
/* coverity[unnecessary_header] needed for MuslC */
#include <sys/file.h>
+#include <time.h>
static void _search_devs_for_pvids(struct cmd_context *cmd, struct dm_list *search_pvids, struct dm_list *found_devs)
{
@@ -119,18 +120,38 @@ static void _search_devs_for_pvids(struct cmd_context *cmd, struct dm_list *sear
}
}
+static int _all_pvids_online(struct cmd_context *cmd, struct dm_list *wait_pvids)
+{
+ struct device_id_list *dil, *dil2;
+ int notfound = 0;
+
+ dm_list_iterate_items_safe(dil, dil2, wait_pvids) {
+ if (online_pvid_file_exists(dil->pvid))
+ dm_list_del(&dil->list);
+ else
+ notfound++;
+ }
+
+ return notfound ? 0 : 1;
+}
+
int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
{
struct dm_list search_pvids;
+ struct dm_list wait_pvids;
struct dm_list found_devs;
struct device_id_list *dil;
struct device_list *devl;
struct device *dev;
struct dev_use *du, *du2;
const char *deviceidtype;
+ time_t begin;
+ int wait_pvids_count;
+ int wait_sec;
int changes = 0;
dm_list_init(&search_pvids);
+ dm_list_init(&wait_pvids);
dm_list_init(&found_devs);
if (!setup_devices_file(cmd))
@@ -141,6 +162,9 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
+ if (arg_is_set(cmd, wait_ARG))
+ cmd->print_device_id_not_found = 0;
+
if (arg_is_set(cmd, update_ARG) ||
arg_is_set(cmd, adddev_ARG) || arg_is_set(cmd, deldev_ARG) ||
arg_is_set(cmd, addpvid_ARG) || arg_is_set(cmd, delpvid_ARG)) {
@@ -457,6 +481,77 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
goto out;
}
+ if (arg_is_set(cmd, wait_ARG)) {
+ int service_only = 0, event_only = 0, service_and_event = 0, pvscan_hints = 0;
+
+ if (strcmp("pvsonline", arg_str_value(cmd, wait_ARG, ""))) {
+ log_error("wait option invalid.");
+ goto bad;
+ }
+
+ /* TODO: lvm.conf lvmdevices_wait_settings "disabled" do nothing? */
+
+ get_autoactivation_config_settings(cmd, &service_only, &event_only, &service_and_event, &pvscan_hints);
+ if (event_only) {
+ log_print("Skip wait for auto_activation_settings event_only.");
+ goto out;
+ }
+
+ /* for each du, if du->wwid matched, wait for /run/lvm/pvs_online/du->pvid */
+ dm_list_iterate_items(du, &cmd->use_devices) {
+ if (!du->dev)
+ continue;
+ if (!(dil = dm_pool_zalloc(cmd->mem, sizeof(*dil))))
+ continue;
+ dil->dev = du->dev;
+ memcpy(dil->pvid, du->pvid, ID_LEN);
+ dm_list_add(&wait_pvids, &dil->list);
+ }
+
+ wait_pvids_count = dm_list_size(&wait_pvids);
+ wait_sec = find_config_tree_int(cmd, devices_lvmdevices_wait_seconds_CFG, NULL);
+ if (wait_sec == -1) {
+ if (wait_pvids_count <= 20)
+ wait_sec = 1;
+ else if (wait_pvids_count <= 100)
+ wait_sec = 5;
+ else if (wait_pvids_count <= 500)
+ wait_sec = 10;
+ else
+ wait_sec = 20;
+ }
+ log_print("Waiting for PVs online for %u matched devices file entries for %u sec.", wait_pvids_count, wait_sec);
+
+ begin = time(NULL);
+
+ while (1) {
+ if (_all_pvids_online(cmd, &wait_pvids)) {
+ log_print("Found all PVs online");
+ goto out;
+ }
+ log_print("Waiting for PVs online for %u devices.", dm_list_size(&wait_pvids));
+
+ /* TODO: lvm.conf lvmdevices_wait_ids "sys_wwid=111", "sys_wwid=222" etc
+ waits for the specifically named devices even if the devices do not exist. */
+
+ if (!wait_sec || (time(NULL) - begin >= wait_sec)) {
+ log_print("Time out waiting for PVs online:");
+ dm_list_iterate_items(dil, &wait_pvids)
+ log_print("Need PVID %s on %s", dil->pvid, dev_name(dil->dev));
+ break;
+ }
+
+ if (dm_list_size(&wait_pvids) > 10) {
+ if (interruptible_usleep(1000000)) /* 1 sec */
+ break;
+ } else {
+ if (interruptible_usleep(500000)) /* .5 sec */
+ break;
+ }
+ }
+ goto out;
+ }
+
/* If no options, print use_devices list */
dm_list_iterate_items(du, &cmd->use_devices) {