From 90bbed325544365efa177a9823019c44f5109dbb Mon Sep 17 00:00:00 2001 From: Jonathan Brassow Date: Mon, 27 Jan 2014 05:27:16 -0600 Subject: [PATCH] cache: New 'cachepool' segment type This patch adds the new cachepool segment type - the first of two necessary to eventually create 'cache' logical volumes. In addition to the new segment type, updates to makefiles, configure files, the lv_segment struct, and some necessary libdevmapper flags. The cachepool is the LV and corresponding segment type that will hold all information pertinent to the cache itself - it's size, cachemode, cache policy, core arguments (like migration_threshold), etc. --- configure | 32 ++- configure.in | 22 ++ lib/Makefile.in | 11 +- lib/cache_segtype/.exported_symbols | 1 + lib/cache_segtype/Makefile.in | 24 +++ lib/cache_segtype/cache.c | 316 ++++++++++++++++++++++++++++ lib/commands/toolcontext.c | 9 +- lib/metadata/metadata-exported.h | 7 + lib/metadata/segtype.h | 10 + lib/misc/configure.h.in | 3 + libdm/libdevmapper.h | 4 + 11 files changed, 435 insertions(+), 4 deletions(-) create mode 100644 lib/cache_segtype/.exported_symbols create mode 100644 lib/cache_segtype/Makefile.in create mode 100644 lib/cache_segtype/cache.c diff --git a/configure b/configure index a15646053..20d99ddb9 100755 --- a/configure +++ b/configure @@ -606,6 +606,7 @@ kernelvsn missingkernel kerneldir interface +CACHE CMIRRORD_PIDFILE CLVMD_PIDFILE LVMETAD_PIDFILE @@ -839,6 +840,7 @@ with_thin with_thin_check with_thin_dump with_thin_repair +with_cache enable_readline enable_realtime enable_ocf @@ -1615,6 +1617,7 @@ Optional Packages: --with-mirrors=TYPE mirror support: internal/shared/none [[TYPE=internal]] --with-raid=TYPE raid support: internal/shared/none [[TYPE=internal]] + --with-cache=TYPE cache support: internal/shared/none [[TYPE=internal]] --with-replicators=TYPE replicator support: internal/shared/none [[TYPE=none]] --with-thin=TYPE thin provisioning support: internal/shared/none @@ -7116,6 +7119,31 @@ $as_echo "#define RAID_INTERNAL 1" >>confdefs.h fi +################################################################################ +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include cache" >&5 +$as_echo_n "checking whether to include cache... " >&6; } + +# Check whether --with-cache was given. +if test "${with_cache+set}" = set; then : + withval=$with_cache; CACHE=$withval +else + CACHE=internal +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CACHE" >&5 +$as_echo "$CACHE" >&6; } + +if [ "x$CACHE" != xnone -a "x$CACHE" != xinternal -a "x$CACHE" != xshared ]; + then as_fn_error $? "--with-cache parameter invalid +" "$LINENO" 5 +fi; + +if test x$CACHE = xinternal; then + +$as_echo "#define CACHE_INTERNAL 1" >>confdefs.h + +fi + ################################################################################ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include replicators" >&5 $as_echo_n "checking whether to include replicators... " >&6; } @@ -10150,6 +10178,7 @@ fi if [ \( "x$LVM1" = xshared -o "x$POOL" = xshared -o "x$CLUSTER" = xshared \ -o "x$SNAPSHOTS" = xshared -o "x$MIRRORS" = xshared \ -o "x$RAID" = xshared \ + -o "x$CACHE" = xshared \ \) -a "x$STATIC_LINK" = xyes ]; then as_fn_error $? "Features cannot be 'shared' when building statically " "$LINENO" 5 @@ -11424,7 +11453,7 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'` ################################################################################ -ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile conf/Makefile conf/example.conf conf/default.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_monitoring_init_red_hat scripts/dm_event_systemd_red_hat.socket scripts/dm_event_systemd_red_hat.service scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile" +ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile conf/Makefile conf/example.conf conf/default.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/raid/Makefile lib/cache_segtype/Makefile lib/snapshot/Makefile lib/thin/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_monitoring_init_red_hat scripts/dm_event_systemd_red_hat.socket scripts/dm_event_systemd_red_hat.service scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -12140,6 +12169,7 @@ do "lib/replicator/Makefile") CONFIG_FILES="$CONFIG_FILES lib/replicator/Makefile" ;; "lib/misc/lvm-version.h") CONFIG_FILES="$CONFIG_FILES lib/misc/lvm-version.h" ;; "lib/raid/Makefile") CONFIG_FILES="$CONFIG_FILES lib/raid/Makefile" ;; + "lib/cache_segtype/Makefile") CONFIG_FILES="$CONFIG_FILES lib/cache_segtype/Makefile" ;; "lib/snapshot/Makefile") CONFIG_FILES="$CONFIG_FILES lib/snapshot/Makefile" ;; "lib/thin/Makefile") CONFIG_FILES="$CONFIG_FILES lib/thin/Makefile" ;; "libdaemon/Makefile") CONFIG_FILES="$CONFIG_FILES libdaemon/Makefile" ;; diff --git a/configure.in b/configure.in index 3e0e508c3..7b56b134c 100644 --- a/configure.in +++ b/configure.in @@ -476,6 +476,25 @@ AC_DEFINE_UNQUOTED([THIN_DUMP_CMD], ["$THIN_DUMP_CMD"], AC_DEFINE_UNQUOTED([THIN_REPAIR_CMD], ["$THIN_REPAIR_CMD"], [The path to 'thin_repair', if available.]) +################################################################################ +dnl -- cache inclusion type +AC_MSG_CHECKING(whether to include cache) +AC_ARG_WITH(cache, + AC_HELP_STRING([--with-cache=TYPE], + [cache support: internal/shared/none + [[TYPE=internal]]]), + CACHE=$withval, CACHE=internal) +AC_MSG_RESULT($CACHE) + +if [[ "x$CACHE" != xnone -a "x$CACHE" != xinternal -a "x$CACHE" != xshared ]]; + then AC_MSG_ERROR( +--with-cache parameter invalid +) +fi; + +if test x$CACHE = xinternal; then + AC_DEFINE([CACHE_INTERNAL], 1, [Define to 1 to include built-in support for cache.]) +fi ################################################################################ dnl -- Disable readline @@ -1241,6 +1260,7 @@ dnl -- Check for shared/static conflicts if [[ \( "x$LVM1" = xshared -o "x$POOL" = xshared -o "x$CLUSTER" = xshared \ -o "x$SNAPSHOTS" = xshared -o "x$MIRRORS" = xshared \ -o "x$RAID" = xshared \ + -o "x$CACHE" = xshared \ \) -a "x$STATIC_LINK" = xyes ]]; then AC_MSG_ERROR( Features cannot be 'shared' when building statically @@ -1596,6 +1616,7 @@ AC_SUBST(BLKID_WIPING) AC_SUBST(BUILD_CMIRRORD) AC_SUBST(BUILD_DMEVENTD) AC_SUBST(BUILD_LVMETAD) +AC_SUBST(CACHE) AC_SUBST(CFLAGS) AC_SUBST(CFLOW_CMD) AC_SUBST(CLDFLAGS) @@ -1752,6 +1773,7 @@ lib/misc/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile +lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile diff --git a/lib/Makefile.in b/lib/Makefile.in index c3ace5f3d..380826997 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -1,6 +1,6 @@ # # Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. -# Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved. +# Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved. # # This file is part of LVM2. # @@ -44,6 +44,10 @@ ifeq ("@THIN@", "shared") SUBDIRS += thin endif +ifeq ("@CACHE@", "shared") + SUBDIRS += cache_segtype +endif + SOURCES =\ activate/activate.c \ cache/lvmcache.c \ @@ -165,6 +169,10 @@ ifeq ("@THIN@", "internal") SOURCES += thin/thin.c endif +ifeq ("@CACHE@", "internal") + SOURCES += cache_segtype/cache.c +endif + ifeq ("@DEVMAPPER@", "yes") SOURCES +=\ activate/dev_manager.c \ @@ -199,6 +207,7 @@ ifeq ($(MAKECMDGOALS),distclean) raid \ replicator \ thin \ + cache_segtype \ locking endif diff --git a/lib/cache_segtype/.exported_symbols b/lib/cache_segtype/.exported_symbols new file mode 100644 index 000000000..95cb3ffbc --- /dev/null +++ b/lib/cache_segtype/.exported_symbols @@ -0,0 +1 @@ +init_cache_segtypes diff --git a/lib/cache_segtype/Makefile.in b/lib/cache_segtype/Makefile.in new file mode 100644 index 000000000..32a1f2b6b --- /dev/null +++ b/lib/cache_segtype/Makefile.in @@ -0,0 +1,24 @@ +# Copyright (C) 2013-2014 Red Hat, Inc. All rights reserved. +# +# This file is part of LVM2. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions +# of the GNU General Public License v.2. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ + +SOURCES = cache.c + +LIB_SHARED = liblvm2cache.$(LIB_SUFFIX) +LIB_VERSION = $(LIB_VERSION_LVM) + +include $(top_builddir)/make.tmpl + +install: install_lvm2_plugin diff --git a/lib/cache_segtype/cache.c b/lib/cache_segtype/cache.c new file mode 100644 index 000000000..0c60b7e26 --- /dev/null +++ b/lib/cache_segtype/cache.c @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2013-2014 Red Hat, Inc. All rights reserved. + * + * This file is part of LVM2. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License v.2.1. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "lib.h" +#include "toolcontext.h" +#include "segtype.h" +#include "display.h" +#include "text_export.h" +#include "text_import.h" +#include "config.h" +#include "str_list.h" +#include "targets.h" +#include "lvm-string.h" +#include "activate.h" +#include "metadata.h" +#include "lv_alloc.h" +#include "defaults.h" + +#define SEG_LOG_ERROR(t, p...) \ + log_error(t " segment %s of logical volume %s.", ## p, \ + dm_config_parent_name(sn), seg->lv->name), 0; + + +static const char *_name(const struct lv_segment *seg) +{ + return seg->segtype->name; +} + +static int _cache_pool_text_import(struct lv_segment *seg, + const struct dm_config_node *sn, + struct dm_hash_table *pv_hash __attribute__((unused))) +{ + uint32_t chunk_size; + struct logical_volume *data_lv, *meta_lv; + const char *str = NULL; + char *argv_str; + struct dm_pool *mem = seg->lv->vg->vgmem; //FIXME: what mempool should be used? + + if (!dm_config_has_node(sn, "data")) + return SEG_LOG_ERROR("Cache data not specified in"); + if (!(str = dm_config_find_str(sn, "data", NULL))) + return SEG_LOG_ERROR("Cache data must be a string in"); + if (!(data_lv = find_lv(seg->lv->vg, str))) + return SEG_LOG_ERROR("Unknown logical volume %s specified for " + "cache data in", str); + + if (!dm_config_has_node(sn, "metadata")) + return SEG_LOG_ERROR("Cache metadata not specified in"); + if (!(str = dm_config_find_str(sn, "metadata", NULL))) + return SEG_LOG_ERROR("Cache metadata must be a string in"); + if (!(meta_lv = find_lv(seg->lv->vg, str))) + return SEG_LOG_ERROR("Unknown logical volume %s specified for " + "cache metadata in", str); + + if (!dm_config_get_uint32(sn, "chunk_size", &chunk_size)) + return SEG_LOG_ERROR("Couldn't read cache chunk_size in"); + + /* + * Read in features: + * cache_mode = {writethrough|writeback} + * + * 'cache_mode' does not have to be present. + */ + if (dm_config_has_node(sn, "cache_mode")) { + if (!(str = dm_config_find_str(sn, "cache_mode", NULL))) + return SEG_LOG_ERROR("cache_mode must be a string in"); + if (!strcmp(str, "writethrough")) + seg->feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH; + else if (!strcmp(str, "writeback")) + seg->feature_flags |= DM_CACHE_FEATURE_WRITEBACK; + else + return SEG_LOG_ERROR("Unknown cache_mode in"); + } + + /* + * Read in core arguments (these are key/value pairs) + * core_argc = <# args> + * core_argv = "[ ]..." + * + * 'core_argc' does not have to be present. If it is not present, + * any other core_* fields are ignored. If it is present, then + * 'core_argv' must be present - even if they are + * 'core_argc = 0' and 'core_argv = ""'. + */ + if (dm_config_has_node(sn, "core_argc")) { + if (!dm_config_has_node(sn, "core_argv")) + return SEG_LOG_ERROR("not all core arguments defined in"); + + if (!dm_config_get_int(sn, "core_argc", &seg->core_argc)) + return SEG_LOG_ERROR("Unable to read core_argc in"); + + str = dm_config_find_str(sn, "core_argv", NULL); + if ((str && !seg->core_argc) || (!str && seg->core_argc)) + return SEG_LOG_ERROR("core_argc and core_argv do" + " not match in"); + + if (!(seg->core_argv = + dm_pool_alloc(mem, sizeof(char *) * seg->core_argc))) + return_0; + if (str && + (!(argv_str = dm_pool_strdup(mem, str)) || + (seg->core_argc != dm_split_words(argv_str, seg->core_argc, + 0, seg->core_argv)))) + return SEG_LOG_ERROR("core_argc and core_argv do" + " not match in"); + } + + /* + * Read in policy: + * policy_name = "" + * policy_argc = <# args> + * policy_argv = "[ ]..." + * + * 'policy_name' does not have to be present. If it is not present, + * any other policy_* fields are ignored. If it is present, then + * the other policy_* fields must be present - even if they are + * 'policy_argc = 0' and 'policy_argv = ""'. + */ + if (dm_config_has_node(sn, "policy_name")) { + if (!dm_config_has_node(sn, "policy_argc") || + !dm_config_has_node(sn, "policy_argv")) + return SEG_LOG_ERROR("not all policy arguments defined in"); + if (!(str = dm_config_find_str(sn, "policy_name", NULL))) + return SEG_LOG_ERROR("policy_name must be a string in"); + seg->policy_name = dm_pool_strdup(mem, str); + + if (!dm_config_get_int(sn, "policy_argc", &seg->policy_argc)) + return SEG_LOG_ERROR("Unable to read policy_argc in"); + + str = dm_config_find_str(sn, "policy_argv", NULL); + if ((str && !seg->policy_argc) || (!str && seg->policy_argc)) + return SEG_LOG_ERROR("policy_argc and policy_argv do" + " not match in"); + + if (!(seg->policy_argv = + dm_pool_alloc(mem, sizeof(char *) * seg->policy_argc))) + return_0; + if (str && + (!(argv_str = dm_pool_strdup(mem, str)) || + (seg->policy_argc != dm_split_words(argv_str, + seg->policy_argc, + 0, seg->policy_argv)))) + return SEG_LOG_ERROR("policy_argc and policy_argv do" + " not match in"); + } + + if (!attach_pool_data_lv(seg, data_lv)) + return_0; + if (!attach_pool_metadata_lv(seg, meta_lv)) + return_0; + seg->chunk_size = chunk_size; + + return 1; +} + +static int _cache_pool_text_import_area_count(const struct dm_config_node *sn, + uint32_t *area_count) +{ + *area_count = 1; + + return 1; +} + +static int _cache_pool_text_export(const struct lv_segment *seg, + struct formatter *f) +{ + int i; + char buf[256]; //FIXME: IS THERE AN 'outf' THAT DOESN'T DO NEWLINE?!? + uint32_t feature_flags = seg->feature_flags; + + outf(f, "data = \"%s\"", seg_lv(seg, 0)->name); + outf(f, "metadata = \"%s\"", seg->metadata_lv->name); + outf(f, "chunk_size = %" PRIu32, seg->chunk_size); + + if (feature_flags) { + if (feature_flags & DM_CACHE_FEATURE_WRITETHROUGH) { + outf(f, "cache_mode = \"writethrough\""); + feature_flags &= ~DM_CACHE_FEATURE_WRITETHROUGH; + } else if (feature_flags & DM_CACHE_FEATURE_WRITEBACK) { + outf(f, "cache_mode = \"writeback\""); + feature_flags &= ~DM_CACHE_FEATURE_WRITEBACK; + } else { + log_error(INTERNAL_ERROR "Unknown feature flags " + "in cache_pool segment for %s", seg->lv->name); + return 0; + } + } + + if (seg->core_argc) { + outf(f, "core_argc = %d", seg->core_argc); + outf(f, "core_argv = \""); + for (i = 0; i < seg->core_argc; i++) + outf(f, "%s%s", i ? " " : "", seg->core_argv[i]); + outf(f, "\""); + } + + if (seg->policy_name) { + outf(f, "policy_name = \"%s\"", seg->policy_name); + outf(f, "policy_argc = %d", seg->policy_argc); + buf[0] = '\0'; + for (i = 0; i < seg->policy_argc; i++) + sprintf(buf, "%s%s", i ? " " : "", seg->policy_argv[i]); + outf(f, "policy_argv = \"%s\"", buf); + } + + return 1; +} + +static int _cache_pool_add_target_line(struct dev_manager *dm, + struct dm_pool *mem, + struct cmd_context *cmd __attribute__((unused)), + void **target_state __attribute__((unused)), + struct lv_segment *seg, + const struct lv_activate_opts *laopts __attribute__((unused)), + struct dm_tree_node *node, uint64_t len, + uint32_t *pvmove_mirror_count __attribute__((unused))) +{ + /* + * This /could/ be directed at _cdata, but I prefer + * not to give a user direct access to a sub-LV via + * this cache_pool. + */ + return dm_tree_node_add_error_target(node, len); +} + +static int _modules_needed(struct dm_pool *mem, + const struct lv_segment *seg __attribute__((unused)), + struct dm_list *modules) +{ + if (!str_list_add(mem, modules, "cache")) { + log_error("cache module string list allocation failed"); + return 0; + } + + return 1; +} + +static void _destroy(struct segment_type *segtype) +{ + dm_free((void *) segtype); +} + +#ifdef DEVMAPPER_SUPPORT +static int _target_present(struct cmd_context *cmd, + const struct lv_segment *seg __attribute__((unused)), + unsigned *attributes __attribute__((unused))) +{ + static int _cache_checked = 0; + static int _cache_present = 0; + + if (!_cache_checked) + _cache_present = target_present(cmd, "cache", 1); + + _cache_checked = 1; + + return _cache_present; +} + +#endif /* DEVMAPPER_SUPPORT */ + +static struct segtype_handler _cache_pool_ops = { + .name = _name, + .text_import = _cache_pool_text_import, + .text_import_area_count = _cache_pool_text_import_area_count, + .text_export = _cache_pool_text_export, + .add_target_line = _cache_pool_add_target_line, +#ifdef DEVMAPPER_SUPPORT + .target_present = _target_present, +# ifdef DMEVENTD +# endif /* DMEVENTD */ +#endif + .modules_needed = _modules_needed, + .destroy = _destroy, +}; + +#ifdef CACHE_INTERNAL /* Shared */ +int init_cache_segtypes(struct cmd_context *cmd, + struct segtype_library *seglib) +#else +int init_cache_segtypes(struct cmd_context *cmd, + struct segtype_library *seglib); +int init_cache_segtypes(struct cmd_context *cmd, + struct segtype_library *seglib) +#endif +{ + struct segment_type *segtype = dm_zalloc(sizeof(*segtype)); + + if (!segtype) { + log_error("Failed to allocate memory for cache_pool segtype"); + return 0; + } + segtype->cmd = cmd; + + segtype->name = "cache_pool"; + segtype->flags = SEG_CACHE_POOL; + segtype->ops = &_cache_pool_ops; + segtype->private = NULL; + + if (!lvm_register_segtype(seglib, segtype)) + return_0; + log_very_verbose("Initialised segtype: %s", segtype->name); + + return 1; +} + diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c index 9d6ef5e28..a709284bc 100644 --- a/lib/commands/toolcontext.c +++ b/lib/commands/toolcontext.c @@ -1,6 +1,6 @@ - /* +/* * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. - * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved. * * This file is part of LVM2. * @@ -1181,6 +1181,11 @@ static int _init_segtypes(struct cmd_context *cmd) return 0; #endif +#ifdef CACHE_INTERNAL + if (!init_cache_segtypes(cmd, &seglib)) + return 0; +#endif + #ifdef HAVE_LIBDL /* Load any formats in shared libs unless static */ if (!is_static() && diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h index 2f1f9ecd7..bdf5c9d59 100644 --- a/lib/metadata/metadata-exported.h +++ b/lib/metadata/metadata-exported.h @@ -385,6 +385,13 @@ struct lv_segment { struct logical_volume *pool_lv; /* For thin */ uint32_t device_id; /* For thin, 24bit */ + uint32_t feature_flags; /* For cache */ + int core_argc; /* For cache */ + char **core_argv; /* For cache */ + char *policy_name; /* For cache */ + int policy_argc; /* For cache */ + char **policy_argv; /* For cache */ + struct logical_volume *replicator;/* For replicator-devs - link to replicator LV */ struct logical_volume *rlog_lv; /* For replicators */ const char *rlog_type; /* For replicators */ diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h index 2c02d1ba8..75429b405 100644 --- a/lib/metadata/segtype.h +++ b/lib/metadata/segtype.h @@ -41,8 +41,12 @@ struct dev_manager; #define SEG_RAID 0x00000400U #define SEG_THIN_POOL 0x00000800U #define SEG_THIN_VOLUME 0x00001000U +#define SEG_CACHE 0x00002000U +#define SEG_CACHE_POOL 0x00004000U #define SEG_UNKNOWN 0x80000000U +#define segtype_is_cache(segtype) ((segtype)->flags & SEG_CACHE ? 1 : 0) +#define segtype_is_cache_pool(segtype) ((segtype)->flags & SEG_CACHE_POOL ? 1 : 0) #define segtype_is_mirrored(segtype) ((segtype)->flags & SEG_AREAS_MIRRORED ? 1 : 0) #define segtype_is_raid(segtype) ((segtype)->flags & SEG_RAID ? 1 : 0) #define segtype_is_striped(segtype) ((segtype)->flags & SEG_AREAS_STRIPED ? 1 : 0) @@ -51,6 +55,8 @@ struct dev_manager; #define segtype_is_thin_volume(segtype) ((segtype)->flags & SEG_THIN_VOLUME ? 1 : 0) #define segtype_is_virtual(segtype) ((segtype)->flags & SEG_VIRTUAL ? 1 : 0) +#define seg_is_cache(seg) segtype_is_cache((seg)->segtype) +#define seg_is_cache_pool(seg) segtype_is_cache_pool((seg)->segtype) #define seg_is_linear(seg) (seg_is_striped(seg) && ((seg)->area_count == 1)) #define seg_is_mirrored(seg) segtype_is_mirrored((seg)->segtype) #define seg_is_raid(seg) segtype_is_raid((seg)->segtype) @@ -147,6 +153,10 @@ int init_replicator_segtype(struct cmd_context *cmd, struct segtype_library *seg int init_thin_segtypes(struct cmd_context *cmd, struct segtype_library *seglib); #endif +#ifdef CACHE_INTERNAL +int init_cache_segtypes(struct cmd_context *cmd, struct segtype_library *seglib); +#endif + #ifdef SNAPSHOT_INTERNAL struct segment_type *init_snapshot_segtype(struct cmd_context *cmd); #endif diff --git a/lib/misc/configure.h.in b/lib/misc/configure.h.in index 4e9ffd189..0acb9b758 100644 --- a/lib/misc/configure.h.in +++ b/lib/misc/configure.h.in @@ -558,6 +558,9 @@ /* The path to 'thin_repair', if available. */ #undef THIN_REPAIR_CMD +/* Define to 1 to include built-in support for cache[pool] segment types. */ +#undef CACHE_INTERNAL + /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h index 3bf8bd6ca..307450085 100644 --- a/libdm/libdevmapper.h +++ b/libdm/libdevmapper.h @@ -712,6 +712,10 @@ int dm_tree_node_add_raid_target_with_params(struct dm_tree_node *node, uint64_t size, struct dm_tree_node_raid_params *p); +/* Cache feature_flags */ +#define DM_CACHE_FEATURE_WRITEBACK 0x00000001 +#define DM_CACHE_FEATURE_WRITETHROUGH 0x00000002 + /* * Replicator operation mode * Note: API for Replicator is not yet stable