summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WHATS_NEW3
-rw-r--r--lib/cache/lvmetad.c52
-rw-r--r--lib/cache/lvmetad.h17
-rw-r--r--man/pvscan.8.in11
-rw-r--r--tools/commands.h2
-rw-r--r--tools/pvremove.c3
-rw-r--r--tools/pvscan.c109
7 files changed, 126 insertions, 71 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index e464fb91..adca43e2 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,8 @@
Version 2.02.95 -
================================
+ Scan all devices for lvmetad if 'pvscan --cache' used without device list.
+ Populate lvmcache from lvmetad before displaying PVs in pvscan. (2.02.94)
+ Suppress incorrect -n pvscan warning now always displayed. (2.02.94)
Version 2.02.94 - 3rd March 2012
================================
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index f3e3727a..47b71fee 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -607,7 +607,7 @@ int lvmetad_pv_found(struct id pvid, struct device *device, const struct format_
return result;
}
-static int _lvmetad_pv_gone(dev_t device, const char *pv_name)
+int lvmetad_pv_gone(dev_t device, const char *pv_name)
{
int result;
int found;
@@ -625,9 +625,9 @@ static int _lvmetad_pv_gone(dev_t device, const char *pv_name)
return result;
}
-int lvmetad_pv_gone(struct device *dev)
+int lvmetad_pv_gone_by_dev(struct device *dev)
{
- return _lvmetad_pv_gone(dev->dev, dev_name(dev));
+ return lvmetad_pv_gone(dev->dev, dev_name(dev));
}
int lvmetad_active(void)
@@ -663,33 +663,8 @@ static int _pvscan_lvmetad_single(struct metadata_area *mda, void *baton)
return 1;
}
-static dev_t _parse_devt(const char *str)
-{ /* Oh. */
- char *where = (char *) str;
- int major = strtol(str, &where, 10);
- int minor;
-
- if (where == str)
- return -1;
-
- if (*where != ':')
- return -1;
-
- str = ++where;
- minor = strtol(str, &where, 10);
-
- if (where == str)
- return -1;
-
- if (*where)
- return -1;
-
- return MKDEV(major, minor);
-}
-
-int pvscan_lvmetad_single(struct cmd_context *cmd, const char *pv_name)
+int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev)
{
- struct device *dev;
struct label *label;
struct lvmcache_info *info;
struct physical_volume pv;
@@ -702,26 +677,9 @@ int pvscan_lvmetad_single(struct cmd_context *cmd, const char *pv_name)
return 0;
}
- dev = dev_cache_get(pv_name, NULL);
- if (!dev && _parse_devt(pv_name) != -1)
- dev = dev_cache_get_by_devt(_parse_devt(pv_name), NULL);
-
- if (!dev) {
- if (_parse_devt(pv_name) == -1) {
- log_error("Unrecognised device name %s. (Use MAJOR:MINOR for new devices.)", pv_name);
- return 0;
- }
-
- if (!_lvmetad_pv_gone(_parse_devt(pv_name), pv_name))
- goto_bad;
-
- log_print("Device %s not found. Cleared from lvmetad cache.", pv_name);
- return 1;
- }
-
if (!label_read(dev, &label, 0)) {
log_print("No PV label found on %s.", dev_name(dev));
- if (!lvmetad_pv_gone(dev))
+ if (!lvmetad_pv_gone_by_dev(dev))
goto_bad;
return 1;
}
diff --git a/lib/cache/lvmetad.h b/lib/cache/lvmetad.h
index c59c775d..091ff5e3 100644
--- a/lib/cache/lvmetad.h
+++ b/lib/cache/lvmetad.h
@@ -67,11 +67,10 @@ int lvmetad_pv_found(struct id pvid, struct device *device,
struct volume_group *vg);
/*
- * Inform the daemon that the device no longer exists. We do not support
- * multiple device names, so this needs a unique and stable name, the same as
- * provided to lvmetad_pv_found.
+ * Inform the daemon that the device no longer exists.
*/
-int lvmetad_pv_gone(struct device *dev);
+int lvmetad_pv_gone(dev_t devno, const char *pv_name);
+int lvmetad_pv_gone_by_dev(struct device *dev);
/*
* Request a list of all PVs available to lvmetad. If requested, this will also
@@ -101,10 +100,9 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd,
const char *vgname, const char *vgid);
/*
- * Scan a single device and update lvmetad with the result(s). If the device
- * node does not exist, it must be supplied in a major:minor format.
+ * Scan a single device and update lvmetad with the result(s).
*/
-int pvscan_lvmetad_single(struct cmd_context *cmd, const char *pv_name);
+int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev);
# else /* LVMETAD_SUPPORT */
@@ -114,13 +112,14 @@ int pvscan_lvmetad_single(struct cmd_context *cmd, const char *pv_name);
# define lvmetad_vg_update(vg) (1)
# define lvmetad_vg_remove(vg) (1)
# define lvmetad_pv_found(pvid, device, fmt, label_sector, vg) (1)
-# define lvmetad_pv_gone(dev) (1)
+# define lvmetad_pv_gone(devno, pv_name) (1)
+# define lvmetad_pv_gone_by_dev(dev) (1)
# define lvmetad_pv_list_to_lvmcache(cmd) (1)
# define lvmetad_pv_lookup(cmd, pvid, found) (0)
# define lvmetad_pv_lookup_by_dev(cmd, dev, found) (0)
# define lvmetad_vg_list_to_lvmcache(cmd) (1)
# define lvmetad_vg_lookup(cmd, vgname, vgid) (NULL)
-# define pvscan_lvmetad_single(cmd, pv_name) (0)
+# define pvscan_lvmetad_single(cmd, dev) (0)
# endif /* LVMETAD_SUPPORT */
diff --git a/man/pvscan.8.in b/man/pvscan.8.in
index 0b5ad703..6f6f829a 100644
--- a/man/pvscan.8.in
+++ b/man/pvscan.8.in
@@ -3,7 +3,7 @@
pvscan \- scan all disks for physical volumes
.SH SYNOPSIS
.B pvscan
-.RB [ \-\-cache " " DevicePath [ DevicePath ... ] ]
+.RB [ \-\-cache " " [ DevicePath ... ] ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-\-help ]
.RB [ \-v | \-\-verbose ]
@@ -31,10 +31,11 @@ Short listing format.
.BR \-u ", " \-\-uuid
Show UUIDs (Uniform Unique Identifiers) in addition to device special names.
.TP
-.BR \-\-cache " " DevicePath [ DevicePath... ]
-Scan a single device and instruct the lvmetad daemon to update its cached
-state. Called internally by udev rules. The device is processed
-\fBregardless\fP of any device filters set in lvm.conf.
+.BR \-\-cache " " [ DevicePath... ]
+Scan one or more devices and instruct the lvmetad daemon to update its cached
+state accordingly. Called internally by udev rules.
+All devices listed explicitly are processed \fBregardless\fP of any device
+filters set in lvm.conf.
.SH SEE ALSO
.BR lvm (8),
.BR pvcreate (8),
diff --git a/tools/commands.h b/tools/commands.h
index 073727f3..ac25b1a3 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -663,7 +663,7 @@ xx(pvscan,
"List all physical volumes",
PERMITTED_READ_ONLY,
"pvscan " "\n"
- "\t[--cache DevicePath [DevicePath...]] " "\n"
+ "\t[--cache [DevicePath...]] " "\n"
"\t[-d|--debug] " "\n"
"\t{-e|--exported | -n|--novolumegroup} " "\n"
"\t[-h|-?|--help]" "\n"
diff --git a/tools/pvremove.c b/tools/pvremove.c
index f90f88a2..0c06c7f4 100644
--- a/tools/pvremove.c
+++ b/tools/pvremove.c
@@ -128,8 +128,7 @@ static int pvremove_single(struct cmd_context *cmd, const char *pv_name,
goto out;
}
- /* FIXME Avoid error if we expect that daemon might not know device */
- if (!lvmetad_pv_gone(dev))
+ if (!lvmetad_pv_gone_by_dev(dev))
goto_out;
log_print("Labels on physical volume \"%s\" successfully wiped",
diff --git a/tools/pvscan.c b/tools/pvscan.c
index c91d5912..c2191778 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -21,6 +21,52 @@
int pv_max_name_len = 0;
int vg_max_name_len = 0;
+static dev_t _parse_devt(const char *str)
+{ /* Oh. */
+ char *where = (char *) str;
+ int major = strtol(str, &where, 10);
+ int minor;
+
+ if (where == str)
+ return -1;
+
+ if (*where != ':')
+ return -1;
+
+ str = ++where;
+ minor = strtol(str, &where, 10);
+
+ if (where == str)
+ return -1;
+
+ if (*where)
+ return -1;
+
+ return MKDEV(major, minor);
+}
+
+/*
+ * Convert pv_name to struct device or to *devno.
+ */
+static struct device *_device_from_pv_name(const char *pv_name, dev_t *devno)
+{
+ struct device *dev;
+
+ if ((dev = dev_cache_get(pv_name, NULL)))
+ return dev;
+
+ if ((*devno = _parse_devt(pv_name)) == -1) {
+ log_error("Unrecognised device name %s. "
+ "(Use MAJOR:MINOR for new devices.)", pv_name);
+ return NULL;
+ }
+
+ if ((dev = dev_cache_get_by_devt(*devno, NULL)))
+ return dev;
+
+ return NULL;
+}
+
static void _pvscan_display_single(struct cmd_context *cmd,
struct physical_volume *pv,
void *handle __attribute__((unused)))
@@ -99,30 +145,78 @@ static void _pvscan_display_single(struct cmd_context *cmd,
pv_pe_size(pv)));
}
-static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv)
+static int _pvscan_lvmetad_all_devs(struct cmd_context *cmd)
{
- int ret = ECMD_PROCESSED;
+ struct dev_iter *iter;
+ struct device *dev;
+ int r = 1;
- if (!argc) {
- log_error("List of Physical Volumes to be cached by the lvmetad daemon required.");
- return EINVALID_CMD_LINE;
+ if (!(iter = dev_iter_create(cmd->filter, 1))) {
+ log_error("dev_iter creation failed");
+ return 0;
}
+ while ((dev = dev_iter_get(iter))) {
+ if (!pvscan_lvmetad_single(cmd, dev)) {
+ r = 0;
+ break;
+ }
+
+ if (sigint_caught())
+ break;
+ }
+
+ dev_iter_destroy(iter);
+
+ return r;
+}
+
+static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv)
+{
+ int ret = ECMD_PROCESSED;
+ struct device *dev;
+ const char *pv_name;
+ dev_t devno;
+
if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ)) {
log_error("Unable to obtain global lock.");
return ECMD_FAILED;
}
+ if (!argc) {
+ if (!_pvscan_lvmetad_all_devs(cmd))
+ ret = ECMD_FAILED;
+ goto out;
+ }
+
log_verbose("Using physical volume(s) on command line");
+
while (argc--) {
- if (!pvscan_lvmetad_single(cmd, *argv++)) {
+ pv_name = *argv++;
+ dev = _device_from_pv_name(pv_name, &devno);
+
+ if (!dev && devno != -1) {
+ /* FIXME Filters? */
+ if (!lvmetad_pv_gone(devno, pv_name)) {
+ ret = ECMD_FAILED;
+ break;
+ }
+
+ log_print("Device %s not found. "
+ "Cleared from lvmetad cache.", pv_name);
+ continue;
+ }
+
+ if (!pvscan_lvmetad_single(cmd, dev)) {
ret = ECMD_FAILED;
break;
}
+
if (sigint_caught())
break;
}
+out:
unlock_vg(cmd, VG_GLOBAL);
return ret;
@@ -184,6 +278,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
&& !(pv_status(pv) & EXPORTED_VG)) ||
(arg_count(cmd, novolumegroup_ARG) && (!is_orphan(pv)))) {
dm_list_del(&pvl->list);
+ free_pv_fid(pv);
continue;
}