summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/example.conf.in16
-rw-r--r--configure.in22
-rw-r--r--doc/aio_design.txt215
-rw-r--r--include/configure.h.in3
-rw-r--r--lib/cache/lvmcache.c51
-rw-r--r--lib/cache/lvmcache.h2
-rw-r--r--lib/cache/lvmetad.c2
-rw-r--r--lib/commands/toolcontext.c16
-rw-r--r--lib/commands/toolcontext.h1
-rw-r--r--lib/config/config.c154
-rw-r--r--lib/config/config.h8
-rw-r--r--lib/config/config_settings.h10
-rw-r--r--lib/config/defaults.h3
-rw-r--r--lib/device/dev-cache.c12
-rw-r--r--lib/device/dev-cache.h8
-rw-r--r--lib/device/dev-io.c600
-rw-r--r--lib/device/dev-luks.c2
-rw-r--r--lib/device/dev-md.c2
-rw-r--r--lib/device/dev-swap.c3
-rw-r--r--lib/device/dev-type.c2
-rw-r--r--lib/device/device.h102
-rw-r--r--lib/filters/filter-composite.c4
-rw-r--r--lib/filters/filter-persistent.c8
-rw-r--r--lib/filters/filter.h2
-rw-r--r--lib/format1/disk-rep.c10
-rw-r--r--lib/format1/format1.c2
-rw-r--r--lib/format1/lvm1-label.c19
-rw-r--r--lib/format_pool/disk_rep.c2
-rw-r--r--lib/format_pool/format_pool.c2
-rw-r--r--lib/format_pool/pool_label.c13
-rw-r--r--lib/format_text/archive.c4
-rw-r--r--lib/format_text/archiver.c2
-rw-r--r--lib/format_text/export.c21
-rw-r--r--lib/format_text/format-text.c541
-rw-r--r--lib/format_text/import-export.h8
-rw-r--r--lib/format_text/import.c235
-rw-r--r--lib/format_text/layout.h12
-rw-r--r--lib/format_text/text_label.c197
-rw-r--r--lib/label/label.c173
-rw-r--r--lib/label/label.h6
-rw-r--r--lib/metadata/metadata-liblvm.c3
-rw-r--r--lib/metadata/metadata.c8
-rw-r--r--lib/metadata/metadata.h5
-rw-r--r--make.tmpl.in3
-rw-r--r--tools/command.c11
-rw-r--r--tools/toollib.c1
46 files changed, 566 insertions, 1960 deletions
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 3b0638f60..aab274d74 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -59,22 +59,6 @@ devices {
# This configuration option is advanced.
scan = [ "/dev" ]
- # Configuration option devices/use_aio.
- # Use linux asynchronous I/O for parallel device access where possible.
- # This configuration option has an automatic default value.
- # use_aio = 1
-
- # Configuration option devices/aio_max.
- # Maximum number of asynchronous I/Os to issue concurrently.
- # This configuration option has an automatic default value.
- # aio_max = 128
-
- # Configuration option devices/aio_memory.
- # Approximate maximum total amount of memory (in MB) used
- # for asynchronous I/O buffers.
- # This configuration option has an automatic default value.
- # aio_memory = 10
-
# Configuration option devices/obtain_device_list_from_udev.
# Obtain the list of available devices from udev.
# This avoids opening or using any inapplicable non-block devices or
diff --git a/configure.in b/configure.in
index 605b6b212..b8e162351 100644
--- a/configure.in
+++ b/configure.in
@@ -39,7 +39,6 @@ case "$host_os" in
LDDEPS="$LDDEPS .export.sym"
LIB_SUFFIX=so
DEVMAPPER=yes
- AIO=yes
BUILD_LVMETAD=no
BUILD_LVMPOLLD=no
LOCKDSANLOCK=no
@@ -59,7 +58,6 @@ case "$host_os" in
CLDNOWHOLEARCHIVE=
LIB_SUFFIX=dylib
DEVMAPPER=yes
- AIO=no
ODIRECT=no
DM_IOCTLS=no
SELINUX=no
@@ -1125,24 +1123,6 @@ if test "$DEVMAPPER" = yes; then
fi
################################################################################
-dnl -- Disable aio
-AC_MSG_CHECKING(whether to use asynchronous I/O)
-AC_ARG_ENABLE(aio,
- AC_HELP_STRING([--disable-aio],
- [disable asynchronous I/O]),
- AIO=$enableval)
-AC_MSG_RESULT($AIO)
-
-if test "$AIO" = yes; then
- AC_CHECK_LIB(aio, io_setup,
- [AC_DEFINE([AIO_SUPPORT], 1, [Define to 1 if aio is available.])
- AIO_LIBS="-laio"
- AIO_SUPPORT=yes],
- [AIO_LIBS=
- AIO_SUPPORT=no ])
-fi
-
-################################################################################
dnl -- Build lvmetad
AC_MSG_CHECKING(whether to build LVMetaD)
AC_ARG_ENABLE(lvmetad,
@@ -2081,11 +2061,9 @@ AC_SUBST(DEFAULT_USE_LVMETAD)
AC_SUBST(DEFAULT_USE_LVMPOLLD)
AC_SUBST(DEFAULT_USE_LVMLOCKD)
AC_SUBST(DEVMAPPER)
-AC_SUBST(AIO)
AC_SUBST(DLM_CFLAGS)
AC_SUBST(DLM_LIBS)
AC_SUBST(DL_LIBS)
-AC_SUBST(AIO_LIBS)
AC_SUBST(DMEVENTD_PATH)
AC_SUBST(DM_LIB_PATCHLEVEL)
AC_SUBST(ELDFLAGS)
diff --git a/doc/aio_design.txt b/doc/aio_design.txt
deleted file mode 100644
index c6eb44352..000000000
--- a/doc/aio_design.txt
+++ /dev/null
@@ -1,215 +0,0 @@
-Introducing asynchronous I/O to LVM
-===================================
-
-Issuing I/O asynchronously means instructing the kernel to perform specific
-I/O and return immediately without waiting for it to complete. The data
-is collected from the kernel later.
-
-Advantages
-----------
-
-A1. While waiting for the I/O to happen, the program could perform other
-operations.
-
-A2. When LVM is searching for its Physical Volumes, it issues a small amount of
-I/O to a large number of disks. If this was issued in parallel the overall
-runtime might be shorter while there should be little effect on the cpu time.
-
-A3. If more than one timeout occurs when accessing any devices, these can be
-taken in parallel, again reducing the runtime. This applies globally,
-not just while the code is searching for Physical Volumes, so reading,
-writing and committing the metadata may occasionally benefit too to some
-extent and there are probably maintenance advantages in using the same
-method of I/O throughout the main body of the code.
-
-A4. By introducing a simple callback function mechanism, the conversion can be
-performed largely incrementally by first refactoring and continuing to
-use synchronous I/O with the callbacks performed immediately. This allows the
-callbacks to be introduced without changing the running sequence of the code
-initially. Future projects could refactor some of the calling sites to
-simplify the code structure and even eliminate some of the nesting.
-This allows each part of what might ultimately amount to a large change to be
-introduced and tested independently.
-
-
-Disadvantages
--------------
-
-D1. The resulting code may be more complex with more failure modes to
-handle. Mitigate by thorough auditing and testing, rolling out
-gradually, and offering a simple switch to revert to the old behaviour.
-
-D2. The linux asynchronous I/O implementation is less mature than
-its synchronous I/O implementation and might show up problems that
-depend on the version of the kernel or library used. Fixes or
-workarounds for some of these might require kernel changes. For
-example, there are suggestions that despite being supposedly async,
-there are still cases where system calls can block. There might be
-resource dependencies on other processes running on the system that make
-it unsuitable for use while any devices are suspended. Mitigation
-as for D1.
-
-D3. The error handling within callbacks becomes more complicated.
-However we know that existing call paths can already sometimes discard
-errors, sometimes deliberately, sometimes not, so this aspect is in need
-of a complete review anyway and the new approach will make the error
-handling more transparent. Aim initially for overall behaviour that is
-no worse than that of the existing code, then work on improving it
-later.
-
-D4. The work will take a few weeks to code and test. This leads to a
-significant opportunity cost when compared against other enhancements
-that could be achieved in that time. However, the proof-of-concept work
-performed while writing this design has satisfied me that the work could
-proceed and be committed incrementally as a background task.
-
-
-Observations regarding LVM's I/O Architecture
----------------------------------------------
-
-H1. All device, metadata and config file I/O is constrained to pass through a
-single route in lib/device.
-
-H2. The first step of the analysis was to instrument this code path with
-log_debug messages. I/O is split into the following categories:
-
- "dev signatures",
- "PV labels",
- "VG metadata header",
- "VG metadata content",
- "extra VG metadata header",
- "extra VG metadata content",
- "LVM1 metadata",
- "pool metadata",
- "LV content",
- "logging",
-
-H3. A bounce buffer is used for most I/O.
-
-H4. Most callers finish using the supplied data before any further I/O is
-issued. The few that don't could be converted trivially to do so.
-
-H5. There is one stream of I/O per metadata area on each device.
-
-H6. Some reads fall at offsets close to immediately preceding reads, so it's
-possible to avoid these by caching one "block" per metadata area I/O stream.
-
-H7. Simple analysis suggests a minimum aligned read size of 8k would deliver
-immediate gains from this caching. A larger size might perform worse because
-almost all the time the extra data read would not be used, but this can be
-re-examined and tuned after the code is in place.
-
-
-Proposal
---------
-
-P1. Retain the "single I/O path" but offer an asynchronous option.
-
-P2. Eliminate the bounce buffer in most cases by improving alignment.
-
-P3. Reduce the number of reads by always reading a minimum of an aligned
-8k block.
-
-P4. Eliminate repeated reads by caching the last block read and changing
-the lib/device interface to return a pointer to read-only data within
-this block.
-
-P5. Only perform these interface changes for code on the critical path
-for now by converting other code sites to use wrappers around the new
-interface.
-
-P6. Treat asynchronous I/O as the interface of choice and optimise only
-for this case.
-
-P7. Convert the callers on the critical path to pass callback functions
-to the device layer. These functions will be called later with the
-read-only data, a context pointer and a success/failure indicator.
-Where an existing function performs a sequence of I/O, this has the
-advantage of breaking up the large function into smaller ones and
-wrapping the parameters used into structures. While this might look
-rather messy and ad-hoc in the short-term, it's a first step towards
-breaking up confusingly long functions into component parts and wrapping
-the existing long parameter lists into more appropriate structures and
-refactoring these parts of the code.
-
-P8. Limit the resources used by the asynchronous I/O by using two
-tunable parameters, one limiting the number of outstanding I/Os issued
-and another limiting the total amount of memory used.
-
-P9. Provide a fallback option if asynchronous I/O is unavailable by
-sharing the code paths but issuing the I/O synchronously and calling the
-callback immediately.
-
-P10. Only allocate the buffer for the I/O at the point where the I/O is
-about to be issued.
-
-P11. If the thresholds are exceeded, add the request to a simple queue,
-and process it later after some I/O has completed.
-
-
-Future work
------------
-F1. Perform a complete review of the error tracking so that device
-failures are handled and reported more cleanly, extending the existing
-basic error counting mechanism.
-
-F2. Consider whether some of the nested callbacks can be eliminated,
-which would allow for additional simplifications.
-
-F3. Adjust the contents of the adhoc context structs into more logical
-arrangements and use them more widely.
-
-F4. Perform wider refactoring of these areas of code.
-
-
-Testing considerations
-----------------------
-T1. The changes touch code on the device path, so a thorough re-test of
-the device layer is required. The new code needs a full audit down
-through the library layer into the kernel to check that all the error
-conditions that are currently implemented (such as EAGAIN) are handled
-sensibly. (LVM's I/O layer needs to remain as solid as we can make it.)
-
-T2. The current test suite provides a reasonably broad range of coverage
-of this area but is far from comprehensive.
-
-
-Acceptance criteria
--------------------
-A1. The current test suite should pass to the same extent as before the
-changes.
-
-A2. When all debugging and logging is disabled, strace -c must show
-improvements e.g. the expected fewer number of reads.
-
-A3. Running a range of commands under valgrind must not reveal any
-new leaks due to the changes.
-
-A4. All new coverity reports from the change must be addressed.
-
-A5. CPU time should be similar to that before, as the same work
-is being done overall, just in a different order.
-
-A6. Tests need to show improved behaviour in targetted areas. For example,
-if several devices are slow and time out, the delays should occur
-in parallel and the elapsed time should be less than before.
-
-
-Release considerations
-----------------------
-R1. Async I/O should be widely available and largely reliable on linux
-nowadays (even though parts of its interface and implementation remain a
-matter of controversy) so we should try to make its use the default
-whereever it is supported. If certain types of systems have problems we
-should try to detect those cases and disable it automatically there.
-
-R2. Because the implications of an unexpected problem in the new code
-could be severe for the people affected, the roll out needs to be gentle
-without a deadline to allow us plenty of time to gain confidence in the
-new code. Our own testing will only be able to cover a tiny fraction of
-the different setups our users have, so we need to look out for problems
-caused by this proactively and encourage people to test it on their own
-systems and report back. It must go into the tree near the start of a
-release cycle rather than at the end to provide time for our confidence
-in it to grow.
-
diff --git a/include/configure.h.in b/include/configure.h.in
index a4918071f..be2f66031 100644
--- a/include/configure.h.in
+++ b/include/configure.h.in
@@ -1,8 +1,5 @@
/* include/configure.h.in. Generated from configure.in by autoheader. */
-/* Define to 1 if aio is available. */
-#undef AIO_SUPPORT
-
/* Define to 1 to use libblkid detection of signatures when wiping. */
#undef BLKID_WIPING_SUPPORT
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 5ff28274c..fb8100222 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -141,8 +141,6 @@ void lvmcache_seed_infos_from_lvmetad(struct cmd_context *cmd)
/* Volume Group metadata cache functions */
static void _free_cached_vgmetadata(struct lvmcache_vginfo *vginfo)
{
- struct lvmcache_info *info;
-
if (!vginfo || !vginfo->vgmetadata)
return;
@@ -156,10 +154,6 @@ static void _free_cached_vgmetadata(struct lvmcache_vginfo *vginfo)
vginfo->cft = NULL;
}
- /* Invalidate any cached device buffers */
- dm_list_iterate_items(info, &vginfo->infos)
- devbufs_release(info->dev);
-
log_debug_cache("lvmcache: VG %s wiped.", vginfo->vgname);
release_vg(vginfo->cached_vg);
@@ -548,6 +542,7 @@ const struct format_type *lvmcache_fmt_from_vgname(struct cmd_context *cmd,
{
struct lvmcache_vginfo *vginfo;
struct lvmcache_info *info;
+ struct label *label;
struct dm_list *devh, *tmp;
struct dm_list devs;
struct device_list *devl;
@@ -592,7 +587,7 @@ const struct format_type *lvmcache_fmt_from_vgname(struct cmd_context *cmd,
dm_list_iterate_safe(devh, tmp, &devs) {
devl = dm_list_item(devh, struct device_list);
- (void) label_read(devl->dev, NULL, UINT64_C(0));
+ (void) label_read(devl->dev, &label, UINT64_C(0));
dm_list_del(&devl->list);
dm_free(devl);
}
@@ -773,8 +768,10 @@ char *lvmcache_vgname_from_pvid(struct cmd_context *cmd, const char *pvid)
static void _rescan_entry(struct lvmcache_info *info)
{
+ struct label *label;
+
if (info->status & CACHE_INVALID)
- (void) label_read(info->dev, NULL, UINT64_C(0));
+ (void) label_read(info->dev, &label, UINT64_C(0));
}
static int _scan_invalid(void)
@@ -1096,31 +1093,17 @@ next:
goto next;
}
-/* Track the number of outstanding label reads */
-/* FIXME Switch to struct and also track failed */
-static void _process_label_data(int failed, unsigned ioflags, void *context, const void *data)
-{
- int *nr_labels_outstanding = context;
-
- if (!*nr_labels_outstanding) {
- log_error(INTERNAL_ERROR "_process_label_data called too many times");
- return;
- }
-
- (*nr_labels_outstanding)--;
-}
-
int lvmcache_label_scan(struct cmd_context *cmd)
{
struct dm_list del_cache_devs;
struct dm_list add_cache_devs;
struct lvmcache_info *info;
struct device_list *devl;
+ struct label *label;
struct dev_iter *iter;
struct device *dev;
struct format_type *fmt;
int dev_count = 0;
- int nr_labels_outstanding = 0;
int r = 0;
@@ -1159,22 +1142,13 @@ int lvmcache_label_scan(struct cmd_context *cmd)
_destroy_duplicate_device_list(&_found_duplicate_devs);
while ((dev = dev_iter_get(iter))) {
- log_debug_io("Scanning device %s", dev_name(dev));
- nr_labels_outstanding++;
- if (!label_read_callback(dev, UINT64_C(0), AIO_SUPPORTED_CODE_PATH, _process_label_data, &nr_labels_outstanding))
- nr_labels_outstanding--;
+ (void) label_read(dev, &label, UINT64_C(0));
dev_count++;
}
dev_iter_destroy(iter);
- while (nr_labels_outstanding) {
- log_very_verbose("Scanned %d device labels (%d outstanding)", dev_count, nr_labels_outstanding);
- if (!dev_async_getevents())
- return_0;
- }
-
- log_very_verbose("Scanned %d device labels (%d outstanding)", dev_count, nr_labels_outstanding);
+ log_very_verbose("Scanned %d device labels", dev_count);
/*
* _choose_preferred_devs() returns:
@@ -1208,7 +1182,7 @@ int lvmcache_label_scan(struct cmd_context *cmd)
dm_list_iterate_items(devl, &add_cache_devs) {
log_debug_cache("Rescan preferred device %s for lvmcache", dev_name(devl->dev));
- (void) label_read(devl->dev, NULL, UINT64_C(0));
+ (void) label_read(devl->dev, &label, UINT64_C(0));
}
dm_list_splice(&_unused_duplicate_devs, &del_cache_devs);
@@ -1228,7 +1202,7 @@ int lvmcache_label_scan(struct cmd_context *cmd)
*/
if (_force_label_scan && cmd->is_long_lived &&
cmd->dump_filter && cmd->full_filter && cmd->full_filter->dump &&
- !cmd->full_filter->dump(cmd->full_filter, cmd->mem, 0))
+ !cmd->full_filter->dump(cmd->full_filter, 0))
stack;
r = 1;
@@ -1529,6 +1503,7 @@ const char *lvmcache_pvid_from_devname(struct cmd_context *cmd,
const char *devname)
{
struct device *dev;
+ struct label *label;
if (!(dev = dev_cache_get(devname, cmd->filter))) {
log_error("%s: Couldn't find device. Check your filters?",
@@ -1536,7 +1511,7 @@ const char *lvmcache_pvid_from_devname(struct cmd_context *cmd,
return NULL;
}
- if (!(label_read(dev, NULL, UINT64_C(0))))
+ if (!(label_read(dev, &label, UINT64_C(0))))
return NULL;
return dev->pvid;
@@ -2001,7 +1976,7 @@ int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt)
return _lvmcache_update_vgname(NULL, vgname, vgname, 0, "", fmt);
}
-int lvmcache_update_vgname_and_id(struct lvmcache_info *info, const struct lvmcache_vgsummary *vgsummary)
+int lvmcache_update_vgname_and_id(struct lvmcache_info *info, struct lvmcache_vgsummary *vgsummary)
{
const char *vgname = vgsummary->vgname;
const char *vgid = (char *)&vgsummary->vgid;
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 3c76b780b..847c208f1 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -85,7 +85,7 @@ void lvmcache_del(struct lvmcache_info *info);
/* Update things */
int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
- const struct lvmcache_vgsummary *vgsummary);
+ struct lvmcache_vgsummary *vgsummary);
int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted);
void lvmcache_lock_vgname(const char *vgname, int read_only);
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 589b48eae..4b7410cec 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -1771,7 +1771,7 @@ static int _lvmetad_pvscan_single(struct metadata_area *mda, void *baton)
struct volume_group *vg;
if (mda_is_ignored(mda) ||
- !(vg = mda->ops->vg_read(b->fid, "", mda, NULL, NULL, 1, 0)))
+ !(vg = mda->ops->vg_read(b->fid, "", mda, NULL, NULL, 1)))
return 1;
/* FIXME Also ensure contents match etc. */
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index b613b8f72..c99849587 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -636,16 +636,6 @@ static int _process_config(struct cmd_context *cmd)
*/
cmd->default_settings.udev_fallback = udev_disabled ? 1 : -1;
-#ifdef AIO_SUPPORT
- cmd->use_aio = find_config_tree_bool(cmd, devices_use_aio_CFG, NULL);
-#else
- cmd->use_aio = 0;
-#endif
- if (cmd->use_aio && !dev_async_setup(cmd))
- cmd->use_aio = 0;
-
- log_debug_io("%ssing asynchronous I/O.", cmd->use_aio ? "U" : "Not u");
-
init_retry_deactivation(find_config_tree_bool(cmd, activation_retry_deactivation_CFG, NULL));
init_activation_checks(find_config_tree_bool(cmd, activation_checks_CFG, NULL));
@@ -1298,7 +1288,7 @@ int init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
lvm_stat_ctim(&ts, &st);
cts = config_file_timestamp(cmd->cft);
if (timespeccmp(&ts, &cts, >) &&
- !persistent_filter_load(cmd->mem, cmd->filter, NULL))
+ !persistent_filter_load(cmd->filter, NULL))
log_verbose("Failed to load existing device cache from %s",
dev_cache);
}
@@ -2160,8 +2150,6 @@ int refresh_toolcontext(struct cmd_context *cmd)
cmd->lib_dir = NULL;
- label_init();
-
if (!_init_lvm_conf(cmd))
return_0;
@@ -2249,7 +2237,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
int flags;
if (cmd->dump_filter && cmd->filter && cmd->filter->dump &&
- !cmd->filter->dump(cmd->filter, cmd->mem, 1))
+ !cmd->filter->dump(cmd->filter, 1))
stack;
archive_exit(cmd);
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 89d1088ee..f04afec8c 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -165,7 +165,6 @@ struct cmd_context {
unsigned vg_notify:1;
unsigned lv_notify:1;
unsigned pv_notify:1;
- unsigned use_aio:1;
unsigned activate_component:1; /* command activates component LV */
unsigned process_component_lvs:1; /* command processes also component LVs */
diff --git a/lib/config/config.c b/lib/config/config.c
index 97c5db8a1..8fca3728e 100644
--- a/lib/config/config.c
+++ b/lib/config/config.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -279,7 +279,7 @@ struct dm_config_tree *config_file_open_and_read(const char *config_file,
}
log_very_verbose("Loading config file: %s", config_file);
- if (!config_file_read(cmd->mem, cft)) {
+ if (!config_file_read(cft)) {
log_error("Failed to load config file %s", config_file);
goto bad;
}
@@ -489,102 +489,32 @@ int override_config_tree_from_profile(struct cmd_context *cmd,
return 0;
}
-struct process_config_file_params {
- struct dm_config_tree *cft;
- struct device *dev;
- off_t offset;
- size_t size;
- off_t offset2;
- size_t size2;
- checksum_fn_t checksum_fn;
- uint32_t checksum;
- int checksum_only;
- int no_dup_node_check;
- lvm_callback_fn_t config_file_read_fd_callback;
- void *config_file_read_fd_context;
- int ret;
-};
-
-static void _process_config_file_buffer(int failed, unsigned ioflags, void *context, const void *data)
-{
- struct process_config_file_params *pcfp = context;
- const char *fb = data, *fe;
-
- if (failed) {
- pcfp->ret = 0;
- goto_out;
- }
-
- if (pcfp->checksum_fn && pcfp->checksum !=
- (pcfp->checksum_fn(pcfp->checksum_fn(INITIAL_CRC, (const uint8_t *)fb, pcfp->size),
- (const uint8_t *)(fb + pcfp->size), pcfp->size2))) {
- log_error("%s: Checksum error at offset %" PRIu64, dev_name(pcfp->dev), (uint64_t) pcfp->offset);
- pcfp->ret = 0;
- goto out;
- }
-
- if (!pcfp->checksum_only) {
- fe = fb + pcfp->size + pcfp->size2;
- if (pcfp->no_dup_node_check) {
- if (!dm_config_parse_without_dup_node_check(pcfp->cft, fb, fe))
- pcfp->ret = 0;
- } else if (!dm_config_parse(pcfp->cft, fb, fe))
- pcfp->ret = 0;
- }
-
-out:
- if (pcfp->config_file_read_fd_callback)
- pcfp->config_file_read_fd_callback(!pcfp->ret, ioflags, pcfp->config_file_read_fd_context, NULL);
-}
-
/*
* When checksum_only is set, the checksum of buffer is only matched
* and function avoids parsing of mda into config tree which
* remains unmodified and should not be used.
*/
-int config_file_read_fd(struct dm_pool *mem, struct dm_config_tree *cft, struct device *dev, dev_io_reason_t reason,
+int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_reason_t reason,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum,
- int checksum_only, int no_dup_node_check, unsigned ioflags,
- lvm_callback_fn_t config_file_read_fd_callback, void *config_file_read_fd_context)
+ int checksum_only, int no_dup_node_check)
{
- char *fb;
+ char *fb, *fe;
int r = 0;
- off_t mmap_offset = 0;
int use_mmap = 1;
- const char *buf = NULL;
- unsigned circular = size2 ? 1 : 0; /* Wrapped around end of disk metadata buffer? */
+ off_t mmap_offset = 0;
+ char *buf = NULL;
struct config_source *cs = dm_config_get_custom(cft);
- struct process_config_file_params *pcfp;
if (!_is_file_based_config_source(cs->type)) {
log_error(INTERNAL_ERROR "config_file_read_fd: expected file, special file "
"or profile config source, found %s config source.",
_config_source_names[cs->type]);
- goto bad;
- }
-
- if (!(pcfp = dm_pool_zalloc(mem, sizeof(*pcfp)))) {
- log_debug("config_file_read_fd: process_config_file_params struct allocation failed");
- goto bad;
+ return 0;
}
- pcfp->cft = cft;
- pcfp->dev = dev;
- pcfp->offset = offset;
- pcfp->size = size;
- pcfp->offset2 = offset2;
- pcfp->size2 = size2;
- pcfp->checksum_fn = checksum_fn;
- pcfp->checksum = checksum;
- pcfp->checksum_only = checksum_only;
- pcfp->no_dup_node_check = no_dup_node_check;
- pcfp->config_file_read_fd_callback = config_file_read_fd_callback;
- pcfp->config_file_read_fd_context = config_file_read_fd_context;
- pcfp->ret = 1;
-
/* Only use mmap with regular files */
- if (!(dev->flags & DEV_REGULAR) || circular)
+ if (!(dev->flags & DEV_REGULAR) || size2)
use_mmap = 0;
if (use_mmap) {
@@ -594,40 +524,56 @@ int config_file_read_fd(struct dm_pool *mem, struct dm_config_tree *cft, struct
MAP_PRIVATE, dev_fd(dev), offset - mmap_offset);
if (fb == (caddr_t) (-1)) {
log_sys_error("mmap", dev_name(dev));
- goto bad;
- }
- _process_config_file_buffer(0, ioflags, pcfp, fb + mmap_offset);
- r = pcfp->ret;
- /* unmap the file */
- if (munmap(fb, size + mmap_offset)) {
- log_sys_error("munmap", dev_name(dev));
- r = 0;
+ goto out;
}
+ fb = fb + mmap_offset;
} else {
- if (circular) {
- if (!(buf = dev_read_circular(dev, (uint64_t) offset, size, (uint64_t) offset2, size2, reason)))
+ if (!(buf = dm_malloc(size + size2))) {
+ log_error("Failed to allocate circular buffer.");
+ return 0;
+ }
+ if (!dev_read_circular(dev, (uint64_t) offset, size,
+ (uint64_t) offset2, size2, reason, buf)) {
+ goto out;
+ }
+ fb = buf;
+ }
+
+ if (checksum_fn && checksum !=
+ (checksum_fn(checksum_fn(INITIAL_CRC, (const uint8_t *)fb, size),
+ (const uint8_t *)(fb + size), size2))) {
+ log_error("%s: Checksum error at offset %" PRIu64, dev_name(dev), (uint64_t) offset);
+ goto out;
+ }
+
+ if (!checksum_only) {
+ fe = fb + size + size2;
+ if (no_dup_node_check) {
+ if (!dm_config_parse_without_dup_node_check(cft, fb, fe))
goto_out;
- _process_config_file_buffer(0, ioflags, pcfp, buf);
- dm_free((void *)buf);
} else {
- dev_read_callback(dev, (uint64_t) offset, size, reason, ioflags, _process_config_file_buffer, pcfp);
- if (config_file_read_fd_callback)
- return 1;
+ if (!dm_config_parse(cft, fb, fe))
+ goto_out;
}
- r = pcfp->ret;
}
-out:
- return r;
+ r = 1;
-bad:
- if (config_file_read_fd_callback)
- config_file_read_fd_callback(1, ioflags, config_file_read_fd_context, NULL);
+ out:
+ if (!use_mmap)
+ dm_free(buf);
+ else {
+ /* unmap the file */
+ if (munmap(fb - mmap_offset, size + mmap_offset)) {
+ log_sys_error("munmap", dev_name(dev));
+ r = 0;
+ }
+ }
- return 0;
+ return r;
}
-int config_file_read(struct dm_pool *mem, struct dm_config_tree *cft)
+int config_file_read(struct dm_config_tree *cft)
{
const char *filename = NULL;
struct config_source *cs = dm_config_get_custom(cft);
@@ -655,8 +601,8 @@ int config_file_read(struct dm_pool *mem, struct dm_config_tree *cft)
}
}
- r = config_file_read_fd(mem, cft, cf->dev, DEV_IO_MDA_CONTENT, 0, (size_t) info.st_size, 0, 0,
- (checksum_fn_t) NULL, 0, 0, 0, 0, NULL, NULL);
+ r = config_file_read_fd(cft, cf->dev, DEV_IO_MDA_CONTENT, 0, (size_t) info.st_size, 0, 0,
+ (checksum_fn_t) NULL, 0, 0, 0);
if (!cf->keep_open) {
if (!dev_close(cf->dev))
diff --git a/lib/config/config.h b/lib/config/config.h
index 4517cb7b0..d01306b36 100644
--- a/lib/config/config.h
+++ b/lib/config/config.h
@@ -239,13 +239,11 @@ config_source_t config_get_source_type(struct dm_config_tree *cft);
typedef uint32_t (*checksum_fn_t) (uint32_t initial, const uint8_t *buf, uint32_t size);
struct dm_config_tree *config_open(config_source_t source, const char *filename, int keep_open);
-int config_file_read_fd(struct dm_pool *mem, struct dm_config_tree *cft, struct device *dev, dev_io_reason_t reason,
+int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_reason_t reason,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum,
- int skip_parse, int no_dup_node_check, unsigned ioflags,
- lvm_callback_fn_t config_file_read_fd_callback, void *config_file_read_fd_context);
-
-int config_file_read(struct dm_pool *mem, struct dm_config_tree *cft);
+ int skip_parse, int no_dup_node_check);
+int config_file_read(struct dm_config_tree *cft);
struct dm_config_tree *config_file_open_and_read(const char *config_file, config_source_t source,
struct cmd_context *cmd);
int config_write(struct dm_config_tree *cft, struct config_def_tree_spec *tree_spec,
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index f1db79786..077fb15ce 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -226,16 +226,6 @@ cfg(devices_dir_CFG, "dir", devices_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_STRING,
cfg_array(devices_scan_CFG, "scan", devices_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_STRING, "#S/dev", vsn(1, 0, 0), NULL, 0, NULL,
"Directories containing device nodes to use with LVM.\n")
-cfg(devices_use_aio_CFG, "use_aio", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_USE_AIO, vsn(2, 2, 178), NULL, 0, NULL,
- "Use linux asynchronous I/O for parallel device access where possible.\n")
-
-cfg(devices_aio_max_CFG, "aio_max", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_AIO_MAX, vsn(2, 2, 178), NULL, 0, NULL,
- "Maximum number of asynchronous I/Os to issue concurrently.\n")
-
-cfg(devices_aio_memory_CFG, "aio_memory", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_AIO_MEMORY, vsn(2, 2, 178), NULL, 0, NULL,
- "Approximate maximum total amount of memory (in MB) used\n"
- "for asynchronous I/O buffers.\n")
-
cfg_array(devices_loopfiles_CFG, "loopfiles", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED | CFG_UNSUPPORTED, CFG_TYPE_STRING, NULL, vsn(1, 2, 0), NULL, 0, NULL, NULL)
cfg(devices_obtain_device_list_from_udev_CFG, "obtain_device_list_from_udev", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV, vsn(2, 2, 85), NULL, 0, NULL,
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 1c730a9ce..d9e19d971 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -32,9 +32,6 @@
#define DEFAULT_SYSTEM_ID_SOURCE "none"
#define DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV 1
#define DEFAULT_EXTERNAL_DEVICE_INFO_SOURCE "none"
-#define DEFAULT_USE_AIO 1
-#define DEFAULT_AIO_MAX 128
-#define DEFAULT_AIO_MEMORY 10
#define DEFAULT_SYSFS_SCAN 1
#define DEFAULT_MD_COMPONENT_DETECTION 1
#define DEFAULT_FW_RAID_COMPONENT_DETECTION 0
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index 711c2d88b..e72ffd6fd 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -1245,24 +1245,12 @@ int dev_cache_check_for_open_devices(void)
int dev_cache_exit(void)
{
- struct btree_iter *b;
int num_open = 0;
- dev_async_exit();
-
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);
- if (_cache.devices) {
- /* FIXME Replace with structured devbuf cache */
- b = btree_first(_cache.devices);
- while (b) {
- devbufs_release(btree_get_data(b));
- b = btree_next(b);
- }
- }
-
if (_cache.mem)
dm_pool_destroy(_cache.mem);
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
index 560355387..546b1fe2a 100644
--- a/lib/device/dev-cache.h
+++ b/lib/device/dev-cache.h
@@ -23,10 +23,10 @@
* predicate for devices.
*/
struct dev_filter {
- int (*passes_filter) (struct dev_filter *f, struct device *dev);
- void (*destroy) (struct dev_filter *f);
- void (*wipe) (struct dev_filter *f);
- int (*dump) (struct dev_filter *f, struct dm_pool *mem, int merge_existing);
+ int (*passes_filter) (struct dev_filter * f, struct device * dev);
+ void (*destroy) (struct dev_filter * f);
+ void (*wipe) (struct dev_filter * f);
+ int (*dump) (struct dev_filter * f, int merge_existing);
void *private;
unsigned use_count;
};
diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c
index d631b8613..c321e61ad 100644
--- a/lib/device/dev-io.c
+++ b/lib/device/dev-io.c
@@ -53,12 +53,6 @@
# endif
#endif
-/*
- * Always read at least 8k from disk.
- * This seems to be a good compromise for the existing LVM2 metadata layout.
- */
-#define MIN_READ_SIZE (8 * 1024)
-
static DM_LIST_INIT(_open_devices);
static unsigned _dev_size_seqno = 1;
@@ -80,319 +74,38 @@ static const char *_reason_text(dev_io_reason_t reason)
return _reasons[(unsigned) reason];
}
-/*
- * Release the memory holding the last data we read
- */
-static void _release_devbuf(struct device_buffer *devbuf)
-{
- dm_free(devbuf->malloc_address);
- devbuf->malloc_address = NULL;
-}
-
-void devbufs_release(struct device *dev)
-{
- if ((dev->flags & DEV_REGULAR))
- return;
-
- _release_devbuf(&dev->last_devbuf);
- _release_devbuf(&dev->last_extra_devbuf);
-}
-
-#ifdef AIO_SUPPORT
-
-# include <libaio.h>
-
-static io_context_t _aio_ctx = 0;
-static struct io_event *_aio_events = NULL;
-static int _aio_max = 0;
-static int64_t _aio_memory_max = 0;
-static int _aio_must_queue = 0; /* Have we reached AIO capacity? */
-
-static DM_LIST_INIT(_aio_queue);
-
-#define DEFAULT_AIO_COLLECTION_EVENTS 32
-
-int dev_async_setup(struct cmd_context *cmd)
+/*-----------------------------------------------------------------
+ * The standard io loop that keeps submitting an io until it's
+ * all gone.
+ *---------------------------------------------------------------*/
+static int _io(struct device_area *where, char *buffer, int should_write, dev_io_reason_t reason)
{
- int r;
-
- _aio_max = find_config_tree_int(cmd, devices_aio_max_CFG, NULL);
- _aio_memory_max = find_config_tree_int(cmd, devices_aio_memory_CFG, NULL) * INT64_C(1024 * 1024);
-
- /* Threshold is zero? */
- if (!_aio_max || !_aio_memory_max) {
- if (_aio_ctx)
- dev_async_exit();
- return 1;
- }
-
- /* Already set up? */
- if (_aio_ctx)
- return 1;
-
- log_debug_io("Setting up aio context for up to %" PRId64 " MB across %d events.", _aio_memory_max, _aio_max);
-
- if (!_aio_events && !(_aio_events = dm_zalloc(sizeof(*_aio_events) * DEFAULT_AIO_COLLECTION_EVENTS))) {
- log_error("Failed to allocate io_event array for asynchronous I/O.");
- return 0;
- }
+ int fd = dev_fd(where->dev);
+ ssize_t n = 0;
+ size_t total = 0;
- if ((r = io_setup(_aio_max, &_aio_ctx)) < 0) {
- /*
- * Possible errors:
- * ENOSYS - aio not available in current kernel
- * EAGAIN - _aio_max is too big
- * EFAULT - invalid pointer
- * EINVAL - _aio_ctx != 0 or kernel aio limits exceeded
- * ENOMEM
- */
- log_warn("WARNING: Asynchronous I/O setup for %d events failed: %s", _aio_max, strerror(-r));
- log_warn("WARNING: Using only synchronous I/O.");
- dm_free(_aio_events);
- _aio_events = NULL;
- _aio_ctx = 0;
+ if (fd < 0) {
+ log_error("Attempt to read an unopened device (%s).",
+ dev_name(where->dev));
return 0;
}
- return 1;
-}
-
-/* Reset aio context after fork */
-int dev_async_reset(struct cmd_context *cmd)
-{
- log_debug_io("Resetting asynchronous I/O context.");
- _aio_ctx = 0;
- dm_free(_aio_events);
- _aio_events = NULL;
-
- return dev_async_setup(cmd);
-}
-
-/*
- * Track the amount of in-flight async I/O.
- * If it exceeds the defined threshold set _aio_must_queue.
- */
-static void _update_aio_counters(int nr, ssize_t bytes)
-{
- static int64_t aio_bytes = 0;
- static int aio_count = 0;
-
- aio_bytes += bytes;
- aio_count += nr;
-
- if (aio_count >= _aio_max || aio_bytes > _aio_memory_max)
- _aio_must_queue = 1;
- else
- _aio_must_queue = 0;
-}
-
-static int _io(struct device_buffer *devbuf, unsigned ioflags);
+ log_debug_io("%s %s:%8" PRIu64 " bytes (sync) at %" PRIu64 "%s (for %s)",
+ should_write ? "Write" : "Read ", dev_name(where->dev),
+ where->size, (uint64_t) where->start,
+ (should_write && test_mode()) ? " (test mode - suppressed)" : "", _reason_text(reason));
-int dev_async_getevents(void)
-{
- struct device_buffer *devbuf, *tmp;
- lvm_callback_fn_t dev_read_callback_fn;
- void *dev_read_callback_context;
- int r, event_nr;
-
- if (!_aio_ctx)
+ /*
+ * Skip all writes in test mode.
+ */
+ if (should_write && test_mode())
return 1;
- do {
- /* FIXME Add timeout - currently NULL - waits for ever for at least 1 item */
- r = io_getevents(_aio_ctx, 1, DEFAULT_AIO_COLLECTION_EVENTS, _aio_events, NULL);
- if (r > 0)
- break;
- if (!r)
- return 1; /* Timeout elapsed */
- if (r == -EINTR)
- continue;
- if (r == -EAGAIN) {
- usleep(100);
- return 1; /* Give the caller the opportunity to do other work before repeating */
- }
- /*
- * ENOSYS - not supported by kernel
- * EFAULT - memory invalid
- * EINVAL - _aio_ctx invalid or min_nr/nr/timeout out of range
- */
- log_error("Asynchronous event collection failed: %s", strerror(-r));
- return 0;
- } while (1);
-
- for (event_nr = 0; event_nr < r; event_nr++) {
- devbuf = _aio_events[event_nr].obj->data;
- dm_free(_aio_events[event_nr].obj);
-
- _update_aio_counters(-1, -devbuf->where.size);
-
- dev_read_callback_fn = devbuf->dev_read_callback_fn;
- dev_read_callback_context = devbuf->dev_read_callback_context;
-
- /* Clear the callbacks as a precaution */
- devbuf->dev_read_callback_context = NULL;
- devbuf->dev_read_callback_fn = NULL;
-
- if (_aio_events[event_nr].res == devbuf->where.size) {
- if (dev_read_callback_fn)
- dev_read_callback_fn(0, AIO_SUPPORTED_CODE_PATH, dev_read_callback_context, (char *)devbuf->buf + devbuf->data_offset);
- } else {
- /* FIXME If partial read is possible, resubmit remainder */
- log_error("%s: asynchronous read only I/O failed (" FMTd64 ") of " FMTu64 " bytes at " FMTu64 " (for %s): %s",
- dev_name(devbuf->where.dev), _aio_events[event_nr].res,
- (uint64_t) devbuf->where.size, (uint64_t) devbuf->where.start,
- _reason_text(devbuf->reason),
- (((int64_t)_aio_events[event_nr].res) < 0) ? strerror(-(int64_t)_aio_events[event_nr].res) : 0);
- _release_devbuf(devbuf);
- if (dev_read_callback_fn)
- dev_read_callback_fn(1, AIO_SUPPORTED_CODE_PATH, dev_read_callback_context, NULL);
- else
- r = 0;
- }
- }
-
- /* Submit further queued events if we can */
- dm_list_iterate_items_gen_safe(devbuf, tmp, &_aio_queue, aio_queued) {
- if (_aio_must_queue)
- break;
- dm_list_del(&devbuf->aio_queued);
- _io(devbuf, 1);
- }
-
- return 1;
-}
-
-static int _io_async(struct device_buffer *devbuf)
-{
- struct device_area *where = &devbuf->where;
- struct iocb *iocb;
- int r;
-
- _update_aio_counters(1, devbuf->where.size);
-
- if (!(iocb = dm_malloc(sizeof(*iocb)))) {
- log_error("Failed to allocate I/O control block array for asynchronous I/O.");
+ if (where->size > SSIZE_MAX) {
+ log_error("Read size too large: %" PRIu64, where->size);
return 0;
}
- io_prep_pread(iocb, dev_fd(where->dev), devbuf->buf, where->size, where->start);
- iocb->data = devbuf;
-
- do {
- r = io_submit(_aio_ctx, 1L, &iocb);
- if (r ==1)
- break; /* Success */
- if (r == -EAGAIN) {
- /* Try to release some resources then retry */
- usleep(100);
- if (dev_async_getevents())
- return_0;
- /* FIXME Add counter/timeout so we can't get stuck here for ever */
- continue;
- }
- /*
- * Possible errors:
- * EFAULT - invalid data
- * ENOSYS - no aio support in kernel
- * EBADF - bad file descriptor in iocb
- * EINVAL - invalid _aio_ctx / iocb not initialised / invalid operation for this fd
- */
- log_error("Asynchronous event submission failed: %s", strerror(-r));
- return 0;
- } while (1);
-
- return 1;
-}
-
-void dev_async_exit(void)
-{
- struct device_buffer *devbuf, *tmp;
- lvm_callback_fn_t dev_read_callback_fn;
- void *dev_read_callback_context;
- int r;
-
- if (!_aio_ctx)
- return;
-
- /* Discard any queued requests */
- dm_list_iterate_items_gen_safe(devbuf, tmp, &_aio_queue, aio_queued) {
- dm_list_del(&devbuf->aio_queued);
-
- _update_aio_counters(-1, -devbuf->where.size);
-
- dev_read_callback_fn = devbuf->dev_read_callback_fn;
- dev_read_callback_context = devbuf->dev_read_callback_context;
-
- _release_devbuf(devbuf);
-
- if (dev_read_callback_fn)
- dev_read_callback_fn(1, AIO_SUPPORTED_CODE_PATH, dev_read_callback_context, NULL);
- }
-
- log_debug_io("Destroying aio context.");
- if ((r = io_destroy(_aio_ctx)) < 0)
- /* Returns -ENOSYS if aio not in kernel or -EINVAL if _aio_ctx invalid */
- log_error("Failed to destroy asynchronous I/O context: %s", strerror(-r));
-
- dm_free(_aio_events);
- _aio_events = NULL;
-
- _aio_ctx = 0;
-}
-
-static void _queue_aio(struct device_buffer *devbuf)
-{
- dm_list_add(&_aio_queue, &devbuf->aio_queued);
- log_debug_io("Queueing aio.");
-}
-
-#else
-
-static int _aio_ctx = 0;
-static int _aio_must_queue = 0;
-
-int dev_async_setup(struct cmd_context *cmd)
-{
- return 1;
-}
-
-int dev_async_reset(struct cmd_context *cmd)
-{
- return 1;
-}
-
-int dev_async_getevents(void)
-{
- return 1;
-}
-
-void dev_async_exit(void)
-{
-}
-
-static int _io_async(struct device_buffer *devbuf)
-{
- return 0;
-}
-
-static void _queue_aio(struct device_buffer *devbuf)
-{
-}
-
-#endif /* AIO_SUPPORT */
-
-/*-----------------------------------------------------------------
- * The standard io loop that keeps submitting an io until it's
- * all gone.
- *---------------------------------------------------------------*/
-static int _io_sync(struct device_buffer *devbuf)
-{
- struct device_area *where = &devbuf->where;
- int fd = dev_fd(where->dev);
- char *buffer = devbuf->buf;
- ssize_t n = 0;
- size_t total = 0;
-
if (lseek(fd, (off_t) where->start, SEEK_SET) == (off_t) -1) {
log_error("%s: lseek %" PRIu64 " failed: %s",
dev_name(where->dev), (uint64_t) where->start,
@@ -402,19 +115,18 @@ static int _io_sync(struct device_buffer *devbuf)
while (total < (size_t) where->size) {
do
- n = devbuf->write ?
+ n = should_write ?
write(fd, buffer, (size_t) where->size - total) :
read(fd, buffer, (size_t) where->size - total);
while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
if (n < 0)
- log_error("%s: synchronous %s failed after %" PRIu64 " of %" PRIu64
- " at %" PRIu64 " (for %s): %s", dev_name(where->dev),
- devbuf->write ? "write" : "read",
- (uint64_t) total,
- (uint64_t) where->size, (uint64_t) where->start,
- _reason_text(devbuf->reason),
- strerror(errno));
+ log_error_once("%s: %s failed after %" PRIu64 " of %" PRIu64
+ " at %" PRIu64 ": %s", dev_name(where->dev),
+ should_write ? "write" : "read",
+ (uint64_t) total,
+ (uint64_t) where->size,
+ (uint64_t) where->start, strerror(errno));
if (n <= 0)
break;
@@ -426,42 +138,6 @@ static int _io_sync(struct device_buffer *devbuf)
return (total == (size_t) where->size);
}
-static int _io(struct device_buffer *devbuf, unsigned ioflags)
-{
- struct device_area *where = &devbuf->where;
- int fd = dev_fd(where->dev);
- int async = (!devbuf->write && _aio_ctx && aio_supported_code_path(ioflags) && devbuf->dev_read_callback_fn) ? 1 : 0;
-
- if (fd < 0) {
- log_error("Attempt to read an unopened device (%s).",
- dev_name(where->dev));
- return 0;
- }
-
- if (!devbuf->buf && !(devbuf->malloc_address = devbuf->buf = dm_malloc_aligned((size_t) devbuf->where.size, 0))) {
- log_error("I/O buffer malloc failed");
- return 0;
- }
-
- log_debug_io("%s %s(fd %d):%8" PRIu64 " bytes (%ssync) at %" PRIu64 "%s (for %s)",
- devbuf->write ? "Write" : "Read ", dev_name(where->dev), fd,
- where->size, async ? "a" : "", (uint64_t) where->start,
- (devbuf->write && test_mode()) ? " (test mode - suppressed)" : "", _reason_text(devbuf->reason));
-
- /*
- * Skip all writes in test mode.
- */
- if (devbuf->write && test_mode())
- return 1;
-
- if (where->size > SSIZE_MAX) {
- log_error("Read size too large: %" PRIu64, where->size);
- return 0;
- }
-
- return async ? _io_async(devbuf) : _io_sync(devbuf);
-}
-
/*-----------------------------------------------------------------
* LVM2 uses O_DIRECT when performing metadata io, which requires
* block size aligned accesses. If any io is not aligned we have
@@ -551,16 +227,15 @@ static void _widen_region(unsigned int block_size, struct device_area *region,
result->size += block_size - delta;
}
-static int _aligned_io(struct device_area *where, char *write_buffer,
- int should_write, dev_io_reason_t reason,
- unsigned ioflags, lvm_callback_fn_t dev_read_callback_fn, void *dev_read_callback_context)
+static int _aligned_io(struct device_area *where, char *buffer,
+ int should_write, dev_io_reason_t reason)
{
+ char *bounce, *bounce_buf;
unsigned int physical_block_size = 0;
unsigned int block_size = 0;
unsigned buffer_was_widened = 0;
uintptr_t mask;
struct device_area widened;
- struct device_buffer *devbuf;
int r = 0;
if (!(where->dev->flags & DEV_REGULAR) &&
@@ -569,11 +244,6 @@ static int _aligned_io(struct device_area *where, char *write_buffer,
if (!block_size)
block_size = lvm_getpagesize();
-
- /* Apply minimum read size */
- if (!should_write && block_size < MIN_READ_SIZE)
- block_size = MIN_READ_SIZE;
-
mask = block_size - 1;
_widen_region(block_size, where, &widened);
@@ -583,75 +253,50 @@ static int _aligned_io(struct device_area *where, char *write_buffer,
buffer_was_widened = 1;
log_debug_io("Widening request for %" PRIu64 " bytes at %" PRIu64 " to %" PRIu64 " bytes at %" PRIu64 " on %s (for %s)",
where->size, (uint64_t) where->start, widened.size, (uint64_t) widened.start, dev_name(where->dev), _reason_text(reason));
- }
-
- devbuf = DEV_DEVBUF(where->dev, reason);
- _release_devbuf(devbuf);
- devbuf->where.dev = where->dev;
- devbuf->where.start = widened.start;
- devbuf->where.size = widened.size;
- devbuf->write = should_write;
- devbuf->reason = reason;
- devbuf->dev_read_callback_fn = dev_read_callback_fn;
- devbuf->dev_read_callback_context = dev_read_callback_context;
-
- /* Store location of requested data relative to start of buf */
- devbuf->data_offset = where->start - devbuf->where.start;
-
- if (should_write && !buffer_was_widened && !((uintptr_t) write_buffer & mask))
+ } else if (!((uintptr_t) buffer & mask))
/* Perform the I/O directly. */
- devbuf->buf = write_buffer;
- else if (!should_write)
- /* Postpone buffer allocation until we're about to issue the I/O */
- devbuf->buf = NULL;
- else {
- /* Allocate a bounce buffer with an extra block */
- if (!(devbuf->malloc_address = devbuf->buf = dm_malloc((size_t) devbuf->where.size + block_size))) {
- log_error("Bounce buffer malloc failed");
- return 0;
- }
-
- /*
- * Realign start of bounce buffer (using the extra sector)
- */
- if (((uintptr_t) devbuf->buf) & mask)
- devbuf->buf = (char *) ((((uintptr_t) devbuf->buf) + mask) & ~mask);
- }
+ return _io(where, buffer, should_write, reason);
- /* If we've reached our concurrent AIO limit, add this request to the queue */
- if (!devbuf->write && _aio_ctx && aio_supported_code_path(ioflags) && dev_read_callback_fn && _aio_must_queue) {
- _queue_aio(devbuf);
- return 1;
+ /* Allocate a bounce buffer with an extra block */
+ if (!(bounce_buf = bounce = dm_malloc((size_t) widened.size + block_size))) {
+ log_error("Bounce buffer malloc failed");
+ return 0;
}
- devbuf->write = 0;
+ /*
+ * Realign start of bounce buffer (using the extra sector)
+ */
+ if (((uintptr_t) bounce) & mask)
+ bounce = (char *) ((((uintptr_t) bounce) + mask) & ~mask);
/* Do we need to read into the bounce buffer? */
- if ((!should_write || buffer_was_widened) && !_io(devbuf, ioflags)) {
+ if ((!should_write || buffer_was_widened) &&
+ !_io(&widened, bounce, 0, reason)) {
if (!should_write)
- goto_bad;
+ goto_out;
/* FIXME Handle errors properly! */
/* FIXME pre-extend the file */
- memset(devbuf->buf, '\n', devbuf->where.size);
+ memset(bounce, '\n', widened.size);
}
- if (!should_write)
- return 1;
-
- /* writes */
+ if (should_write) {
+ memcpy(bounce + (where->start - widened.start), buffer,
+ (size_t) where->size);
- if (devbuf->malloc_address) {
- memcpy((char *) devbuf->buf + devbuf->data_offset, write_buffer, (size_t) where->size);
- log_debug_io("Overwriting %" PRIu64 " bytes at %" PRIu64 " (for %s)", where->size,
- (uint64_t) where->start, _reason_text(devbuf->reason));
+ /* ... then we write */
+ if (!(r = _io(&widened, bounce, 1, reason)))
+ stack;
+
+ goto out;
}
- /* ... then we write */
- devbuf->write = 1;
- if (!(r = _io(devbuf, 0)))
- stack;
-bad:
- _release_devbuf(devbuf);
+ memcpy(buffer, bounce + (where->start - widened.start),
+ (size_t) where->size);
+
+ r = 1;
+
+out:
+ dm_free(bounce_buf);
return r;
}
@@ -1005,7 +650,6 @@ static void _close(struct device *dev)
dev->phys_block_size = -1;
dev->block_size = -1;
dm_list_del(&dev->open_list);
- devbufs_release(dev);
log_debug_devs("Closed %s", dev_name(dev));
@@ -1078,121 +722,55 @@ static void _dev_inc_error_count(struct device *dev)
dev->max_error_count, dev_name(dev));
}
-/*
- * Data is returned (read-only) at DEV_DEVBUF_DATA(dev, reason).
- * If dev_read_callback_fn is supplied, we always return 1 and take
- * responsibility for calling it exactly once. This might happen before the
- * function returns (if there's an error or the I/O is synchronous) or after.
- * Any error is passed to that function, which must track it if required.
- */
-static int _dev_read_callback(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason,
- unsigned ioflags, lvm_callback_fn_t dev_read_callback_fn, void *callback_context)
+int dev_read(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason, void *buffer)
{
struct device_area where;
- struct device_buffer *devbuf;
- uint64_t buf_end;
- int cached = 0;
- int ret = 0;
+ int ret;
- if (!dev->open_count) {
- log_error(INTERNAL_ERROR "Attempt to access device %s while closed.", dev_name(dev));
- goto out;
- }
+ if (!dev->open_count)
+ return_0;
if (!_dev_is_valid(dev))
- goto_out;
-
- /*
- * Can we satisfy this from data we stored last time we read?
- */
- if ((devbuf = DEV_DEVBUF(dev, reason)) && devbuf->malloc_address) {
- buf_end = devbuf->where.start + devbuf->where.size - 1;
- if (offset >= devbuf->where.start && offset <= buf_end && offset + len - 1 <= buf_end) {
- /* Reuse this buffer */
- cached = 1;
- devbuf->data_offset = offset - devbuf->where.start;
- log_debug_io("Cached read for %" PRIu64 " bytes at %" PRIu64 " on %s (for %s)",
- (uint64_t) len, (uint64_t) offset, dev_name(dev), _reason_text(reason));
- ret = 1;
- goto out;
- }
- }
+ return 0;
where.dev = dev;
where.start = offset;
where.size = len;
- ret = _aligned_io(&where, NULL, 0, reason, ioflags, dev_read_callback_fn, callback_context);
- if (!ret) {
- log_debug("Read from %s failed (for %s).", dev_name(dev), _reason_text(reason));
+ ret = _aligned_io(&where, buffer, 0, reason);
+ if (!ret)
_dev_inc_error_count(dev);
- }
-
-out:
- /* If we had an error or this was sync I/O, pass the result to any callback fn */
- if ((!ret || !_aio_ctx || !aio_supported_code_path(ioflags) || cached) && dev_read_callback_fn) {
- dev_read_callback_fn(!ret, ioflags, callback_context, DEV_DEVBUF_DATA(dev, reason));
- return 1;
- }
return ret;
}
-void dev_read_callback(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason,
- unsigned ioflags, lvm_callback_fn_t dev_read_callback_fn, void *callback_context)
-{
- /* Always returns 1 if callback fn is supplied */
- if (!_dev_read_callback(dev, offset, len, reason, ioflags, dev_read_callback_fn, callback_context))
- log_error(INTERNAL_ERROR "_dev_read_callback failed");
-}
-
-/* Returns pointer to read-only buffer. Caller does not free it. */
-const char *dev_read(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason)
-{
- if (!_dev_read_callback(dev, offset, len, reason, 0, NULL, NULL))
- return_NULL;
-
- return DEV_DEVBUF_DATA(dev, reason);
-}
-
-/* Read into supplied retbuf owned by the caller. */
-int dev_read_buf(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason, void *retbuf)
-{
- if (!_dev_read_callback(dev, offset, len, reason, 0, NULL, NULL))
- return_0;
-
- memcpy(retbuf, DEV_DEVBUF_DATA(dev, reason), len);
-
- return 1;
-}
-
/*
- * Read from 'dev' in 2 distinct regions, denoted by (offset,len) and (offset2,len2).
- * Caller is responsible for dm_free().
+ * Read from 'dev' into 'buf', possibly in 2 distinct regions, denoted
+ * by (offset,len) and (offset2,len2). Thus, the total size of
+ * 'buf' should be len+len2.
*/
-const char *dev_read_circular(struct device *dev, uint64_t offset, size_t len,
- uint64_t offset2, size_t len2, dev_io_reason_t reason)
+int dev_read_circular(struct device *dev, uint64_t offset, size_t len,
+ uint64_t offset2, size_t len2, dev_io_reason_t reason, char *buf)
{
- char *buf = NULL;
-
- if (!(buf = dm_malloc(len + len2))) {
- log_error("Buffer allocation failed for split metadata.");
- return NULL;
+ if (!dev_read(dev, offset, len, reason, buf)) {
+ log_error("Read from %s failed", dev_name(dev));
+ return 0;
}
- if (!dev_read_buf(dev, offset, len, reason, buf)) {
- log_error("Read from %s failed.", dev_name(dev));
- dm_free(buf);
- return NULL;
- }
+ /*
+ * The second region is optional, and allows for
+ * a circular buffer on the device.
+ */
+ if (!len2)
+ return 1;
- if (!dev_read_buf(dev, offset2, len2, reason, buf + len)) {
- log_error("Circular read from %s failed.", dev_name(dev));
- dm_free(buf);
- return NULL;
+ if (!dev_read(dev, offset2, len2, reason, buf + len)) {
+ log_error("Circular read from %s failed",
+ dev_name(dev));
+ return 0;
}
- return buf;
+ return 1;
}
/* FIXME If O_DIRECT can't extend file, dev_extend first; dev_truncate after.
@@ -1238,7 +816,7 @@ int dev_write(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t r
dev->flags |= DEV_ACCESSED_W;
- ret = _aligned_io(&where, buffer, 1, reason, 0, NULL, NULL);
+ ret = _aligned_io(&where, buffer, 1, reason);
if (!ret)
_dev_inc_error_count(dev);
@@ -1248,7 +826,7 @@ int dev_write(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t r
int dev_set(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason, int value)
{
size_t s;
- char buffer[4096] __attribute__((aligned(4096)));
+ char buffer[4096] __attribute__((aligned(8)));
if (!dev_open(dev))
return_0;
diff --git a/lib/device/dev-luks.c b/lib/device/dev-luks.c
index f29161508..8513e1462 100644
--- a/lib/device/dev-luks.c
+++ b/lib/device/dev-luks.c
@@ -31,7 +31,7 @@ int dev_is_luks(struct device *dev, uint64_t *offset_found)
if (offset_found)
*offset_found = 0;
- if (!dev_read_buf(dev, 0, LUKS_SIGNATURE_SIZE, DEV_IO_SIGNATURES, buf))
+ if (!dev_read(dev, 0, LUKS_SIGNATURE_SIZE, DEV_IO_SIGNATURES, buf))
goto_out;
ret = memcmp(buf, LUKS_SIGNATURE, LUKS_SIGNATURE_SIZE) ? 0 : 1;
diff --git a/lib/device/dev-md.c b/lib/device/dev-md.c
index 1a5d47062..92ee2144b 100644
--- a/lib/device/dev-md.c
+++ b/lib/device/dev-md.c
@@ -37,7 +37,7 @@ static int _dev_has_md_magic(struct device *dev, uint64_t sb_offset)
uint32_t md_magic;
/* Version 1 is little endian; version 0.90.0 is machine endian */
- if (dev_read_buf(dev, sb_offset, sizeof(uint32_t), DEV_IO_SIGNATURES, &md_magic) &&
+ if (dev_read(dev, sb_offset, sizeof(uint32_t), DEV_IO_SIGNATURES, &md_magic) &&
((md_magic == MD_SB_MAGIC) ||
((MD_SB_MAGIC != xlate32(MD_SB_MAGIC)) && (md_magic == xlate32(MD_SB_MAGIC)))))
return 1;
diff --git a/lib/device/dev-swap.c b/lib/device/dev-swap.c
index 094eb05e4..a7ff10bb1 100644
--- a/lib/device/dev-swap.c
+++ b/lib/device/dev-swap.c
@@ -60,7 +60,8 @@ int dev_is_swap(struct device *dev, uint64_t *offset_found)
continue;
if (size < (page >> SECTOR_SHIFT))
break;
- if (!dev_read_buf(dev, page - SIGNATURE_SIZE, SIGNATURE_SIZE, DEV_IO_SIGNATURES, buf)) {
+ if (!dev_read(dev, page - SIGNATURE_SIZE,
+ SIGNATURE_SIZE, DEV_IO_SIGNATURES, buf)) {
ret = -1;
break;
}
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
index b9e77f81e..9608146b9 100644
--- a/lib/device/dev-type.c
+++ b/lib/device/dev-type.c
@@ -363,7 +363,7 @@ static int _has_partition_table(struct device *dev)
uint16_t magic;
} __attribute__((packed)) buf; /* sizeof() == SECTOR_SIZE */
- if (!dev_read_buf(dev, UINT64_C(0), sizeof(buf), DEV_IO_SIGNATURES, &buf))
+ if (!dev_read(dev, UINT64_C(0), sizeof(buf), DEV_IO_SIGNATURES, &buf))
return_0;
/* FIXME Check for other types of partition table too */
diff --git a/lib/device/device.h b/lib/device/device.h
index ea71d00a4..503373f88 100644
--- a/lib/device/device.h
+++ b/lib/device/device.h
@@ -32,18 +32,6 @@
#define DEV_ASSUMED_FOR_LV 0x00000200 /* Is device assumed for an LV */
#define DEV_NOT_O_NOATIME 0x00000400 /* Don't use O_NOATIME */
-/* ioflags */
-#define AIO_SUPPORTED_CODE_PATH 0x00000001 /* Set if the code path supports AIO */
-
-#define aio_supported_code_path(ioflags) (((ioflags) & AIO_SUPPORTED_CODE_PATH) ? 1 : 0)
-
-/*
- * Standard format for callback functions.
- * When provided, callback functions are called exactly once.
- * If failed is set, data cannot be accessed.
- */
-typedef void (*lvm_callback_fn_t)(int failed, unsigned ioflags, void *context, const void *data);
-
/*
* Support for external device info.
* Any new external device info source needs to be
@@ -62,48 +50,6 @@ struct dev_ext {
};
/*
- * All I/O is annotated with the reason it is performed.
- */
-typedef enum dev_io_reason {
- DEV_IO_SIGNATURES = 0, /* Scanning device signatures */
- DEV_IO_LABEL, /* LVM PV disk label */
- DEV_IO_MDA_HEADER, /* Text format metadata area header */
- DEV_IO_MDA_CONTENT, /* Text format metadata area content */
- DEV_IO_MDA_EXTRA_HEADER, /* Header of any extra metadata areas on device */
- DEV_IO_MDA_EXTRA_CONTENT, /* Content of any extra metadata areas on device */
- DEV_IO_FMT1, /* Original LVM1 metadata format */
- DEV_IO_POOL, /* Pool metadata format */
- DEV_IO_LV, /* Content written to an LV */
- DEV_IO_LOG /* Logging messages */
-} dev_io_reason_t;
-
-/*
- * Is this I/O for a device's extra metadata area?
- */
-#define EXTRA_IO(reason) ((reason) == DEV_IO_MDA_EXTRA_HEADER || (reason) == DEV_IO_MDA_EXTRA_CONTENT)
-#define DEV_DEVBUF(dev, reason) (EXTRA_IO((reason)) ? &(dev)->last_extra_devbuf : &(dev)->last_devbuf)
-#define DEV_DEVBUF_DATA(dev, reason) ((char *) DEV_DEVBUF((dev), (reason))->buf + DEV_DEVBUF((dev), (reason))->data_offset)
-
-struct device_area {
- struct device *dev;
- uint64_t start; /* Bytes */
- uint64_t size; /* Bytes */
-};
-
-struct device_buffer {
- uint64_t data_offset; /* Offset to start of requested data within buf */
- void *malloc_address; /* Start of allocated memory */
- void *buf; /* Aligned buffer that contains data within it */
- struct device_area where; /* Location of buf */
- dev_io_reason_t reason;
- unsigned write:1; /* 1 if write; 0 if read */
-
- lvm_callback_fn_t dev_read_callback_fn;
- void *dev_read_callback_context;
- struct dm_list aio_queued; /* Queue of async I/O waiting to be issued */
-};
-
-/*
* All devices in LVM will be represented by one of these.
* pointer comparisons are valid.
*/
@@ -125,8 +71,6 @@ struct device {
uint64_t end;
struct dm_list open_list;
struct dev_ext ext;
- struct device_buffer last_devbuf; /* Last data buffer read from the device */
- struct device_buffer last_extra_devbuf; /* Last data buffer read from the device for extra metadata area */
const char *vgid; /* if device is an LV */
const char *lvid; /* if device is an LV */
@@ -135,11 +79,33 @@ struct device {
char _padding[7];
};
+/*
+ * All I/O is annotated with the reason it is performed.
+ */
+typedef enum dev_io_reason {
+ DEV_IO_SIGNATURES = 0, /* Scanning device signatures */
+ DEV_IO_LABEL, /* LVM PV disk label */
+ DEV_IO_MDA_HEADER, /* Text format metadata area header */
+ DEV_IO_MDA_CONTENT, /* Text format metadata area content */
+ DEV_IO_MDA_EXTRA_HEADER, /* Header of any extra metadata areas on device */
+ DEV_IO_MDA_EXTRA_CONTENT, /* Content of any extra metadata areas on device */
+ DEV_IO_FMT1, /* Original LVM1 metadata format */
+ DEV_IO_POOL, /* Pool metadata format */
+ DEV_IO_LV, /* Content written to an LV */
+ DEV_IO_LOG /* Logging messages */
+} dev_io_reason_t;
+
struct device_list {
struct dm_list list;
struct device *dev;
};
+struct device_area {
+ struct device *dev;
+ uint64_t start; /* Bytes */
+ uint64_t size; /* Bytes */
+};
+
/*
* Support for external device info.
*/
@@ -179,19 +145,9 @@ int dev_test_excl(struct device *dev);
int dev_fd(struct device *dev);
const char *dev_name(const struct device *dev);
-/* Returns a read-only buffer */
-const char *dev_read(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason);
-const char *dev_read_circular(struct device *dev, uint64_t offset, size_t len,
- uint64_t offset2, size_t len2, dev_io_reason_t reason);
-
-/* Passes the data (or error) to dev_read_callback_fn */
-void dev_read_callback(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason,
- unsigned ioflags, lvm_callback_fn_t dev_read_callback_fn, void *callback_context);
-
-/* Read data and copy it into a supplied private buffer. */
-/* Only use for tiny reads or on unimportant code paths. */
-int dev_read_buf(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason, void *retbuf);
-
+int dev_read(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason, void *buffer);
+int dev_read_circular(struct device *dev, uint64_t offset, size_t len,
+ uint64_t offset2, size_t len2, dev_io_reason_t reason, char *buf);
int dev_write(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason, void *buffer);
int dev_append(struct device *dev, size_t len, dev_io_reason_t reason, char *buffer);
int dev_set(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason, int value);
@@ -201,15 +157,7 @@ struct device *dev_create_file(const char *filename, struct device *dev,
struct dm_str_list *alias, int use_malloc);
void dev_destroy_file(struct device *dev);
-void devbufs_release(struct device *dev);
-
/* Return a valid device name from the alias list; NULL otherwise */
const char *dev_name_confirmed(struct device *dev, int quiet);
-struct cmd_context;
-int dev_async_getevents(void);
-int dev_async_setup(struct cmd_context *cmd);
-void dev_async_exit(void);
-int dev_async_reset(struct cmd_context *cmd);
-
#endif
diff --git a/lib/filters/filter-composite.c b/lib/filters/filter-composite.c
index 83a0f02bb..c63589640 100644
--- a/lib/filters/filter-composite.c
+++ b/lib/filters/filter-composite.c
@@ -52,13 +52,13 @@ static void _composite_destroy(struct dev_filter *f)
dm_free(f);
}
-static int _dump(struct dev_filter *f, struct dm_pool *mem, int merge_existing)
+static int _dump(struct dev_filter *f, int merge_existing)
{
struct dev_filter **filters;
for (filters = (struct dev_filter **) f->private; *filters; ++filters)
if ((*filters)->dump &&
- !(*filters)->dump(*filters, mem, merge_existing))
+ !(*filters)->dump(*filters, merge_existing))
return_0;
return 1;
diff --git a/lib/filters/filter-persistent.c b/lib/filters/filter-persistent.c
index 7542e0200..5bc0861fd 100644
--- a/lib/filters/filter-persistent.c
+++ b/lib/filters/filter-persistent.c
@@ -87,7 +87,7 @@ static int _read_array(struct pfilter *pf, struct dm_config_tree *cft,
return 1;
}
-int persistent_filter_load(struct dm_pool *mem, struct dev_filter *f, struct dm_config_tree **cft_out)
+int persistent_filter_load(struct dev_filter *f, struct dm_config_tree **cft_out)
{
struct pfilter *pf = (struct pfilter *) f->private;
struct dm_config_tree *cft;
@@ -116,7 +116,7 @@ int persistent_filter_load(struct dm_pool *mem, struct dev_filter *f, struct dm_
if (!(cft = config_open(CONFIG_FILE_SPECIAL, pf->file, 1)))
return_0;
- if (!config_file_read(mem, cft))
+ if (!config_file_read(cft))
goto_out;
log_debug_devs("Loading persistent filter cache from %s", pf->file);
@@ -175,7 +175,7 @@ static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
fprintf(fp, "\n\t]\n");
}
-static int _persistent_filter_dump(struct dev_filter *f, struct dm_pool *mem, int merge_existing)
+static int _persistent_filter_dump(struct dev_filter *f, int merge_existing)
{
struct pfilter *pf;
char *tmp_file;
@@ -234,7 +234,7 @@ static int _persistent_filter_dump(struct dev_filter *f, struct dm_pool *mem, in
lvm_stat_ctim(&ts, &info);
if (merge_existing && timespeccmp(&ts, &pf->ctime, !=))
/* Keep cft open to avoid losing lock */
- persistent_filter_load(mem, f, &cft);
+ persistent_filter_load(f, &cft);
tmp_file = alloca(strlen(pf->file) + 5);
sprintf(tmp_file, "%s.tmp", pf->file);
diff --git a/lib/filters/filter.h b/lib/filters/filter.h
index 5dbf0b497..d75f6e11c 100644
--- a/lib/filters/filter.h
+++ b/lib/filters/filter.h
@@ -53,6 +53,6 @@ typedef enum {
} filter_mode_t;
struct dev_filter *usable_filter_create(struct dev_types *dt, filter_mode_t mode);
-int persistent_filter_load(struct dm_pool *mem, struct dev_filter *f, struct dm_config_tree **cft_out);
+int persistent_filter_load(struct dev_filter *f, struct dm_config_tree **cft_out);
#endif /* _LVM_FILTER_H */
diff --git a/lib/format1/disk-rep.c b/lib/format1/disk-rep.c
index cf34e91cb..41955afc0 100644
--- a/lib/format1/disk-rep.c
+++ b/lib/format1/disk-rep.c
@@ -205,7 +205,7 @@ int munge_pvd(struct device *dev, struct pv_disk *pvd)
static int _read_pvd(struct device *dev, struct pv_disk *pvd)
{
- if (!dev_read_buf(dev, UINT64_C(0), sizeof(*pvd), DEV_IO_FMT1, pvd)) {
+ if (!dev_read(dev, UINT64_C(0), sizeof(*pvd), DEV_IO_FMT1, pvd)) {
log_very_verbose("Failed to read PV data from %s",
dev_name(dev));
return 0;
@@ -216,7 +216,7 @@ static int _read_pvd(struct device *dev, struct pv_disk *pvd)
static int _read_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk)
{
- if (!dev_read_buf(dev, pos, sizeof(*disk), DEV_IO_FMT1, disk))
+ if (!dev_read(dev, pos, sizeof(*disk), DEV_IO_FMT1, disk))
return_0;
_xlate_lvd(disk);
@@ -228,7 +228,7 @@ int read_vgd(struct device *dev, struct vg_disk *vgd, struct pv_disk *pvd)
{
uint64_t pos = pvd->vg_on_disk.base;
- if (!dev_read_buf(dev, pos, sizeof(*vgd), DEV_IO_FMT1, vgd))
+ if (!dev_read(dev, pos, sizeof(*vgd), DEV_IO_FMT1, vgd))
return_0;
_xlate_vgd(vgd);
@@ -252,7 +252,7 @@ static int _read_uuids(struct disk_list *data)
uint64_t end = pos + data->pvd.pv_uuidlist_on_disk.size;
while (pos < end && num_read < data->vgd.pv_cur) {
- if (!dev_read_buf(data->dev, pos, sizeof(buffer), DEV_IO_FMT1, buffer))
+ if (!dev_read(data->dev, pos, sizeof(buffer), DEV_IO_FMT1, buffer))
return_0;
if (!(ul = dm_pool_alloc(data->mem, sizeof(*ul))))
@@ -311,7 +311,7 @@ static int _read_extents(struct disk_list *data)
if (!extents)
return_0;
- if (!dev_read_buf(data->dev, pos, len, DEV_IO_FMT1, extents))
+ if (!dev_read(data->dev, pos, len, DEV_IO_FMT1, extents))
return_0;
_xlate_extents(extents, data->pvd.pe_total);
diff --git a/lib/format1/format1.c b/lib/format1/format1.c
index 7d84e6981..b3569e08e 100644
--- a/lib/format1/format1.c
+++ b/lib/format1/format1.c
@@ -182,7 +182,7 @@ static struct volume_group *_format1_vg_read(struct format_instance *fid,
struct metadata_area *mda __attribute__((unused)),
struct cached_vg_fmtdata **vg_fmtdata __attribute__((unused)),
unsigned *use_previous_vg __attribute__((unused)),
- int single_device __attribute__((unused)), unsigned ioflags)
+ int single_device __attribute__((unused)))
{
struct volume_group *vg;
struct disk_list *dl;
diff --git a/lib/format1/lvm1-label.c b/lib/format1/lvm1-label.c
index d334fdc2e..3b8a655e9 100644
--- a/lib/format1/lvm1-label.c
+++ b/lib/format1/lvm1-label.c
@@ -54,17 +54,15 @@ static int _lvm1_write(struct label *label __attribute__((unused)), void *buf __
return 0;
}
-static int _lvm1_read(struct labeller *l, struct device *dev, void *buf, unsigned ioflags,
- lvm_callback_fn_t read_label_callback_fn, void *read_label_callback_context)
+static int _lvm1_read(struct labeller *l, struct device *dev, void *buf,
+ struct label **label)
{
struct pv_disk *pvd = (struct pv_disk *) buf;
struct vg_disk vgd;
struct lvmcache_info *info;
- struct label *label = NULL;
const char *vgid = FMT_LVM1_ORPHAN_VG_NAME;
const char *vgname = FMT_LVM1_ORPHAN_VG_NAME;
unsigned exported = 0;
- int r = 0;
munge_pvd(dev, pvd);
@@ -78,9 +76,8 @@ static int _lvm1_read(struct labeller *l, struct device *dev, void *buf, unsigne
if (!(info = lvmcache_add(l, (char *)pvd->pv_uuid, dev, vgname, vgid,
exported)))
- goto_out;
-
- label = lvmcache_get_label(info);
+ return_0;
+ *label = lvmcache_get_label(info);
lvmcache_set_device_size(info, ((uint64_t)xlate32(pvd->pv_size)) << SECTOR_SHIFT);
lvmcache_set_ext_version(info, 0);
@@ -89,13 +86,7 @@ static int _lvm1_read(struct labeller *l, struct device *dev, void *buf, unsigne
lvmcache_del_bas(info);
lvmcache_make_valid(info);
- r = 1;
-
-out:
- if (read_label_callback_fn)
- read_label_callback_fn(!r, 0, read_label_callback_context, label);
-
- return r;
+ return 1;
}
static int _lvm1_initialise_label(struct labeller *l __attribute__((unused)), struct label *label)
diff --git a/lib/format_pool/disk_rep.c b/lib/format_pool/disk_rep.c
index 4b2e7fb12..374ff44a0 100644
--- a/lib/format_pool/disk_rep.c
+++ b/lib/format_pool/disk_rep.c
@@ -40,7 +40,7 @@ static int __read_pool_disk(const struct format_type *fmt, struct device *dev,
char buf[512] __attribute__((aligned(8)));
/* FIXME: Need to check the cache here first */
- if (!dev_read_buf(dev, UINT64_C(0), 512, DEV_IO_POOL, buf)) {
+ if (!dev_read(dev, UINT64_C(0), 512, DEV_IO_POOL, buf)) {
log_very_verbose("Failed to read PV data from %s",
dev_name(dev));
return 0;
diff --git a/lib/format_pool/format_pool.c b/lib/format_pool/format_pool.c
index c6990580b..f6e5e011b 100644
--- a/lib/format_pool/format_pool.c
+++ b/lib/format_pool/format_pool.c
@@ -103,7 +103,7 @@ static struct volume_group *_pool_vg_read(struct format_instance *fid,
struct metadata_area *mda __attribute__((unused)),
struct cached_vg_fmtdata **vg_fmtdata __attribute__((unused)),
unsigned *use_previous_vg __attribute__((unused)),
- int single_device __attribute__((unused)), unsigned ioflags)
+ int single_device __attribute__((unused)))
{
struct volume_group *vg;
struct user_subpool *usp;
diff --git a/lib/format_pool/pool_label.c b/lib/format_pool/pool_label.c
index 888a2eb8c..2e30a7b19 100644
--- a/lib/format_pool/pool_label.c
+++ b/lib/format_pool/pool_label.c
@@ -55,19 +55,12 @@ static int _pool_write(struct label *label __attribute__((unused)), void *buf __
return 0;
}
-static int _pool_read(struct labeller *l, struct device *dev, void *buf, unsigned ioflags,
- lvm_callback_fn_t read_label_callback_fn, void *read_label_callback_context)
+static int _pool_read(struct labeller *l, struct device *dev, void *buf,
+ struct label **label)
{
struct pool_list pl;
- struct label *label;
- int r;
- r = read_pool_label(&pl, l, dev, buf, &label);
-
- if (read_label_callback_fn)
- read_label_callback_fn(!r, 0, read_label_callback_context, label);
-
- return r;
+ return read_pool_label(&pl, l, dev, buf, label);
}
static int _pool_initialise_label(struct labeller *l __attribute__((unused)), struct label *label)
diff --git a/lib/format_text/archive.c b/lib/format_text/archive.c
index 2186de860..72ec40b66 100644
--- a/lib/format_text/archive.c
+++ b/lib/format_text/archive.c
@@ -135,8 +135,8 @@ static struct dm_list *_scan_archive(struct dm_pool *mem,
dm_list_init(results);
- /* Use versionsort to handle numbers beyond 5 digits */
- if ((count = scandir(dir, &dirent, NULL, versionsort)) < 0) {
+ /* Sort fails beyond 5-digit indexes */
+ if ((count = scandir(dir, &dirent, NULL, alphasort)) < 0) {
log_error("Couldn't scan the archive directory (%s).", dir);
return 0;
}
diff --git a/lib/format_text/archiver.c b/lib/format_text/archiver.c
index 2c8e75145..1eb665436 100644
--- a/lib/format_text/archiver.c
+++ b/lib/format_text/archiver.c
@@ -320,7 +320,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
}
dm_list_iterate_items(mda, &tf->metadata_areas_in_use) {
- if (!(vg = mda->ops->vg_read(tf, vg_name, mda, NULL, NULL, 0, 0)))
+ if (!(vg = mda->ops->vg_read(tf, vg_name, mda, NULL, NULL, 0)))
stack;
break;
}
diff --git a/lib/format_text/export.c b/lib/format_text/export.c
index 08e1cda43..e5352376d 100644
--- a/lib/format_text/export.c
+++ b/lib/format_text/export.c
@@ -23,7 +23,6 @@
#include "lvm-version.h"
#include "toolcontext.h"
#include "config-util.h"
-#include "layout.h"
#include <stdarg.h>
#include <time.h>
@@ -124,12 +123,11 @@ static int _extend_buffer(struct formatter *f)
log_debug_metadata("Doubling metadata output buffer to " FMTu32,
f->data.buf.size * 2);
- if (!(newbuf = dm_malloc_aligned(f->data.buf.size * 2, 0)))
- return_0;
-
- memcpy(newbuf, f->data.buf.start, f->data.buf.size);
- free(f->data.buf.start);
-
+ if (!(newbuf = dm_realloc(f->data.buf.start,
+ f->data.buf.size * 2))) {
+ log_error("Buffer reallocation failed.");
+ return 0;
+ }
f->data.buf.start = newbuf;
f->data.buf.size *= 2;
@@ -1066,7 +1064,7 @@ size_t text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
return_0;
f->data.buf.size = 65536; /* Initial metadata limit */
- if (!(f->data.buf.start = dm_malloc_aligned(f->data.buf.size, 0))) {
+ if (!(f->data.buf.start = dm_malloc(f->data.buf.size))) {
log_error("text_export buffer allocation failed");
goto out;
}
@@ -1081,12 +1079,7 @@ size_t text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
goto_out;
}
- f->data.buf.used += 1; /* Terminating NUL */
-
- /* Zero fill up to next alignment boundary */
- memset(f->data.buf.start + f->data.buf.used, 0, MDA_ALIGNMENT - f->data.buf.used % MDA_ALIGNMENT);
-
- r = f->data.buf.used;
+ r = f->data.buf.used + 1;
*buf = f->data.buf.start;
out:
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 2e7e2b85e..be9a8b906 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -37,12 +37,6 @@
#include <dirent.h>
#include <ctype.h>
-/*
- * Round up offset within buffer to next location that is an exact multiple of alignment.
- * (We shouldn't assume the start of the metadata area was aligned the same way when it was created.)
- */
-#define ALIGN_ABSOLUTE(offset, buffer_start, alignment) ((offset) + (alignment) - UINT64_C(1) - ((buffer_start) + (offset) + (alignment) - UINT64_C(1)) % (alignment))
-
static struct format_instance *_text_create_text_instance(const struct format_type *fmt,
const struct format_instance_ctx *fic);
@@ -182,10 +176,9 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
uint64_t offset2;
size_t size;
size_t size2;
- const char *buf = NULL;
+ char *buf=NULL;
struct device_area *area;
struct mda_context *mdac;
- unsigned circular = 0;
int r=0;
mdac = (struct mda_context *) mda->metadata_locn;
@@ -197,7 +190,7 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
if (!dev_open_readonly(area->dev))
return_0;
- if (!(mdah = raw_read_mda_header(fmt->cmd->mem, area, mda_is_primary(mda))))
+ if (!(mdah = raw_read_mda_header(fmt, area, mda_is_primary(mda))))
goto_out;
rlocn = mdah->raw_locns;
@@ -226,7 +219,6 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
prev_sector);
if (prev_sector > prev_sector2)
goto_out;
-
/*
* FIXME: for some reason, the whole metadata region from
* area->start to area->start+area->size is not used.
@@ -235,13 +227,10 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
* "dm_config_maybe_section" returning true when there's no valid
* metadata in a sector (sectors with all nulls).
*/
+ if (!(buf = dm_malloc(size + size2)))
+ goto_out;
- circular = size2 ? 1 : 0;
-
- if (circular) {
- if (!(buf = dev_read_circular(area->dev, offset, size, offset2, size2, MDA_CONTENT_REASON(mda_is_primary(mda)))))
- goto_out;
- } else if (!(buf = dev_read(area->dev, offset, size, MDA_CONTENT_REASON(mda_is_primary(mda)))))
+ if (!dev_read_circular(area->dev, offset, size, offset2, size2, MDA_CONTENT_REASON(mda_is_primary(mda)), buf))
goto_out;
/*
@@ -272,20 +261,20 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
size += SECTOR_SIZE;
}
}
- if (circular)
- dm_free((void *)buf);
+ dm_free(buf);
buf = NULL;
}
r = 1;
out:
- if (circular)
- dm_free((void *)buf);
+ dm_free(buf);
if (!dev_close(area->dev))
stack;
return r;
}
+
+
static int _text_lv_setup(struct format_instance *fid __attribute__((unused)),
struct logical_volume *lv)
{
@@ -326,27 +315,19 @@ static void _xlate_mdah(struct mda_header *mdah)
}
}
-struct process_raw_mda_header_params {
- struct mda_header *mdah;
- struct device_area dev_area;
- lvm_callback_fn_t mdah_callback_fn;
- void *mdah_callback_context;
- int ret;
-};
-
-static void _process_raw_mda_header(int failed, unsigned ioflags, void *context, const void *data)
+static int _raw_read_mda_header(struct mda_header *mdah, struct device_area *dev_area, int primary_mda)
{
- struct process_raw_mda_header_params *prmp = context;
- struct mda_header *mdah = prmp->mdah;
- struct device_area *dev_area = &prmp->dev_area;
-
- if (!dev_close(dev_area->dev))
- goto_bad;
+ if (!dev_open_readonly(dev_area->dev))
+ return_0;
- if (failed)
- goto_bad;
+ if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, MDA_HEADER_REASON(primary_mda), mdah)) {
+ if (!dev_close(dev_area->dev))
+ stack;
+ return_0;
+ }
- memcpy(mdah, data, MDA_HEADER_SIZE);
+ if (!dev_close(dev_area->dev))
+ return_0;
if (mdah->checksum_xl != xlate32(calc_crc(INITIAL_CRC, (uint8_t *)mdah->magic,
MDA_HEADER_SIZE -
@@ -354,7 +335,7 @@ static void _process_raw_mda_header(int failed, unsigned ioflags, void *context,
log_error("Incorrect metadata area header checksum on %s"
" at offset " FMTu64, dev_name(dev_area->dev),
dev_area->start);
- goto bad;
+ return 0;
}
_xlate_mdah(mdah);
@@ -363,83 +344,42 @@ static void _process_raw_mda_header(int failed, unsigned ioflags, void *context,
log_error("Wrong magic number in metadata area header on %s"
" at offset " FMTu64, dev_name(dev_area->dev),
dev_area->start);
- goto bad;
+ return 0;
}
if (mdah->version != FMTT_VERSION) {
log_error("Incompatible metadata area header version: %d on %s"
" at offset " FMTu64, mdah->version,
dev_name(dev_area->dev), dev_area->start);
- goto bad;
+ return 0;
}
if (mdah->start != dev_area->start) {
log_error("Incorrect start sector in metadata area header: "
FMTu64 " on %s at offset " FMTu64, mdah->start,
dev_name(dev_area->dev), dev_area->start);
- goto bad;
+ return 0;
}
- goto out;
-
-bad:
- prmp->ret = 0;
-out:
- if (prmp->mdah_callback_fn)
- prmp->mdah_callback_fn(!prmp->ret, ioflags, prmp->mdah_callback_context, mdah);
+ return 1;
}
-static struct mda_header *_raw_read_mda_header(struct dm_pool *mem, struct device_area *dev_area, int primary_mda,
- unsigned ioflags, lvm_callback_fn_t mdah_callback_fn, void *mdah_callback_context)
+struct mda_header *raw_read_mda_header(const struct format_type *fmt,
+ struct device_area *dev_area, int primary_mda)
{
struct mda_header *mdah;
- struct process_raw_mda_header_params *prmp;
- if (!(mdah = dm_pool_alloc(mem, MDA_HEADER_SIZE))) {
+ if (!(mdah = dm_pool_alloc(fmt->cmd->mem, MDA_HEADER_SIZE))) {
log_error("struct mda_header allocation failed");
return NULL;
}
- if (!(prmp = dm_pool_zalloc(mem, sizeof (*prmp)))) {
- log_error("struct process_raw_mda_header_params allocation failed");
- dm_pool_free(mem, mdah);
+ if (!_raw_read_mda_header(mdah, dev_area, primary_mda)) {
+ dm_pool_free(fmt->cmd->mem, mdah);
return NULL;
}
- if (!dev_open_readonly(dev_area->dev)) {
- dm_pool_free(mem, mdah);
- return_NULL;
- }
-
- prmp->mdah = mdah;
- prmp->dev_area = *dev_area;
- prmp->mdah_callback_fn = mdah_callback_fn;
- prmp->mdah_callback_context = mdah_callback_context;
- prmp->ret = 1;
-
- dev_read_callback(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, MDA_HEADER_REASON(primary_mda),
- ioflags, _process_raw_mda_header, prmp);
- if (mdah_callback_fn)
- return mdah;
-
- if (!prmp->ret)
- return_NULL;
- else
- return mdah;
-}
-
-struct mda_header *raw_read_mda_header(struct dm_pool *mem, struct device_area *dev_area, int primary_mda)
-{
- return _raw_read_mda_header(mem, dev_area, primary_mda, 0, NULL, NULL);
-}
-
-int raw_read_mda_header_callback(struct dm_pool *mem, struct device_area *dev_area, int primary_mda,
- unsigned ioflags, lvm_callback_fn_t mdah_callback_fn, void *mdah_callback_context)
-{
- if (!_raw_read_mda_header(mem, dev_area, primary_mda, ioflags, mdah_callback_fn, mdah_callback_context))
- return_0;
-
- return 1;
+ return mdah;
}
static int _raw_write_mda_header(const struct format_type *fmt,
@@ -467,13 +407,13 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
int *precommitted)
{
size_t len;
+ char vgnamebuf[NAME_LEN + 2] __attribute__((aligned(8)));
struct raw_locn *rlocn, *rlocn_precommitted;
struct lvmcache_info *info;
struct lvmcache_vgsummary vgsummary_orphan = {
.vgname = FMT_TEXT_ORPHAN_VG_NAME,
};
int rlocn_was_ignored;
- const char *buf;
memcpy(&vgsummary_orphan.vgid, FMT_TEXT_ORPHAN_VG_NAME, sizeof(FMT_TEXT_ORPHAN_VG_NAME));
@@ -508,12 +448,12 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
/* FIXME Loop through rlocns two-at-a-time. List null-terminated. */
/* FIXME Ignore if checksum incorrect!!! */
- if (!(buf = dev_read(dev_area->dev, dev_area->start + rlocn->offset,
- NAME_LEN + 2, MDA_CONTENT_REASON(primary_mda))))
+ if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
+ sizeof(vgnamebuf), MDA_CONTENT_REASON(primary_mda), vgnamebuf))
goto_bad;
- if (!strncmp(buf, vgname, len = strlen(vgname)) &&
- (isspace(*(buf + len)) || *(buf + len) == '{'))
+ if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) &&
+ (isspace(vgnamebuf[len]) || vgnamebuf[len] == '{'))
return rlocn;
log_debug_metadata("Volume group name found in %smetadata on %s at " FMTu64 " does "
@@ -530,46 +470,25 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
}
/*
- * Find first aligned offset after end of existing metadata.
- * Based on the alignment provided, this is the exact offset to use for the new metadata.
- * The caller is responsible for validating the result.
+ * Determine offset for uncommitted metadata
*/
static uint64_t _next_rlocn_offset(struct raw_locn *rlocn, struct mda_header *mdah, uint64_t mdac_area_start, uint64_t alignment)
{
- uint64_t old_end, new_start_offset;
- int old_wrapped = 0; /* Does the old metadata wrap around? */
+ uint64_t new_start_offset;
if (!rlocn)
/* Find an empty slot */
- /* FIXME Assumes only one VG per mdah for now */
- return ALIGN_ABSOLUTE(MDA_HEADER_SIZE, mdac_area_start, alignment);
+ /* FIXME Assume only one VG per mdah for now */
+ return alignment;
- /* First find the end of the old metadata */
- old_end = rlocn->offset + rlocn->size;
-
- if (old_end > mdah->size) {
- old_wrapped = 1;
- old_end -= (mdah->size - MDA_HEADER_SIZE);
- }
+ /* Calculate new start position within buffer rounded up to absolute alignment */
+ new_start_offset = rlocn->offset + rlocn->size +
+ (alignment - (mdac_area_start + rlocn->offset + rlocn->size) % alignment);
- /* Calculate new start position relative to start of buffer rounded up to absolute alignment */
- new_start_offset = ALIGN_ABSOLUTE(old_end, mdac_area_start, alignment);
-
- /* If new location is beyond the end of the buffer, return to start of circular buffer and realign */
- if (new_start_offset >= mdah->size) {
- /* If the start of the buffer is occupied, move past it */
- if (old_wrapped || rlocn->offset == MDA_HEADER_SIZE)
- new_start_offset = old_end;
- else
- new_start_offset = MDA_HEADER_SIZE;
-
- new_start_offset = ALIGN_ABSOLUTE(new_start_offset, mdac_area_start, alignment);
- }
+ /* If new location is beyond the end of the buffer, wrap around back to start of circular buffer */
+ if (new_start_offset > mdah->size - MDA_HEADER_SIZE)
+ new_start_offset -= (mdah->size - MDA_HEADER_SIZE);
- /*
- * Note that we don't check here that this location isn't inside the existing metadata.
- * If it is, then it means this value of alignment cannot be used.
- */
return new_start_offset;
}
@@ -583,7 +502,7 @@ static int _raw_holds_vgname(struct format_instance *fid,
if (!dev_open_readonly(dev_area->dev))
return_0;
- if (!(mdah = raw_read_mda_header(fid->fmt->cmd->mem, dev_area, 0)))
+ if (!(mdah = raw_read_mda_header(fid->fmt, dev_area, 0)))
return_0;
if (_find_vg_rlocn(dev_area, mdah, 0, vgname, &noprecommit))
@@ -600,7 +519,7 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
struct device_area *area,
struct cached_vg_fmtdata **vg_fmtdata,
unsigned *use_previous_vg,
- int precommitted, unsigned ioflags,
+ int precommitted,
int single_device, int primary_mda)
{
struct volume_group *vg = NULL;
@@ -610,7 +529,7 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
char *desc;
uint32_t wrap = 0;
- if (!(mdah = raw_read_mda_header(fid->fmt->cmd->mem, area, primary_mda)))
+ if (!(mdah = raw_read_mda_header(fid->fmt, area, primary_mda)))
goto_out;
if (!(rlocn = _find_vg_rlocn(area, mdah, primary_mda, vgname, &precommitted))) {
@@ -633,7 +552,7 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
(off_t) (area->start + rlocn->offset),
(uint32_t) (rlocn->size - wrap),
(off_t) (area->start + MDA_HEADER_SIZE),
- wrap, calc_crc, rlocn->checksum, ioflags, &when,
+ wrap, calc_crc, rlocn->checksum, &when,
&desc)) && (!use_previous_vg || !*use_previous_vg))
goto_out;
@@ -660,7 +579,7 @@ static struct volume_group *_vg_read_raw(struct format_instance *fid,
struct metadata_area *mda,
struct cached_vg_fmtdata **vg_fmtdata,
unsigned *use_previous_vg,
- int single_device, unsigned ioflags)
+ int single_device)
{
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
struct volume_group *vg;
@@ -668,7 +587,7 @@ static struct volume_group *_vg_read_raw(struct format_instance *fid,
if (!dev_open_readonly(mdac->area.dev))
return_NULL;
- vg = _vg_read_raw_area(fid, vgname, &mdac->area, vg_fmtdata, use_previous_vg, 0, ioflags, single_device, mda_is_primary(mda));
+ vg = _vg_read_raw_area(fid, vgname, &mdac->area, vg_fmtdata, use_previous_vg, 0, single_device, mda_is_primary(mda));
if (!dev_close(mdac->area.dev))
stack;
@@ -680,7 +599,7 @@ static struct volume_group *_vg_read_precommit_raw(struct format_instance *fid,
const char *vgname,
struct metadata_area *mda,
struct cached_vg_fmtdata **vg_fmtdata,
- unsigned *use_previous_vg, unsigned ioflags)
+ unsigned *use_previous_vg)
{
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
struct volume_group *vg;
@@ -688,7 +607,7 @@ static struct volume_group *_vg_read_precommit_raw(struct format_instance *fid,
if (!dev_open_readonly(mdac->area.dev))
return_NULL;
- vg = _vg_read_raw_area(fid, vgname, &mdac->area, vg_fmtdata, use_previous_vg, 1, ioflags, 0, mda_is_primary(mda));
+ vg = _vg_read_raw_area(fid, vgname, &mdac->area, vg_fmtdata, use_previous_vg, 1, 0, mda_is_primary(mda));
if (!dev_close(mdac->area.dev))
stack;
@@ -696,59 +615,6 @@ static struct volume_group *_vg_read_precommit_raw(struct format_instance *fid,
return vg;
}
-static int _metadata_fits_into_buffer(struct mda_context *mdac, struct mda_header *mdah,
- struct raw_locn *rlocn, uint64_t new_wrap)
-{
- uint64_t old_wrap = 0; /* Amount of wrap around in existing metadata */
- uint64_t old_end = 0; /* The (byte after the) end of the existing metadata */
- uint64_t new_end; /* The (byte after the) end of the new metadata */
- uint64_t old_start = 0; /* The start of the existing metadata */
- uint64_t new_start = mdac->rlocn.offset; /* The proposed start of the new metadata */
-
- /*
- * If the (aligned) start of the new metadata is already beyond the end
- * of the buffer this means it didn't fit with the given alignment.
- * (The caller has already tried to wrap it back to the start
- * of the buffer but the alignment pushed it back outside.)
- */
- if (new_start >= mdah->size)
- return_0;
-
- /* Does the total amount of metadata, old and new, fit inside the buffer? */
- if (MDA_HEADER_SIZE + (rlocn ? rlocn->size : 0) + mdac->rlocn.size >= mdah->size)
- return_0;
-
- /* If there's existing metadata, set old_start, old_end and old_wrap. */
- if (rlocn) {
- old_start = rlocn->offset;
- old_end = old_start + rlocn->size;
-
- /* Does the existing metadata wrap around the end of the buffer? */
- if (old_end > mdah->size)
- old_wrap = old_end - mdah->size;
- }
-
- new_end = new_wrap ? new_wrap + MDA_HEADER_SIZE : new_start + mdac->rlocn.size;
-
- /* If both wrap around, there's necessarily overlap */
- if (new_wrap && old_wrap)
- return_0;
-
- /* If there's no existing metadata, we're OK */
- if (!rlocn)
- return 1;
-
- /* If either wraps around, there's overlap if the new end falls beyond the old start */
- if ((new_wrap || old_wrap) && (new_end > old_start))
- return_0;
-
- /* If there's no wrap, check there's no overlap */
- if (!new_wrap && !old_wrap && (old_end > new_start) && (old_start < new_end))
- return_0;
-
- return 1;
-}
-
static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
struct metadata_area *mda)
{
@@ -758,12 +624,10 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
struct mda_header *mdah;
struct pv_list *pvl;
int r = 0;
- uint64_t new_wrap = 0; /* Number of bytes of new metadata that wrap around to start of buffer */
- uint64_t alignment = MDA_ALIGNMENT;
+ uint64_t new_wrap = 0, old_wrap = 0, new_end;
int found = 0;
int noprecommit = 0;
const char *old_vg_name = NULL;
- uint64_t new_size_rounded = 0;
/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
dm_list_iterate_items(pvl, &vg->pvs) {
@@ -778,19 +642,12 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
if (!found)
return 1;
- /*
- * This is paired with the following closes:
- * - at the end of this fn if returning 0
- * - in _vg_commit_raw_rlocn regardless of return code
- * which handles commit (but not pre-commit) and revert.
- */
if (!dev_open(mdac->area.dev))
return_0;
- if (!(mdah = raw_read_mda_header(fid->fmt->cmd->mem, &mdac->area, mda_is_primary(mda))))
+ if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area, mda_is_primary(mda))))
goto_out;
- /* Following space is zero-filled up to the next MDA_ALIGNMENT boundary */
if (!fidtc->raw_metadata_buf &&
!(fidtc->raw_metadata_buf_size =
text_vg_export_raw(vg, "", &fidtc->raw_metadata_buf))) {
@@ -800,64 +657,37 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
rlocn = _find_vg_rlocn(&mdac->area, mdah, mda_is_primary(mda), old_vg_name ? : vg->name, &noprecommit);
+ mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah, mdac->area.start, MDA_ORIGINAL_ALIGNMENT);
mdac->rlocn.size = fidtc->raw_metadata_buf_size;
- /* Find where the new metadata would be written with our preferred alignment */
- mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah, mdac->area.start, alignment);
-
- /* If metadata extends beyond the buffer, return to the start instead of wrapping it */
if (mdac->rlocn.offset + mdac->rlocn.size > mdah->size)
- mdac->rlocn.offset = ALIGN_ABSOLUTE(MDA_HEADER_SIZE, mdac->area.start, alignment);
+ new_wrap = (mdac->rlocn.offset + mdac->rlocn.size) - mdah->size;
- /*
- * If the metadata doesn't fit into the buffer correctly with these
- * settings, fall back to the 512-byte alignment used by the original
- * LVM2 code and allow the metadata to be split into two parts,
- * wrapping around from the end of the circular buffer back to the
- * beginning.
- */
- if (!_metadata_fits_into_buffer(mdac, mdah, rlocn, 0)) {
- alignment = MDA_ORIGINAL_ALIGNMENT;
- mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah, mdac->area.start, alignment);
+ if (rlocn && (rlocn->offset + rlocn->size > mdah->size))
+ old_wrap = (rlocn->offset + rlocn->size) - mdah->size;
- /* Does the new metadata wrap around? */
- if (mdac->rlocn.offset + mdac->rlocn.size > mdah->size)
- new_wrap = (mdac->rlocn.offset + mdac->rlocn.size) - mdah->size;
- else
- new_wrap = 0;
-
- if (!_metadata_fits_into_buffer(mdac, mdah, rlocn, new_wrap)) {
- log_error("VG %s metadata on %s (" FMTu64 " bytes) too large for circular buffer (" FMTu64 " bytes with " FMTu64 " used)",
- vg->name, dev_name(mdac->area.dev), mdac->rlocn.size, mdah->size - MDA_HEADER_SIZE, rlocn ? rlocn->size : 0);
- goto out;
- }
+ new_end = new_wrap ? new_wrap + MDA_HEADER_SIZE :
+ mdac->rlocn.offset + mdac->rlocn.size;
- new_size_rounded = mdac->rlocn.size;
- } else {
- /* Round up to a multiple of the new alignment */
- if (mdac->rlocn.offset + new_size_rounded < mdah->size)
- new_size_rounded = (mdac->rlocn.size | (alignment - 1)) + 1;
- else
- new_size_rounded = mdac->rlocn.size;
+ if ((new_wrap && old_wrap) ||
+ (rlocn && (new_wrap || old_wrap) && (new_end > rlocn->offset)) ||
+ (MDA_HEADER_SIZE + (rlocn ? rlocn->size : 0) + mdac->rlocn.size >= mdah->size)) {
+ log_error("VG %s metadata on %s (" FMTu64 " bytes) too large for circular buffer (" FMTu64 " bytes with " FMTu64 " used)",
+ vg->name, dev_name(mdac->area.dev), mdac->rlocn.size, mdah->size - MDA_HEADER_SIZE, rlocn ? rlocn->size : 0);
+ goto out;
}
- log_debug_metadata("Writing %s metadata to %s at " FMTu64 " len " FMTu64 " (rounded to " FMTu64 ") of " FMTu64 " aligned to " FMTu64,
+ log_debug_metadata("Writing %s metadata to %s at " FMTu64 " len " FMTu64 " of " FMTu64,
vg->name, dev_name(mdac->area.dev), mdac->area.start +
- mdac->rlocn.offset, mdac->rlocn.size - new_wrap, new_size_rounded, mdac->rlocn.size, alignment);
+ mdac->rlocn.offset, mdac->rlocn.size - new_wrap, mdac->rlocn.size);
- if (!new_wrap) {
- /* Write text out, in alignment-sized blocks */
- if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
- (size_t) new_size_rounded, MDA_CONTENT_REASON(mda_is_primary(mda)),
- fidtc->raw_metadata_buf))
- goto_out;
- } else {
- /* Write text out, circularly */
- if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
- (size_t) (mdac->rlocn.size - new_wrap), MDA_CONTENT_REASON(mda_is_primary(mda)),
- fidtc->raw_metadata_buf))
- goto_out;
+ /* Write text out, circularly */
+ if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
+ (size_t) (mdac->rlocn.size - new_wrap), MDA_CONTENT_REASON(mda_is_primary(mda)),
+ fidtc->raw_metadata_buf))
+ goto_out;
+ if (new_wrap) {
log_debug_metadata("Writing wrapped metadata to %s at " FMTu64 " len " FMTu64 " of " FMTu64,
dev_name(mdac->area.dev), mdac->area.start +
MDA_HEADER_SIZE, new_wrap, mdac->rlocn.size);
@@ -919,7 +749,7 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
if (!found)
return 1;
- if (!(mdah = raw_read_mda_header(fid->fmt->cmd->mem, &mdac->area, mda_is_primary(mda))))
+ if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area, mda_is_primary(mda))))
goto_out;
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, mda_is_primary(mda), old_vg_name ? : vg->name, &noprecommit))) {
@@ -957,9 +787,10 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
rlocn->offset = mdac->rlocn.offset;
rlocn->size = mdac->rlocn.size;
rlocn->checksum = mdac->rlocn.checksum;
- log_debug_metadata("%sCommitting %s %smetadata (%u) to %s header at " FMTu64 " (offset " FMTu64 ", size " FMTu64 ")",
- precommit ? "Pre-" : "", vg->name, mda_is_ignored(mda) ? "(ignored) " : "", vg->seqno,
- dev_name(mdac->area.dev), mdac->area.start, mdac->rlocn.offset, mdac->rlocn.size);
+ log_debug_metadata("%sCommitting %s %smetadata (%u) to %s header at "
+ FMTu64, precommit ? "Pre-" : "", vg->name,
+ mda_is_ignored(mda) ? "(ignored) " : "", vg->seqno,
+ dev_name(mdac->area.dev), mdac->area.start);
} else
log_debug_metadata("Wiping pre-committed %s %smetadata from %s "
"header at " FMTu64, vg->name,
@@ -979,7 +810,6 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
out:
if (!precommit) {
- /* This is an paired with the open at the start of _vg_write_raw */
if (!dev_close(mdac->area.dev))
stack;
@@ -1039,7 +869,7 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
if (!dev_open(mdac->area.dev))
return_0;
- if (!(mdah = raw_read_mda_header(fid->fmt->cmd->mem, &mdac->area, mda_is_primary(mda))))
+ if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area, mda_is_primary(mda))))
goto_out;
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, mda_is_primary(mda), vg->name, &noprecommit))) {
@@ -1102,8 +932,7 @@ static struct volume_group *_vg_read_file(struct format_instance *fid,
struct metadata_area *mda,
struct cached_vg_fmtdata **vg_fmtdata,
unsigned *use_previous_vg __attribute__((unused)),
- int single_device __attribute__((unused)),
- unsigned ioflags __attribute__((unused)))
+ int single_device __attribute__((unused)))
{
struct text_context *tc = (struct text_context *) mda->metadata_locn;
@@ -1114,8 +943,7 @@ static struct volume_group *_vg_read_precommit_file(struct format_instance *fid,
const char *vgname,
struct metadata_area *mda,
struct cached_vg_fmtdata **vg_fmtdata,
- unsigned *use_previous_vg __attribute__((unused)),
- unsigned ioflags __attribute__((unused)))
+ unsigned *use_previous_vg __attribute__((unused)))
{
struct text_context *tc = (struct text_context *) mda->metadata_locn;
struct volume_group *vg;
@@ -1347,83 +1175,41 @@ static int _scan_file(const struct format_type *fmt, const char *vgname)
return 1;
}
-struct vgname_from_mda_params{
- const struct format_type *fmt;
- const struct mda_header *mdah;
- struct device_area *dev_area;
- int primary_mda;
- struct lvmcache_vgsummary *vgsummary;
- uint64_t *mda_free_sectors;
- lvm_callback_fn_t update_vgsummary_fn;
- void *update_vgsummary_context;
- uint32_t wrap;
- unsigned used_cached_metadata;
- int ret;
-};
-
-static void _vgname_from_mda_process(int failed, unsigned ioflags, void *context, const void *data)
+int vgname_from_mda(const struct format_type *fmt,
+ struct mda_header *mdah, int primary_mda, struct device_area *dev_area,
+ struct lvmcache_vgsummary *vgsummary, uint64_t *mda_free_sectors)
{
- struct vgname_from_mda_params *vfmp = context;
- const struct mda_header *mdah = vfmp->mdah;
- struct device_area *dev_area = vfmp->dev_area;
- struct lvmcache_vgsummary *vgsummary = vfmp->vgsummary;
- uint64_t *mda_free_sectors = vfmp->mda_free_sectors;
- const struct raw_locn *rlocn = mdah->raw_locns;
+ struct raw_locn *rlocn;
+ uint32_t wrap = 0;
+ unsigned int len = 0;
+ char buf[NAME_LEN + 1] __attribute__((aligned(8)));
uint64_t buffer_size, current_usage;
+ unsigned used_cached_metadata = 0;
- if (failed) {
- vfmp->ret = 0;
- goto_out;
- }
-
- /* Ignore this entry if the characters aren't permissible */
- if (!validate_name(vgsummary->vgname)) {
- vfmp->ret = 0;
- goto_out;
- }
-
- log_debug_metadata("%s: %s metadata at " FMTu64 " size " FMTu64 " with wrap " FMTu32
- " (in area at " FMTu64 " size " FMTu64
- ") for %s (" FMTVGID ")",
- dev_name(dev_area->dev),
- vfmp->used_cached_metadata ? "Using cached" : "Found",
- dev_area->start + rlocn->offset,
- rlocn->size, vfmp->wrap, dev_area->start, dev_area->size, vgsummary->vgname,
- (char *)&vgsummary->vgid);
-
- if (mda_free_sectors) {
- current_usage = ALIGN_ABSOLUTE(rlocn->size, dev_area->start + rlocn->offset, MDA_ALIGNMENT);
-
- buffer_size = mdah->size - MDA_HEADER_SIZE;
+ if (mda_free_sectors)
+ *mda_free_sectors = ((dev_area->size - MDA_HEADER_SIZE) / 2) >> SECTOR_SHIFT;
- if (current_usage * 2 >= buffer_size)
- *mda_free_sectors = UINT64_C(0);
- else
- *mda_free_sectors = ((buffer_size - 2 * current_usage) / 2) >> SECTOR_SHIFT;
+ if (!mdah) {
+ log_error(INTERNAL_ERROR "vgname_from_mda called with NULL pointer for mda_header");
+ return 0;
}
-out:
- vfmp->update_vgsummary_fn(!vfmp->ret, ioflags, vfmp->update_vgsummary_context, vfmp->vgsummary);
-}
-
-static void _vgname_from_mda_validate(int failed, unsigned ioflags, void *context, const void *data)
-{
- struct vgname_from_mda_params *vfmp = context;
- const char *buffer = data;
- const struct format_type *fmt = vfmp->fmt;
- const struct mda_header *mdah = vfmp->mdah;
- struct device_area *dev_area = vfmp->dev_area;
- struct lvmcache_vgsummary *vgsummary = vfmp->vgsummary;
- const struct raw_locn *rlocn = mdah->raw_locns;
- unsigned len = 0;
- char buf[NAME_LEN + 1] __attribute__((aligned(8)));
+ /* FIXME Cope with returning a list */
+ rlocn = mdah->raw_locns;
- if (failed) {
- vfmp->ret = 0;
- goto_out;
+ /*
+ * If no valid offset, do not try to search for vgname
+ */
+ if (!rlocn->offset) {
+ log_debug("%s: found metadata with offset 0.",
+ dev_name(dev_area->dev));
+ return 0;
}
- memcpy(buf, buffer, NAME_LEN);
+ /* Do quick check for a vgname */
+ if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
+ NAME_LEN, MDA_CONTENT_REASON(primary_mda), buf))
+ return_0;
while (buf[len] && !isspace(buf[len]) && buf[len] != '{' &&
len < (NAME_LEN - 1))
@@ -1432,20 +1218,17 @@ static void _vgname_from_mda_validate(int failed, unsigned ioflags, void *contex
buf[len] = '\0';
/* Ignore this entry if the characters aren't permissible */
- if (!validate_name(buf)) {
- vfmp->ret = 0;
- goto_out;
- }
+ if (!validate_name(buf))
+ return_0;
/* We found a VG - now check the metadata */
if (rlocn->offset + rlocn->size > mdah->size)
- vfmp->wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size);
+ wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size);
- if (vfmp->wrap > rlocn->offset) {
+ if (wrap > rlocn->offset) {
log_error("%s: metadata (" FMTu64 " bytes) too large for circular buffer (" FMTu64 " bytes)",
dev_name(dev_area->dev), rlocn->size, mdah->size - MDA_HEADER_SIZE);
- vfmp->ret = 0;
- goto out;
+ return 0;
}
/* Did we see this metadata before? */
@@ -1453,75 +1236,42 @@ static void _vgname_from_mda_validate(int failed, unsigned ioflags, void *contex
vgsummary->mda_size = rlocn->size;
if (lvmcache_lookup_mda(vgsummary))
- vfmp->used_cached_metadata = 1;
+ used_cached_metadata = 1;
/* FIXME 64-bit */
- if (!text_vgsummary_import(fmt, dev_area->dev, MDA_CONTENT_REASON(vfmp->primary_mda),
+ if (!text_vgsummary_import(fmt, dev_area->dev, MDA_CONTENT_REASON(primary_mda),
(off_t) (dev_area->start + rlocn->offset),
- (uint32_t) (rlocn->size - vfmp->wrap),
+ (uint32_t) (rlocn->size - wrap),
(off_t) (dev_area->start + MDA_HEADER_SIZE),
- vfmp->wrap, calc_crc, vgsummary->vgname ? 1 : 0, ioflags,
- vgsummary, _vgname_from_mda_process, vfmp)) {
- vfmp->ret = 0;
- goto_out;
- }
-
-out:
- if (!vfmp->ret && vfmp->update_vgsummary_fn)
- vfmp->update_vgsummary_fn(1, ioflags, vfmp->update_vgsummary_context, vfmp->vgsummary);
-}
-
-int vgname_from_mda(const struct format_type *fmt,
- const struct mda_header *mdah, int primary_mda, struct device_area *dev_area,
- struct lvmcache_vgsummary *vgsummary, uint64_t *mda_free_sectors, unsigned ioflags,
- lvm_callback_fn_t update_vgsummary_fn, void *update_vgsummary_context)
-{
- const struct raw_locn *rlocn;
- struct vgname_from_mda_params *vfmp;
-
- if (mda_free_sectors)
- *mda_free_sectors = ((dev_area->size - MDA_HEADER_SIZE) / 2) >> SECTOR_SHIFT;
+ wrap, calc_crc, vgsummary->vgname ? 1 : 0,
+ vgsummary))
+ return_0;
- if (!mdah) {
- log_error(INTERNAL_ERROR "vgname_from_mda called with NULL pointer for mda_header");
- return 0;
- }
+ /* Ignore this entry if the characters aren't permissible */
+ if (!validate_name(vgsummary->vgname))
+ return_0;
- /* FIXME Cope with returning a list */
- rlocn = mdah->raw_locns;
+ log_debug_metadata("%s: %s metadata at " FMTu64 " size " FMTu64
+ " (in area at " FMTu64 " size " FMTu64
+ ") for %s (" FMTVGID ")",
+ dev_name(dev_area->dev),
+ used_cached_metadata ? "Using cached" : "Found",
+ dev_area->start + rlocn->offset,
+ rlocn->size, dev_area->start, dev_area->size, vgsummary->vgname,
+ (char *)&vgsummary->vgid);
- /*
- * If no valid offset, do not try to search for vgname
- */
- if (!rlocn->offset) {
- log_debug("%s: found metadata with offset 0.",
- dev_name(dev_area->dev));
- return 0;
- }
+ if (mda_free_sectors) {
+ current_usage = (rlocn->size + SECTOR_SIZE - UINT64_C(1)) -
+ (rlocn->size + SECTOR_SIZE - UINT64_C(1)) % SECTOR_SIZE;
+ buffer_size = mdah->size - MDA_HEADER_SIZE;
- if (!(vfmp = dm_pool_zalloc(fmt->cmd->mem, sizeof(*vfmp)))) {
- log_error("vgname_from_mda_params allocation failed");
- return 0;
+ if (current_usage * 2 >= buffer_size)
+ *mda_free_sectors = UINT64_C(0);
+ else
+ *mda_free_sectors = ((buffer_size - 2 * current_usage) / 2) >> SECTOR_SHIFT;
}
- vfmp->fmt = fmt;
- vfmp->mdah = mdah;
- vfmp->dev_area = dev_area;
- vfmp->vgsummary = vgsummary;
- vfmp->primary_mda = primary_mda;
- vfmp->mda_free_sectors = mda_free_sectors;
- vfmp->update_vgsummary_fn = update_vgsummary_fn;
- vfmp->update_vgsummary_context = update_vgsummary_context;
- vfmp->ret = 1;
-
- /* Do quick check for a vgname */
- /* We cannot read the full metadata here because the name has to be validated before we use the size field */
- dev_read_callback(dev_area->dev, dev_area->start + rlocn->offset, NAME_LEN, MDA_CONTENT_REASON(primary_mda),
- ioflags, _vgname_from_mda_validate, vfmp);
- if (update_vgsummary_fn)
- return 1;
- else
- return vfmp->ret;
+ return 1;
}
static int _scan_raw(const struct format_type *fmt, const char *vgname __attribute__((unused)))
@@ -1546,14 +1296,14 @@ static int _scan_raw(const struct format_type *fmt, const char *vgname __attribu
continue;
}
- if (!(mdah = raw_read_mda_header(fmt->cmd->mem, &rl->dev_area, 0))) {
+ if (!(mdah = raw_read_mda_header(fmt, &rl->dev_area, 0))) {
stack;
goto close_dev;
}
/* TODO: caching as in vgname_from_mda() (trigger this code?) */
- if (vgname_from_mda(fmt, mdah, 0, &rl->dev_area, &vgsummary, NULL, 0, NULL, NULL)) {
- vg = _vg_read_raw_area(&fid, vgsummary.vgname, &rl->dev_area, NULL, NULL, 0, 0, 0, 0);
+ if (vgname_from_mda(fmt, mdah, 0, &rl->dev_area, &vgsummary, NULL)) {
+ vg = _vg_read_raw_area(&fid, vgsummary.vgname, &rl->dev_area, NULL, NULL, 0, 0, 0);
if (vg)
lvmcache_update_vg(vg, 0);
}
@@ -2024,8 +1774,9 @@ static int _mda_export_text_raw(struct metadata_area *mda,
struct dm_config_node *parent)
{
struct mda_context *mdc = (struct mda_context *) mda->metadata_locn;
+ char mdah[MDA_HEADER_SIZE]; /* temporary */
- if (!mdc || !_raw_read_mda_header(cft->mem, &mdc->area, mda_is_primary(mda), 0, NULL, NULL))
+ if (!mdc || !_raw_read_mda_header((struct mda_header *)mdah, &mdc->area, mda_is_primary(mda)))
return 1; /* pretend the MDA does not exist */
return config_make_nodes(cft, parent, NULL,
diff --git a/lib/format_text/import-export.h b/lib/format_text/import-export.h
index 2c329d076..894d88141 100644
--- a/lib/format_text/import-export.h
+++ b/lib/format_text/import-export.h
@@ -80,7 +80,7 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
off_t offset, uint32_t size,
off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn,
- uint32_t checksum, unsigned ioflags,
+ uint32_t checksum,
time_t *when, char **desc);
int text_vgsummary_import(const struct format_type *fmt,
@@ -88,9 +88,7 @@ int text_vgsummary_import(const struct format_type *fmt,
off_t offset, uint32_t size,
off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn,
- int checksum_only, unsigned ioflags,
- struct lvmcache_vgsummary *vgsummary,
- lvm_callback_fn_t process_vgsummary_fn,
- void *process_vgsummary_context);
+ int checksum_only,
+ struct lvmcache_vgsummary *vgsummary);
#endif
diff --git a/lib/format_text/import.c b/lib/format_text/import.c
index 0138ddd8b..da4cefdb8 100644
--- a/lib/format_text/import.c
+++ b/lib/format_text/import.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -16,7 +16,6 @@
#include "lib.h"
#include "metadata.h"
#include "import-export.h"
-#include "toolcontext.h"
/* FIXME Use tidier inclusion method */
static struct text_vg_version_ops *(_text_vsn_list[2]);
@@ -33,55 +32,6 @@ static void _init_text_import(void)
_text_import_initialised = 1;
}
-struct import_vgsummary_params {
- const struct format_type *fmt;
- struct dm_config_tree *cft;
- int checksum_only;
- struct lvmcache_vgsummary *vgsummary;
- lvm_callback_fn_t process_vgsummary_fn;
- void *process_vgsummary_context;
- int ret;
-};
-
-static void _import_vgsummary(int failed, unsigned ioflags, void *context, const void *data)
-{
- struct import_vgsummary_params *ivsp = context;
- struct text_vg_version_ops **vsn;
-
- if (failed) {
- ivsp->ret = 0;
- goto_out;
- }
-
- if (ivsp->checksum_only)
- /* Checksum matches already-cached content - no need to reparse. */
- goto out;
-
- /*
- * Find a set of version functions that can read this file
- */
- for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
- if (!(*vsn)->check_version(ivsp->cft))
- continue;
-
- if (!(*vsn)->read_vgsummary(ivsp->fmt, ivsp->cft, ivsp->vgsummary)) {
- ivsp->ret = 0;
- goto_out;
- }
-
- goto out;
- }
-
- /* Nothing found */
- ivsp->ret = 0;
-
-out:
- config_destroy(ivsp->cft);
-
- if (ivsp->process_vgsummary_fn)
- ivsp->process_vgsummary_fn(!ivsp->ret, ioflags, ivsp->process_vgsummary_context, NULL);
-}
-
/*
* Find out vgname on a given device.
*/
@@ -90,76 +40,30 @@ int text_vgsummary_import(const struct format_type *fmt,
off_t offset, uint32_t size,
off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn,
- int checksum_only, unsigned ioflags,
- struct lvmcache_vgsummary *vgsummary,
- lvm_callback_fn_t process_vgsummary_fn,
- void *process_vgsummary_context)
+ int checksum_only,
+ struct lvmcache_vgsummary *vgsummary)
{
- struct import_vgsummary_params *ivsp;
+ struct dm_config_tree *cft;
+ struct text_vg_version_ops **vsn;
+ int r = 0;
_init_text_import();
- if (!(ivsp = dm_pool_zalloc(fmt->cmd->mem, sizeof(*ivsp)))) {
- log_error("Failed to allocate import_vgsummary_params struct.");
- return 0;
- }
-
- if (!(ivsp->cft = config_open(CONFIG_FILE_SPECIAL, NULL, 0)))
+ if (!(cft = config_open(CONFIG_FILE_SPECIAL, NULL, 0)))
return_0;
- ivsp->fmt = fmt;
- ivsp->checksum_only = checksum_only;
- ivsp->vgsummary = vgsummary;
- ivsp->process_vgsummary_fn = process_vgsummary_fn;
- ivsp->process_vgsummary_context = process_vgsummary_context;
- ivsp->ret = 1;
-
- if (!dev) {
- if (!config_file_read(fmt->cmd->mem, ivsp->cft)) {
- log_error("Couldn't read volume group metadata.");
- ivsp->ret = 0;
- }
- _import_vgsummary(!ivsp->ret, ioflags, ivsp, NULL);
- } else if (!config_file_read_fd(fmt->cmd->mem, ivsp->cft, dev, reason, offset, size,
- offset2, size2, checksum_fn,
- vgsummary->mda_checksum,
- checksum_only, 1, ioflags, &_import_vgsummary, ivsp)) {
+ if ((!dev && !config_file_read(cft)) ||
+ (dev && !config_file_read_fd(cft, dev, reason, offset, size,
+ offset2, size2, checksum_fn,
+ vgsummary->mda_checksum,
+ checksum_only, 1))) {
log_error("Couldn't read volume group metadata.");
- return 0;
+ goto out;
}
- return ivsp->ret;
-}
-
-struct cached_vg_fmtdata {
- uint32_t cached_mda_checksum;
- size_t cached_mda_size;
-};
-
-struct import_vg_params {
- struct format_instance *fid;
- struct dm_config_tree *cft;
- int single_device;
- int skip_parse;
- unsigned *use_previous_vg;
- struct volume_group *vg;
- uint32_t checksum;
- uint32_t total_size;
- time_t *when;
- struct cached_vg_fmtdata **vg_fmtdata;
- char **desc;
-};
-
-static void _import_vg(int failed, unsigned ioflags, void *context, const void *data)
-{
- struct import_vg_params *ivp = context;
- struct text_vg_version_ops **vsn;
-
- ivp->vg = NULL;
-
- if (ivp->skip_parse) {
- if (ivp->use_previous_vg)
- *ivp->use_previous_vg = 1;
+ if (checksum_only) {
+ /* Checksum matches already-cached content - no need to reparse. */
+ r = 1;
goto out;
}
@@ -167,28 +71,26 @@ static void _import_vg(int failed, unsigned ioflags, void *context, const void *
* Find a set of version functions that can read this file
*/
for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
- if (!(*vsn)->check_version(ivp->cft))
+ if (!(*vsn)->check_version(cft))
continue;
- if (!(ivp->vg = (*vsn)->read_vg(ivp->fid, ivp->cft, ivp->single_device, 0)))
+ if (!(*vsn)->read_vgsummary(fmt, cft, vgsummary))
goto_out;
- (*vsn)->read_desc(ivp->vg->vgmem, ivp->cft, ivp->when, ivp->desc);
+ r = 1;
break;
}
- if (ivp->vg && ivp->vg_fmtdata && *ivp->vg_fmtdata) {
- (*ivp->vg_fmtdata)->cached_mda_size = ivp->total_size;
- (*ivp->vg_fmtdata)->cached_mda_checksum = ivp->checksum;
- }
-
- if (ivp->use_previous_vg)
- *ivp->use_previous_vg = 0;
-
-out:
- config_destroy(ivp->cft);
+ out:
+ config_destroy(cft);
+ return r;
}
+struct cached_vg_fmtdata {
+ uint32_t cached_mda_checksum;
+ size_t cached_mda_size;
+};
+
struct volume_group *text_vg_import_fd(struct format_instance *fid,
const char *file,
struct cached_vg_fmtdata **vg_fmtdata,
@@ -198,10 +100,13 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
off_t offset, uint32_t size,
off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn,
- uint32_t checksum, unsigned ioflags,
+ uint32_t checksum,
time_t *when, char **desc)
{
- struct import_vg_params *ivp;
+ struct volume_group *vg = NULL;
+ struct dm_config_tree *cft;
+ struct text_vg_version_ops **vsn;
+ int skip_parse;
if (vg_fmtdata && !*vg_fmtdata &&
!(*vg_fmtdata = dm_pool_zalloc(fid->mem, sizeof(**vg_fmtdata)))) {
@@ -209,48 +114,56 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
return NULL;
}
- if (!(ivp = dm_pool_zalloc(fid->fmt->cmd->mem, sizeof(*ivp)))) {
- log_error("Failed to allocate import_vgsummary_params struct.");
- return NULL;
- }
-
_init_text_import();
- ivp->fid = fid;
- ivp->when = when;
- *ivp->when = 0;
- ivp->desc = desc;
- *ivp->desc = NULL;
- ivp->single_device = single_device;
- ivp->use_previous_vg = use_previous_vg;
- ivp->checksum = checksum;
- ivp->total_size = size + size2;
- ivp->vg_fmtdata = vg_fmtdata;
-
- if (!(ivp->cft = config_open(CONFIG_FILE_SPECIAL, file, 0)))
+ *desc = NULL;
+ *when = 0;
+
+ if (!(cft = config_open(CONFIG_FILE_SPECIAL, file, 0)))
return_NULL;
/* Does the metadata match the already-cached VG? */
- ivp->skip_parse = vg_fmtdata &&
- ((*vg_fmtdata)->cached_mda_checksum == checksum) &&
- ((*vg_fmtdata)->cached_mda_size == ivp->total_size);
+ skip_parse = vg_fmtdata &&
+ ((*vg_fmtdata)->cached_mda_checksum == checksum) &&
+ ((*vg_fmtdata)->cached_mda_size == (size + size2));
+
+ if ((!dev && !config_file_read(cft)) ||
+ (dev && !config_file_read_fd(cft, dev, MDA_CONTENT_REASON(primary_mda), offset, size,
+ offset2, size2, checksum_fn, checksum,
+ skip_parse, 1)))
+ goto_out;
- if (!dev && !config_file_read(fid->mem, ivp->cft)) {
- config_destroy(ivp->cft);
- return_NULL;
+ if (skip_parse) {
+ if (use_previous_vg)
+ *use_previous_vg = 1;
+ goto out;
}
- if (dev) {
- if (!config_file_read_fd(fid->mem, ivp->cft, dev, MDA_CONTENT_REASON(primary_mda), offset, size,
- offset2, size2, checksum_fn, checksum,
- ivp->skip_parse, 1, ioflags, &_import_vg, ivp)) {
- config_destroy(ivp->cft);
- return_NULL;
- }
- } else
- _import_vg(0, 0, ivp, NULL);
+ /*
+ * Find a set of version functions that can read this file
+ */
+ for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
+ if (!(*vsn)->check_version(cft))
+ continue;
+
+ if (!(vg = (*vsn)->read_vg(fid, cft, single_device, 0)))
+ goto_out;
+
+ (*vsn)->read_desc(vg->vgmem, cft, when, desc);
+ break;
+ }
+
+ if (vg && vg_fmtdata && *vg_fmtdata) {
+ (*vg_fmtdata)->cached_mda_size = (size + size2);
+ (*vg_fmtdata)->cached_mda_checksum = checksum;
+ }
- return ivp->vg;
+ if (use_previous_vg)
+ *use_previous_vg = 0;
+
+ out:
+ config_destroy(cft);
+ return vg;
}
struct volume_group *text_vg_import_file(struct format_instance *fid,
@@ -258,7 +171,7 @@ struct volume_group *text_vg_import_file(struct format_instance *fid,
time_t *when, char **desc)
{
return text_vg_import_fd(fid, file, NULL, NULL, 0, NULL, 0, (off_t)0, 0, (off_t)0, 0, NULL, 0,
- 0, when, desc);
+ when, desc);
}
static struct volume_group *_import_vg_from_config_tree(const struct dm_config_tree *cft,
diff --git a/lib/format_text/layout.h b/lib/format_text/layout.h
index 98a0b362f..1746b9ccd 100644
--- a/lib/format_text/layout.h
+++ b/lib/format_text/layout.h
@@ -17,7 +17,6 @@
#define _LVM_TEXT_LAYOUT_H
#include "config.h"
-#include "format-text.h"
#include "metadata.h"
#include "lvmcache.h"
#include "uuid.h"
@@ -81,9 +80,8 @@ struct mda_header {
struct raw_locn raw_locns[0]; /* NULL-terminated list */
} __attribute__ ((packed));
-struct mda_header *raw_read_mda_header(struct dm_pool *mem, struct device_area *dev_area, int primary_mda);
-int raw_read_mda_header_callback(struct dm_pool *mem, struct device_area *dev_area, int primary_mda,
- unsigned ioflags, lvm_callback_fn_t mdah_callback_fn, void *mdah_callback_context);
+struct mda_header *raw_read_mda_header(const struct format_type *fmt,
+ struct device_area *dev_area, int primary_mda);
struct mda_lists {
struct dm_list dirs;
@@ -105,11 +103,9 @@ struct mda_context {
#define LVM2_LABEL "LVM2 001"
#define MDA_SIZE_MIN (8 * (unsigned) lvm_getpagesize())
#define MDA_ORIGINAL_ALIGNMENT 512 /* Original alignment used for start of VG metadata content */
-#define MDA_ALIGNMENT 4096 /* Default alignment in bytes since 2.02.177 for start of VG metadata content. */
-int vgname_from_mda(const struct format_type *fmt, const struct mda_header *mdah, int primary_mda,
+int vgname_from_mda(const struct format_type *fmt, struct mda_header *mdah, int primary_mda,
struct device_area *dev_area, struct lvmcache_vgsummary *vgsummary,
- uint64_t *mda_free_sectors, unsigned ioflags,
- lvm_callback_fn_t update_vgsummary_callback_fn, void *update_vgsummary_callback_context);
+ uint64_t *mda_free_sectors);
#endif
diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c
index 45136e9c4..7058f70c6 100644
--- a/lib/format_text/text_label.c
+++ b/lib/format_text/text_label.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -19,7 +19,6 @@
#include "label.h"
#include "xlate.h"
#include "lvmcache.h"
-#include "toolcontext.h"
#include <sys/stat.h>
#include <fcntl.h>
@@ -36,14 +35,14 @@ static int _text_can_handle(struct labeller *l __attribute__((unused)),
return 0;
}
-struct dl_setup_baton {
+struct _dl_setup_baton {
struct disk_locn *pvh_dlocn_xl;
struct device *dev;
};
static int _da_setup(struct disk_locn *da, void *baton)
{
- struct dl_setup_baton *p = baton;
+ struct _dl_setup_baton *p = baton;
p->pvh_dlocn_xl->offset = xlate64(da->offset);
p->pvh_dlocn_xl->size = xlate64(da->size);
p->pvh_dlocn_xl++;
@@ -57,7 +56,7 @@ static int _ba_setup(struct disk_locn *ba, void *baton)
static int _mda_setup(struct metadata_area *mda, void *baton)
{
- struct dl_setup_baton *p = baton;
+ struct _dl_setup_baton *p = baton;
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
if (mdac->area.dev != p->dev)
@@ -72,7 +71,7 @@ static int _mda_setup(struct metadata_area *mda, void *baton)
static int _dl_null_termination(void *baton)
{
- struct dl_setup_baton *p = baton;
+ struct _dl_setup_baton *p = baton;
p->pvh_dlocn_xl->offset = xlate64(UINT64_C(0));
p->pvh_dlocn_xl->size = xlate64(UINT64_C(0));
@@ -87,7 +86,7 @@ static int _text_write(struct label *label, void *buf)
struct pv_header *pvhdr;
struct pv_header_extension *pvhdr_ext;
struct lvmcache_info *info;
- struct dl_setup_baton baton;
+ struct _dl_setup_baton baton;
char buffer[64] __attribute__((aligned(8)));
int ba1, da1, mda1, mda2;
@@ -319,106 +318,18 @@ static int _text_initialise_label(struct labeller *l __attribute__((unused)),
return 1;
}
-struct update_mda_baton {
+struct _update_mda_baton {
struct lvmcache_info *info;
struct label *label;
- int nr_outstanding_mdas;
- unsigned ioflags;
- lvm_callback_fn_t read_label_callback_fn;
- void *read_label_callback_context;
- int ret;
};
-struct process_mda_header_params {
- struct update_mda_baton *umb;
- struct metadata_area *mda;
- struct device *dev;
- struct lvmcache_vgsummary vgsummary;
- int ret;
-};
-
-static void _process_vgsummary(int failed, unsigned ioflags, void *context, const void *data)
-{
- struct process_mda_header_params *pmp = context;
- const struct lvmcache_vgsummary *vgsummary = data;
-
- --pmp->umb->nr_outstanding_mdas;
-
- /* FIXME Need to distinguish genuine errors here */
- if (failed)
- goto_out;
-
- if (!lvmcache_update_vgname_and_id(pmp->umb->info, vgsummary)) {
- pmp->umb->ret = 0;
- pmp->ret = 0;
- }
-
-out:
- if (!pmp->umb->nr_outstanding_mdas && pmp->umb->ret)
- lvmcache_make_valid(pmp->umb->info);
-
- if (!dev_close(pmp->dev))
- stack;
-
- if (!pmp->umb->nr_outstanding_mdas && pmp->umb->read_label_callback_fn)
- pmp->umb->read_label_callback_fn(!pmp->umb->ret, ioflags, pmp->umb->read_label_callback_context, pmp->umb->label);
-}
-
-static void _process_mda_header(int failed, unsigned ioflags, void *context, const void *data)
-{
- struct process_mda_header_params *pmp = context;
- const struct mda_header *mdah = data;
- struct update_mda_baton *umb = pmp->umb;
- const struct format_type *fmt = umb->label->labeller->fmt;
- struct metadata_area *mda = pmp->mda;
- struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
-
- if (failed)
- goto_bad;
-
- mda_set_ignored(mda, rlocn_is_ignored(mdah->raw_locns));
-
- if (mda_is_ignored(mda)) {
- log_debug_metadata("Ignoring mda on device %s at offset " FMTu64,
- dev_name(mdac->area.dev),
- mdac->area.start);
- goto bad;
- }
-
- if (!vgname_from_mda(fmt, mdah, mda_is_primary(mda), &mdac->area, &pmp->vgsummary, &mdac->free_sectors, ioflags, _process_vgsummary, pmp)) {
- /* FIXME Separate fatal and non-fatal error cases? */
- goto_bad;
- }
-
- return;
-
-bad:
- _process_vgsummary(1, ioflags, pmp, NULL);
- return;
-}
-
-static int _count_mda(struct metadata_area *mda, void *baton)
-{
- struct update_mda_baton *umb = baton;
-
- umb->nr_outstanding_mdas++;
-
- return 1;
-}
-
static int _update_mda(struct metadata_area *mda, void *baton)
{
- struct process_mda_header_params *pmp;
- struct update_mda_baton *umb = baton;
- const struct format_type *fmt = umb->label->labeller->fmt;
- struct dm_pool *mem = umb->label->labeller->fmt->cmd->mem;
+ struct _update_mda_baton *p = baton;
+ const struct format_type *fmt = p->label->labeller->fmt;
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
- unsigned ioflags = umb->ioflags;
-
- if (!(pmp = dm_pool_zalloc(mem, sizeof(*pmp)))) {
- log_error("struct process_mda_header_params allocation failed");
- return 0;
- }
+ struct mda_header *mdah;
+ struct lvmcache_vgsummary vgsummary = { 0 };
/*
* Using the labeller struct to preserve info about
@@ -427,34 +338,45 @@ static int _update_mda(struct metadata_area *mda, void *baton)
* TODO: make lvmcache smarter and move this cache logic there
*/
- pmp->dev = mdac->area.dev;
- pmp->umb = umb;
- pmp->mda = mda;
-
if (!dev_open_readonly(mdac->area.dev)) {
mda_set_ignored(mda, 1);
stack;
- if (!--umb->nr_outstanding_mdas && umb->read_label_callback_fn)
- umb->read_label_callback_fn(!umb->ret, ioflags, umb->read_label_callback_context, umb->label);
return 1;
}
- pmp->ret = 1;
-
- if (!raw_read_mda_header_callback(fmt->cmd->mem, &mdac->area, mda_is_primary(mda), ioflags, _process_mda_header, pmp)) {
- _process_vgsummary(1, ioflags, pmp, NULL);
+ if (!(mdah = raw_read_mda_header(fmt, &mdac->area, mda_is_primary(mda)))) {
stack;
- return 1;
+ goto close_dev;
}
- if (umb->read_label_callback_fn)
+ mda_set_ignored(mda, rlocn_is_ignored(mdah->raw_locns));
+
+ if (mda_is_ignored(mda)) {
+ log_debug_metadata("Ignoring mda on device %s at offset " FMTu64,
+ dev_name(mdac->area.dev),
+ mdac->area.start);
+ if (!dev_close(mdac->area.dev))
+ stack;
return 1;
- else
- return pmp->ret;
+ }
+
+ if (vgname_from_mda(fmt, mdah, mda_is_primary(mda), &mdac->area, &vgsummary,
+ &mdac->free_sectors) &&
+ !lvmcache_update_vgname_and_id(p->info, &vgsummary)) {
+ if (!dev_close(mdac->area.dev))
+ stack;
+ return_0;
+ }
+
+close_dev:
+ if (!dev_close(mdac->area.dev))
+ stack;
+
+ return 1;
}
-static int _text_read(struct labeller *l, struct device *dev, void *buf, unsigned ioflags,
- lvm_callback_fn_t read_label_callback_fn, void *read_label_callback_context)
+static int _text_read(struct labeller *l, struct device *dev, void *buf,
+ struct label **label)
{
struct label_header *lh = (struct label_header *) buf;
struct pv_header *pvhdr;
@@ -463,9 +385,7 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf, unsigne
struct disk_locn *dlocn_xl;
uint64_t offset;
uint32_t ext_version;
- struct dm_pool *mem = l->fmt->cmd->mem;
- struct update_mda_baton *umb;
- struct label *label;
+ struct _update_mda_baton baton;
/*
* PV header base
@@ -475,9 +395,9 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf, unsigne
if (!(info = lvmcache_add(l, (char *)pvhdr->pv_uuid, dev,
FMT_TEXT_ORPHAN_VG_NAME,
FMT_TEXT_ORPHAN_VG_NAME, 0)))
- goto_bad;
+ return_0;
- label = lvmcache_get_label(info);
+ *label = lvmcache_get_label(info);
lvmcache_set_device_size(info, xlate64(pvhdr->device_size_xl));
@@ -523,41 +443,16 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf, unsigne
lvmcache_add_ba(info, offset, xlate64(dlocn_xl->size));
dlocn_xl++;
}
-
out:
- if (!(umb = dm_pool_zalloc(mem, sizeof(*umb)))) {
- log_error("baton allocation failed");
- goto_bad;
- }
+ baton.info = info;
+ baton.label = *label;
- umb->info = info;
- umb->label = label;
- umb->ioflags = ioflags;
- umb->read_label_callback_fn = read_label_callback_fn;
- umb->read_label_callback_context = read_label_callback_context;
+ if (!lvmcache_foreach_mda(info, _update_mda, &baton))
+ return_0;
- umb->ret = 1;
-
- if (!lvmcache_foreach_mda(info, _count_mda, umb))
- goto_bad;
-
- if (!umb->nr_outstanding_mdas) {
- lvmcache_make_valid(info);
- if (read_label_callback_fn)
- read_label_callback_fn(0, ioflags, read_label_callback_context, label);
- return 1;
- }
-
- if (!lvmcache_foreach_mda(info, _update_mda, umb))
- goto_bad;
+ lvmcache_make_valid(info);
return 1;
-
-bad:
- if (read_label_callback_fn)
- read_label_callback_fn(1, ioflags, read_label_callback_context, NULL);
-
- return 0;
}
static void _text_destroy_label(struct labeller *l __attribute__((unused)),
diff --git a/lib/label/label.c b/lib/label/label.c
index 32fad826f..46dd667bd 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -25,8 +25,6 @@
/* FIXME Allow for larger labels? Restricted to single sector currently */
-static struct dm_pool *_labeller_mem;
-
/*
* Internal labeller struct.
*/
@@ -59,13 +57,7 @@ static struct labeller_i *_alloc_li(const char *name, struct labeller *l)
int label_init(void)
{
- if (!(_labeller_mem = dm_pool_create("label scan", 128))) {
- log_error("Labeller pool creation failed.");
- return 0;
- }
-
dm_list_init(&_labellers);
-
return 1;
}
@@ -80,8 +72,6 @@ void label_exit(void)
}
dm_list_init(&_labellers);
-
- dm_pool_destroy(_labeller_mem);
}
int label_register_handler(struct labeller *handler)
@@ -118,74 +108,32 @@ static void _update_lvmcache_orphan(struct lvmcache_info *info)
stack;
}
-struct find_labeller_params {
- struct device *dev;
- uint64_t scan_sector; /* Sector to be scanned */
- uint64_t label_sector; /* Sector where label found */
- lvm_callback_fn_t process_label_data_fn;
- void *process_label_data_context;
-
- struct label **result;
-
- int ret;
-};
-
-static void _set_label_read_result(int failed, unsigned ioflags, void *context, const void *data)
+static struct labeller *_find_labeller(struct device *dev, char *buf,
+ uint64_t *label_sector,
+ uint64_t scan_sector)
{
- struct find_labeller_params *flp = context;
- struct label **result = flp->result;
- struct label *label = (struct label *) data;
-
- if (failed) {
- flp->ret = 0;
- goto_out;
- }
-
- /* Fix up device and label sector which the low-level code doesn't set */
- if (label) {
- label->dev = flp->dev;
- label->sector = flp->label_sector;
- }
-
- if (result)
- *result = (struct label *) label;
-
-out:
- if (!dev_close(flp->dev))
- stack;
-
- if (flp->process_label_data_fn) {
- log_debug_io("Completed label reading for %s", dev_name(flp->dev));
- flp->process_label_data_fn(!flp->ret, ioflags, flp->process_label_data_context, NULL);
- }
-}
-
-static void _find_labeller(int failed, unsigned ioflags, void *context, const void *data)
-{
- struct find_labeller_params *flp = context;
- const char *readbuf = data;
- struct device *dev = flp->dev;
- uint64_t scan_sector = flp->scan_sector;
- char labelbuf[LABEL_SIZE] __attribute__((aligned(8)));
struct labeller_i *li;
- struct labeller *l = NULL; /* Set when a labeller claims the label */
- const struct label_header *lh;
+ struct labeller *r = NULL;
+ struct label_header *lh;
struct lvmcache_info *info;
uint64_t sector;
+ int found = 0;
+ char readbuf[LABEL_SCAN_SIZE] __attribute__((aligned(8)));
- if (failed) {
+ if (!dev_read(dev, scan_sector << SECTOR_SHIFT,
+ LABEL_SCAN_SIZE, DEV_IO_LABEL, readbuf)) {
log_debug_devs("%s: Failed to read label area", dev_name(dev));
- _set_label_read_result(1, ioflags, flp, NULL);
- return;
+ goto out;
}
/* Scan a few sectors for a valid label */
for (sector = 0; sector < LABEL_SCAN_SECTORS;
sector += LABEL_SIZE >> SECTOR_SHIFT) {
- lh = (struct label_header *) (readbuf + (sector << SECTOR_SHIFT));
+ lh = (struct label_header *) (readbuf +
+ (sector << SECTOR_SHIFT));
if (!strncmp((char *)lh->id, LABEL_ID, sizeof(lh->id))) {
- if (l) {
+ if (found) {
log_error("Ignoring additional label on %s at "
"sector %" PRIu64, dev_name(dev),
sector + scan_sector);
@@ -205,7 +153,7 @@ static void _find_labeller(int failed, unsigned ioflags, void *context, const vo
"ignoring", dev_name(dev));
continue;
}
- if (l)
+ if (found)
continue;
}
@@ -216,44 +164,46 @@ static void _find_labeller(int failed, unsigned ioflags, void *context, const vo
"sector %" PRIu64,
dev_name(dev), li->name,
sector + scan_sector);
- if (l) {
+ if (found) {
log_error("Ignoring additional label "
"on %s at sector %" PRIu64,
dev_name(dev),
sector + scan_sector);
continue;
}
- memcpy(labelbuf, lh, LABEL_SIZE);
- flp->label_sector = sector + scan_sector;
- l = li->l;
+ r = li->l;
+ memcpy(buf, lh, LABEL_SIZE);
+ if (label_sector)
+ *label_sector = sector + scan_sector;
+ found = 1;
break;
}
}
}
- if (!l) {
+ out:
+ if (!found) {
if ((info = lvmcache_info_from_pvid(dev->pvid, dev, 0)))
_update_lvmcache_orphan(info);
log_very_verbose("%s: No label detected", dev_name(dev));
- flp->ret = 0;
- _set_label_read_result(1, ioflags, flp, NULL);
- } else
- (void) (l->ops->read)(l, dev, labelbuf, ioflags, &_set_label_read_result, flp);
+ }
+
+ return r;
}
/* FIXME Also wipe associated metadata area headers? */
int label_remove(struct device *dev)
{
- char labelbuf[LABEL_SIZE] __attribute__((aligned(8)));
+ char buf[LABEL_SIZE] __attribute__((aligned(8)));
+ char readbuf[LABEL_SCAN_SIZE] __attribute__((aligned(8)));
int r = 1;
uint64_t sector;
int wipe;
struct labeller_i *li;
struct label_header *lh;
struct lvmcache_info *info;
- const char *readbuf = NULL;
- memset(labelbuf, 0, LABEL_SIZE);
+ memset(buf, 0, LABEL_SIZE);
log_very_verbose("Scanning for labels to wipe from %s", dev_name(dev));
@@ -266,7 +216,7 @@ int label_remove(struct device *dev)
*/
dev_flush(dev);
- if (!(readbuf = dev_read(dev, UINT64_C(0), LABEL_SCAN_SIZE, DEV_IO_LABEL))) {
+ if (!dev_read(dev, UINT64_C(0), LABEL_SCAN_SIZE, DEV_IO_LABEL, readbuf)) {
log_debug_devs("%s: Failed to read label area", dev_name(dev));
goto out;
}
@@ -274,7 +224,8 @@ int label_remove(struct device *dev)
/* Scan first few sectors for anything looking like a label */
for (sector = 0; sector < LABEL_SCAN_SECTORS;
sector += LABEL_SIZE >> SECTOR_SHIFT) {
- lh = (struct label_header *) (readbuf + (sector << SECTOR_SHIFT));
+ lh = (struct label_header *) (readbuf +
+ (sector << SECTOR_SHIFT));
wipe = 0;
@@ -294,7 +245,8 @@ int label_remove(struct device *dev)
if (wipe) {
log_very_verbose("%s: Wiping label at sector %" PRIu64,
dev_name(dev), sector);
- if (dev_write(dev, sector << SECTOR_SHIFT, LABEL_SIZE, DEV_IO_LABEL, labelbuf)) {
+ if (dev_write(dev, sector << SECTOR_SHIFT, LABEL_SIZE, DEV_IO_LABEL,
+ buf)) {
/* Also remove the PV record from cache. */
info = lvmcache_info_from_pvid(dev->pvid, dev, 0);
if (info)
@@ -315,39 +267,21 @@ int label_remove(struct device *dev)
return r;
}
-static int _label_read(struct device *dev, uint64_t scan_sector, struct label **result,
- unsigned ioflags, lvm_callback_fn_t process_label_data_fn, void *process_label_data_context)
+int label_read(struct device *dev, struct label **result,
+ uint64_t scan_sector)
{
+ char buf[LABEL_SIZE] __attribute__((aligned(8)));
+ struct labeller *l;
+ uint64_t sector;
struct lvmcache_info *info;
- struct find_labeller_params *flp;
+ int r = 0;
if ((info = lvmcache_info_from_pvid(dev->pvid, dev, 1))) {
log_debug_devs("Reading label from lvmcache for %s", dev_name(dev));
- if (result)
- *result = lvmcache_get_label(info);
- if (process_label_data_fn) {
- log_debug_io("Completed label reading for %s", dev_name(dev));
- process_label_data_fn(0, ioflags, process_label_data_context, NULL);
- }
+ *result = lvmcache_get_label(info);
return 1;
}
- if (!(flp = dm_pool_zalloc(_labeller_mem, sizeof *flp))) {
- log_error("find_labeller_params allocation failed.");
- return 0;
- }
-
- flp->dev = dev;
- flp->scan_sector = scan_sector;
- flp->result = result;
- flp->process_label_data_fn = process_label_data_fn;
- flp->process_label_data_context = process_label_data_context;
- flp->ret = 1;
-
- /* Ensure result is always wiped as a precaution */
- if (result)
- *result = NULL;
-
log_debug_devs("Reading label from device %s", dev_name(dev));
if (!dev_open_readonly(dev)) {
@@ -356,26 +290,19 @@ static int _label_read(struct device *dev, uint64_t scan_sector, struct label **
if ((info = lvmcache_info_from_pvid(dev->pvid, dev, 0)))
_update_lvmcache_orphan(info);
- return 0;
+ return r;
}
- dev_read_callback(dev, scan_sector << SECTOR_SHIFT, LABEL_SCAN_SIZE, DEV_IO_LABEL, ioflags, _find_labeller, flp);
- if (process_label_data_fn)
- return 1;
- else
- return flp->ret;
-}
+ if ((l = _find_labeller(dev, buf, &sector, scan_sector)))
+ if ((r = (l->ops->read)(l, dev, buf, result)) && result && *result) {
+ (*result)->dev = dev;
+ (*result)->sector = sector;
+ }
-/* result may be NULL if caller doesn't need it */
-int label_read(struct device *dev, struct label **result, uint64_t scan_sector)
-{
- return _label_read(dev, scan_sector, result, 0, NULL, NULL);
-}
+ if (!dev_close(dev))
+ stack;
-int label_read_callback(struct device *dev, uint64_t scan_sector, unsigned ioflags,
- lvm_callback_fn_t process_label_data_fn, void *process_label_data_context)
-{
- return _label_read(dev, scan_sector, NULL, ioflags, process_label_data_fn, process_label_data_context);
+ return r;
}
/* Caller may need to use label_get_handler to create label struct! */
diff --git a/lib/label/label.h b/lib/label/label.h
index 6d31eb053..ea1129019 100644
--- a/lib/label/label.h
+++ b/lib/label/label.h
@@ -62,8 +62,8 @@ struct label_ops {
/*
* Read a label from a volume.
*/
- int (*read) (struct labeller *l, struct device *dev, void *buf,
- unsigned ioflags, lvm_callback_fn_t label_read_callback_fn, void *label_read_callback_context);
+ int (*read) (struct labeller * l, struct device * dev,
+ void *buf, struct label ** label);
/*
* Populate label_type etc.
@@ -96,8 +96,6 @@ struct labeller *label_get_handler(const char *name);
int label_remove(struct device *dev);
int label_read(struct device *dev, struct label **result,
uint64_t scan_sector);
-int label_read_callback(struct device *dev, uint64_t scan_sector,
- unsigned ioflags, lvm_callback_fn_t process_label_data_fn, void *process_label_data_context);
int label_write(struct device *dev, struct label *label);
struct label *label_create(struct labeller *labeller);
void label_destroy(struct label *label);
diff --git a/lib/metadata/metadata-liblvm.c b/lib/metadata/metadata-liblvm.c
index d192b1597..a4284bc89 100644
--- a/lib/metadata/metadata-liblvm.c
+++ b/lib/metadata/metadata-liblvm.c
@@ -491,6 +491,7 @@ static int _pvremove_check(struct cmd_context *cmd, const char *name,
{
static const char really_wipe_msg[] = "Really WIPE LABELS from physical volume";
struct device *dev;
+ struct label *label;
struct pv_list *pvl;
struct physical_volume *pv = NULL;
int used;
@@ -505,7 +506,7 @@ static int _pvremove_check(struct cmd_context *cmd, const char *name,
/* Is there a pv here already? */
/* If not, this is an error unless you used -f. */
- if (!label_read(dev, NULL, 0)) {
+ if (!label_read(dev, &label, 0)) {
if (force_count)
return 1;
log_error("No PV label found on %s.", name);
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index b5b97c2f4..2249d2fc7 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3912,9 +3912,9 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
use_previous_vg = 0;
if ((use_precommitted &&
- !(vg = mda->ops->vg_read_precommit(fid, vgname, mda, &vg_fmtdata, &use_previous_vg, 0)) && !use_previous_vg) ||
+ !(vg = mda->ops->vg_read_precommit(fid, vgname, mda, &vg_fmtdata, &use_previous_vg)) && !use_previous_vg) ||
(!use_precommitted &&
- !(vg = mda->ops->vg_read(fid, vgname, mda, &vg_fmtdata, &use_previous_vg, 0, 0)) && !use_previous_vg)) {
+ !(vg = mda->ops->vg_read(fid, vgname, mda, &vg_fmtdata, &use_previous_vg, 0)) && !use_previous_vg)) {
inconsistent = 1;
vg_fmtdata = NULL;
continue;
@@ -4104,9 +4104,9 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
use_previous_vg = 0;
if ((use_precommitted &&
- !(vg = mda->ops->vg_read_precommit(fid, vgname, mda, &vg_fmtdata, &use_previous_vg, 0)) && !use_previous_vg) ||
+ !(vg = mda->ops->vg_read_precommit(fid, vgname, mda, &vg_fmtdata, &use_previous_vg)) && !use_previous_vg) ||
(!use_precommitted &&
- !(vg = mda->ops->vg_read(fid, vgname, mda, &vg_fmtdata, &use_previous_vg, 0, 0)) && !use_previous_vg)) {
+ !(vg = mda->ops->vg_read(fid, vgname, mda, &vg_fmtdata, &use_previous_vg, 0)) && !use_previous_vg)) {
inconsistent = 1;
vg_fmtdata = NULL;
continue;
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index f6b19f44b..1fa14e839 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -48,6 +48,7 @@
*/
#define dm_round_up(n, sz) (dm_div_up((n), (sz)) * (sz))
+
/* Various flags */
/* See metadata-exported.h for the complete list. */
/* Note that the bits no longer necessarily correspond to LVM1 disk format */
@@ -80,12 +81,12 @@ struct metadata_area_ops {
struct metadata_area * mda,
struct cached_vg_fmtdata **vg_fmtdata,
unsigned *use_previous_vg,
- int single_device, unsigned ioflags);
+ int single_device);
struct volume_group *(*vg_read_precommit) (struct format_instance * fi,
const char *vg_name,
struct metadata_area * mda,
struct cached_vg_fmtdata **vg_fmtdata,
- unsigned *use_previous_vg, unsigned ioflags);
+ unsigned *use_previous_vg);
/*
* Write out complete VG metadata. You must ensure internal
* consistency before calling. eg. PEs can't refer to PVs not
diff --git a/make.tmpl.in b/make.tmpl.in
index 414b1dd5c..bdf234918 100644
--- a/make.tmpl.in
+++ b/make.tmpl.in
@@ -62,8 +62,7 @@ CLDFLAGS += @CLDFLAGS@
ELDFLAGS += @ELDFLAGS@
LDDEPS += @LDDEPS@
LIB_SUFFIX = @LIB_SUFFIX@
-LVMINTERNAL_LIBS = -llvm-internal $(DMEVENT_LIBS) $(DAEMON_LIBS) $(SYSTEMD_LIBS) $(UDEV_LIBS) $(DL_LIBS) $(BLKID_LIBS) $(AIO_LIBS)
-AIO_LIBS = @AIO_LIBS@
+LVMINTERNAL_LIBS = -llvm-internal $(DMEVENT_LIBS) $(DAEMON_LIBS) $(SYSTEMD_LIBS) $(UDEV_LIBS) $(DL_LIBS) $(BLKID_LIBS)
DL_LIBS = @DL_LIBS@
RT_LIBS = @RT_LIBS@
M_LIBS = @M_LIBS@
diff --git a/tools/command.c b/tools/command.c
index a40b327b4..8944399b3 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -1357,11 +1357,13 @@ static void _create_opt_names_alpha(void)
qsort(opt_names_alpha, ARG_COUNT, sizeof(long), _long_name_compare);
}
-static int _copy_line(char *line, int max_line, int *position, int *len)
+static int _copy_line(char *line, int max_line, int *position)
{
int p = *position;
int i = 0;
+ memset(line, 0, max_line);
+
while (1) {
line[i] = _command_input[p];
i++;
@@ -1375,9 +1377,7 @@ static int _copy_line(char *line, int max_line, int *position, int *len)
if (i == (max_line - 1))
break;
}
- line[i] = '\0';
*position = p;
- *len = i + 1;
return 1;
}
@@ -1395,7 +1395,6 @@ int define_commands(struct cmd_context *cmdtool, const char *run_name)
int prev_was_oo = 0;
int prev_was_op = 0;
int copy_pos = 0;
- int copy_len = 0;
int skip = 0;
int i;
@@ -1406,14 +1405,14 @@ int define_commands(struct cmd_context *cmdtool, const char *run_name)
/* Process each line of command-lines-input.h (from command-lines.in) */
- while (_copy_line(line, MAX_LINE, &copy_pos, &copy_len)) {
+ while (_copy_line(line, MAX_LINE, &copy_pos)) {
if (line[0] == '\n')
break;
if ((n = strchr(line, '\n')))
*n = '\0';
- memcpy(line_orig, line, copy_len);
+ memcpy(line_orig, line, sizeof(line));
_split_line(line, &line_argc, line_argv, ' ');
if (!line_argc)
diff --git a/tools/toollib.c b/tools/toollib.c
index 3f27a7af4..451f24dab 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -116,7 +116,6 @@ int become_daemon(struct cmd_context *cmd, int skip_lvm)
/* FIXME Clean up properly here */
_exit(ECMD_FAILED);
}
- dev_async_reset(cmd);
dev_close_all();
return 1;